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 17 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
8002 160020 341650.110050
8003 160040 341737.177284
8004 160060 341824.246700
8005 160080 341911.318299
8006 160100 341998.392079
8007 160120 342085.468041
8008 160140 342172.546185
8009 160160 342259.626509
8010 160180 342346.709015
8011 160200 342433.793700
8012 160220 342520.880566
8013 160240 342607.969611
8014 160260 342695.060835
8015 160280 342782.154238
8016 160300 342869.249820
8017 160320 342956.347581
8018 160340 343043.447519
8019 160360 343130.549635
8020 160380 343217.653928
8021 160400 343304.760398
8022 160420 343391.869044
8023 160440 343478.979867
8024 160460 343566.092866
8025 160480 343653.208040
8026 160500 343740.325390
8027 160520 343827.444914
8028 160540 343914.566613
8029 160560 344001.690486
8030 160580 344088.816533
8031 160600 344175.944754
8032 160620 344263.075148
8033 160640 344350.207715
8034 160660 344437.342454
8035 160680 344524.479366
8036 160700 344611.618449
8037 160720 344698.759704
8038 160740 344785.903130
8039 160760 344873.048728
8040 160780 344960.196495
8041 160800 345047.346433
8042 160820 345134.498541
8043 160840 345221.652818
8044 160860 345308.809264
8045 160880 345395.967879
8046 160900 345483.128663
8047 160920 345570.291615
8048 160940 345657.456735
8049 160960 345744.624022
8050 160980 345831.793476
8051 161000 345918.965097
8052 161020 346006.138885
8053 161040 346093.314839
8054 161060 346180.492959
8055 161080 346267.673244
8056 161100 346354.855695
8057 161120 346442.040310
8058 161140 346529.227090
8059 161160 346616.416034
8060 161180 346703.607142
8061 161200 346790.800413
8062 161220 346877.995847
8063 161240 346965.193445
8064 161260 347052.393204
8065 161280 347139.595126
8066 161300 347226.799210
8067 161320 347314.005455
8068 161340 347401.213862
8069 161360 347488.424429
8070 161380 347575.637157
8071 161400 347662.852045
8072 161420 347750.069093
8073 161440 347837.288300
8074 161460 347924.509666
8075 161480 348011.733192
8076 161500 348098.958875
8077 161520 348186.186717
8078 161540 348273.416717
8079 161560 348360.648875
8080 161580 348447.883189
8081 161600 348535.119660
8082 161620 348622.358288
8083 161640 348709.599072
8084 161660 348796.842012
8085 161680 348884.087107
8086 161700 348971.334358
8087 161720 349058.583763
8088 161740 349145.835323
8089 161760 349233.089037
8090 161780 349320.344905
8091 161800 349407.602927
8092 161820 349494.863102
8093 161840 349582.125429
8094 161860 349669.389909
8095 161880 349756.656542
8096 161900 349843.925326
8097 161920 349931.196261
8098 161940 350018.469348
8099 161960 350105.744586
8100 161980 350193.021975
8101 162000 350280.301513
8102 162020 350367.583202
8103 162040 350454.867040
8104 162060 350542.153027
8105 162080 350629.441163
8106 162100 350716.731448
8107 162120 350804.023881
8108 162140 350891.318462
8109 162160 350978.615190
8110 162180 351065.914066
8111 162200 351153.215089
8112 162220 351240.518258
8113 162240 351327.823574
8114 162260 351415.131035
8115 162280 351502.440643
8116 162300 351589.752395
8117 162320 351677.066292
8118 162340 351764.382334
8119 162360 351851.700521
8120 162380 351939.020851
8121 162400 352026.343325
8122 162420 352113.667942
8123 162440 352200.994702
8124 162460 352288.323605
8125 162480 352375.654650
8126 162500 352462.987838
8127 162520 352550.323166
8128 162540 352637.660637
8129 162560 352725.000248
8130 162580 352812.342000
8131 162600 352899.685892
8132 162620 352987.031925
8133 162640 353074.380097
8134 162660 353161.730408
8135 162680 353249.082859
8136 162700 353336.437448
8137 162720 353423.794176
8138 162740 353511.153041
8139 162760 353598.514045
8140 162780 353685.877186
8141 162800 353773.242464
8142 162820 353860.609879
8143 162840 353947.979430
8144 162860 354035.351117
8145 162880 354122.724940
8146 162900 354210.100899
8147 162920 354297.478993
8148 162940 354384.859221
8149 162960 354472.241584
8150 162980 354559.626082
8151 163000 354647.012713
8152 163020 354734.401477
8153 163040 354821.792375
8154 163060 354909.185406
8155 163080 354996.580569
8156 163100 355083.977864
8157 163120 355171.377292
8158 163140 355258.778851
8159 163160 355346.182541
8160 163180 355433.588362
8161 163200 355520.996313
8162 163220 355608.406395
8163 163240 355695.818607
8164 163260 355783.232949
8165 163280 355870.649419
8166 163300 355958.068019
8167 163320 356045.488748
8168 163340 356132.911604
8169 163360 356220.336589
8170 163380 356307.763701
8171 163400 356395.192941
8172 163420 356482.624308
8173 163440 356570.057801
8174 163460 356657.493421
8175 163480 356744.931167
8176 163500 356832.371039
8177 163520 356919.813036
8178 163540 357007.257158
8179 163560 357094.703405
8180 163580 357182.151777
8181 163600 357269.602272
8182 163620 357357.054891
8183 163640 357444.509634
8184 163660 357531.966500
8185 163680 357619.425489
8186 163700 357706.886600
8187 163720 357794.349834
8188 163740 357881.815189
8189 163760 357969.282666
8190 163780 358056.752264
8191 163800 358144.223983
8192 163820 358231.697823
8193 163840 358319.173783
8194 163860 358406.651863
8195 163880 358494.132062
8196 163900 358581.614381
8197 163920 358669.098819
8198 163940 358756.585375
8199 163960 358844.074050
8200 163980 358931.564843
8201 164000 359019.057753
8202 164020 359106.552781
8203 164040 359194.049926
8204 164060 359281.549187
8205 164080 359369.050565
8206 164100 359456.554059
8207 164120 359544.059669
8208 164140 359631.567395
8209 164160 359719.077235
8210 164180 359806.589190
8211 164200 359894.103260
8212 164220 359981.619444
8213 164240 360069.137742
8214 164260 360156.658153
8215 164280 360244.180677
8216 164300 360331.705315
8217 164320 360419.232065
8218 164340 360506.760927
8219 164360 360594.291901
8220 164380 360681.824987
8221 164400 360769.360184
8222 164420 360856.897492
8223 164440 360944.436911
8224 164460 361031.978440
8225 164480 361119.522079
8226 164500 361207.067828
8227 164520 361294.615686
8228 164540 361382.165653
8229 164560 361469.717729
8230 164580 361557.271913
8231 164600 361644.828206
8232 164620 361732.386606
8233 164640 361819.947114
8234 164660 361907.509729
8235 164680 361995.074451
8236 164700 362082.641279
8237 164720 362170.210214
8238 164740 362257.781254
8239 164760 362345.354400
8240 164780 362432.929651
8241 164800 362520.507007
8242 164820 362608.086468
8243 164840 362695.668033
8244 164860 362783.251702
8245 164880 362870.837475
8246 164900 362958.425351
8247 164920 363046.015330
8248 164940 363133.607412
8249 164960 363221.201596
8250 164980 363308.797883
8251 165000 363396.396271
8252 165020 363483.996760
8253 165040 363571.599351
8254 165060 363659.204042
8255 165080 363746.810834
8256 165100 363834.419727
8257 165120 363922.030719
8258 165140 364009.643810
8259 165160 364097.259001
8260 165180 364184.876291
8261 165200 364272.495679
8262 165220 364360.117166
8263 165240 364447.740751
8264 165260 364535.366433
8265 165280 364622.994213
8266 165300 364710.624090
8267 165320 364798.256063
8268 165340 364885.890133
8269 165360 364973.526299
8270 165380 365061.164561
8271 165400 365148.804918
8272 165420 365236.447370
8273 165440 365324.091918
8274 165460 365411.738559
8275 165480 365499.387295
8276 165500 365587.038125
8277 165520 365674.691048
8278 165540 365762.346065
8279 165560 365850.003175
8280 165580 365937.662377
8281 165600 366025.323672
8282 165620 366112.987058
8283 165640 366200.652536
8284 165660 366288.320106
8285 165680 366375.989767
8286 165700 366463.661518
8287 165720 366551.335360
8288 165740 366639.011292
8289 165760 366726.689314
8290 165780 366814.369426
8291 165800 366902.051626
8292 165820 366989.735916
8293 165840 367077.422294
8294 165860 367165.110760
8295 165880 367252.801314
8296 165900 367340.493956
8297 165920 367428.188685
8298 165940 367515.885501
8299 165960 367603.584404
8300 165980 367691.285393
8301 166000 367778.988469
8302 166020 367866.693630
8303 166040 367954.400876
8304 166060 368042.110208
8305 166080 368129.821624
8306 166100 368217.535125
8307 166120 368305.250711
8308 166140 368392.968380
8309 166160 368480.688132
8310 166180 368568.409968
8311 166200 368656.133887
8312 166220 368743.859889
8313 166240 368831.587973
8314 166260 368919.318138
8315 166280 369007.050386
8316 166300 369094.784715
8317 166320 369182.521125
8318 166340 369270.259616
8319 166360 369358.000187
8320 166380 369445.742839
8321 166400 369533.487570
8322 166420 369621.234381
8323 166440 369708.983271
8324 166460 369796.734240
8325 166480 369884.487288
8326 166500 369972.242414
8327 166520 370059.999618
8328 166540 370147.758899
8329 166560 370235.520259
8330 166580 370323.283695
8331 166600 370411.049207
8332 166620 370498.816797
8333 166640 370586.586462
8334 166660 370674.358203
8335 166680 370762.132020
8336 166700 370849.907912
8337 166720 370937.685879
8338 166740 371025.465920
8339 166760 371113.248036
8340 166780 371201.032226
8341 166800 371288.818489
8342 166820 371376.606826
8343 166840 371464.397236
8344 166860 371552.189718
8345 166880 371639.984273
8346 166900 371727.780900
8347 166920 371815.579599
8348 166940 371903.380370
8349 166960 371991.183211
8350 166980 372078.988124
8351 167000 372166.795107
8352 167020 372254.604160
8353 167040 372342.415284
8354 167060 372430.228477
8355 167080 372518.043739
8356 167100 372605.861070
8357 167120 372693.680470
8358 167140 372781.501939
8359 167160 372869.325476
8360 167180 372957.151080
8361 167200 373044.978752
8362 167220 373132.808492
8363 167240 373220.640298
8364 167260 373308.474171
8365 167280 373396.310110
8366 167300 373484.148115
8367 167320 373571.988186
8368 167340 373659.830322
8369 167360 373747.674523
8370 167380 373835.520789
8371 167400 373923.369119
8372 167420 374011.219514
8373 167440 374099.071972
8374 167460 374186.926494
8375 167480 374274.783079
8376 167500 374362.641727
8377 167520 374450.502438
8378 167540 374538.365211
8379 167560 374626.230046
8380 167580 374714.096943
8381 167600 374801.965901
8382 167620 374889.836920
8383 167640 374977.710000
8384 167660 375065.585141
8385 167680 375153.462341
8386 167700 375241.341602
8387 167720 375329.222922
8388 167740 375417.106301
8389 167760 375504.991740
8390 167780 375592.879237
8391 167800 375680.768792
8392 167820 375768.660406
8393 167840 375856.554077
8394 167860 375944.449805
8395 167880 376032.347591
8396 167900 376120.247434
8397 167920 376208.149333
8398 167940 376296.053288
8399 167960 376383.959300
8400 167980 376471.867366
8401 168000 376559.777489
8402 168020 376647.689666
8403 168040 376735.603898
8404 168060 376823.520184
8405 168080 376911.438525
8406 168100 376999.358919
8407 168120 377087.281367
8408 168140 377175.205868
8409 168160 377263.132422
8410 168180 377351.061028
8411 168200 377438.991687
8412 168220 377526.924397
8413 168240 377614.859160
8414 168260 377702.795974
8415 168280 377790.734839
8416 168300 377878.675754
8417 168320 377966.618720
8418 168340 378054.563737
8419 168360 378142.510803
8420 168380 378230.459919
8421 168400 378318.411084
8422 168420 378406.364298
8423 168440 378494.319560
8424 168460 378582.276871
8425 168480 378670.236230
8426 168500 378758.197637
8427 168520 378846.161091
8428 168540 378934.126593
8429 168560 379022.094141
8430 168580 379110.063736
8431 168600 379198.035377
8432 168620 379286.009064
8433 168640 379373.984797
8434 168660 379461.962575
8435 168680 379549.942398
8436 168700 379637.924266
8437 168720 379725.908179
8438 168740 379813.894135
8439 168760 379901.882136
8440 168780 379989.872180
8441 168800 380077.864267
8442 168820 380165.858397
8443 168840 380253.854570
8444 168860 380341.852785
8445 168880 380429.853042
8446 168900 380517.855341
8447 168920 380605.859682
8448 168940 380693.866063
8449 168960 380781.874486
8450 168980 380869.884949
8451 169000 380957.897452
8452 169020 381045.911995
8453 169040 381133.928578
8454 169060 381221.947200
8455 169080 381309.967861
8456 169100 381397.990562
8457 169120 381486.015300
8458 169140 381574.042077
8459 169160 381662.070891
8460 169180 381750.101744
8461 169200 381838.134633
8462 169220 381926.169559
8463 169240 382014.206522
8464 169260 382102.245522
8465 169280 382190.286557
8466 169300 382278.329629
8467 169320 382366.374735
8468 169340 382454.421877
8469 169360 382542.471054
8470 169380 382630.522266
8471 169400 382718.575511
8472 169420 382806.630791
8473 169440 382894.688105
8474 169460 382982.747451
8475 169480 383070.808831
8476 169500 383158.872244
8477 169520 383246.937689
8478 169540 383335.005167
8479 169560 383423.074676
8480 169580 383511.146217
8481 169600 383599.219789
8482 169620 383687.295393
8483 169640 383775.373027
8484 169660 383863.452691
8485 169680 383951.534386
8486 169700 384039.618110
8487 169720 384127.703864
8488 169740 384215.791648
8489 169760 384303.881460
8490 169780 384391.973301
8491 169800 384480.067170
8492 169820 384568.163067
8493 169840 384656.260992
8494 169860 384744.360945
8495 169880 384832.462925
8496 169900 384920.566931
8497 169920 385008.672964
8498 169940 385096.781024
8499 169960 385184.891109
8500 169980 385273.003220
8501 170000 385361.117357

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