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 26 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
12502 250020 751625.424501
12503 250040 751719.898968
12504 250060 751814.374700
12505 250080 751908.851697
12506 250100 752003.329959
12507 250120 752097.809484
12508 250140 752192.290275
12509 250160 752286.772329
12510 250180 752381.255647
12511 250200 752475.740229
12512 250220 752570.226075
12513 250240 752664.713185
12514 250260 752759.201558
12515 250280 752853.691195
12516 250300 752948.182095
12517 250320 753042.674258
12518 250340 753137.167684
12519 250360 753231.662373
12520 250380 753326.158325
12521 250400 753420.655540
12522 250420 753515.154017
12523 250440 753609.653757
12524 250460 753704.154759
12525 250480 753798.657023
12526 250500 753893.160549
12527 250520 753987.665338
12528 250540 754082.171388
12529 250560 754176.678700
12530 250580 754271.187273
12531 250600 754365.697108
12532 250620 754460.208205
12533 250640 754554.720562
12534 250660 754649.234181
12535 250680 754743.749061
12536 250700 754838.265202
12537 250720 754932.782603
12538 250740 755027.301265
12539 250760 755121.821188
12540 250780 755216.342371
12541 250800 755310.864814
12542 250820 755405.388518
12543 250840 755499.913481
12544 250860 755594.439705
12545 250880 755688.967188
12546 250900 755783.495931
12547 250920 755878.025933
12548 250940 755972.557195
12549 250960 756067.089716
12550 250980 756161.623496
12551 251000 756256.158536
12552 251020 756350.694834
12553 251040 756445.232392
12554 251060 756539.771208
12555 251080 756634.311282
12556 251100 756728.852615
12557 251120 756823.395207
12558 251140 756917.939056
12559 251160 757012.484164
12560 251180 757107.030530
12561 251200 757201.578153
12562 251220 757296.127034
12563 251240 757390.677173
12564 251260 757485.228570
12565 251280 757579.781224
12566 251300 757674.335135
12567 251320 757768.890303
12568 251340 757863.446728
12569 251360 757958.004410
12570 251380 758052.563349
12571 251400 758147.123545
12572 251420 758241.684997
12573 251440 758336.247706
12574 251460 758430.811671
12575 251480 758525.376892
12576 251500 758619.943369
12577 251520 758714.511102
12578 251540 758809.080091
12579 251560 758903.650336
12580 251580 758998.221836
12581 251600 759092.794591
12582 251620 759187.368603
12583 251640 759281.943869
12584 251660 759376.520390
12585 251680 759471.098166
12586 251700 759565.677198
12587 251720 759660.257484
12588 251740 759754.839024
12589 251760 759849.421819
12590 251780 759944.005869
12591 251800 760038.591172
12592 251820 760133.177730
12593 251840 760227.765542
12594 251860 760322.354608
12595 251880 760416.944928
12596 251900 760511.536501
12597 251920 760606.129328
12598 251940 760700.723408
12599 251960 760795.318741
12600 251980 760889.915328
12601 252000 760984.513168
12602 252020 761079.112261
12603 252040 761173.712606
12604 252060 761268.314204
12605 252080 761362.917055
12606 252100 761457.521159
12607 252120 761552.126514
12608 252140 761646.733122
12609 252160 761741.340982
12610 252180 761835.950094
12611 252200 761930.560458
12612 252220 762025.172074
12613 252240 762119.784941
12614 252260 762214.399060
12615 252280 762309.014430
12616 252300 762403.631052
12617 252320 762498.248924
12618 252340 762592.868048
12619 252360 762687.488423
12620 252380 762782.110048
12621 252400 762876.732924
12622 252420 762971.357051
12623 252440 763065.982428
12624 252460 763160.609055
12625 252480 763255.236933
12626 252500 763349.866060
12627 252520 763444.496438
12628 252540 763539.128066
12629 252560 763633.760943
12630 252580 763728.395070
12631 252600 763823.030446
12632 252620 763917.667072
12633 252640 764012.304947
12634 252660 764106.944071
12635 252680 764201.584444
12636 252700 764296.226066
12637 252720 764390.868937
12638 252740 764485.513056
12639 252760 764580.158424
12640 252780 764674.805041
12641 252800 764769.452905
12642 252820 764864.102018
12643 252840 764958.752379
12644 252860 765053.403988
12645 252880 765148.056845
12646 252900 765242.710950
12647 252920 765337.366302
12648 252940 765432.022901
12649 252960 765526.680748
12650 252980 765621.339842
12651 253000 765716.000183
12652 253020 765810.661772
12653 253040 765905.324607
12654 253060 765999.988689
12655 253080 766094.654017
12656 253100 766189.320592
12657 253120 766283.988414
12658 253140 766378.657481
12659 253160 766473.327795
12660 253180 766567.999355
12661 253200 766662.672161
12662 253220 766757.346213
12663 253240 766852.021510
12664 253260 766946.698053
12665 253280 767041.375842
12666 253300 767136.054875
12667 253320 767230.735154
12668 253340 767325.416678
12669 253360 767420.099448
12670 253380 767514.783462
12671 253400 767609.468720
12672 253420 767704.155224
12673 253440 767798.842972
12674 253460 767893.531964
12675 253480 767988.222200
12676 253500 768082.913681
12677 253520 768177.606406
12678 253540 768272.300374
12679 253560 768366.995587
12680 253580 768461.692043
12681 253600 768556.389743
12682 253620 768651.088686
12683 253640 768745.788873
12684 253660 768840.490302
12685 253680 768935.192975
12686 253700 769029.896891
12687 253720 769124.602050
12688 253740 769219.308451
12689 253760 769314.016095
12690 253780 769408.724982
12691 253800 769503.435111
12692 253820 769598.146482
12693 253840 769692.859096
12694 253860 769787.572951
12695 253880 769882.288049
12696 253900 769977.004388
12697 253920 770071.721969
12698 253940 770166.440791
12699 253960 770261.160855
12700 253980 770355.882160
12701 254000 770450.604707
12702 254020 770545.328494
12703 254040 770640.053523
12704 254060 770734.779792
12705 254080 770829.507302
12706 254100 770924.236053
12707 254120 771018.966045
12708 254140 771113.697276
12709 254160 771208.429748
12710 254180 771303.163460
12711 254200 771397.898413
12712 254220 771492.634605
12713 254240 771587.372037
12714 254260 771682.110708
12715 254280 771776.850620
12716 254300 771871.591770
12717 254320 771966.334160
12718 254340 772061.077790
12719 254360 772155.822658
12720 254380 772250.568765
12721 254400 772345.316112
12722 254420 772440.064697
12723 254440 772534.814520
12724 254460 772629.565582
12725 254480 772724.317883
12726 254500 772819.071422
12727 254520 772913.826199
12728 254540 773008.582214
12729 254560 773103.339467
12730 254580 773198.097958
12731 254600 773292.857686
12732 254620 773387.618652
12733 254640 773482.380856
12734 254660 773577.144297
12735 254680 773671.908975
12736 254700 773766.674890
12737 254720 773861.442043
12738 254740 773956.210432
12739 254760 774050.980058
12740 254780 774145.750920
12741 254800 774240.523020
12742 254820 774335.296355
12743 254840 774430.070927
12744 254860 774524.846735
12745 254880 774619.623779
12746 254900 774714.402060
12747 254920 774809.181575
12748 254940 774903.962327
12749 254960 774998.744314
12750 254980 775093.527537
12751 255000 775188.311995
12752 255020 775283.097689
12753 255040 775377.884617
12754 255060 775472.672781
12755 255080 775567.462179
12756 255100 775662.252813
12757 255120 775757.044681
12758 255140 775851.837783
12759 255160 775946.632120
12760 255180 776041.427691
12761 255200 776136.224497
12762 255220 776231.022536
12763 255240 776325.821810
12764 255260 776420.622317
12765 255280 776515.424059
12766 255300 776610.227033
12767 255320 776705.031242
12768 255340 776799.836683
12769 255360 776894.643358
12770 255380 776989.451267
12771 255400 777084.260408
12772 255420 777179.070782
12773 255440 777273.882389
12774 255460 777368.695228
12775 255480 777463.509301
12776 255500 777558.324605
12777 255520 777653.141143
12778 255540 777747.958912
12779 255560 777842.777913
12780 255580 777937.598147
12781 255600 778032.419612
12782 255620 778127.242309
12783 255640 778222.066238
12784 255660 778316.891398
12785 255680 778411.717790
12786 255700 778506.545413
12787 255720 778601.374267
12788 255740 778696.204353
12789 255760 778791.035669
12790 255780 778885.868216
12791 255800 778980.701994
12792 255820 779075.537002
12793 255840 779170.373241
12794 255860 779265.210711
12795 255880 779360.049411
12796 255900 779454.889340
12797 255920 779549.730500
12798 255940 779644.572890
12799 255960 779739.416510
12800 255980 779834.261359
12801 256000 779929.107438
12802 256020 780023.954746
12803 256040 780118.803284
12804 256060 780213.653051
12805 256080 780308.504047
12806 256100 780403.356272
12807 256120 780498.209726
12808 256140 780593.064408
12809 256160 780687.920320
12810 256180 780782.777460
12811 256200 780877.635828
12812 256220 780972.495425
12813 256240 781067.356250
12814 256260 781162.218302
12815 256280 781257.081583
12816 256300 781351.946092
12817 256320 781446.811829
12818 256340 781541.678793
12819 256360 781636.546984
12820 256380 781731.416403
12821 256400 781826.287050
12822 256420 781921.158923
12823 256440 782016.032023
12824 256460 782110.906351
12825 256480 782205.781905
12826 256500 782300.658686
12827 256520 782395.536694
12828 256540 782490.415928
12829 256560 782585.296388
12830 256580 782680.178075
12831 256600 782775.060987
12832 256620 782869.945126
12833 256640 782964.830491
12834 256660 783059.717081
12835 256680 783154.604897
12836 256700 783249.493939
12837 256720 783344.384206
12838 256740 783439.275698
12839 256760 783534.168416
12840 256780 783629.062359
12841 256800 783723.957526
12842 256820 783818.853919
12843 256840 783913.751536
12844 256860 784008.650378
12845 256880 784103.550445
12846 256900 784198.451736
12847 256920 784293.354251
12848 256940 784388.257990
12849 256960 784483.162954
12850 256980 784578.069141
12851 257000 784672.976552
12852 257020 784767.885187
12853 257040 784862.795046
12854 257060 784957.706128
12855 257080 785052.618433
12856 257100 785147.531962
12857 257120 785242.446714
12858 257140 785337.362689
12859 257160 785432.279886
12860 257180 785527.198307
12861 257200 785622.117950
12862 257220 785717.038816
12863 257240 785811.960905
12864 257260 785906.884215
12865 257280 786001.808748
12866 257300 786096.734503
12867 257320 786191.661480
12868 257340 786286.589679
12869 257360 786381.519100
12870 257380 786476.449743
12871 257400 786571.381607
12872 257420 786666.314692
12873 257440 786761.248999
12874 257460 786856.184527
12875 257480 786951.121276
12876 257500 787046.059246
12877 257520 787140.998437
12878 257540 787235.938848
12879 257560 787330.880481
12880 257580 787425.823334
12881 257600 787520.767407
12882 257620 787615.712700
12883 257640 787710.659214
12884 257660 787805.606948
12885 257680 787900.555902
12886 257700 787995.506075
12887 257720 788090.457469
12888 257740 788185.410082
12889 257760 788280.363914
12890 257780 788375.318966
12891 257800 788470.275237
12892 257820 788565.232728
12893 257840 788660.191437
12894 257860 788755.151365
12895 257880 788850.112513
12896 257900 788945.074879
12897 257920 789040.038463
12898 257940 789135.003266
12899 257960 789229.969287
12900 257980 789324.936527
12901 258000 789419.904985
12902 258020 789514.874660
12903 258040 789609.845554
12904 258060 789704.817666
12905 258080 789799.790995
12906 258100 789894.765541
12907 258120 789989.741306
12908 258140 790084.718287
12909 258160 790179.696486
12910 258180 790274.675902
12911 258200 790369.656535
12912 258220 790464.638385
12913 258240 790559.621452
12914 258260 790654.605735
12915 258280 790749.591235
12916 258300 790844.577951
12917 258320 790939.565884
12918 258340 791034.555033
12919 258360 791129.545398
12920 258380 791224.536979
12921 258400 791319.529775
12922 258420 791414.523788
12923 258440 791509.519016
12924 258460 791604.515460
12925 258480 791699.513120
12926 258500 791794.511994
12927 258520 791889.512084
12928 258540 791984.513389
12929 258560 792079.515909
12930 258580 792174.519643
12931 258600 792269.524593
12932 258620 792364.530757
12933 258640 792459.538136
12934 258660 792554.546729
12935 258680 792649.556536
12936 258700 792744.567558
12937 258720 792839.579793
12938 258740 792934.593243
12939 258760 793029.607906
12940 258780 793124.623784
12941 258800 793219.640874
12942 258820 793314.659179
12943 258840 793409.678697
12944 258860 793504.699428
12945 258880 793599.721372
12946 258900 793694.744529
12947 258920 793789.768899
12948 258940 793884.794482
12949 258960 793979.821278
12950 258980 794074.849287
12951 259000 794169.878508
12952 259020 794264.908941
12953 259040 794359.940586
12954 259060 794454.973444
12955 259080 794550.007514
12956 259100 794645.042796
12957 259120 794740.079289
12958 259140 794835.116995
12959 259160 794930.155912
12960 259180 795025.196040
12961 259200 795120.237380
12962 259220 795215.279931
12963 259240 795310.323693
12964 259260 795405.368666
12965 259280 795500.414850
12966 259300 795595.462245
12967 259320 795690.510851
12968 259340 795785.560667
12969 259360 795880.611694
12970 259380 795975.663931
12971 259400 796070.717379
12972 259420 796165.772036
12973 259440 796260.827904
12974 259460 796355.884982
12975 259480 796450.943269
12976 259500 796546.002766
12977 259520 796641.063473
12978 259540 796736.125389
12979 259560 796831.188514
12980 259580 796926.252849
12981 259600 797021.318393
12982 259620 797116.385146
12983 259640 797211.453108
12984 259660 797306.522278
12985 259680 797401.592657
12986 259700 797496.664245
12987 259720 797591.737042
12988 259740 797686.811046
12989 259760 797781.886259
12990 259780 797876.962681
12991 259800 797972.040310
12992 259820 798067.119147
12993 259840 798162.199192
12994 259860 798257.280444
12995 259880 798352.362904
12996 259900 798447.446572
12997 259920 798542.531447
12998 259940 798637.617529
12999 259960 798732.704818
13000 259980 798827.793315
13001 260000 798922.883018

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