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 31 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
15002 300020 991477.703412
15003 300040 991575.009148
15004 300060 991672.315901
15005 300080 991769.623671
15006 300100 991866.932459
15007 300120 991964.242263
15008 300140 992061.553084
15009 300160 992158.864922
15010 300180 992256.177777
15011 300200 992353.491648
15012 300220 992450.806536
15013 300240 992548.122440
15014 300260 992645.439360
15015 300280 992742.757297
15016 300300 992840.076250
15017 300320 992937.396219
15018 300340 993034.717204
15019 300360 993132.039205
15020 300380 993229.362222
15021 300400 993326.686255
15022 300420 993424.011303
15023 300440 993521.337367
15024 300460 993618.664447
15025 300480 993715.992542
15026 300500 993813.321652
15027 300520 993910.651778
15028 300540 994007.982919
15029 300560 994105.315075
15030 300580 994202.648247
15031 300600 994299.982433
15032 300620 994397.317634
15033 300640 994494.653850
15034 300660 994591.991080
15035 300680 994689.329326
15036 300700 994786.668586
15037 300720 994884.008860
15038 300740 994981.350149
15039 300760 995078.692452
15040 300780 995176.035770
15041 300800 995273.380102
15042 300820 995370.725447
15043 300840 995468.071807
15044 300860 995565.419181
15045 300880 995662.767569
15046 300900 995760.116970
15047 300920 995857.467385
15048 300940 995954.818814
15049 300960 996052.171256
15050 300980 996149.524712
15051 301000 996246.879181
15052 301020 996344.234663
15053 301040 996441.591159
15054 301060 996538.948668
15055 301080 996636.307190
15056 301100 996733.666725
15057 301120 996831.027273
15058 301140 996928.388833
15059 301160 997025.751407
15060 301180 997123.114993
15061 301200 997220.479591
15062 301220 997317.845202
15063 301240 997415.211826
15064 301260 997512.579462
15065 301280 997609.948110
15066 301300 997707.317770
15067 301320 997804.688443
15068 301340 997902.060127
15069 301360 997999.432824
15070 301380 998096.806532
15071 301400 998194.181252
15072 301420 998291.556984
15073 301440 998388.933728
15074 301460 998486.311483
15075 301480 998583.690249
15076 301500 998681.070027
15077 301520 998778.450816
15078 301540 998875.832617
15079 301560 998973.215428
15080 301580 999070.599251
15081 301600 999167.984084
15082 301620 999265.369929
15083 301640 999362.756784
15084 301660 999460.144650
15085 301680 999557.533527
15086 301700 999654.923415
15087 301720 999752.314313
15088 301740 999849.706221
15089 301760 999947.099140
15090 301780 1000044.493069
15091 301800 1000141.888008
15092 301820 1000239.283957
15093 301840 1000336.680917
15094 301860 1000434.078886
15095 301880 1000531.477865
15096 301900 1000628.877854
15097 301920 1000726.278853
15098 301940 1000823.680861
15099 301960 1000921.083879
15100 301980 1001018.487906
15101 302000 1001115.892943
15102 302020 1001213.298989
15103 302040 1001310.706045
15104 302060 1001408.114109
15105 302080 1001505.523183
15106 302100 1001602.933266
15107 302120 1001700.344357
15108 302140 1001797.756458
15109 302160 1001895.169567
15110 302180 1001992.583685
15111 302200 1002089.998811
15112 302220 1002187.414946
15113 302240 1002284.832090
15114 302260 1002382.250241
15115 302280 1002479.669401
15116 302300 1002577.089570
15117 302320 1002674.510746
15118 302340 1002771.932931
15119 302360 1002869.356123
15120 302380 1002966.780324
15121 302400 1003064.205532
15122 302420 1003161.631748
15123 302440 1003259.058972
15124 302460 1003356.487203
15125 302480 1003453.916442
15126 302500 1003551.346688
15127 302520 1003648.777941
15128 302540 1003746.210202
15129 302560 1003843.643470
15130 302580 1003941.077745
15131 302600 1004038.513027
15132 302620 1004135.949316
15133 302640 1004233.386612
15134 302660 1004330.824914
15135 302680 1004428.264224
15136 302700 1004525.704540
15137 302720 1004623.145862
15138 302740 1004720.588192
15139 302760 1004818.031527
15140 302780 1004915.475869
15141 302800 1005012.921217
15142 302820 1005110.367571
15143 302840 1005207.814931
15144 302860 1005305.263297
15145 302880 1005402.712670
15146 302900 1005500.163048
15147 302920 1005597.614431
15148 302940 1005695.066821
15149 302960 1005792.520216
15150 302980 1005889.974616
15151 303000 1005987.430023
15152 303020 1006084.886434
15153 303040 1006182.343851
15154 303060 1006279.802273
15155 303080 1006377.261700
15156 303100 1006474.722132
15157 303120 1006572.183569
15158 303140 1006669.646011
15159 303160 1006767.109458
15160 303180 1006864.573909
15161 303200 1006962.039365
15162 303220 1007059.505826
15163 303240 1007156.973292
15164 303260 1007254.441761
15165 303280 1007351.911235
15166 303300 1007449.381714
15167 303320 1007546.853196
15168 303340 1007644.325683
15169 303360 1007741.799174
15170 303380 1007839.273668
15171 303400 1007936.749167
15172 303420 1008034.225669
15173 303440 1008131.703175
15174 303460 1008229.181685
15175 303480 1008326.661198
15176 303500 1008424.141715
15177 303520 1008521.623235
15178 303540 1008619.105758
15179 303560 1008716.589285
15180 303580 1008814.073815
15181 303600 1008911.559348
15182 303620 1009009.045884
15183 303640 1009106.533423
15184 303660 1009204.021965
15185 303680 1009301.511509
15186 303700 1009399.002057
15187 303720 1009496.493606
15188 303740 1009593.986159
15189 303760 1009691.479714
15190 303780 1009788.974271
15191 303800 1009886.469831
15192 303820 1009983.966392
15193 303840 1010081.463956
15194 303860 1010178.962522
15195 303880 1010276.462090
15196 303900 1010373.962660
15197 303920 1010471.464232
15198 303940 1010568.966806
15199 303960 1010666.470381
15200 303980 1010763.974958
15201 304000 1010861.480536
15202 304020 1010958.987116
15203 304040 1011056.494697
15204 304060 1011154.003280
15205 304080 1011251.512863
15206 304100 1011349.023448
15207 304120 1011446.535034
15208 304140 1011544.047621
15209 304160 1011641.561209
15210 304180 1011739.075797
15211 304200 1011836.591387
15212 304220 1011934.107977
15213 304240 1012031.625567
15214 304260 1012129.144158
15215 304280 1012226.663750
15216 304300 1012324.184342
15217 304320 1012421.705934
15218 304340 1012519.228526
15219 304360 1012616.752119
15220 304380 1012714.276711
15221 304400 1012811.802304
15222 304420 1012909.328896
15223 304440 1013006.856488
15224 304460 1013104.385080
15225 304480 1013201.914671
15226 304500 1013299.445263
15227 304520 1013396.976853
15228 304540 1013494.509443
15229 304560 1013592.043033
15230 304580 1013689.577621
15231 304600 1013787.113209
15232 304620 1013884.649796
15233 304640 1013982.187382
15234 304660 1014079.725967
15235 304680 1014177.265551
15236 304700 1014274.806133
15237 304720 1014372.347715
15238 304740 1014469.890295
15239 304760 1014567.433873
15240 304780 1014664.978450
15241 304800 1014762.524025
15242 304820 1014860.070599
15243 304840 1014957.618171
15244 304860 1015055.166741
15245 304880 1015152.716310
15246 304900 1015250.266876
15247 304920 1015347.818440
15248 304940 1015445.371002
15249 304960 1015542.924562
15250 304980 1015640.479120
15251 305000 1015738.034675
15252 305020 1015835.591228
15253 305040 1015933.148778
15254 305060 1016030.707325
15255 305080 1016128.266870
15256 305100 1016225.827412
15257 305120 1016323.388952
15258 305140 1016420.951488
15259 305160 1016518.515022
15260 305180 1016616.079552
15261 305200 1016713.645079
15262 305220 1016811.211603
15263 305240 1016908.779124
15264 305260 1017006.347641
15265 305280 1017103.917155
15266 305300 1017201.487666
15267 305320 1017299.059172
15268 305340 1017396.631675
15269 305360 1017494.205175
15270 305380 1017591.779670
15271 305400 1017689.355162
15272 305420 1017786.931649
15273 305440 1017884.509133
15274 305460 1017982.087612
15275 305480 1018079.667087
15276 305500 1018177.247558
15277 305520 1018274.829024
15278 305540 1018372.411486
15279 305560 1018469.994943
15280 305580 1018567.579396
15281 305600 1018665.164844
15282 305620 1018762.751288
15283 305640 1018860.338726
15284 305660 1018957.927160
15285 305680 1019055.516588
15286 305700 1019153.107012
15287 305720 1019250.698430
15288 305740 1019348.290843
15289 305760 1019445.884251
15290 305780 1019543.478653
15291 305800 1019641.074050
15292 305820 1019738.670441
15293 305840 1019836.267827
15294 305860 1019933.866207
15295 305880 1020031.465581
15296 305900 1020129.065950
15297 305920 1020226.667312
15298 305940 1020324.269669
15299 305960 1020421.873019
15300 305980 1020519.477363
15301 306000 1020617.082701
15302 306020 1020714.689033
15303 306040 1020812.296358
15304 306060 1020909.904677
15305 306080 1021007.513989
15306 306100 1021105.124295
15307 306120 1021202.735594
15308 306140 1021300.347886
15309 306160 1021397.961172
15310 306180 1021495.575450
15311 306200 1021593.190721
15312 306220 1021690.806986
15313 306240 1021788.424243
15314 306260 1021886.042493
15315 306280 1021983.661735
15316 306300 1022081.281971
15317 306320 1022178.903198
15318 306340 1022276.525418
15319 306360 1022374.148631
15320 306380 1022471.772836
15321 306400 1022569.398033
15322 306420 1022667.024222
15323 306440 1022764.651404
15324 306460 1022862.279577
15325 306480 1022959.908742
15326 306500 1023057.538899
15327 306520 1023155.170048
15328 306540 1023252.802189
15329 306560 1023350.435321
15330 306580 1023448.069444
15331 306600 1023545.704560
15332 306620 1023643.340666
15333 306640 1023740.977764
15334 306660 1023838.615853
15335 306680 1023936.254933
15336 306700 1024033.895004
15337 306720 1024131.536067
15338 306740 1024229.178120
15339 306760 1024326.821164
15340 306780 1024424.465199
15341 306800 1024522.110224
15342 306820 1024619.756240
15343 306840 1024717.403247
15344 306860 1024815.051244
15345 306880 1024912.700232
15346 306900 1025010.350209
15347 306920 1025108.001177
15348 306940 1025205.653136
15349 306960 1025303.306084
15350 306980 1025400.960022
15351 307000 1025498.614950
15352 307020 1025596.270868
15353 307040 1025693.927776
15354 307060 1025791.585674
15355 307080 1025889.244561
15356 307100 1025986.904438
15357 307120 1026084.565304
15358 307140 1026182.227159
15359 307160 1026279.890004
15360 307180 1026377.553838
15361 307200 1026475.218661
15362 307220 1026572.884474
15363 307240 1026670.551275
15364 307260 1026768.219065
15365 307280 1026865.887844
15366 307300 1026963.557612
15367 307320 1027061.228369
15368 307340 1027158.900114
15369 307360 1027256.572848
15370 307380 1027354.246570
15371 307400 1027451.921281
15372 307420 1027549.596980
15373 307440 1027647.273667
15374 307460 1027744.951342
15375 307480 1027842.630006
15376 307500 1027940.309657
15377 307520 1028037.990297
15378 307540 1028135.671924
15379 307560 1028233.354539
15380 307580 1028331.038142
15381 307600 1028428.722732
15382 307620 1028526.408310
15383 307640 1028624.094876
15384 307660 1028721.782429
15385 307680 1028819.470969
15386 307700 1028917.160497
15387 307720 1029014.851011
15388 307740 1029112.542513
15389 307760 1029210.235002
15390 307780 1029307.928477
15391 307800 1029405.622940
15392 307820 1029503.318390
15393 307840 1029601.014826
15394 307860 1029698.712248
15395 307880 1029796.410658
15396 307900 1029894.110054
15397 307920 1029991.810436
15398 307940 1030089.511805
15399 307960 1030187.214159
15400 307980 1030284.917500
15401 308000 1030382.621828
15402 308020 1030480.327141
15403 308040 1030578.033440
15404 308060 1030675.740725
15405 308080 1030773.448996
15406 308100 1030871.158253
15407 308120 1030968.868495
15408 308140 1031066.579723
15409 308160 1031164.291936
15410 308180 1031262.005135
15411 308200 1031359.719319
15412 308220 1031457.434489
15413 308240 1031555.150643
15414 308260 1031652.867783
15415 308280 1031750.585908
15416 308300 1031848.305018
15417 308320 1031946.025112
15418 308340 1032043.746192
15419 308360 1032141.468256
15420 308380 1032239.191305
15421 308400 1032336.915339
15422 308420 1032434.640357
15423 308440 1032532.366359
15424 308460 1032630.093346
15425 308480 1032727.821317
15426 308500 1032825.550273
15427 308520 1032923.280212
15428 308540 1033021.011136
15429 308560 1033118.743044
15430 308580 1033216.475935
15431 308600 1033314.209811
15432 308620 1033411.944670
15433 308640 1033509.680513
15434 308660 1033607.417339
15435 308680 1033705.155149
15436 308700 1033802.893942
15437 308720 1033900.633719
15438 308740 1033998.374480
15439 308760 1034096.116223
15440 308780 1034193.858949
15441 308800 1034291.602659
15442 308820 1034389.347352
15443 308840 1034487.093027
15444 308860 1034584.839686
15445 308880 1034682.587327
15446 308900 1034780.335951
15447 308920 1034878.085558
15448 308940 1034975.836147
15449 308960 1035073.587718
15450 308980 1035171.340272
15451 309000 1035269.093809
15452 309020 1035366.848327
15453 309040 1035464.603828
15454 309060 1035562.360311
15455 309080 1035660.117776
15456 309100 1035757.876223
15457 309120 1035855.635652
15458 309140 1035953.396062
15459 309160 1036051.157455
15460 309180 1036148.919829
15461 309200 1036246.683184
15462 309220 1036344.447521
15463 309240 1036442.212840
15464 309260 1036539.979140
15465 309280 1036637.746421
15466 309300 1036735.514683
15467 309320 1036833.283927
15468 309340 1036931.054151
15469 309360 1037028.825357
15470 309380 1037126.597543
15471 309400 1037224.370710
15472 309420 1037322.144858
15473 309440 1037419.919987
15474 309460 1037517.696096
15475 309480 1037615.473186
15476 309500 1037713.251256
15477 309520 1037811.030307
15478 309540 1037908.810338
15479 309560 1038006.591349
15480 309580 1038104.373340
15481 309600 1038202.156311
15482 309620 1038299.940263
15483 309640 1038397.725194
15484 309660 1038495.511105
15485 309680 1038593.297996
15486 309700 1038691.085867
15487 309720 1038788.874717
15488 309740 1038886.664547
15489 309760 1038984.455356
15490 309780 1039082.247145
15491 309800 1039180.039913
15492 309820 1039277.833660
15493 309840 1039375.628386
15494 309860 1039473.424092
15495 309880 1039571.220776
15496 309900 1039669.018440
15497 309920 1039766.817082
15498 309940 1039864.616703
15499 309960 1039962.417303
15500 309980 1040060.218882
15501 310000 1040158.021439

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())