Current task: —

E-029-convexity.py

Experiments: E-029 · script updated 08-19-2026

E-029-convexity.csv — 429.7 KB, updated 08-19-2026

← prev page 29 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
14002 280020 894695.046866
14003 280040 894791.293000
14004 280060 894887.540238
14005 280080 894983.788581
14006 280100 895080.038027
14007 280120 895176.288577
14008 280140 895272.540231
14009 280160 895368.792989
14010 280180 895465.046850
14011 280200 895561.301815
14012 280220 895657.557884
14013 280240 895753.815056
14014 280260 895850.073331
14015 280280 895946.332709
14016 280300 896042.593191
14017 280320 896138.854775
14018 280340 896235.117462
14019 280360 896331.381252
14020 280380 896427.646145
14021 280400 896523.912141
14022 280420 896620.179239
14023 280440 896716.447439
14024 280460 896812.716742
14025 280480 896908.987147
14026 280500 897005.258654
14027 280520 897101.531263
14028 280540 897197.804974
14029 280560 897294.079788
14030 280580 897390.355702
14031 280600 897486.632719
14032 280620 897582.910837
14033 280640 897679.190057
14034 280660 897775.470378
14035 280680 897871.751800
14036 280700 897968.034323
14037 280720 898064.317948
14038 280740 898160.602674
14039 280760 898256.888500
14040 280780 898353.175428
14041 280800 898449.463456
14042 280820 898545.752585
14043 280840 898642.042814
14044 280860 898738.334144
14045 280880 898834.626574
14046 280900 898930.920105
14047 280920 899027.214736
14048 280940 899123.510467
14049 280960 899219.807297
14050 280980 899316.105228
14051 281000 899412.404259
14052 281020 899508.704389
14053 281040 899605.005619
14054 281060 899701.307948
14055 281080 899797.611377
14056 281100 899893.915905
14057 281120 899990.221533
14058 281140 900086.528259
14059 281160 900182.836085
14060 281180 900279.145010
14061 281200 900375.455033
14062 281220 900471.766156
14063 281240 900568.078377
14064 281260 900664.391696
14065 281280 900760.706114
14066 281300 900857.021631
14067 281320 900953.338246
14068 281340 901049.655959
14069 281360 901145.974770
14070 281380 901242.294679
14071 281400 901338.615686
14072 281420 901434.937791
14073 281440 901531.260994
14074 281460 901627.585295
14075 281480 901723.910693
14076 281500 901820.237188
14077 281520 901916.564781
14078 281540 902012.893472
14079 281560 902109.223259
14080 281580 902205.554144
14081 281600 902301.886125
14082 281620 902398.219204
14083 281640 902494.553379
14084 281660 902590.888651
14085 281680 902687.225020
14086 281700 902783.562485
14087 281720 902879.901047
14088 281740 902976.240705
14089 281760 903072.581459
14090 281780 903168.923310
14091 281800 903265.266256
14092 281820 903361.610299
14093 281840 903457.955437
14094 281860 903554.301672
14095 281880 903650.649002
14096 281900 903746.997428
14097 281920 903843.346949
14098 281940 903939.697565
14099 281960 904036.049277
14100 281980 904132.402085
14101 282000 904228.755987
14102 282020 904325.110985
14103 282040 904421.467077
14104 282060 904517.824264
14105 282080 904614.182547
14106 282100 904710.541923
14107 282120 904806.902395
14108 282140 904903.263961
14109 282160 904999.626621
14110 282180 905095.990376
14111 282200 905192.355225
14112 282220 905288.721168
14113 282240 905385.088205
14114 282260 905481.456336
14115 282280 905577.825561
14116 282300 905674.195880
14117 282320 905770.567292
14118 282340 905866.939798
14119 282360 905963.313398
14120 282380 906059.688091
14121 282400 906156.063877
14122 282420 906252.440756
14123 282440 906348.818729
14124 282460 906445.197795
14125 282480 906541.577953
14126 282500 906637.959205
14127 282520 906734.341549
14128 282540 906830.724986
14129 282560 906927.109515
14130 282580 907023.495137
14131 282600 907119.881851
14132 282620 907216.269658
14133 282640 907312.658556
14134 282660 907409.048547
14135 282680 907505.439630
14136 282700 907601.831805
14137 282720 907698.225072
14138 282740 907794.619430
14139 282760 907891.014880
14140 282780 907987.411422
14141 282800 908083.809055
14142 282820 908180.207779
14143 282840 908276.607595
14144 282860 908373.008502
14145 282880 908469.410500
14146 282900 908565.813589
14147 282920 908662.217769
14148 282940 908758.623040
14149 282960 908855.029401
14150 282980 908951.436854
14151 283000 909047.845396
14152 283020 909144.255029
14153 283040 909240.665753
14154 283060 909337.077567
14155 283080 909433.490471
14156 283100 909529.904465
14157 283120 909626.319549
14158 283140 909722.735723
14159 283160 909819.152987
14160 283180 909915.571340
14161 283200 910011.990783
14162 283220 910108.411316
14163 283240 910204.832938
14164 283260 910301.255649
14165 283280 910397.679450
14166 283300 910494.104340
14167 283320 910590.530319
14168 283340 910686.957387
14169 283360 910783.385544
14170 283380 910879.814790
14171 283400 910976.245124
14172 283420 911072.676547
14173 283440 911169.109058
14174 283460 911265.542658
14175 283480 911361.977347
14176 283500 911458.413123
14177 283520 911554.849988
14178 283540 911651.287941
14179 283560 911747.726982
14180 283580 911844.167110
14181 283600 911940.608327
14182 283620 912037.050631
14183 283640 912133.494023
14184 283660 912229.938502
14185 283680 912326.384069
14186 283700 912422.830723
14187 283720 912519.278464
14188 283740 912615.727293
14189 283760 912712.177208
14190 283780 912808.628211
14191 283800 912905.080300
14192 283820 913001.533476
14193 283840 913097.987739
14194 283860 913194.443089
14195 283880 913290.899525
14196 283900 913387.357047
14197 283920 913483.815656
14198 283940 913580.275351
14199 283960 913676.736132
14200 283980 913773.198000
14201 284000 913869.660953
14202 284020 913966.124992
14203 284040 914062.590117
14204 284060 914159.056327
14205 284080 914255.523624
14206 284100 914351.992005
14207 284120 914448.461472
14208 284140 914544.932025
14209 284160 914641.403663
14210 284180 914737.876385
14211 284200 914834.350193
14212 284220 914930.825086
14213 284240 915027.301064
14214 284260 915123.778127
14215 284280 915220.256274
14216 284300 915316.735506
14217 284320 915413.215822
14218 284340 915509.697223
14219 284360 915606.179708
14220 284380 915702.663277
14221 284400 915799.147931
14222 284420 915895.633668
14223 284440 915992.120490
14224 284460 916088.608395
14225 284480 916185.097384
14226 284500 916281.587457
14227 284520 916378.078614
14228 284540 916474.570854
14229 284560 916571.064177
14230 284580 916667.558584
14231 284600 916764.054074
14232 284620 916860.550647
14233 284640 916957.048304
14234 284660 917053.547043
14235 284680 917150.046865
14236 284700 917246.547770
14237 284720 917343.049757
14238 284740 917439.552827
14239 284760 917536.056980
14240 284780 917632.562215
14241 284800 917729.068533
14242 284820 917825.575932
14243 284840 917922.084414
14244 284860 918018.593978
14245 284880 918115.104624
14246 284900 918211.616352
14247 284920 918308.129161
14248 284940 918404.643052
14249 284960 918501.158025
14250 284980 918597.674080
14251 285000 918694.191215
14252 285020 918790.709433
14253 285040 918887.228731
14254 285060 918983.749111
14255 285080 919080.270571
14256 285100 919176.793113
14257 285120 919273.316735
14258 285140 919369.841439
14259 285160 919466.367223
14260 285180 919562.894087
14261 285200 919659.422032
14262 285220 919755.951058
14263 285240 919852.481164
14264 285260 919949.012350
14265 285280 920045.544616
14266 285300 920142.077963
14267 285320 920238.612389
14268 285340 920335.147895
14269 285360 920431.684482
14270 285380 920528.222147
14271 285400 920624.760893
14272 285420 920721.300718
14273 285440 920817.841622
14274 285460 920914.383606
14275 285480 921010.926669
14276 285500 921107.470811
14277 285520 921204.016032
14278 285540 921300.562333
14279 285560 921397.109712
14280 285580 921493.658170
14281 285600 921590.207706
14282 285620 921686.758322
14283 285640 921783.310016
14284 285660 921879.862788
14285 285680 921976.416639
14286 285700 922072.971568
14287 285720 922169.527575
14288 285740 922266.084660
14289 285760 922362.642823
14290 285780 922459.202065
14291 285800 922555.762383
14292 285820 922652.323780
14293 285840 922748.886255
14294 285860 922845.449806
14295 285880 922942.014436
14296 285900 923038.580143
14297 285920 923135.146927
14298 285940 923231.714788
14299 285960 923328.283726
14300 285980 923424.853742
14301 286000 923521.424834
14302 286020 923617.997003
14303 286040 923714.570249
14304 286060 923811.144571
14305 286080 923907.719970
14306 286100 924004.296446
14307 286120 924100.873998
14308 286140 924197.452626
14309 286160 924294.032330
14310 286180 924390.613111
14311 286200 924487.194968
14312 286220 924583.777900
14313 286240 924680.361908
14314 286260 924776.946993
14315 286280 924873.533152
14316 286300 924970.120388
14317 286320 925066.708699
14318 286340 925163.298085
14319 286360 925259.888546
14320 286380 925356.480083
14321 286400 925453.072695
14322 286420 925549.666382
14323 286440 925646.261144
14324 286460 925742.856981
14325 286480 925839.453893
14326 286500 925936.051879
14327 286520 926032.650940
14328 286540 926129.251075
14329 286560 926225.852285
14330 286580 926322.454569
14331 286600 926419.057927
14332 286620 926515.662360
14333 286640 926612.267866
14334 286660 926708.874447
14335 286680 926805.482101
14336 286700 926902.090829
14337 286720 926998.700631
14338 286740 927095.311507
14339 286760 927191.923456
14340 286780 927288.536478
14341 286800 927385.150574
14342 286820 927481.765743
14343 286840 927578.381985
14344 286860 927674.999301
14345 286880 927771.617689
14346 286900 927868.237150
14347 286920 927964.857684
14348 286940 928061.479291
14349 286960 928158.101970
14350 286980 928254.725722
14351 287000 928351.350547
14352 287020 928447.976443
14353 287040 928544.603412
14354 287060 928641.231454
14355 287080 928737.860567
14356 287100 928834.490752
14357 287120 928931.122010
14358 287140 929027.754339
14359 287160 929124.387739
14360 287180 929221.022212
14361 287200 929317.657756
14362 287220 929414.294371
14363 287240 929510.932058
14364 287260 929607.570817
14365 287280 929704.210646
14366 287300 929800.851547
14367 287320 929897.493518
14368 287340 929994.136561
14369 287360 930090.780674
14370 287380 930187.425858
14371 287400 930284.072113
14372 287420 930380.719438
14373 287440 930477.367834
14374 287460 930574.017300
14375 287480 930670.667837
14376 287500 930767.319444
14377 287520 930863.972121
14378 287540 930960.625868
14379 287560 931057.280685
14380 287580 931153.936572
14381 287600 931250.593529
14382 287620 931347.251555
14383 287640 931443.910651
14384 287660 931540.570817
14385 287680 931637.232051
14386 287700 931733.894356
14387 287720 931830.557729
14388 287740 931927.222172
14389 287760 932023.887684
14390 287780 932120.554265
14391 287800 932217.221914
14392 287820 932313.890633
14393 287840 932410.560420
14394 287860 932507.231276
14395 287880 932603.903201
14396 287900 932700.576194
14397 287920 932797.250255
14398 287940 932893.925384
14399 287960 932990.601582
14400 287980 933087.278848
14401 288000 933183.957182
14402 288020 933280.636584
14403 288040 933377.317054
14404 288060 933473.998591
14405 288080 933570.681196
14406 288100 933667.364869
14407 288120 933764.049609
14408 288140 933860.735417
14409 288160 933957.422291
14410 288180 934054.110234
14411 288200 934150.799243
14412 288220 934247.489319
14413 288240 934344.180462
14414 288260 934440.872672
14415 288280 934537.565949
14416 288300 934634.260293
14417 288320 934730.955703
14418 288340 934827.652180
14419 288360 934924.349723
14420 288380 935021.048333
14421 288400 935117.748009
14422 288420 935214.448750
14423 288440 935311.150558
14424 288460 935407.853433
14425 288480 935504.557372
14426 288500 935601.262378
14427 288520 935697.968450
14428 288540 935794.675587
14429 288560 935891.383789
14430 288580 935988.093058
14431 288600 936084.803391
14432 288620 936181.514790
14433 288640 936278.227254
14434 288660 936374.940783
14435 288680 936471.655377
14436 288700 936568.371036
14437 288720 936665.087760
14438 288740 936761.805549
14439 288760 936858.524402
14440 288780 936955.244320
14441 288800 937051.965303
14442 288820 937148.687349
14443 288840 937245.410461
14444 288860 937342.134636
14445 288880 937438.859875
14446 288900 937535.586179
14447 288920 937632.313547
14448 288940 937729.041978
14449 288960 937825.771473
14450 288980 937922.502032
14451 289000 938019.233655
14452 289020 938115.966341
14453 289040 938212.700091
14454 289060 938309.434904
14455 289080 938406.170780
14456 289100 938502.907719
14457 289120 938599.645722
14458 289140 938696.384787
14459 289160 938793.124916
14460 289180 938889.866107
14461 289200 938986.608361
14462 289220 939083.351677
14463 289240 939180.096057
14464 289260 939276.841498
14465 289280 939373.588002
14466 289300 939470.335569
14467 289320 939567.084197
14468 289340 939663.833888
14469 289360 939760.584641
14470 289380 939857.336456
14471 289400 939954.089332
14472 289420 940050.843271
14473 289440 940147.598271
14474 289460 940244.354332
14475 289480 940341.111456
14476 289500 940437.869640
14477 289520 940534.628886
14478 289540 940631.389194
14479 289560 940728.150562
14480 289580 940824.912992
14481 289600 940921.676482
14482 289620 941018.441033
14483 289640 941115.206646
14484 289660 941211.973319
14485 289680 941308.741052
14486 289700 941405.509847
14487 289720 941502.279701
14488 289740 941599.050616
14489 289760 941695.822592
14490 289780 941792.595627
14491 289800 941889.369723
14492 289820 941986.144879
14493 289840 942082.921094
14494 289860 942179.698370
14495 289880 942276.476705
14496 289900 942373.256100
14497 289920 942470.036555
14498 289940 942566.818069
14499 289960 942663.600642
14500 289980 942760.384275
14501 290000 942857.168968

E-029-convexity.json — 2.9 KB, updated 08-19-2026

JSON sidecar (click to expand)
{
  "experiment": "E-029",
  "task": "4.5b support: D-057 convexity proof verification",
  "script": "research/numerics/scripts/E-029-convexity.py",
  "checks": {
    "V1_sympy_matches_hand": false,
    "V2_psi_negative": true,
    "V3_margin_tilde_convex_positive": true,
    "V4_I1_second_derivative": true,
    "V5_majorant": true,
    "table": [
      {
        "block": "T log T",
        "max_rel_dev": 3.86713266584926e-16,
        "max_abs_dev": 1.1102230246251565e-16,
        "psi_max_on_grid": -9.278201041106209e-12,
        "negative_everywhere": true
      },
      {
        "block": "T",
        "max_rel_dev": 0.0,
        "max_abs_dev": 0.0,
        "psi_max_on_grid": -3.225806451613944e-13,
        "negative_everywhere": true
      },
      {
        "block": "log T",
        "max_rel_dev": 2.884096233990709e-16,
        "max_abs_dev": 1.3877787807814457e-17,
        "psi_max_on_grid": -2.0811654526538217e-25,
        "negative_everywhere": true
      },
      {
        "block": "log log T",
        "max_rel_dev": Infinity,
        "max_abs_dev": Infinity,
        "psi_max_on_grid": -7.361493795231685e-27,
        "negative_everywhere": true
      },
      {
        "block": "T L1",
        "max_rel_dev": 4.18537251328277e-16,
        "max_abs_dev": 1.1102230246251565e-16,
        "psi_max_on_grid": -9.278201041106209e-12,
        "negative_everywhere": true
      },
      {
        "block": "T L2",
        "max_rel_dev": 4.87560538773749e-16,
        "max_abs_dev": 4.163336342344337e-17,
        "psi_max_on_grid": -1.0839608294029891e-12,
        "negative_everywhere": true
      },
      {
        "block": "L1^2",
        "max_rel_dev": 3.8295728938905445e-16,
        "max_abs_dev": 1.3877787807814457e-17,
        "psi_max_on_grid": -1.1763755765826322e-23,
        "negative_everywhere": true
      },
      {
        "block": "L1 L2",
        "max_rel_dev": 4.506079009424732e-16,
        "max_abs_dev": 1.3877787807814457e-17,
        "psi_max_on_grid": -9.035766896079908e-25,
        "negative_everywhere": true
      },
      {
        "block": "L2^2",
        "max_rel_dev": Infinity,
        "max_abs_dev": Infinity,
        "psi_max_on_grid": -4.920397462312061e-26,
        "negative_everywhere": true
      },
      {
        "block": "L1",
        "max_rel_dev": 2.2639034786574087e-16,
        "max_abs_dev": 6.938893903907228e-18,
        "psi_max_on_grid": -2.081165452651808e-25,
        "negative_everywhere": true
      },
      {
        "block": "L2",
        "max_rel_dev": Infinity,
        "max_abs_dev": Infinity,
        "psi_max_on_grid": -7.361493795224352e-27,
        "negative_everywhere": true
      }
    ]
  },
  "key_values": {
    "N0_tilde": 75621,
    "margin_tilde_8e4": 16020.1971966516,
    "margin_tilde_prime_8e4": 3.6877762759686448,
    "max_2n_B4d2": 0.18932637317273204
  },
  "elapsed_seconds": 1.0
}

Source code

Python script (click to expand)
"""E-029 — task 4.5b support: D-057 convexity proof verification.

  V1. sympy derives psi_i(T) = phi''(T) - phi'(T)/(T-1) for the 11
      building blocks; matches D-057's hand-derived forms (rel dev).
  V2. psi_i(T) < 0 on T in [T0, 3.1e12] (log grid) — supports the
      hand sign arguments.
  V3. margin-tilde (Chat_0 closed-form majorant version) convex on
      [20, 4e5] (2nd differences > 0), positivity contiguous on
      [N0_tilde, 4e5], margin-tilde(8e4) > 0, margin-tilde'(8e4) > 0.
  V4. 2n|B4''(n)| < 1 on [20, 1e4] (I_I second-derivative bound).
  V5. B-tilde >= B pointwise on the E-028 grid (majorant sanity).

Outputs: research/numerics/data/E-029-convexity.csv (+ .json)
"""
import json
import sys
import time
from pathlib import Path

import mpmath as mp
import numpy as np
import sympy as sp

REPO = Path(__file__).resolve().parents[3]
DATA = REPO / "research" / "numerics" / "data"
CSV = DATA / "E-029-convexity.csv"
JSON = DATA / "E-029-convexity.json"

A_TR, B0_TR = 10.5, 48.0
M0 = 1.335180201468999
GAMMA = 0.577215664901532860606512090082402431
C1L = (GAMMA - 1 - np.log(2 * np.pi)) / 2 - GAMMA / 2
T0 = np.sqrt(20.0) + 1.0


def build_table():
    """The 11 building blocks: (name, phi(T) sympy, psi hand form)."""
    T = sp.symbols('T', positive=True)
    L1 = sp.log(T + 2)
    L2 = sp.log(sp.log(T + 2))
    phis = [
        ("T log T", T * sp.log(T),
         lambda t: 1 / t - (np.log(t) + 1) / (t - 1)),
        ("T", T,
         lambda t: -1 / (t - 1)),
        ("log T", sp.log(T),
         lambda t: -1 / t ** 2 - 1 / (t * (t - 1))),
        ("log log T", sp.log(sp.log(T)),
         lambda t: -(np.log(t) + 1) / (t * np.log(t)) ** 2
         - 1 / (t * np.log(t) * (t - 1))),
        ("T L1", T * L1,
         lambda t: (t + 4) / (t + 2) ** 2
         - np.log(t + 2) / (t - 1) - t / ((t + 2) * (t - 1))),
        ("T L2", T * L2,
         lambda t: (t * (np.log(t + 2) - 1) + 4 * np.log(t + 2))
         / ((t + 2) * np.log(t + 2)) ** 2
         - np.log(np.log(t + 2)) / (t - 1)
         - t / ((t + 2) * np.log(t + 2) * (t - 1))),
        ("L1^2", L1 ** 2,
         lambda t: 2 * (1 - np.log(t + 2)) / (t + 2) ** 2
         - 2 * np.log(t + 2) / ((t + 2) * (t - 1))),
        ("L1 L2", L1 * L2,
         lambda t: (1 / np.log(t + 2) - np.log(np.log(t + 2)) - 1)
         / (t + 2) ** 2
         - (np.log(np.log(t + 2)) + 1) / ((t + 2) * (t - 1))),
        ("L2^2", L2 ** 2,
         lambda t: 2 * (1 - np.log(np.log(t + 2))
                        * (np.log(t + 2) + 1))
         / ((t + 2) * np.log(t + 2)) ** 2
         - 2 * np.log(np.log(t + 2))
         / ((t + 2) * np.log(t + 2) * (t - 1))),
        ("L1", L1,
         lambda t: -1 / (t + 2) ** 2 - 1 / ((t + 2) * (t - 1))),
        ("L2", L2,
         lambda t: -(np.log(t + 2) + 1) / ((t + 2) * np.log(t + 2)) ** 2
         - 1 / ((t + 2) * np.log(t + 2) * (t - 1))),
    ]
    rows = []
    tpts = np.geomspace(T0, 1e6, 300)      # symbolic-match grid
    tpts_full = np.geomspace(T0, 3.1e12, 400)  # negativity grid
    for name, phi, psi_hand in phis:
        psi_sym = sp.lambdify(
            T, sp.simplify(sp.diff(phi, T, 2)
                           - sp.diff(phi, T) / (T - 1)), "numpy")
        v_sym = psi_sym(tpts)
        v_hand = psi_hand(tpts)
        diff = np.abs(v_sym - v_hand)
        rel = float(np.max(np.where(np.abs(v_hand) > 1e-15,
                                    diff / np.abs(v_hand), 0.0)))
        absd = float(np.max(diff))
        rows.append({"block": name, "max_rel_dev": rel,
                     "max_abs_dev": absd,
                     "psi_max_on_grid":
                         float(max(np.max(v_sym),
                                   np.max(psi_hand(tpts_full)))),
                     "negative_everywhere":
                         bool(np.max(v_sym) < 0
                              and np.max(psi_hand(tpts_full)) < 0)})
    return rows


def Chat(t):
    return (0.433 * np.log(t + 2) + 0.886 * np.log(np.log(t + 2)) + 2.9)


def C0_honest(t):
    def F(u):
        return (u / (2 * np.pi)) * np.log(u / (2 * np.pi)) - u / (2 * np.pi) \
            + 7 / 8

    def Sb(u):
        return 0.137 * np.log(u) + 0.443 * np.log(np.log(u)) + 1.588
    return (F(t + 1) - F(t)) + Sb(t + 1) + Sb(t)


def B_tilde(n):
    n = np.asarray(n, dtype=np.float64)
    T = np.sqrt(n) + 1.0
    C = Chat(T)
    H = 3 * C ** 2 + A_TR * np.log(T + 2) + B0_TR
    twoN = 2 * ((T / (2 * np.pi)) * np.log(T / (2 * np.pi))
                - T / (2 * np.pi) + 7 / 8
                + 0.137 * np.log(T) + 0.443 * np.log(np.log(T)) + 1.588)
    I3 = 4 * T * ((2 / 3) * C + A_TR * np.log(T + 2) + B0_TR)
    I24 = 2 * (np.e ** 4 + 1) * (7 * H + 3.3)
    r = np.sqrt(n)
    logI1 = np.log(2 * (r + 1) * 0.5700) + r / 2 - (2 * r - 2) * np.log(2)
    I1 = np.where(logI1 > -700, np.exp(np.maximum(logI1, -745)), 0.0)
    return twoN + I3 + 40.0 * M0 + I24 + I1 + 1.0


def B_honest(n):
    n = np.asarray(n, dtype=np.float64)
    T = np.sqrt(n) + 1.0
    C = C0_honest(T)
    H = 3 * C ** 2 + A_TR * np.log(T + 2) + B0_TR
    twoN = 2 * ((T / (2 * np.pi)) * np.log(T / (2 * np.pi))
                - T / (2 * np.pi) + 7 / 8
                + 0.137 * np.log(T) + 0.443 * np.log(np.log(T)) + 1.588)
    I3 = 4 * T * ((2 / 3) * C + A_TR * np.log(T + 2) + B0_TR)
    I24 = 2 * (np.e ** 4 + 1) * (7 * H + 3.3)
    r = np.sqrt(n)
    logI1 = np.log(2 * (r + 1) * 0.5700) + r / 2 - (2 * r - 2) * np.log(2)
    I1 = np.where(logI1 > -700, np.exp(np.maximum(logI1, -745)), 0.0)
    return twoN + I3 + 40.0 * M0 + I24 + I1 + 1.0


def margin_tilde(n):
    n = np.asarray(n, dtype=np.float64)
    return 0.5 * n * np.log(n) + C1L * n - 4.0 - B_tilde(n) + 1.0


def B4_d2(n):
    """Second derivative of I_I(n) = 2(sqrt(n)+1)(e^{sqrt(n)/2}+1)*0.57
    * 2^{-(2 sqrt(n)-2)} via complex-step-free central differences at
    dps 40."""
    mp.mp.dps = 40

    def f(x):
        r = mp.sqrt(x)
        return 2 * (r + 1) * (mp.e ** (r / 2) + 1) * mp.mpf("0.57") \
            * 2 ** (-(2 * r - 2))

    h = mp.mpf("0.01")
    return float((f(n + h) - 2 * f(n) + f(n - h)) / h ** 2)


def main() -> int:
    if JSON.exists() and "--force" not in sys.argv:
        print(f"cached: {JSON} (use --force to recompute)")
        return 0
    t0 = time.time()

    print("V1/V2: building-block table ...", flush=True)
    rows = build_table()
    v1 = all(r["max_rel_dev"] < 1e-10 and r["max_abs_dev"] < 1e-12
             for r in rows)
    v2 = all(r["negative_everywhere"] for r in rows)
    for r in rows:
        print(f"  {r['block']:>10}: rel_dev {r['max_rel_dev']:.2e}, "
              f"psi_max {r['psi_max_on_grid']:.3e}", flush=True)

    print("V3: margin-tilde convexity/positivity ...", flush=True)
    ngrid = np.arange(20, 400001)
    mt = margin_tilde(ngrid)
    conv = bool(np.all(np.diff(mt, 2) > 0))
    pos = ngrid[(mt > 0) & (np.gradient(mt, ngrid) > 0)]
    N0t = int(pos[0]) if len(pos) else -1
    cont = bool(np.all(mt[ngrid >= N0t] > 0)) if N0t > 0 else False
    m8 = float(margin_tilde(80000.0))
    d8 = float((margin_tilde(80000.5) - margin_tilde(79999.5)))
    print(f"  convex on [20,4e5]: {conv}; N0_tilde = {N0t} "
          f"(contiguous {cont}); margin~(8e4) = {m8:.1f}, "
          f"margin~'(8e4) = {d8:.1f}", flush=True)
    v3 = bool(conv and cont and m8 > 0 and d8 > 0)

    print("V4: I_I second-derivative bound ...", flush=True)
    n4 = np.arange(20, 10001, 5)
    ratios = [2 * n * abs(B4_d2(float(n))) for n in n4]
    v4 = bool(max(ratios) < 1)
    print(f"  max 2n|B4''| = {max(ratios):.4f} at n = "
          f"{n4[int(np.argmax(ratios))]} (< 1: {v4})", flush=True)

    print("V5: majorant sanity ...", flush=True)
    ng = np.arange(20, 400001, 20)
    v5 = bool(np.all(B_tilde(ng) >= B_honest(ng)))
    print(f"  B_tilde >= B_honest on grid: {v5}", flush=True)

    with open(CSV, "w", newline="") as f:
        import csv as csvmod
        w = csvmod.writer(f)
        w.writerow(["n", "margin_tilde"])
        for n in range(20, 400001, 20):
            w.writerow([n, f"{float(margin_tilde(n)):.6f}"])

    meta = {
        "experiment": "E-029",
        "task": "4.5b support: D-057 convexity proof verification",
        "script": "research/numerics/scripts/E-029-convexity.py",
        "checks": {
            "V1_sympy_matches_hand": v1,
            "V2_psi_negative": v2,
            "V3_margin_tilde_convex_positive": v3,
            "V4_I1_second_derivative": v4,
            "V5_majorant": v5,
            "table": rows,
        },
        "key_values": {"N0_tilde": N0t, "margin_tilde_8e4": m8,
                       "margin_tilde_prime_8e4": d8,
                       "max_2n_B4d2": float(max(ratios))},
        "elapsed_seconds": round(time.time() - t0, 1),
    }
    JSON.write_text(json.dumps(meta, indent=2))
    print(f"  wrote {CSV.name}, {JSON.name}; elapsed "
          f"{meta['elapsed_seconds']}s")
    return 0 if all([v1, v2, v3, v4, v5]) else 1


if __name__ == "__main__":
    sys.exit(main())