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 12 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
5502 110020 131895.328289
5503 110040 131975.527250
5504 110060 132055.729714
5505 110080 132135.935682
5506 110100 132216.145151
5507 110120 132296.358122
5508 110140 132376.574594
5509 110160 132456.794565
5510 110180 132537.018035
5511 110200 132617.245002
5512 110220 132697.475468
5513 110240 132777.709429
5514 110260 132857.946886
5515 110280 132938.187838
5516 110300 133018.432284
5517 110320 133098.680223
5518 110340 133178.931654
5519 110360 133259.186577
5520 110380 133339.444991
5521 110400 133419.706894
5522 110420 133499.972287
5523 110440 133580.241168
5524 110460 133660.513536
5525 110480 133740.789391
5526 110500 133821.068732
5527 110520 133901.351558
5528 110540 133981.637868
5529 110560 134061.927661
5530 110580 134142.220937
5531 110600 134222.517695
5532 110620 134302.817934
5533 110640 134383.121653
5534 110660 134463.428851
5535 110680 134543.739528
5536 110700 134624.053683
5537 110720 134704.371315
5538 110740 134784.692423
5539 110760 134865.017006
5540 110780 134945.345064
5541 110800 135025.676595
5542 110820 135106.011600
5543 110840 135186.350076
5544 110860 135266.692024
5545 110880 135347.037443
5546 110900 135427.386331
5547 110920 135507.738688
5548 110940 135588.094513
5549 110960 135668.453806
5550 110980 135748.816565
5551 111000 135829.182789
5552 111020 135909.552479
5553 111040 135989.925633
5554 111060 136070.302250
5555 111080 136150.682329
5556 111100 136231.065870
5557 111120 136311.452873
5558 111140 136391.843335
5559 111160 136472.237256
5560 111180 136552.634636
5561 111200 136633.035474
5562 111220 136713.439769
5563 111240 136793.847520
5564 111260 136874.258726
5565 111280 136954.673387
5566 111300 137035.091501
5567 111320 137115.513068
5568 111340 137195.938088
5569 111360 137276.366559
5570 111380 137356.798480
5571 111400 137437.233851
5572 111420 137517.672671
5573 111440 137598.114940
5574 111460 137678.560655
5575 111480 137759.009818
5576 111500 137839.462426
5577 111520 137919.918479
5578 111540 138000.377976
5579 111560 138080.840916
5580 111580 138161.307300
5581 111600 138241.777125
5582 111620 138322.250391
5583 111640 138402.727097
5584 111660 138483.207243
5585 111680 138563.690828
5586 111700 138644.177850
5587 111720 138724.668309
5588 111740 138805.162205
5589 111760 138885.659536
5590 111780 138966.160302
5591 111800 139046.664502
5592 111820 139127.172135
5593 111840 139207.683201
5594 111860 139288.197698
5595 111880 139368.715626
5596 111900 139449.236983
5597 111920 139529.761770
5598 111940 139610.289986
5599 111960 139690.821629
5600 111980 139771.356699
5601 112000 139851.895195
5602 112020 139932.437116
5603 112040 140012.982462
5604 112060 140093.531232
5605 112080 140174.083424
5606 112100 140254.639039
5607 112120 140335.198075
5608 112140 140415.760532
5609 112160 140496.326408
5610 112180 140576.895703
5611 112200 140657.468417
5612 112220 140738.044548
5613 112240 140818.624096
5614 112260 140899.207060
5615 112280 140979.793439
5616 112300 141060.383232
5617 112320 141140.976439
5618 112340 141221.573059
5619 112360 141302.173090
5620 112380 141382.776533
5621 112400 141463.383387
5622 112420 141543.993650
5623 112440 141624.607322
5624 112460 141705.224402
5625 112480 141785.844889
5626 112500 141866.468783
5627 112520 141947.096083
5628 112540 142027.726788
5629 112560 142108.360897
5630 112580 142188.998409
5631 112600 142269.639324
5632 112620 142350.283641
5633 112640 142430.931360
5634 112660 142511.582478
5635 112680 142592.236997
5636 112700 142672.894914
5637 112720 142753.556229
5638 112740 142834.220941
5639 112760 142914.889050
5640 112780 142995.560555
5641 112800 143076.235455
5642 112820 143156.913748
5643 112840 143237.595436
5644 112860 143318.280516
5645 112880 143398.968987
5646 112900 143479.660850
5647 112920 143560.356104
5648 112940 143641.054747
5649 112960 143721.756778
5650 112980 143802.462198
5651 113000 143883.171005
5652 113020 143963.883198
5653 113040 144044.598778
5654 113060 144125.317742
5655 113080 144206.040090
5656 113100 144286.765822
5657 113120 144367.494937
5658 113140 144448.227433
5659 113160 144528.963311
5660 113180 144609.702569
5661 113200 144690.445206
5662 113220 144771.191223
5663 113240 144851.940617
5664 113260 144932.693389
5665 113280 145013.449537
5666 113300 145094.209061
5667 113320 145174.971960
5668 113340 145255.738234
5669 113360 145336.507881
5670 113380 145417.280900
5671 113400 145498.057292
5672 113420 145578.837055
5673 113440 145659.620188
5674 113460 145740.406691
5675 113480 145821.196563
5676 113500 145901.989803
5677 113520 145982.786411
5678 113540 146063.586385
5679 113560 146144.389725
5680 113580 146225.196431
5681 113600 146306.006500
5682 113620 146386.819933
5683 113640 146467.636729
5684 113660 146548.456888
5685 113680 146629.280407
5686 113700 146710.107287
5687 113720 146790.937527
5688 113740 146871.771126
5689 113760 146952.608084
5690 113780 147033.448399
5691 113800 147114.292071
5692 113820 147195.139098
5693 113840 147275.989481
5694 113860 147356.843219
5695 113880 147437.700311
5696 113900 147518.560755
5697 113920 147599.424552
5698 113940 147680.291700
5699 113960 147761.162199
5700 113980 147842.036048
5701 114000 147922.913247
5702 114020 148003.793794
5703 114040 148084.677688
5704 114060 148165.564930
5705 114080 148246.455518
5706 114100 148327.349452
5707 114120 148408.246730
5708 114140 148489.147352
5709 114160 148570.051318
5710 114180 148650.958626
5711 114200 148731.869276
5712 114220 148812.783267
5713 114240 148893.700598
5714 114260 148974.621268
5715 114280 149055.545278
5716 114300 149136.472625
5717 114320 149217.403310
5718 114340 149298.337331
5719 114360 149379.274688
5720 114380 149460.215381
5721 114400 149541.159407
5722 114420 149622.106767
5723 114440 149703.057460
5724 114460 149784.011484
5725 114480 149864.968841
5726 114500 149945.929527
5727 114520 150026.893544
5728 114540 150107.860889
5729 114560 150188.831563
5730 114580 150269.805565
5731 114600 150350.782893
5732 114620 150431.763548
5733 114640 150512.747528
5734 114660 150593.734832
5735 114680 150674.725461
5736 114700 150755.719412
5737 114720 150836.716686
5738 114740 150917.717282
5739 114760 150998.721198
5740 114780 151079.728435
5741 114800 151160.738991
5742 114820 151241.752866
5743 114840 151322.770059
5744 114860 151403.790569
5745 114880 151484.814395
5746 114900 151565.841537
5747 114920 151646.871995
5748 114940 151727.905766
5749 114960 151808.942851
5750 114980 151889.983249
5751 115000 151971.026959
5752 115020 152052.073980
5753 115040 152133.124312
5754 115060 152214.177953
5755 115080 152295.234904
5756 115100 152376.295163
5757 115120 152457.358730
5758 115140 152538.425604
5759 115160 152619.495784
5760 115180 152700.569269
5761 115200 152781.646059
5762 115220 152862.726153
5763 115240 152943.809550
5764 115260 153024.896250
5765 115280 153105.986251
5766 115300 153187.079554
5767 115320 153268.176157
5768 115340 153349.276059
5769 115360 153430.379260
5770 115380 153511.485760
5771 115400 153592.595557
5772 115420 153673.708650
5773 115440 153754.825039
5774 115460 153835.944724
5775 115480 153917.067703
5776 115500 153998.193975
5777 115520 154079.323541
5778 115540 154160.456399
5779 115560 154241.592549
5780 115580 154322.731989
5781 115600 154403.874720
5782 115620 154485.020739
5783 115640 154566.170048
5784 115660 154647.322644
5785 115680 154728.478528
5786 115700 154809.637698
5787 115720 154890.800153
5788 115740 154971.965894
5789 115760 155053.134919
5790 115780 155134.307228
5791 115800 155215.482819
5792 115820 155296.661693
5793 115840 155377.843848
5794 115860 155459.029283
5795 115880 155540.217999
5796 115900 155621.409993
5797 115920 155702.605267
5798 115940 155783.803817
5799 115960 155865.005645
5800 115980 155946.210750
5801 116000 156027.419130
5802 116020 156108.630784
5803 116040 156189.845713
5804 116060 156271.063916
5805 116080 156352.285391
5806 116100 156433.510138
5807 116120 156514.738156
5808 116140 156595.969445
5809 116160 156677.204004
5810 116180 156758.441832
5811 116200 156839.682928
5812 116220 156920.927292
5813 116240 157002.174922
5814 116260 157083.425820
5815 116280 157164.679982
5816 116300 157245.937410
5817 116320 157327.198101
5818 116340 157408.462056
5819 116360 157489.729273
5820 116380 157570.999753
5821 116400 157652.273494
5822 116420 157733.550495
5823 116440 157814.830756
5824 116460 157896.114276
5825 116480 157977.401054
5826 116500 158058.691090
5827 116520 158139.984383
5828 116540 158221.280932
5829 116560 158302.580737
5830 116580 158383.883797
5831 116600 158465.190110
5832 116620 158546.499677
5833 116640 158627.812497
5834 116660 158709.128568
5835 116680 158790.447891
5836 116700 158871.770464
5837 116720 158953.096287
5838 116740 159034.425359
5839 116760 159115.757680
5840 116780 159197.093248
5841 116800 159278.432063
5842 116820 159359.774124
5843 116840 159441.119431
5844 116860 159522.467983
5845 116880 159603.819779
5846 116900 159685.174818
5847 116920 159766.533100
5848 116940 159847.894624
5849 116960 159929.259390
5850 116980 160010.627395
5851 117000 160091.998641
5852 117020 160173.373126
5853 117040 160254.750849
5854 117060 160336.131810
5855 117080 160417.516009
5856 117100 160498.903443
5857 117120 160580.294113
5858 117140 160661.688018
5859 117160 160743.085158
5860 117180 160824.485530
5861 117200 160905.889136
5862 117220 160987.295974
5863 117240 161068.706043
5864 117260 161150.119343
5865 117280 161231.535872
5866 117300 161312.955632
5867 117320 161394.378619
5868 117340 161475.804835
5869 117360 161557.234278
5870 117380 161638.666947
5871 117400 161720.102842
5872 117420 161801.541962
5873 117440 161882.984307
5874 117460 161964.429875
5875 117480 162045.878666
5876 117500 162127.330679
5877 117520 162208.785914
5878 117540 162290.244370
5879 117560 162371.706046
5880 117580 162453.170942
5881 117600 162534.639056
5882 117620 162616.110389
5883 117640 162697.584939
5884 117660 162779.062705
5885 117680 162860.543688
5886 117700 162942.027885
5887 117720 163023.515298
5888 117740 163105.005924
5889 117760 163186.499763
5890 117780 163267.996815
5891 117800 163349.497079
5892 117820 163431.000554
5893 117840 163512.507239
5894 117860 163594.017134
5895 117880 163675.530238
5896 117900 163757.046551
5897 117920 163838.566071
5898 117940 163920.088798
5899 117960 164001.614731
5900 117980 164083.143870
5901 118000 164164.676213
5902 118020 164246.211761
5903 118040 164327.750513
5904 118060 164409.292467
5905 118080 164490.837623
5906 118100 164572.385980
5907 118120 164653.937539
5908 118140 164735.492297
5909 118160 164817.050254
5910 118180 164898.611411
5911 118200 164980.175765
5912 118220 165061.743316
5913 118240 165143.314064
5914 118260 165224.888008
5915 118280 165306.465147
5916 118300 165388.045481
5917 118320 165469.629008
5918 118340 165551.215729
5919 118360 165632.805641
5920 118380 165714.398746
5921 118400 165795.995042
5922 118420 165877.594528
5923 118440 165959.197204
5924 118460 166040.803068
5925 118480 166122.412121
5926 118500 166204.024362
5927 118520 166285.639789
5928 118540 166367.258403
5929 118560 166448.880203
5930 118580 166530.505187
5931 118600 166612.133355
5932 118620 166693.764707
5933 118640 166775.399242
5934 118660 166857.036959
5935 118680 166938.677857
5936 118700 167020.321937
5937 118720 167101.969196
5938 118740 167183.619634
5939 118760 167265.273252
5940 118780 167346.930047
5941 118800 167428.590020
5942 118820 167510.253169
5943 118840 167591.919495
5944 118860 167673.588995
5945 118880 167755.261671
5946 118900 167836.937520
5947 118920 167918.616542
5948 118940 168000.298737
5949 118960 168081.984104
5950 118980 168163.672643
5951 119000 168245.364352
5952 119020 168327.059230
5953 119040 168408.757278
5954 119060 168490.458494
5955 119080 168572.162879
5956 119100 168653.870430
5957 119120 168735.581148
5958 119140 168817.295031
5959 119160 168899.012080
5960 119180 168980.732293
5961 119200 169062.455670
5962 119220 169144.182210
5963 119240 169225.911912
5964 119260 169307.644777
5965 119280 169389.380802
5966 119300 169471.119987
5967 119320 169552.862333
5968 119340 169634.607837
5969 119360 169716.356500
5970 119380 169798.108320
5971 119400 169879.863298
5972 119420 169961.621431
5973 119440 170043.382721
5974 119460 170125.147165
5975 119480 170206.914764
5976 119500 170288.685516
5977 119520 170370.459421
5978 119540 170452.236479
5979 119560 170534.016688
5980 119580 170615.800048
5981 119600 170697.586559
5982 119620 170779.376219
5983 119640 170861.169028
5984 119660 170942.964985
5985 119680 171024.764090
5986 119700 171106.566341
5987 119720 171188.371739
5988 119740 171270.180283
5989 119760 171351.991972
5990 119780 171433.806804
5991 119800 171515.624781
5992 119820 171597.445900
5993 119840 171679.270161
5994 119860 171761.097565
5995 119880 171842.928109
5996 119900 171924.761793
5997 119920 172006.598617
5998 119940 172088.438579
5999 119960 172170.281680
6000 119980 172252.127919
6001 120000 172333.977294

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