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 16 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
7502 150020 298397.256727
7503 150040 298483.187942
7504 150060 298569.121521
7505 150080 298655.057466
7506 150100 298740.995776
7507 150120 298826.936451
7508 150140 298912.879489
7509 150160 298998.824891
7510 150180 299084.772656
7511 150200 299170.722784
7512 150220 299256.675275
7513 150240 299342.630127
7514 150260 299428.587342
7515 150280 299514.546917
7516 150300 299600.508854
7517 150320 299686.473150
7518 150340 299772.439808
7519 150360 299858.408824
7520 150380 299944.380200
7521 150400 300030.353935
7522 150420 300116.330029
7523 150440 300202.308480
7524 150460 300288.289290
7525 150480 300374.272456
7526 150500 300460.257980
7527 150520 300546.245860
7528 150540 300632.236097
7529 150560 300718.228689
7530 150580 300804.223636
7531 150600 300890.220939
7532 150620 300976.220596
7533 150640 301062.222608
7534 150660 301148.226973
7535 150680 301234.233692
7536 150700 301320.242763
7537 150720 301406.254188
7538 150740 301492.267965
7539 150760 301578.284093
7540 150780 301664.302573
7541 150800 301750.323404
7542 150820 301836.346586
7543 150840 301922.372118
7544 150860 302008.400000
7545 150880 302094.430232
7546 150900 302180.462813
7547 150920 302266.497742
7548 150940 302352.535020
7549 150960 302438.574646
7550 150980 302524.616620
7551 151000 302610.660941
7552 151020 302696.707608
7553 151040 302782.756622
7554 151060 302868.807982
7555 151080 302954.861688
7556 151100 303040.917739
7557 151120 303126.976135
7558 151140 303213.036875
7559 151160 303299.099959
7560 151180 303385.165387
7561 151200 303471.233159
7562 151220 303557.303273
7563 151240 303643.375730
7564 151260 303729.450529
7565 151280 303815.527670
7566 151300 303901.607152
7567 151320 303987.688976
7568 151340 304073.773140
7569 151360 304159.859644
7570 151380 304245.948488
7571 151400 304332.039671
7572 151420 304418.133194
7573 151440 304504.229055
7574 151460 304590.327254
7575 151480 304676.427792
7576 151500 304762.530667
7577 151520 304848.635879
7578 151540 304934.743428
7579 151560 305020.853313
7580 151580 305106.965534
7581 151600 305193.080091
7582 151620 305279.196983
7583 151640 305365.316210
7584 151660 305451.437771
7585 151680 305537.561666
7586 151700 305623.687895
7587 151720 305709.816457
7588 151740 305795.947353
7589 151760 305882.080580
7590 151780 305968.216140
7591 151800 306054.354032
7592 151820 306140.494255
7593 151840 306226.636809
7594 151860 306312.781694
7595 151880 306398.928908
7596 151900 306485.078453
7597 151920 306571.230327
7598 151940 306657.384530
7599 151960 306743.541062
7600 151980 306829.699922
7601 152000 306915.861111
7602 152020 307002.024626
7603 152040 307088.190469
7604 152060 307174.358639
7605 152080 307260.529135
7606 152100 307346.701957
7607 152120 307432.877104
7608 152140 307519.054577
7609 152160 307605.234375
7610 152180 307691.416497
7611 152200 307777.600943
7612 152220 307863.787713
7613 152240 307949.976807
7614 152260 308036.168223
7615 152280 308122.361962
7616 152300 308208.558023
7617 152320 308294.756406
7618 152340 308380.957111
7619 152360 308467.160136
7620 152380 308553.365482
7621 152400 308639.573148
7622 152420 308725.783135
7623 152440 308811.995441
7624 152460 308898.210066
7625 152480 308984.427009
7626 152500 309070.646271
7627 152520 309156.867852
7628 152540 309243.091749
7629 152560 309329.317964
7630 152580 309415.546496
7631 152600 309501.777345
7632 152620 309588.010509
7633 152640 309674.245990
7634 152660 309760.483785
7635 152680 309846.723896
7636 152700 309932.966321
7637 152720 310019.211060
7638 152740 310105.458114
7639 152760 310191.707480
7640 152780 310277.959160
7641 152800 310364.213153
7642 152820 310450.469458
7643 152840 310536.728074
7644 152860 310622.989003
7645 152880 310709.252242
7646 152900 310795.517793
7647 152920 310881.785654
7648 152940 310968.055825
7649 152960 311054.328305
7650 152980 311140.603095
7651 153000 311226.880194
7652 153020 311313.159601
7653 153040 311399.441317
7654 153060 311485.725340
7655 153080 311572.011671
7656 153100 311658.300309
7657 153120 311744.591253
7658 153140 311830.884504
7659 153160 311917.180061
7660 153180 312003.477923
7661 153200 312089.778091
7662 153220 312176.080563
7663 153240 312262.385340
7664 153260 312348.692421
7665 153280 312435.001805
7666 153300 312521.313493
7667 153320 312607.627483
7668 153340 312693.943776
7669 153360 312780.262372
7670 153380 312866.583269
7671 153400 312952.906467
7672 153420 313039.231967
7673 153440 313125.559767
7674 153460 313211.889868
7675 153480 313298.222268
7676 153500 313384.556968
7677 153520 313470.893967
7678 153540 313557.233265
7679 153560 313643.574862
7680 153580 313729.918756
7681 153600 313816.264948
7682 153620 313902.613438
7683 153640 313988.964224
7684 153660 314075.317307
7685 153680 314161.672686
7686 153700 314248.030361
7687 153720 314334.390331
7688 153740 314420.752597
7689 153760 314507.117157
7690 153780 314593.484011
7691 153800 314679.853160
7692 153820 314766.224602
7693 153840 314852.598337
7694 153860 314938.974365
7695 153880 315025.352685
7696 153900 315111.733298
7697 153920 315198.116202
7698 153940 315284.501398
7699 153960 315370.888884
7700 153980 315457.278661
7701 154000 315543.670729
7702 154020 315630.065086
7703 154040 315716.461733
7704 154060 315802.860669
7705 154080 315889.261893
7706 154100 315975.665406
7707 154120 316062.071207
7708 154140 316148.479296
7709 154160 316234.889672
7710 154180 316321.302335
7711 154200 316407.717284
7712 154220 316494.134520
7713 154240 316580.554041
7714 154260 316666.975848
7715 154280 316753.399939
7716 154300 316839.826316
7717 154320 316926.254976
7718 154340 317012.685921
7719 154360 317099.119149
7720 154380 317185.554661
7721 154400 317271.992455
7722 154420 317358.432532
7723 154440 317444.874890
7724 154460 317531.319531
7725 154480 317617.766453
7726 154500 317704.215655
7727 154520 317790.667139
7728 154540 317877.120903
7729 154560 317963.576946
7730 154580 318050.035269
7731 154600 318136.495872
7732 154620 318222.958753
7733 154640 318309.423912
7734 154660 318395.891349
7735 154680 318482.361065
7736 154700 318568.833057
7737 154720 318655.307326
7738 154740 318741.783872
7739 154760 318828.262695
7740 154780 318914.743793
7741 154800 319001.227166
7742 154820 319087.712815
7743 154840 319174.200738
7744 154860 319260.690936
7745 154880 319347.183407
7746 154900 319433.678153
7747 154920 319520.175171
7748 154940 319606.674463
7749 154960 319693.176027
7750 154980 319779.679863
7751 155000 319866.185971
7752 155020 319952.694350
7753 155040 320039.205001
7754 155060 320125.717922
7755 155080 320212.233114
7756 155100 320298.750575
7757 155120 320385.270307
7758 155140 320471.792307
7759 155160 320558.316576
7760 155180 320644.843114
7761 155200 320731.371920
7762 155220 320817.902994
7763 155240 320904.436335
7764 155260 320990.971944
7765 155280 321077.509819
7766 155300 321164.049960
7767 155320 321250.592367
7768 155340 321337.137040
7769 155360 321423.683978
7770 155380 321510.233181
7771 155400 321596.784649
7772 155420 321683.338381
7773 155440 321769.894376
7774 155460 321856.452635
7775 155480 321943.013157
7776 155500 322029.575942
7777 155520 322116.140989
7778 155540 322202.708298
7779 155560 322289.277868
7780 155580 322375.849700
7781 155600 322462.423793
7782 155620 322549.000146
7783 155640 322635.578760
7784 155660 322722.159633
7785 155680 322808.742766
7786 155700 322895.328157
7787 155720 322981.915808
7788 155740 323068.505717
7789 155760 323155.097883
7790 155780 323241.692308
7791 155800 323328.288990
7792 155820 323414.887928
7793 155840 323501.489123
7794 155860 323588.092575
7795 155880 323674.698282
7796 155900 323761.306245
7797 155920 323847.916462
7798 155940 323934.528935
7799 155960 324021.143662
7800 155980 324107.760643
7801 156000 324194.379877
7802 156020 324281.001365
7803 156040 324367.625106
7804 156060 324454.251099
7805 156080 324540.879345
7806 156100 324627.509842
7807 156120 324714.142591
7808 156140 324800.777591
7809 156160 324887.414842
7810 156180 324974.054343
7811 156200 325060.696095
7812 156220 325147.340096
7813 156240 325233.986346
7814 156260 325320.634846
7815 156280 325407.285594
7816 156300 325493.938590
7817 156320 325580.593834
7818 156340 325667.251326
7819 156360 325753.911065
7820 156380 325840.573051
7821 156400 325927.237283
7822 156420 326013.903761
7823 156440 326100.572485
7824 156460 326187.243455
7825 156480 326273.916670
7826 156500 326360.592129
7827 156520 326447.269833
7828 156540 326533.949780
7829 156560 326620.631971
7830 156580 326707.316406
7831 156600 326794.003083
7832 156620 326880.692003
7833 156640 326967.383165
7834 156660 327054.076569
7835 156680 327140.772214
7836 156700 327227.470101
7837 156720 327314.170228
7838 156740 327400.872596
7839 156760 327487.577204
7840 156780 327574.284051
7841 156800 327660.993138
7842 156820 327747.704464
7843 156840 327834.418028
7844 156860 327921.133831
7845 156880 328007.851871
7846 156900 328094.572149
7847 156920 328181.294665
7848 156940 328268.019417
7849 156960 328354.746405
7850 156980 328441.475630
7851 157000 328528.207091
7852 157020 328614.940787
7853 157040 328701.676718
7854 157060 328788.414884
7855 157080 328875.155284
7856 157100 328961.897918
7857 157120 329048.642786
7858 157140 329135.389887
7859 157160 329222.139221
7860 157180 329308.890788
7861 157200 329395.644587
7862 157220 329482.400617
7863 157240 329569.158880
7864 157260 329655.919373
7865 157280 329742.682097
7866 157300 329829.447052
7867 157320 329916.214237
7868 157340 330002.983652
7869 157360 330089.755296
7870 157380 330176.529169
7871 157400 330263.305271
7872 157420 330350.083601
7873 157440 330436.864159
7874 157460 330523.646945
7875 157480 330610.431958
7876 157500 330697.219198
7877 157520 330784.008665
7878 157540 330870.800358
7879 157560 330957.594276
7880 157580 331044.390421
7881 157600 331131.188790
7882 157620 331217.989385
7883 157640 331304.792203
7884 157660 331391.597246
7885 157680 331478.404513
7886 157700 331565.214003
7887 157720 331652.025716
7888 157740 331738.839652
7889 157760 331825.655810
7890 157780 331912.474191
7891 157800 331999.294793
7892 157820 332086.117616
7893 157840 332172.942660
7894 157860 332259.769925
7895 157880 332346.599410
7896 157900 332433.431115
7897 157920 332520.265040
7898 157940 332607.101184
7899 157960 332693.939546
7900 157980 332780.780128
7901 158000 332867.622927
7902 158020 332954.467944
7903 158040 333041.315179
7904 158060 333128.164631
7905 158080 333215.016299
7906 158100 333301.870184
7907 158120 333388.726285
7908 158140 333475.584602
7909 158160 333562.445134
7910 158180 333649.307881
7911 158200 333736.172843
7912 158220 333823.040019
7913 158240 333909.909409
7914 158260 333996.781013
7915 158280 334083.654830
7916 158300 334170.530860
7917 158320 334257.409103
7918 158340 334344.289558
7919 158360 334431.172224
7920 158380 334518.057102
7921 158400 334604.944192
7922 158420 334691.833492
7923 158440 334778.725003
7924 158460 334865.618724
7925 158480 334952.514655
7926 158500 335039.412795
7927 158520 335126.313144
7928 158540 335213.215702
7929 158560 335300.120468
7930 158580 335387.027443
7931 158600 335473.936625
7932 158620 335560.848015
7933 158640 335647.761611
7934 158660 335734.677415
7935 158680 335821.595424
7936 158700 335908.515640
7937 158720 335995.438061
7938 158740 336082.362688
7939 158760 336169.289519
7940 158780 336256.218556
7941 158800 336343.149796
7942 158820 336430.083240
7943 158840 336517.018888
7944 158860 336603.956739
7945 158880 336690.896793
7946 158900 336777.839050
7947 158920 336864.783508
7948 158940 336951.730169
7949 158960 337038.679031
7950 158980 337125.630094
7951 159000 337212.583358
7952 159020 337299.538823
7953 159040 337386.496487
7954 159060 337473.456352
7955 159080 337560.418415
7956 159100 337647.382678
7957 159120 337734.349140
7958 159140 337821.317800
7959 159160 337908.288658
7960 159180 337995.261714
7961 159200 338082.236967
7962 159220 338169.214417
7963 159240 338256.194064
7964 159260 338343.175907
7965 159280 338430.159946
7966 159300 338517.146181
7967 159320 338604.134611
7968 159340 338691.125236
7969 159360 338778.118056
7970 159380 338865.113070
7971 159400 338952.110278
7972 159420 339039.109679
7973 159440 339126.111274
7974 159460 339213.115062
7975 159480 339300.121042
7976 159500 339387.129214
7977 159520 339474.139579
7978 159540 339561.152135
7979 159560 339648.166882
7980 159580 339735.183820
7981 159600 339822.202948
7982 159620 339909.224267
7983 159640 339996.247775
7984 159660 340083.273473
7985 159680 340170.301360
7986 159700 340257.331436
7987 159720 340344.363701
7988 159740 340431.398153
7989 159760 340518.434793
7990 159780 340605.473621
7991 159800 340692.514636
7992 159820 340779.557837
7993 159840 340866.603225
7994 159860 340953.650800
7995 159880 341040.700559
7996 159900 341127.752505
7997 159920 341214.806635
7998 159940 341301.862950
7999 159960 341388.921449
8000 159980 341475.982133
8001 160000 341563.045000

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