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 8 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
3502 70020 -20083.897667
3503 70040 -20013.029505
3504 70060 -19942.155011
3505 70080 -19871.274187
3506 70100 -19800.387037
3507 70120 -19729.493562
3508 70140 -19658.593765
3509 70160 -19587.687649
3510 70180 -19516.775215
3511 70200 -19445.856466
3512 70220 -19374.931404
3513 70240 -19304.000033
3514 70260 -19233.062354
3515 70280 -19162.118370
3516 70300 -19091.168083
3517 70320 -19020.211495
3518 70340 -18949.248609
3519 70360 -18878.279428
3520 70380 -18807.303953
3521 70400 -18736.322187
3522 70420 -18665.334133
3523 70440 -18594.339793
3524 70460 -18523.339169
3525 70480 -18452.332263
3526 70500 -18381.319079
3527 70520 -18310.299618
3528 70540 -18239.273883
3529 70560 -18168.241876
3530 70580 -18097.203599
3531 70600 -18026.159056
3532 70620 -17955.108248
3533 70640 -17884.051177
3534 70660 -17812.987846
3535 70680 -17741.918258
3536 70700 -17670.842414
3537 70720 -17599.760318
3538 70740 -17528.671971
3539 70760 -17457.577376
3540 70780 -17386.476535
3541 70800 -17315.369451
3542 70820 -17244.256125
3543 70840 -17173.136561
3544 70860 -17102.010760
3545 70880 -17030.878726
3546 70900 -16959.740459
3547 70920 -16888.595964
3548 70940 -16817.445241
3549 70960 -16746.288294
3550 70980 -16675.125124
3551 71000 -16603.955734
3552 71020 -16532.780127
3553 71040 -16461.598305
3554 71060 -16390.410269
3555 71080 -16319.216023
3556 71100 -16248.015569
3557 71120 -16176.808908
3558 71140 -16105.596045
3559 71160 -16034.376979
3560 71180 -15963.151715
3561 71200 -15891.920254
3562 71220 -15820.682599
3563 71240 -15749.438752
3564 71260 -15678.188715
3565 71280 -15606.932491
3566 71300 -15535.670081
3567 71320 -15464.401489
3568 71340 -15393.126717
3569 71360 -15321.845767
3570 71380 -15250.558640
3571 71400 -15179.265341
3572 71420 -15107.965870
3573 71440 -15036.660230
3574 71460 -14965.348423
3575 71480 -14894.030453
3576 71500 -14822.706320
3577 71520 -14751.376028
3578 71540 -14680.039578
3579 71560 -14608.696974
3580 71580 -14537.348216
3581 71600 -14465.993308
3582 71620 -14394.632252
3583 71640 -14323.265050
3584 71660 -14251.891705
3585 71680 -14180.512218
3586 71700 -14109.126592
3587 71720 -14037.734829
3588 71740 -13966.336932
3589 71760 -13894.932903
3590 71780 -13823.522744
3591 71800 -13752.106457
3592 71820 -13680.684045
3593 71840 -13609.255510
3594 71860 -13537.820854
3595 71880 -13466.380079
3596 71900 -13394.933188
3597 71920 -13323.480184
3598 71940 -13252.021067
3599 71960 -13180.555841
3600 71980 -13109.084508
3601 72000 -13037.607070
3602 72020 -12966.123529
3603 72040 -12894.633888
3604 72060 -12823.138149
3605 72080 -12751.636314
3606 72100 -12680.128385
3607 72120 -12608.614365
3608 72140 -12537.094256
3609 72160 -12465.568060
3610 72180 -12394.035779
3611 72200 -12322.497416
3612 72220 -12250.952973
3613 72240 -12179.402451
3614 72260 -12107.845855
3615 72280 -12036.283185
3616 72300 -11964.714443
3617 72320 -11893.139633
3618 72340 -11821.558756
3619 72360 -11749.971815
3620 72380 -11678.378811
3621 72400 -11606.779747
3622 72420 -11535.174626
3623 72440 -11463.563449
3624 72460 -11391.946219
3625 72480 -11320.322938
3626 72500 -11248.693608
3627 72520 -11177.058231
3628 72540 -11105.416810
3629 72560 -11033.769347
3630 72580 -10962.115844
3631 72600 -10890.456303
3632 72620 -10818.790726
3633 72640 -10747.119117
3634 72660 -10675.441476
3635 72680 -10603.757806
3636 72700 -10532.068110
3637 72720 -10460.372389
3638 72740 -10388.670646
3639 72760 -10316.962883
3640 72780 -10245.249102
3641 72800 -10173.529305
3642 72820 -10101.803495
3643 72840 -10030.071674
3644 72860 -9958.333843
3645 72880 -9886.590006
3646 72900 -9814.840164
3647 72920 -9743.084320
3648 72940 -9671.322476
3649 72960 -9599.554633
3650 72980 -9527.780795
3651 73000 -9456.000962
3652 73020 -9384.215139
3653 73040 -9312.423326
3654 73060 -9240.625526
3655 73080 -9168.821741
3656 73100 -9097.011973
3657 73120 -9025.196224
3658 73140 -8953.374497
3659 73160 -8881.546794
3660 73180 -8809.713117
3661 73200 -8737.873468
3662 73220 -8666.027849
3663 73240 -8594.176263
3664 73260 -8522.318712
3665 73280 -8450.455197
3666 73300 -8378.585721
3667 73320 -8306.710286
3668 73340 -8234.828895
3669 73360 -8162.941549
3670 73380 -8091.048250
3671 73400 -8019.149002
3672 73420 -7947.243805
3673 73440 -7875.332663
3674 73460 -7803.415576
3675 73480 -7731.492548
3676 73500 -7659.563581
3677 73520 -7587.628676
3678 73540 -7515.687836
3679 73560 -7443.741064
3680 73580 -7371.788360
3681 73600 -7299.829728
3682 73620 -7227.865169
3683 73640 -7155.894685
3684 73660 -7083.918280
3685 73680 -7011.935954
3686 73700 -6939.947710
3687 73720 -6867.953551
3688 73740 -6795.953477
3689 73760 -6723.947492
3690 73780 -6651.935598
3691 73800 -6579.917796
3692 73820 -6507.894089
3693 73840 -6435.864479
3694 73860 -6363.828968
3695 73880 -6291.787559
3696 73900 -6219.740252
3697 73920 -6147.687051
3698 73940 -6075.627958
3699 73960 -6003.562974
3700 73980 -5931.492102
3701 74000 -5859.415344
3702 74020 -5787.332702
3703 74040 -5715.244178
3704 74060 -5643.149774
3705 74080 -5571.049493
3706 74100 -5498.943336
3707 74120 -5426.831306
3708 74140 -5354.713404
3709 74160 -5282.589633
3710 74180 -5210.459995
3711 74200 -5138.324493
3712 74220 -5066.183127
3713 74240 -4994.035900
3714 74260 -4921.882815
3715 74280 -4849.723873
3716 74300 -4777.559077
3717 74320 -4705.388428
3718 74340 -4633.211929
3719 74360 -4561.029582
3720 74380 -4488.841389
3721 74400 -4416.647351
3722 74420 -4344.447472
3723 74440 -4272.241753
3724 74460 -4200.030196
3725 74480 -4127.812803
3726 74500 -4055.589577
3727 74520 -3983.360519
3728 74540 -3911.125632
3729 74560 -3838.884917
3730 74580 -3766.638378
3731 74600 -3694.386014
3732 74620 -3622.127830
3733 74640 -3549.863827
3734 74660 -3477.594007
3735 74680 -3405.318372
3736 74700 -3333.036924
3737 74720 -3260.749665
3738 74740 -3188.456597
3739 74760 -3116.157723
3740 74780 -3043.853045
3741 74800 -2971.542563
3742 74820 -2899.226282
3743 74840 -2826.904202
3744 74860 -2754.576325
3745 74880 -2682.242654
3746 74900 -2609.903192
3747 74920 -2537.557938
3748 74940 -2465.206897
3749 74960 -2392.850070
3750 74980 -2320.487459
3751 75000 -2248.119066
3752 75020 -2175.744892
3753 75040 -2103.364941
3754 75060 -2030.979215
3755 75080 -1958.587714
3756 75100 -1886.190442
3757 75120 -1813.787400
3758 75140 -1741.378590
3759 75160 -1668.964015
3760 75180 -1596.543676
3761 75200 -1524.117575
3762 75220 -1451.685716
3763 75240 -1379.248098
3764 75260 -1306.804725
3765 75280 -1234.355599
3766 75300 -1161.900722
3767 75320 -1089.440095
3768 75340 -1016.973720
3769 75360 -944.501601
3770 75380 -872.023738
3771 75400 -799.540134
3772 75420 -727.050791
3773 75440 -654.555710
3774 75460 -582.054895
3775 75480 -509.548346
3776 75500 -437.036066
3777 75520 -364.518057
3778 75540 -291.994321
3779 75560 -219.464859
3780 75580 -146.929675
3781 75600 -74.388770
3782 75620 -1.842145
3783 75640 70.710197
3784 75660 143.268253
3785 75680 215.832023
3786 75700 288.401504
3787 75720 360.976694
3788 75740 433.557590
3789 75760 506.144192
3790 75780 578.736497
3791 75800 651.334503
3792 75820 723.938208
3793 75840 796.547610
3794 75860 869.162707
3795 75880 941.783498
3796 75900 1014.409979
3797 75920 1087.042149
3798 75940 1159.680007
3799 75960 1232.323549
3800 75980 1304.972775
3801 76000 1377.627682
3802 76020 1450.288268
3803 76040 1522.954531
3804 76060 1595.626469
3805 76080 1668.304081
3806 76100 1740.987364
3807 76120 1813.676316
3808 76140 1886.370935
3809 76160 1959.071220
3810 76180 2031.777168
3811 76200 2104.488777
3812 76220 2177.206046
3813 76240 2249.928972
3814 76260 2322.657553
3815 76280 2395.391788
3816 76300 2468.131675
3817 76320 2540.877211
3818 76340 2613.628395
3819 76360 2686.385224
3820 76380 2759.147697
3821 76400 2831.915812
3822 76420 2904.689566
3823 76440 2977.468959
3824 76460 3050.253987
3825 76480 3123.044649
3826 76500 3195.840942
3827 76520 3268.642866
3828 76540 3341.450418
3829 76560 3414.263596
3830 76580 3487.082398
3831 76600 3559.906822
3832 76620 3632.736867
3833 76640 3705.572529
3834 76660 3778.413808
3835 76680 3851.260702
3836 76700 3924.113208
3837 76720 3996.971324
3838 76740 4069.835049
3839 76760 4142.704381
3840 76780 4215.579317
3841 76800 4288.459856
3842 76820 4361.345996
3843 76840 4434.237735
3844 76860 4507.135070
3845 76880 4580.038001
3846 76900 4652.946525
3847 76920 4725.860640
3848 76940 4798.780345
3849 76960 4871.705636
3850 76980 4944.636513
3851 77000 5017.572974
3852 77020 5090.515016
3853 77040 5163.462637
3854 77060 5236.415837
3855 77080 5309.374612
3856 77100 5382.338961
3857 77120 5455.308882
3858 77140 5528.284373
3859 77160 5601.265433
3860 77180 5674.252058
3861 77200 5747.244248
3862 77220 5820.242000
3863 77240 5893.245313
3864 77260 5966.254184
3865 77280 6039.268612
3866 77300 6112.288595
3867 77320 6185.314130
3868 77340 6258.345217
3869 77360 6331.381852
3870 77380 6404.424035
3871 77400 6477.471763
3872 77420 6550.525034
3873 77440 6623.583847
3874 77460 6696.648200
3875 77480 6769.718090
3876 77500 6842.793516
3877 77520 6915.874475
3878 77540 6988.960967
3879 77560 7062.052989
3880 77580 7135.150539
3881 77600 7208.253616
3882 77620 7281.362217
3883 77640 7354.476340
3884 77660 7427.595984
3885 77680 7500.721147
3886 77700 7573.851827
3887 77720 7646.988022
3888 77740 7720.129730
3889 77760 7793.276950
3890 77780 7866.429678
3891 77800 7939.587915
3892 77820 8012.751657
3893 77840 8085.920902
3894 77860 8159.095650
3895 77880 8232.275898
3896 77900 8305.461643
3897 77920 8378.652885
3898 77940 8451.849622
3899 77960 8525.051851
3900 77980 8598.259571
3901 78000 8671.472780
3902 78020 8744.691475
3903 78040 8817.915656
3904 78060 8891.145320
3905 78080 8964.380465
3906 78100 9037.621090
3907 78120 9110.867193
3908 78140 9184.118771
3909 78160 9257.375823
3910 78180 9330.638348
3911 78200 9403.906343
3912 78220 9477.179806
3913 78240 9550.458735
3914 78260 9623.743130
3915 78280 9697.032987
3916 78300 9770.328305
3917 78320 9843.629083
3918 78340 9916.935317
3919 78360 9990.247007
3920 78380 10063.564151
3921 78400 10136.886747
3922 78420 10210.214792
3923 78440 10283.548286
3924 78460 10356.887226
3925 78480 10430.231610
3926 78500 10503.581437
3927 78520 10576.936705
3928 78540 10650.297412
3929 78560 10723.663556
3930 78580 10797.035135
3931 78600 10870.412147
3932 78620 10943.794591
3933 78640 11017.182465
3934 78660 11090.575767
3935 78680 11163.974495
3936 78700 11237.378648
3937 78720 11310.788222
3938 78740 11384.203218
3939 78760 11457.623632
3940 78780 11531.049463
3941 78800 11604.480710
3942 78820 11677.917370
3943 78840 11751.359441
3944 78860 11824.806923
3945 78880 11898.259812
3946 78900 11971.718107
3947 78920 12045.181807
3948 78940 12118.650909
3949 78960 12192.125412
3950 78980 12265.605313
3951 79000 12339.090612
3952 79020 12412.581306
3953 79040 12486.077394
3954 79060 12559.578873
3955 79080 12633.085742
3956 79100 12706.597999
3957 79120 12780.115642
3958 79140 12853.638670
3959 79160 12927.167081
3960 79180 13000.700872
3961 79200 13074.240042
3962 79220 13147.784590
3963 79240 13221.334513
3964 79260 13294.889810
3965 79280 13368.450478
3966 79300 13442.016517
3967 79320 13515.587924
3968 79340 13589.164698
3969 79360 13662.746836
3970 79380 13736.334337
3971 79400 13809.927200
3972 79420 13883.525422
3973 79440 13957.129001
3974 79460 14030.737936
3975 79480 14104.352225
3976 79500 14177.971867
3977 79520 14251.596859
3978 79540 14325.227199
3979 79560 14398.862887
3980 79580 14472.503920
3981 79600 14546.150296
3982 79620 14619.802013
3983 79640 14693.459071
3984 79660 14767.121466
3985 79680 14840.789198
3986 79700 14914.462264
3987 79720 14988.140663
3988 79740 15061.824393
3989 79760 15135.513452
3990 79780 15209.207838
3991 79800 15282.907550
3992 79820 15356.612587
3993 79840 15430.322945
3994 79860 15504.038623
3995 79880 15577.759621
3996 79900 15651.485935
3997 79920 15725.217564
3998 79940 15798.954506
3999 79960 15872.696761
4000 79980 15946.444325
4001 80000 16020.197197

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