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 25 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
12002 240020 704549.213012
12003 240040 704643.039376
12004 240060 704736.867068
12005 240080 704830.696089
12006 240100 704924.526438
12007 240120 705018.358115
12008 240140 705112.191121
12009 240160 705206.025454
12010 240180 705299.861115
12011 240200 705393.698103
12012 240220 705487.536419
12013 240240 705581.376062
12014 240260 705675.217032
12015 240280 705769.059329
12016 240300 705862.902954
12017 240320 705956.747905
12018 240340 706050.594182
12019 240360 706144.441786
12020 240380 706238.290717
12021 240400 706332.140973
12022 240420 706425.992556
12023 240440 706519.845465
12024 240460 706613.699700
12025 240480 706707.555260
12026 240500 706801.412146
12027 240520 706895.270357
12028 240540 706989.129894
12029 240560 707082.990756
12030 240580 707176.852943
12031 240600 707270.716455
12032 240620 707364.581291
12033 240640 707458.447452
12034 240660 707552.314938
12035 240680 707646.183748
12036 240700 707740.053882
12037 240720 707833.925341
12038 240740 707927.798123
12039 240760 708021.672230
12040 240780 708115.547660
12041 240800 708209.424413
12042 240820 708303.302490
12043 240840 708397.181890
12044 240860 708491.062614
12045 240880 708584.944661
12046 240900 708678.828030
12047 240920 708772.712722
12048 240940 708866.598737
12049 240960 708960.486075
12050 240980 709054.374735
12051 241000 709148.264717
12052 241020 709242.156021
12053 241040 709336.048647
12054 241060 709429.942595
12055 241080 709523.837865
12056 241100 709617.734456
12057 241120 709711.632369
12058 241140 709805.531603
12059 241160 709899.432159
12060 241180 709993.334035
12061 241200 710087.237233
12062 241220 710181.141751
12063 241240 710275.047590
12064 241260 710368.954749
12065 241280 710462.863229
12066 241300 710556.773029
12067 241320 710650.684149
12068 241340 710744.596589
12069 241360 710838.510349
12070 241380 710932.425429
12071 241400 711026.341829
12072 241420 711120.259548
12073 241440 711214.178586
12074 241460 711308.098943
12075 241480 711402.020620
12076 241500 711495.943616
12077 241520 711589.867930
12078 241540 711683.793563
12079 241560 711777.720515
12080 241580 711871.648785
12081 241600 711965.578373
12082 241620 712059.509280
12083 241640 712153.441504
12084 241660 712247.375047
12085 241680 712341.309907
12086 241700 712435.246085
12087 241720 712529.183580
12088 241740 712623.122393
12089 241760 712717.062523
12090 241780 712811.003970
12091 241800 712904.946734
12092 241820 712998.890815
12093 241840 713092.836213
12094 241860 713186.782927
12095 241880 713280.730958
12096 241900 713374.680305
12097 241920 713468.630968
12098 241940 713562.582947
12099 241960 713656.536242
12100 241980 713750.490854
12101 242000 713844.446780
12102 242020 713938.404022
12103 242040 714032.362580
12104 242060 714126.322453
12105 242080 714220.283641
12106 242100 714314.246144
12107 242120 714408.209962
12108 242140 714502.175095
12109 242160 714596.141542
12110 242180 714690.109304
12111 242200 714784.078380
12112 242220 714878.048771
12113 242240 714972.020475
12114 242260 715065.993494
12115 242280 715159.967826
12116 242300 715253.943472
12117 242320 715347.920432
12118 242340 715441.898705
12119 242360 715535.878291
12120 242380 715629.859191
12121 242400 715723.841403
12122 242420 715817.824929
12123 242440 715911.809767
12124 242460 716005.795918
12125 242480 716099.783382
12126 242500 716193.772158
12127 242520 716287.762246
12128 242540 716381.753646
12129 242560 716475.746359
12130 242580 716569.740383
12131 242600 716663.735719
12132 242620 716757.732366
12133 242640 716851.730325
12134 242660 716945.729596
12135 242680 717039.730177
12136 242700 717133.732070
12137 242720 717227.735274
12138 242740 717321.739788
12139 242760 717415.745614
12140 242780 717509.752750
12141 242800 717603.761196
12142 242820 717697.770952
12143 242840 717791.782019
12144 242860 717885.794396
12145 242880 717979.808083
12146 242900 718073.823079
12147 242920 718167.839386
12148 242940 718261.857001
12149 242960 718355.875927
12150 242980 718449.896161
12151 243000 718543.917705
12152 243020 718637.940557
12153 243040 718731.964719
12154 243060 718825.990189
12155 243080 718920.016968
12156 243100 719014.045055
12157 243120 719108.074451
12158 243140 719202.105155
12159 243160 719296.137167
12160 243180 719390.170487
12161 243200 719484.205115
12162 243220 719578.241051
12163 243240 719672.278294
12164 243260 719766.316844
12165 243280 719860.356702
12166 243300 719954.397868
12167 243320 720048.440340
12168 243340 720142.484119
12169 243360 720236.529205
12170 243380 720330.575598
12171 243400 720424.623297
12172 243420 720518.672303
12173 243440 720612.722615
12174 243460 720706.774233
12175 243480 720800.827157
12176 243500 720894.881387
12177 243520 720988.936923
12178 243540 721082.993765
12179 243560 721177.051912
12180 243580 721271.111364
12181 243600 721365.172122
12182 243620 721459.234185
12183 243640 721553.297552
12184 243660 721647.362225
12185 243680 721741.428203
12186 243700 721835.495485
12187 243720 721929.564071
12188 243740 722023.633962
12189 243760 722117.705157
12190 243780 722211.777656
12191 243800 722305.851460
12192 243820 722399.926567
12193 243840 722494.002977
12194 243860 722588.080692
12195 243880 722682.159709
12196 243900 722776.240031
12197 243920 722870.321655
12198 243940 722964.404582
12199 243960 723058.488813
12200 243980 723152.574346
12201 244000 723246.661181
12202 244020 723340.749320
12203 244040 723434.838761
12204 244060 723528.929504
12205 244080 723623.021549
12206 244100 723717.114896
12207 244120 723811.209545
12208 244140 723905.305496
12209 244160 723999.402749
12210 244180 724093.501303
12211 244200 724187.601159
12212 244220 724281.702316
12213 244240 724375.804774
12214 244260 724469.908533
12215 244280 724564.013592
12216 244300 724658.119953
12217 244320 724752.227614
12218 244340 724846.336576
12219 244360 724940.446838
12220 244380 725034.558401
12221 244400 725128.671263
12222 244420 725222.785425
12223 244440 725316.900888
12224 244460 725411.017650
12225 244480 725505.135711
12226 244500 725599.255073
12227 244520 725693.375733
12228 244540 725787.497693
12229 244560 725881.620951
12230 244580 725975.745509
12231 244600 726069.871366
12232 244620 726163.998521
12233 244640 726258.126975
12234 244660 726352.256727
12235 244680 726446.387778
12236 244700 726540.520127
12237 244720 726634.653773
12238 244740 726728.788718
12239 244760 726822.924961
12240 244780 726917.062501
12241 244800 727011.201339
12242 244820 727105.341474
12243 244840 727199.482907
12244 244860 727293.625637
12245 244880 727387.769663
12246 244900 727481.914987
12247 244920 727576.061608
12248 244940 727670.209525
12249 244960 727764.358738
12250 244980 727858.509249
12251 245000 727952.661055
12252 245020 728046.814157
12253 245040 728140.968556
12254 245060 728235.124250
12255 245080 728329.281241
12256 245100 728423.439527
12257 245120 728517.599108
12258 245140 728611.759985
12259 245160 728705.922157
12260 245180 728800.085624
12261 245200 728894.250386
12262 245220 728988.416443
12263 245240 729082.583795
12264 245260 729176.752441
12265 245280 729270.922382
12266 245300 729365.093618
12267 245320 729459.266147
12268 245340 729553.439971
12269 245360 729647.615088
12270 245380 729741.791500
12271 245400 729835.969205
12272 245420 729930.148204
12273 245440 730024.328496
12274 245460 730118.510082
12275 245480 730212.692961
12276 245500 730306.877133
12277 245520 730401.062598
12278 245540 730495.249355
12279 245560 730589.437406
12280 245580 730683.626749
12281 245600 730777.817385
12282 245620 730872.009313
12283 245640 730966.202533
12284 245660 731060.397045
12285 245680 731154.592849
12286 245700 731248.789945
12287 245720 731342.988333
12288 245740 731437.188012
12289 245760 731531.388983
12290 245780 731625.591245
12291 245800 731719.794798
12292 245820 731813.999643
12293 245840 731908.205778
12294 245860 732002.413204
12295 245880 732096.621921
12296 245900 732190.831928
12297 245920 732285.043226
12298 245940 732379.255814
12299 245960 732473.469692
12300 245980 732567.684861
12301 246000 732661.901319
12302 246020 732756.119067
12303 246040 732850.338105
12304 246060 732944.558432
12305 246080 733038.780049
12306 246100 733133.002955
12307 246120 733227.227150
12308 246140 733321.452635
12309 246160 733415.679408
12310 246180 733509.907470
12311 246200 733604.136820
12312 246220 733698.367460
12313 246240 733792.599387
12314 246260 733886.832603
12315 246280 733981.067107
12316 246300 734075.302900
12317 246320 734169.539980
12318 246340 734263.778348
12319 246360 734358.018003
12320 246380 734452.258946
12321 246400 734546.501177
12322 246420 734640.744695
12323 246440 734734.989499
12324 246460 734829.235591
12325 246480 734923.482970
12326 246500 735017.731636
12327 246520 735111.981588
12328 246540 735206.232827
12329 246560 735300.485352
12330 246580 735394.739164
12331 246600 735488.994262
12332 246620 735583.250645
12333 246640 735677.508315
12334 246660 735771.767271
12335 246680 735866.027512
12336 246700 735960.289038
12337 246720 736054.551850
12338 246740 736148.815947
12339 246760 736243.081330
12340 246780 736337.347997
12341 246800 736431.615950
12342 246820 736525.885187
12343 246840 736620.155709
12344 246860 736714.427515
12345 246880 736808.700606
12346 246900 736902.974981
12347 246920 736997.250640
12348 246940 737091.527583
12349 246960 737185.805810
12350 246980 737280.085321
12351 247000 737374.366115
12352 247020 737468.648193
12353 247040 737562.931555
12354 247060 737657.216199
12355 247080 737751.502127
12356 247100 737845.789338
12357 247120 737940.077832
12358 247140 738034.367608
12359 247160 738128.658668
12360 247180 738222.951009
12361 247200 738317.244633
12362 247220 738411.539540
12363 247240 738505.835728
12364 247260 738600.133199
12365 247280 738694.431951
12366 247300 738788.731985
12367 247320 738883.033301
12368 247340 738977.335899
12369 247360 739071.639777
12370 247380 739165.944938
12371 247400 739260.251379
12372 247420 739354.559101
12373 247440 739448.868104
12374 247460 739543.178388
12375 247480 739637.489953
12376 247500 739731.802798
12377 247520 739826.116923
12378 247540 739920.432329
12379 247560 740014.749015
12380 247580 740109.066981
12381 247600 740203.386227
12382 247620 740297.706752
12383 247640 740392.028558
12384 247660 740486.351642
12385 247680 740580.676007
12386 247700 740675.001650
12387 247720 740769.328573
12388 247740 740863.656775
12389 247760 740957.986255
12390 247780 741052.317015
12391 247800 741146.649053
12392 247820 741240.982369
12393 247840 741335.316964
12394 247860 741429.652838
12395 247880 741523.989989
12396 247900 741618.328419
12397 247920 741712.668126
12398 247940 741807.009111
12399 247960 741901.351374
12400 247980 741995.694915
12401 248000 742090.039732
12402 248020 742184.385827
12403 248040 742278.733200
12404 248060 742373.081849
12405 248080 742467.431775
12406 248100 742561.782979
12407 248120 742656.135458
12408 248140 742750.489215
12409 248160 742844.844247
12410 248180 742939.200556
12411 248200 743033.558142
12412 248220 743127.917003
12413 248240 743222.277140
12414 248260 743316.638553
12415 248280 743411.001242
12416 248300 743505.365206
12417 248320 743599.730446
12418 248340 743694.096961
12419 248360 743788.464751
12420 248380 743882.833817
12421 248400 743977.204157
12422 248420 744071.575772
12423 248440 744165.948662
12424 248460 744260.322826
12425 248480 744354.698265
12426 248500 744449.074978
12427 248520 744543.452965
12428 248540 744637.832227
12429 248560 744732.212762
12430 248580 744826.594571
12431 248600 744920.977654
12432 248620 745015.362011
12433 248640 745109.747641
12434 248660 745204.134544
12435 248680 745298.522720
12436 248700 745392.912170
12437 248720 745487.302893
12438 248740 745581.694888
12439 248760 745676.088156
12440 248780 745770.482697
12441 248800 745864.878510
12442 248820 745959.275596
12443 248840 746053.673954
12444 248860 746148.073584
12445 248880 746242.474486
12446 248900 746336.876659
12447 248920 746431.280105
12448 248940 746525.684822
12449 248960 746620.090811
12450 248980 746714.498071
12451 249000 746808.906602
12452 249020 746903.316404
12453 249040 746997.727478
12454 249060 747092.139822
12455 249080 747186.553437
12456 249100 747280.968323
12457 249120 747375.384479
12458 249140 747469.801905
12459 249160 747564.220602
12460 249180 747658.640569
12461 249200 747753.061806
12462 249220 747847.484313
12463 249240 747941.908090
12464 249260 748036.333136
12465 249280 748130.759452
12466 249300 748225.187037
12467 249320 748319.615892
12468 249340 748414.046015
12469 249360 748508.477408
12470 249380 748602.910070
12471 249400 748697.344000
12472 249420 748791.779199
12473 249440 748886.215667
12474 249460 748980.653403
12475 249480 749075.092408
12476 249500 749169.532680
12477 249520 749263.974221
12478 249540 749358.417030
12479 249560 749452.861106
12480 249580 749547.306450
12481 249600 749641.753062
12482 249620 749736.200941
12483 249640 749830.650088
12484 249660 749925.100501
12485 249680 750019.552182
12486 249700 750114.005130
12487 249720 750208.459344
12488 249740 750302.914826
12489 249760 750397.371573
12490 249780 750491.829588
12491 249800 750586.288869
12492 249820 750680.749416
12493 249840 750775.211229
12494 249860 750869.674308
12495 249880 750964.138653
12496 249900 751058.604263
12497 249920 751153.071139
12498 249940 751247.539281
12499 249960 751342.008688
12500 249980 751436.479361
12501 250000 751530.951298

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