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 19 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
9002 180020 429754.979942
9003 180040 429844.075200
9004 180060 429933.172344
9005 180080 430022.271374
9006 180100 430111.372290
9007 180120 430200.475093
9008 180140 430289.579780
9009 180160 430378.686353
9010 180180 430467.794811
9011 180200 430556.905153
9012 180220 430646.017380
9013 180240 430735.131491
9014 180260 430824.247487
9015 180280 430913.365365
9016 180300 431002.485128
9017 180320 431091.606773
9018 180340 431180.730302
9019 180360 431269.855713
9020 180380 431358.983006
9021 180400 431448.112182
9022 180420 431537.243239
9023 180440 431626.376178
9024 180460 431715.510999
9025 180480 431804.647700
9026 180500 431893.786283
9027 180520 431982.926746
9028 180540 432072.069089
9029 180560 432161.213313
9030 180580 432250.359416
9031 180600 432339.507399
9032 180620 432428.657261
9033 180640 432517.809002
9034 180660 432606.962623
9035 180680 432696.118121
9036 180700 432785.275498
9037 180720 432874.434753
9038 180740 432963.595886
9039 180760 433052.758896
9040 180780 433141.923784
9041 180800 433231.090549
9042 180820 433320.259190
9043 180840 433409.429708
9044 180860 433498.602102
9045 180880 433587.776372
9046 180900 433676.952518
9047 180920 433766.130539
9048 180940 433855.310436
9049 180960 433944.492207
9050 180980 434033.675854
9051 181000 434122.861374
9052 181020 434212.048769
9053 181040 434301.238038
9054 181060 434390.429181
9055 181080 434479.622197
9056 181100 434568.817086
9057 181120 434658.013848
9058 181140 434747.212483
9059 181160 434836.412990
9060 181180 434925.615369
9061 181200 435014.819621
9062 181220 435104.025744
9063 181240 435193.233738
9064 181260 435282.443603
9065 181280 435371.655340
9066 181300 435460.868947
9067 181320 435550.084424
9068 181340 435639.301772
9069 181360 435728.520989
9070 181380 435817.742076
9071 181400 435906.965033
9072 181420 435996.189858
9073 181440 436085.416553
9074 181460 436174.645116
9075 181480 436263.875547
9076 181500 436353.107847
9077 181520 436442.342014
9078 181540 436531.578049
9079 181560 436620.815951
9080 181580 436710.055721
9081 181600 436799.297357
9082 181620 436888.540859
9083 181640 436977.786229
9084 181660 437067.033464
9085 181680 437156.282565
9086 181700 437245.533531
9087 181720 437334.786363
9088 181740 437424.041060
9089 181760 437513.297622
9090 181780 437602.556048
9091 181800 437691.816339
9092 181820 437781.078493
9093 181840 437870.342512
9094 181860 437959.608394
9095 181880 438048.876139
9096 181900 438138.145747
9097 181920 438227.417218
9098 181940 438316.690552
9099 181960 438405.965748
9100 181980 438495.242806
9101 182000 438584.521726
9102 182020 438673.802507
9103 182040 438763.085150
9104 182060 438852.369653
9105 182080 438941.656018
9106 182100 439030.944242
9107 182120 439120.234328
9108 182140 439209.526273
9109 182160 439298.820078
9110 182180 439388.115742
9111 182200 439477.413266
9112 182220 439566.712649
9113 182240 439656.013890
9114 182260 439745.316990
9115 182280 439834.621948
9116 182300 439923.928765
9117 182320 440013.237439
9118 182340 440102.547970
9119 182360 440191.860359
9120 182380 440281.174605
9121 182400 440370.490707
9122 182420 440459.808666
9123 182440 440549.128482
9124 182460 440638.450153
9125 182480 440727.773680
9126 182500 440817.099063
9127 182520 440906.426300
9128 182540 440995.755393
9129 182560 441085.086341
9130 182580 441174.419143
9131 182600 441263.753799
9132 182620 441353.090309
9133 182640 441442.428674
9134 182660 441531.768891
9135 182680 441621.110962
9136 182700 441710.454886
9137 182720 441799.800662
9138 182740 441889.148291
9139 182760 441978.497773
9140 182780 442067.849106
9141 182800 442157.202291
9142 182820 442246.557328
9143 182840 442335.914215
9144 182860 442425.272954
9145 182880 442514.633544
9146 182900 442603.995984
9147 182920 442693.360274
9148 182940 442782.726415
9149 182960 442872.094405
9150 182980 442961.464244
9151 183000 443050.835933
9152 183020 443140.209471
9153 183040 443229.584858
9154 183060 443318.962093
9155 183080 443408.341176
9156 183100 443497.722108
9157 183120 443587.104887
9158 183140 443676.489514
9159 183160 443765.875988
9160 183180 443855.264309
9161 183200 443944.654477
9162 183220 444034.046491
9163 183240 444123.440352
9164 183260 444212.836058
9165 183280 444302.233611
9166 183300 444391.633009
9167 183320 444481.034252
9168 183340 444570.437340
9169 183360 444659.842273
9170 183380 444749.249051
9171 183400 444838.657673
9172 183420 444928.068139
9173 183440 445017.480449
9174 183460 445106.894602
9175 183480 445196.310599
9176 183500 445285.728438
9177 183520 445375.148121
9178 183540 445464.569646
9179 183560 445553.993013
9180 183580 445643.418223
9181 183600 445732.845274
9182 183620 445822.274167
9183 183640 445911.704901
9184 183660 446001.137476
9185 183680 446090.571893
9186 183700 446180.008149
9187 183720 446269.446246
9188 183740 446358.886183
9189 183760 446448.327960
9190 183780 446537.771577
9191 183800 446627.217033
9192 183820 446716.664328
9193 183840 446806.113462
9194 183860 446895.564435
9195 183880 446985.017246
9196 183900 447074.471895
9197 183920 447163.928382
9198 183940 447253.386706
9199 183960 447342.846868
9200 183980 447432.308867
9201 184000 447521.772703
9202 184020 447611.238376
9203 184040 447700.705885
9204 184060 447790.175230
9205 184080 447879.646411
9206 184100 447969.119428
9207 184120 448058.594280
9208 184140 448148.070968
9209 184160 448237.549490
9210 184180 448327.029847
9211 184200 448416.512039
9212 184220 448505.996064
9213 184240 448595.481924
9214 184260 448684.969617
9215 184280 448774.459144
9216 184300 448863.950504
9217 184320 448953.443697
9218 184340 449042.938723
9219 184360 449132.435581
9220 184380 449221.934272
9221 184400 449311.434794
9222 184420 449400.937148
9223 184440 449490.441334
9224 184460 449579.947351
9225 184480 449669.455199
9226 184500 449758.964878
9227 184520 449848.476387
9228 184540 449937.989726
9229 184560 450027.504896
9230 184580 450117.021895
9231 184600 450206.540724
9232 184620 450296.061383
9233 184640 450385.583870
9234 184660 450475.108186
9235 184680 450564.634331
9236 184700 450654.162304
9237 184720 450743.692105
9238 184740 450833.223734
9239 184760 450922.757191
9240 184780 451012.292475
9241 184800 451101.829586
9242 184820 451191.368524
9243 184840 451280.909289
9244 184860 451370.451880
9245 184880 451459.996297
9246 184900 451549.542540
9247 184920 451639.090608
9248 184940 451728.640503
9249 184960 451818.192222
9250 184980 451907.745766
9251 185000 451997.301135
9252 185020 452086.858328
9253 185040 452176.417346
9254 185060 452265.978187
9255 185080 452355.540853
9256 185100 452445.105341
9257 185120 452534.671653
9258 185140 452624.239788
9259 185160 452713.809746
9260 185180 452803.381526
9261 185200 452892.955129
9262 185220 452982.530553
9263 185240 453072.107799
9264 185260 453161.686867
9265 185280 453251.267756
9266 185300 453340.850466
9267 185320 453430.434997
9268 185340 453520.021349
9269 185360 453609.609521
9270 185380 453699.199513
9271 185400 453788.791325
9272 185420 453878.384956
9273 185440 453967.980407
9274 185460 454057.577677
9275 185480 454147.176765
9276 185500 454236.777673
9277 185520 454326.380399
9278 185540 454415.984943
9279 185560 454505.591305
9280 185580 454595.199484
9281 185600 454684.809481
9282 185620 454774.421295
9283 185640 454864.034927
9284 185660 454953.650374
9285 185680 455043.267639
9286 185700 455132.886719
9287 185720 455222.507616
9288 185740 455312.130328
9289 185760 455401.754856
9290 185780 455491.381199
9291 185800 455581.009357
9292 185820 455670.639330
9293 185840 455760.271118
9294 185860 455849.904719
9295 185880 455939.540135
9296 185900 456029.177365
9297 185920 456118.816408
9298 185940 456208.457265
9299 185960 456298.099935
9300 185980 456387.744417
9301 186000 456477.390712
9302 186020 456567.038820
9303 186040 456656.688740
9304 186060 456746.340472
9305 186080 456835.994015
9306 186100 456925.649370
9307 186120 457015.306536
9308 186140 457104.965513
9309 186160 457194.626300
9310 186180 457284.288898
9311 186200 457373.953307
9312 186220 457463.619525
9313 186240 457553.287553
9314 186260 457642.957391
9315 186280 457732.629038
9316 186300 457822.302494
9317 186320 457911.977759
9318 186340 458001.654832
9319 186360 458091.333714
9320 186380 458181.014403
9321 186400 458270.696901
9322 186420 458360.381206
9323 186440 458450.067319
9324 186460 458539.755238
9325 186480 458629.444965
9326 186500 458719.136498
9327 186520 458808.829838
9328 186540 458898.524984
9329 186560 458988.221936
9330 186580 459077.920693
9331 186600 459167.621256
9332 186620 459257.323624
9333 186640 459347.027798
9334 186660 459436.733776
9335 186680 459526.441558
9336 186700 459616.151145
9337 186720 459705.862536
9338 186740 459795.575730
9339 186760 459885.290728
9340 186780 459975.007530
9341 186800 460064.726134
9342 186820 460154.446542
9343 186840 460244.168752
9344 186860 460333.892764
9345 186880 460423.618579
9346 186900 460513.346196
9347 186920 460603.075614
9348 186940 460692.806833
9349 186960 460782.539854
9350 186980 460872.274676
9351 187000 460962.011298
9352 187020 461051.749721
9353 187040 461141.489944
9354 187060 461231.231968
9355 187080 461320.975791
9356 187100 461410.721413
9357 187120 461500.468835
9358 187140 461590.218056
9359 187160 461679.969076
9360 187180 461769.721894
9361 187200 461859.476510
9362 187220 461949.232925
9363 187240 462038.991138
9364 187260 462128.751148
9365 187280 462218.512956
9366 187300 462308.276561
9367 187320 462398.041963
9368 187340 462487.809161
9369 187360 462577.578156
9370 187380 462667.348948
9371 187400 462757.121535
9372 187420 462846.895918
9373 187440 462936.672096
9374 187460 463026.450070
9375 187480 463116.229839
9376 187500 463206.011403
9377 187520 463295.794761
9378 187540 463385.579914
9379 187560 463475.366861
9380 187580 463565.155601
9381 187600 463654.946136
9382 187620 463744.738463
9383 187640 463834.532584
9384 187660 463924.328498
9385 187680 464014.126205
9386 187700 464103.925704
9387 187720 464193.726995
9388 187740 464283.530078
9389 187760 464373.334953
9390 187780 464463.141620
9391 187800 464552.950078
9392 187820 464642.760327
9393 187840 464732.572366
9394 187860 464822.386197
9395 187880 464912.201817
9396 187900 465002.019228
9397 187920 465091.838429
9398 187940 465181.659419
9399 187960 465271.482199
9400 187980 465361.306768
9401 188000 465451.133126
9402 188020 465540.961273
9403 188040 465630.791208
9404 188060 465720.622931
9405 188080 465810.456443
9406 188100 465900.291742
9407 188120 465990.128829
9408 188140 466079.967703
9409 188160 466169.808364
9410 188180 466259.650812
9411 188200 466349.495047
9412 188220 466439.341068
9413 188240 466529.188875
9414 188260 466619.038468
9415 188280 466708.889847
9416 188300 466798.743012
9417 188320 466888.597961
9418 188340 466978.454696
9419 188360 467068.313215
9420 188380 467158.173519
9421 188400 467248.035607
9422 188420 467337.899479
9423 188440 467427.765135
9424 188460 467517.632575
9425 188480 467607.501798
9426 188500 467697.372804
9427 188520 467787.245593
9428 188540 467877.120164
9429 188560 467966.996518
9430 188580 468056.874655
9431 188600 468146.754573
9432 188620 468236.636273
9433 188640 468326.519754
9434 188660 468416.405017
9435 188680 468506.292061
9436 188700 468596.180886
9437 188720 468686.071491
9438 188740 468775.963876
9439 188760 468865.858042
9440 188780 468955.753988
9441 188800 469045.651713
9442 188820 469135.551217
9443 188840 469225.452501
9444 188860 469315.355564
9445 188880 469405.260405
9446 188900 469495.167025
9447 188920 469585.075424
9448 188940 469674.985600
9449 188960 469764.897554
9450 188980 469854.811286
9451 189000 469944.726795
9452 189020 470034.644081
9453 189040 470124.563144
9454 189060 470214.483983
9455 189080 470304.406599
9456 189100 470394.330991
9457 189120 470484.257160
9458 189140 470574.185103
9459 189160 470664.114823
9460 189180 470754.046317
9461 189200 470843.979587
9462 189220 470933.914632
9463 189240 471023.851451
9464 189260 471113.790044
9465 189280 471203.730412
9466 189300 471293.672553
9467 189320 471383.616468
9468 189340 471473.562156
9469 189360 471563.509618
9470 189380 471653.458853
9471 189400 471743.409860
9472 189420 471833.362640
9473 189440 471923.317192
9474 189460 472013.273516
9475 189480 472103.231612
9476 189500 472193.191479
9477 189520 472283.153118
9478 189540 472373.116528
9479 189560 472463.081709
9480 189580 472553.048661
9481 189600 472643.017383
9482 189620 472732.987875
9483 189640 472822.960137
9484 189660 472912.934169
9485 189680 473002.909970
9486 189700 473092.887541
9487 189720 473182.866881
9488 189740 473272.847989
9489 189760 473362.830867
9490 189780 473452.815512
9491 189800 473542.801926
9492 189820 473632.790108
9493 189840 473722.780057
9494 189860 473812.771774
9495 189880 473902.765258
9496 189900 473992.760509
9497 189920 474082.757527
9498 189940 474172.756311
9499 189960 474262.756862
9500 189980 474352.759178
9501 190000 474442.763261

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