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 15 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
7002 140020 255736.543828
7003 140040 255821.240132
7004 140060 255905.939015
7005 140080 255990.640477
7006 140100 256075.344518
7007 140120 256160.051137
7008 140140 256244.760333
7009 140160 256329.472106
7010 140180 256414.186455
7011 140200 256498.903381
7012 140220 256583.622883
7013 140240 256668.344959
7014 140260 256753.069611
7015 140280 256837.796836
7016 140300 256922.526636
7017 140320 257007.259009
7018 140340 257091.993954
7019 140360 257176.731472
7020 140380 257261.471562
7021 140400 257346.214224
7022 140420 257430.959456
7023 140440 257515.707259
7024 140460 257600.457632
7025 140480 257685.210575
7026 140500 257769.966087
7027 140520 257854.724168
7028 140540 257939.484817
7029 140560 258024.248034
7030 140580 258109.013818
7031 140600 258193.782169
7032 140620 258278.553087
7033 140640 258363.326570
7034 140660 258448.102619
7035 140680 258532.881233
7036 140700 258617.662412
7037 140720 258702.446155
7038 140740 258787.232461
7039 140760 258872.021331
7040 140780 258956.812763
7041 140800 259041.606758
7042 140820 259126.403315
7043 140840 259211.202433
7044 140860 259296.004112
7045 140880 259380.808351
7046 140900 259465.615151
7047 140920 259550.424510
7048 140940 259635.236428
7049 140960 259720.050905
7050 140980 259804.867940
7051 141000 259889.687533
7052 141020 259974.509683
7053 141040 260059.334389
7054 141060 260144.161653
7055 141080 260228.991472
7056 141100 260313.823846
7057 141120 260398.658776
7058 141140 260483.496260
7059 141160 260568.336298
7060 141180 260653.178890
7061 141200 260738.024035
7062 141220 260822.871733
7063 141240 260907.721983
7064 141260 260992.574785
7065 141280 261077.430138
7066 141300 261162.288043
7067 141320 261247.148497
7068 141340 261332.011502
7069 141360 261416.877056
7070 141380 261501.745160
7071 141400 261586.615812
7072 141420 261671.489012
7073 141440 261756.364760
7074 141460 261841.243055
7075 141480 261926.123897
7076 141500 262011.007285
7077 141520 262095.893220
7078 141540 262180.781700
7079 141560 262265.672724
7080 141580 262350.566294
7081 141600 262435.462407
7082 141620 262520.361065
7083 141640 262605.262265
7084 141660 262690.166008
7085 141680 262775.072294
7086 141700 262859.981121
7087 141720 262944.892490
7088 141740 263029.806400
7089 141760 263114.722850
7090 141780 263199.641841
7091 141800 263284.563371
7092 141820 263369.487440
7093 141840 263454.414048
7094 141860 263539.343194
7095 141880 263624.274878
7096 141900 263709.209099
7097 141920 263794.145858
7098 141940 263879.085152
7099 141960 263964.026983
7100 141980 264048.971350
7101 142000 264133.918251
7102 142020 264218.867687
7103 142040 264303.819657
7104 142060 264388.774162
7105 142080 264473.731199
7106 142100 264558.690769
7107 142120 264643.652872
7108 142140 264728.617507
7109 142160 264813.584673
7110 142180 264898.554371
7111 142200 264983.526599
7112 142220 265068.501357
7113 142240 265153.478645
7114 142260 265238.458462
7115 142280 265323.440808
7116 142300 265408.425683
7117 142320 265493.413086
7118 142340 265578.403016
7119 142360 265663.395473
7120 142380 265748.390456
7121 142400 265833.387966
7122 142420 265918.388002
7123 142440 266003.390563
7124 142460 266088.395649
7125 142480 266173.403259
7126 142500 266258.413393
7127 142520 266343.426051
7128 142540 266428.441231
7129 142560 266513.458935
7130 142580 266598.479160
7131 142600 266683.501908
7132 142620 266768.527176
7133 142640 266853.554966
7134 142660 266938.585275
7135 142680 267023.618105
7136 142700 267108.653454
7137 142720 267193.691323
7138 142740 267278.731709
7139 142760 267363.774615
7140 142780 267448.820037
7141 142800 267533.867978
7142 142820 267618.918435
7143 142840 267703.971408
7144 142860 267789.026897
7145 142880 267874.084902
7146 142900 267959.145422
7147 142920 268044.208457
7148 142940 268129.274006
7149 142960 268214.342068
7150 142980 268299.412644
7151 143000 268384.485733
7152 143020 268469.561334
7153 143040 268554.639447
7154 143060 268639.720072
7155 143080 268724.803208
7156 143100 268809.888855
7157 143120 268894.977011
7158 143140 268980.067678
7159 143160 269065.160854
7160 143180 269150.256539
7161 143200 269235.354732
7162 143220 269320.455433
7163 143240 269405.558642
7164 143260 269490.664358
7165 143280 269575.772581
7166 143300 269660.883310
7167 143320 269745.996545
7168 143340 269831.112285
7169 143360 269916.230531
7170 143380 270001.351280
7171 143400 270086.474534
7172 143420 270171.600292
7173 143440 270256.728552
7174 143460 270341.859316
7175 143480 270426.992582
7176 143500 270512.128349
7177 143520 270597.266618
7178 143540 270682.407388
7179 143560 270767.550659
7180 143580 270852.696430
7181 143600 270937.844700
7182 143620 271022.995470
7183 143640 271108.148739
7184 143660 271193.304506
7185 143680 271278.462771
7186 143700 271363.623533
7187 143720 271448.786793
7188 143740 271533.952549
7189 143760 271619.120801
7190 143780 271704.291550
7191 143800 271789.464793
7192 143820 271874.640532
7193 143840 271959.818764
7194 143860 272044.999491
7195 143880 272130.182712
7196 143900 272215.368426
7197 143920 272300.556632
7198 143940 272385.747331
7199 143960 272470.940521
7200 143980 272556.136203
7201 144000 272641.334376
7202 144020 272726.535040
7203 144040 272811.738193
7204 144060 272896.943837
7205 144080 272982.151969
7206 144100 273067.362591
7207 144120 273152.575700
7208 144140 273237.791298
7209 144160 273323.009383
7210 144180 273408.229956
7211 144200 273493.453015
7212 144220 273578.678560
7213 144240 273663.906591
7214 144260 273749.137107
7215 144280 273834.370109
7216 144300 273919.605594
7217 144320 274004.843564
7218 144340 274090.084018
7219 144360 274175.326954
7220 144380 274260.572374
7221 144400 274345.820276
7222 144420 274431.070659
7223 144440 274516.323524
7224 144460 274601.578871
7225 144480 274686.836697
7226 144500 274772.097004
7227 144520 274857.359791
7228 144540 274942.625057
7229 144560 275027.892802
7230 144580 275113.163025
7231 144600 275198.435727
7232 144620 275283.710906
7233 144640 275368.988562
7234 144660 275454.268695
7235 144680 275539.551304
7236 144700 275624.836389
7237 144720 275710.123950
7238 144740 275795.413985
7239 144760 275880.706495
7240 144780 275966.001480
7241 144800 276051.298938
7242 144820 276136.598869
7243 144840 276221.901273
7244 144860 276307.206150
7245 144880 276392.513499
7246 144900 276477.823319
7247 144920 276563.135610
7248 144940 276648.450373
7249 144960 276733.767605
7250 144980 276819.087308
7251 145000 276904.409479
7252 145020 276989.734120
7253 145040 277075.061230
7254 145060 277160.390807
7255 145080 277245.722853
7256 145100 277331.057365
7257 145120 277416.394345
7258 145140 277501.733791
7259 145160 277587.075703
7260 145180 277672.420081
7261 145200 277757.766924
7262 145220 277843.116231
7263 145240 277928.468003
7264 145260 278013.822239
7265 145280 278099.178939
7266 145300 278184.538101
7267 145320 278269.899726
7268 145340 278355.263814
7269 145360 278440.630363
7270 145380 278525.999373
7271 145400 278611.370845
7272 145420 278696.744777
7273 145440 278782.121169
7274 145460 278867.500020
7275 145480 278952.881331
7276 145500 279038.265101
7277 145520 279123.651329
7278 145540 279209.040015
7279 145560 279294.431159
7280 145580 279379.824759
7281 145600 279465.220817
7282 145620 279550.619331
7283 145640 279636.020300
7284 145660 279721.423725
7285 145680 279806.829605
7286 145700 279892.237940
7287 145720 279977.648729
7288 145740 280063.061971
7289 145760 280148.477667
7290 145780 280233.895816
7291 145800 280319.316417
7292 145820 280404.739470
7293 145840 280490.164975
7294 145860 280575.592931
7295 145880 280661.023338
7296 145900 280746.456195
7297 145920 280831.891502
7298 145940 280917.329259
7299 145960 281002.769465
7300 145980 281088.212120
7301 146000 281173.657222
7302 146020 281259.104773
7303 146040 281344.554771
7304 146060 281430.007216
7305 146080 281515.462108
7306 146100 281600.919446
7307 146120 281686.379229
7308 146140 281771.841458
7309 146160 281857.306132
7310 146180 281942.773250
7311 146200 282028.242812
7312 146220 282113.714818
7313 146240 282199.189268
7314 146260 282284.666160
7315 146280 282370.145494
7316 146300 282455.627270
7317 146320 282541.111488
7318 146340 282626.598147
7319 146360 282712.087247
7320 146380 282797.578787
7321 146400 282883.072767
7322 146420 282968.569187
7323 146440 283054.068045
7324 146460 283139.569342
7325 146480 283225.073078
7326 146500 283310.579251
7327 146520 283396.087861
7328 146540 283481.598909
7329 146560 283567.112393
7330 146580 283652.628313
7331 146600 283738.146669
7332 146620 283823.667460
7333 146640 283909.190686
7334 146660 283994.716346
7335 146680 284080.244441
7336 146700 284165.774969
7337 146720 284251.307930
7338 146740 284336.843325
7339 146760 284422.381151
7340 146780 284507.921410
7341 146800 284593.464100
7342 146820 284679.009221
7343 146840 284764.556773
7344 146860 284850.106755
7345 146880 284935.659167
7346 146900 285021.214009
7347 146920 285106.771280
7348 146940 285192.330979
7349 146960 285277.893107
7350 146980 285363.457662
7351 147000 285449.024645
7352 147020 285534.594055
7353 147040 285620.165891
7354 147060 285705.740154
7355 147080 285791.316842
7356 147100 285876.895956
7357 147120 285962.477494
7358 147140 286048.061458
7359 147160 286133.647845
7360 147180 286219.236656
7361 147200 286304.827890
7362 147220 286390.421547
7363 147240 286476.017626
7364 147260 286561.616128
7365 147280 286647.217051
7366 147300 286732.820396
7367 147320 286818.426161
7368 147340 286904.034347
7369 147360 286989.644952
7370 147380 287075.257977
7371 147400 287160.873422
7372 147420 287246.491285
7373 147440 287332.111566
7374 147460 287417.734265
7375 147480 287503.359382
7376 147500 287588.986916
7377 147520 287674.616867
7378 147540 287760.249234
7379 147560 287845.884017
7380 147580 287931.521215
7381 147600 288017.160828
7382 147620 288102.802856
7383 147640 288188.447299
7384 147660 288274.094155
7385 147680 288359.743424
7386 147700 288445.395107
7387 147720 288531.049202
7388 147740 288616.705709
7389 147760 288702.364628
7390 147780 288788.025959
7391 147800 288873.689700
7392 147820 288959.355852
7393 147840 289045.024414
7394 147860 289130.695386
7395 147880 289216.368767
7396 147900 289302.044557
7397 147920 289387.722756
7398 147940 289473.403363
7399 147960 289559.086377
7400 147980 289644.771799
7401 148000 289730.459627
7402 148020 289816.149862
7403 148040 289901.842503
7404 148060 289987.537550
7405 148080 290073.235002
7406 148100 290158.934859
7407 148120 290244.637121
7408 148140 290330.341786
7409 148160 290416.048855
7410 148180 290501.758327
7411 148200 290587.470202
7412 148220 290673.184480
7413 148240 290758.901159
7414 148260 290844.620240
7415 148280 290930.341723
7416 148300 291016.065606
7417 148320 291101.791889
7418 148340 291187.520573
7419 148360 291273.251656
7420 148380 291358.985138
7421 148400 291444.721019
7422 148420 291530.459298
7423 148440 291616.199975
7424 148460 291701.943050
7425 148480 291787.688522
7426 148500 291873.436391
7427 148520 291959.186656
7428 148540 292044.939317
7429 148560 292130.694373
7430 148580 292216.451825
7431 148600 292302.211672
7432 148620 292387.973912
7433 148640 292473.738547
7434 148660 292559.505575
7435 148680 292645.274996
7436 148700 292731.046810
7437 148720 292816.821016
7438 148740 292902.597614
7439 148760 292988.376604
7440 148780 293074.157985
7441 148800 293159.941756
7442 148820 293245.727918
7443 148840 293331.516470
7444 148860 293417.307411
7445 148880 293503.100741
7446 148900 293588.896460
7447 148920 293674.694567
7448 148940 293760.495062
7449 148960 293846.297945
7450 148980 293932.103214
7451 149000 294017.910871
7452 149020 294103.720913
7453 149040 294189.533342
7454 149060 294275.348156
7455 149080 294361.165355
7456 149100 294446.984938
7457 149120 294532.806906
7458 149140 294618.631258
7459 149160 294704.457994
7460 149180 294790.287112
7461 149200 294876.118613
7462 149220 294961.952496
7463 149240 295047.788762
7464 149260 295133.627408
7465 149280 295219.468436
7466 149300 295305.311845
7467 149320 295391.157634
7468 149340 295477.005802
7469 149360 295562.856350
7470 149380 295648.709278
7471 149400 295734.564583
7472 149420 295820.422268
7473 149440 295906.282330
7474 149460 295992.144769
7475 149480 296078.009586
7476 149500 296163.876779
7477 149520 296249.746349
7478 149540 296335.618295
7479 149560 296421.492616
7480 149580 296507.369312
7481 149600 296593.248383
7482 149620 296679.129828
7483 149640 296765.013647
7484 149660 296850.899840
7485 149680 296936.788406
7486 149700 297022.679344
7487 149720 297108.572655
7488 149740 297194.468338
7489 149760 297280.366392
7490 149780 297366.266817
7491 149800 297452.169613
7492 149820 297538.074780
7493 149840 297623.982316
7494 149860 297709.892222
7495 149880 297795.804498
7496 149900 297881.719142
7497 149920 297967.636154
7498 149940 298053.555534
7499 149960 298139.477282
7500 149980 298225.401397
7501 150000 298311.327879

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