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 11 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
5002 100020 92252.810124
5003 100040 92331.146848
5004 100060 92409.487533
5005 100080 92487.832178
5006 100100 92566.180783
5007 100120 92644.533347
5008 100140 92722.889868
5009 100160 92801.250345
5010 100180 92879.614778
5011 100200 92957.983165
5012 100220 93036.355506
5013 100240 93114.731799
5014 100260 93193.112043
5015 100280 93271.496238
5016 100300 93349.884381
5017 100320 93428.276474
5018 100340 93506.672513
5019 100360 93585.072499
5020 100380 93663.476430
5021 100400 93741.884305
5022 100420 93820.296123
5023 100440 93898.711883
5024 100460 93977.131585
5025 100480 94055.555227
5026 100500 94133.982808
5027 100520 94212.414327
5028 100540 94290.849783
5029 100560 94369.289175
5030 100580 94447.732502
5031 100600 94526.179763
5032 100620 94604.630958
5033 100640 94683.086084
5034 100660 94761.545141
5035 100680 94840.008129
5036 100700 94918.475045
5037 100720 94996.945890
5038 100740 95075.420661
5039 100760 95153.899358
5040 100780 95232.381981
5041 100800 95310.868527
5042 100820 95389.358996
5043 100840 95467.853387
5044 100860 95546.351700
5045 100880 95624.853932
5046 100900 95703.360083
5047 100920 95781.870152
5048 100940 95860.384137
5049 100960 95938.902039
5050 100980 96017.423856
5051 101000 96095.949586
5052 101020 96174.479230
5053 101040 96253.012785
5054 101060 96331.550252
5055 101080 96410.091628
5056 101100 96488.636913
5057 101120 96567.186106
5058 101140 96645.739206
5059 101160 96724.296212
5060 101180 96802.857123
5061 101200 96881.421937
5062 101220 96959.990655
5063 101240 97038.563274
5064 101260 97117.139795
5065 101280 97195.720215
5066 101300 97274.304534
5067 101320 97352.892752
5068 101340 97431.484866
5069 101360 97510.080876
5070 101380 97588.680781
5071 101400 97667.284580
5072 101420 97745.892272
5073 101440 97824.503856
5074 101460 97903.119331
5075 101480 97981.738695
5076 101500 98060.361949
5077 101520 98138.989091
5078 101540 98217.620120
5079 101560 98296.255035
5080 101580 98374.893835
5081 101600 98453.536519
5082 101620 98532.183086
5083 101640 98610.833535
5084 101660 98689.487865
5085 101680 98768.146076
5086 101700 98846.808165
5087 101720 98925.474133
5088 101740 99004.143977
5089 101760 99082.817698
5090 101780 99161.495294
5091 101800 99240.176764
5092 101820 99318.862108
5093 101840 99397.551323
5094 101860 99476.244410
5095 101880 99554.941367
5096 101900 99633.642194
5097 101920 99712.346888
5098 101940 99791.055450
5099 101960 99869.767878
5100 101980 99948.484172
5101 102000 100027.204330
5102 102020 100105.928351
5103 102040 100184.656235
5104 102060 100263.387981
5105 102080 100342.123586
5106 102100 100420.863051
5107 102120 100499.606375
5108 102140 100578.353556
5109 102160 100657.104594
5110 102180 100735.859487
5111 102200 100814.618235
5112 102220 100893.380837
5113 102240 100972.147291
5114 102260 101050.917597
5115 102280 101129.691753
5116 102300 101208.469760
5117 102320 101287.251615
5118 102340 101366.037318
5119 102360 101444.826867
5120 102380 101523.620263
5121 102400 101602.417503
5122 102420 101681.218587
5123 102440 101760.023515
5124 102460 101838.832284
5125 102480 101917.644894
5126 102500 101996.461344
5127 102520 102075.281633
5128 102540 102154.105761
5129 102560 102232.933725
5130 102580 102311.765526
5131 102600 102390.601162
5132 102620 102469.440632
5133 102640 102548.283935
5134 102660 102627.131071
5135 102680 102705.982038
5136 102700 102784.836835
5137 102720 102863.695462
5138 102740 102942.557917
5139 102760 103021.424200
5140 102780 103100.294309
5141 102800 103179.168244
5142 102820 103258.046003
5143 102840 103336.927586
5144 102860 103415.812992
5145 102880 103494.702219
5146 102900 103573.595267
5147 102920 103652.492135
5148 102940 103731.392822
5149 102960 103810.297326
5150 102980 103889.205648
5151 103000 103968.117786
5152 103020 104047.033738
5153 103040 104125.953505
5154 103060 104204.877084
5155 103080 104283.804476
5156 103100 104362.735679
5157 103120 104441.670693
5158 103140 104520.609515
5159 103160 104599.552146
5160 103180 104678.498584
5161 103200 104757.448829
5162 103220 104836.402879
5163 103240 104915.360734
5164 103260 104994.322392
5165 103280 105073.287853
5166 103300 105152.257116
5167 103320 105231.230179
5168 103340 105310.207042
5169 103360 105389.187704
5170 103380 105468.172163
5171 103400 105547.160420
5172 103420 105626.152472
5173 103440 105705.148320
5174 103460 105784.147962
5175 103480 105863.151397
5176 103500 105942.158624
5177 103520 106021.169642
5178 103540 106100.184450
5179 103560 106179.203048
5180 103580 106258.225435
5181 103600 106337.251608
5182 103620 106416.281569
5183 103640 106495.315314
5184 103660 106574.352845
5185 103680 106653.394159
5186 103700 106732.439256
5187 103720 106811.488135
5188 103740 106890.540794
5189 103760 106969.597234
5190 103780 107048.657452
5191 103800 107127.721449
5192 103820 107206.789222
5193 103840 107285.860772
5194 103860 107364.936097
5195 103880 107444.015197
5196 103900 107523.098069
5197 103920 107602.184714
5198 103940 107681.275131
5199 103960 107760.369318
5200 103980 107839.467275
5201 104000 107918.569000
5202 104020 107997.674493
5203 104040 108076.783753
5204 104060 108155.896779
5205 104080 108235.013570
5206 104100 108314.134125
5207 104120 108393.258443
5208 104140 108472.386523
5209 104160 108551.518364
5210 104180 108630.653965
5211 104200 108709.793326
5212 104220 108788.936445
5213 104240 108868.083322
5214 104260 108947.233955
5215 104280 109026.388344
5216 104300 109105.546488
5217 104320 109184.708385
5218 104340 109263.874035
5219 104360 109343.043437
5220 104380 109422.216590
5221 104400 109501.393493
5222 104420 109580.574146
5223 104440 109659.758546
5224 104460 109738.946694
5225 104480 109818.138588
5226 104500 109897.334227
5227 104520 109976.533611
5228 104540 110055.736739
5229 104560 110134.943609
5230 104580 110214.154221
5231 104600 110293.368574
5232 104620 110372.586667
5233 104640 110451.808498
5234 104660 110531.034068
5235 104680 110610.263375
5236 104700 110689.496418
5237 104720 110768.733196
5238 104740 110847.973709
5239 104760 110927.217955
5240 104780 111006.465934
5241 104800 111085.717644
5242 104820 111164.973085
5243 104840 111244.232256
5244 104860 111323.495155
5245 104880 111402.761783
5246 104900 111482.032137
5247 104920 111561.306218
5248 104940 111640.584024
5249 104960 111719.865554
5250 104980 111799.150807
5251 105000 111878.439783
5252 105020 111957.732481
5253 105040 112037.028899
5254 105060 112116.329037
5255 105080 112195.632893
5256 105100 112274.940468
5257 105120 112354.251759
5258 105140 112433.566767
5259 105160 112512.885489
5260 105180 112592.207926
5261 105200 112671.534077
5262 105220 112750.863939
5263 105240 112830.197513
5264 105260 112909.534798
5265 105280 112988.875792
5266 105300 113068.220496
5267 105320 113147.568907
5268 105340 113226.921025
5269 105360 113306.276849
5270 105380 113385.636378
5271 105400 113464.999612
5272 105420 113544.366549
5273 105440 113623.737188
5274 105460 113703.111529
5275 105480 113782.489570
5276 105500 113861.871311
5277 105520 113941.256751
5278 105540 114020.645889
5279 105560 114100.038724
5280 105580 114179.435255
5281 105600 114258.835482
5282 105620 114338.239402
5283 105640 114417.647016
5284 105660 114497.058323
5285 105680 114576.473321
5286 105700 114655.892010
5287 105720 114735.314388
5288 105740 114814.740456
5289 105760 114894.170211
5290 105780 114973.603654
5291 105800 115053.040783
5292 105820 115132.481597
5293 105840 115211.926096
5294 105860 115291.374278
5295 105880 115370.826142
5296 105900 115450.281689
5297 105920 115529.740916
5298 105940 115609.203823
5299 105960 115688.670410
5300 105980 115768.140674
5301 106000 115847.614616
5302 106020 115927.092234
5303 106040 116006.573527
5304 106060 116086.058496
5305 106080 116165.547137
5306 106100 116245.039452
5307 106120 116324.535438
5308 106140 116404.035096
5309 106160 116483.538424
5310 106180 116563.045420
5311 106200 116642.556086
5312 106220 116722.070418
5313 106240 116801.588417
5314 106260 116881.110082
5315 106280 116960.635412
5316 106300 117040.164405
5317 106320 117119.697062
5318 106340 117199.233381
5319 106360 117278.773361
5320 106380 117358.317001
5321 106400 117437.864301
5322 106420 117517.415259
5323 106440 117596.969875
5324 106460 117676.528148
5325 106480 117756.090076
5326 106500 117835.655660
5327 106520 117915.224898
5328 106540 117994.797789
5329 106560 118074.374333
5330 106580 118153.954528
5331 106600 118233.538374
5332 106620 118313.125869
5333 106640 118392.717013
5334 106660 118472.311806
5335 106680 118551.910245
5336 106700 118631.512331
5337 106720 118711.118062
5338 106740 118790.727437
5339 106760 118870.340456
5340 106780 118949.957118
5341 106800 119029.577421
5342 106820 119109.201366
5343 106840 119188.828950
5344 106860 119268.460174
5345 106880 119348.095036
5346 106900 119427.733535
5347 106920 119507.375672
5348 106940 119587.021443
5349 106960 119666.670850
5350 106980 119746.323890
5351 107000 119825.980564
5352 107020 119905.640870
5353 107040 119985.304807
5354 107060 120064.972374
5355 107080 120144.643571
5356 107100 120224.318397
5357 107120 120303.996851
5358 107140 120383.678932
5359 107160 120463.364638
5360 107180 120543.053970
5361 107200 120622.746926
5362 107220 120702.443506
5363 107240 120782.143708
5364 107260 120861.847533
5365 107280 120941.554977
5366 107300 121021.266042
5367 107320 121100.980726
5368 107340 121180.699029
5369 107360 121260.420949
5370 107380 121340.146485
5371 107400 121419.875637
5372 107420 121499.608403
5373 107440 121579.344784
5374 107460 121659.084778
5375 107480 121738.828384
5376 107500 121818.575601
5377 107520 121898.326429
5378 107540 121978.080866
5379 107560 122057.838912
5380 107580 122137.600566
5381 107600 122217.365827
5382 107620 122297.134694
5383 107640 122376.907167
5384 107660 122456.683244
5385 107680 122536.462924
5386 107700 122616.246207
5387 107720 122696.033093
5388 107740 122775.823579
5389 107760 122855.617665
5390 107780 122935.415350
5391 107800 123015.216634
5392 107820 123095.021515
5393 107840 123174.829993
5394 107860 123254.642067
5395 107880 123334.457736
5396 107900 123414.276999
5397 107920 123494.099856
5398 107940 123573.926304
5399 107960 123653.756345
5400 107980 123733.589976
5401 108000 123813.427197
5402 108020 123893.268006
5403 108040 123973.112404
5404 108060 124052.960390
5405 108080 124132.811961
5406 108100 124212.667119
5407 108120 124292.525861
5408 108140 124372.388187
5409 108160 124452.254095
5410 108180 124532.123586
5411 108200 124611.996659
5412 108220 124691.873312
5413 108240 124771.753544
5414 108260 124851.637355
5415 108280 124931.524745
5416 108300 125011.415711
5417 108320 125091.310253
5418 108340 125171.208371
5419 108360 125251.110063
5420 108380 125331.015329
5421 108400 125410.924168
5422 108420 125490.836579
5423 108440 125570.752561
5424 108460 125650.672113
5425 108480 125730.595235
5426 108500 125810.521925
5427 108520 125890.452183
5428 108540 125970.386008
5429 108560 126050.323399
5430 108580 126130.264355
5431 108600 126210.208875
5432 108620 126290.156959
5433 108640 126370.108606
5434 108660 126450.063814
5435 108680 126530.022584
5436 108700 126609.984914
5437 108720 126689.950803
5438 108740 126769.920250
5439 108760 126849.893255
5440 108780 126929.869817
5441 108800 127009.849935
5442 108820 127089.833608
5443 108840 127169.820835
5444 108860 127249.811616
5445 108880 127329.805949
5446 108900 127409.803834
5447 108920 127489.805270
5448 108940 127569.810256
5449 108960 127649.818791
5450 108980 127729.830875
5451 109000 127809.846506
5452 109020 127889.865684
5453 109040 127969.888408
5454 109060 128049.914677
5455 109080 128129.944490
5456 109100 128209.977847
5457 109120 128290.014746
5458 109140 128370.055186
5459 109160 128450.099168
5460 109180 128530.146690
5461 109200 128610.197751
5462 109220 128690.252350
5463 109240 128770.310487
5464 109260 128850.372161
5465 109280 128930.437370
5466 109300 129010.506115
5467 109320 129090.578394
5468 109340 129170.654206
5469 109360 129250.733551
5470 109380 129330.816427
5471 109400 129410.902835
5472 109420 129490.992772
5473 109440 129571.086239
5474 109460 129651.183234
5475 109480 129731.283757
5476 109500 129811.387806
5477 109520 129891.495382
5478 109540 129971.606482
5479 109560 130051.721107
5480 109580 130131.839256
5481 109600 130211.960927
5482 109620 130292.086120
5483 109640 130372.214833
5484 109660 130452.347067
5485 109680 130532.482821
5486 109700 130612.622093
5487 109720 130692.764882
5488 109740 130772.911188
5489 109760 130853.061011
5490 109780 130933.214349
5491 109800 131013.371201
5492 109820 131093.531566
5493 109840 131173.695445
5494 109860 131253.862835
5495 109880 131334.033736
5496 109900 131414.208148
5497 109920 131494.386069
5498 109940 131574.567499
5499 109960 131654.752437
5500 109980 131734.940882
5501 110000 131815.132832

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