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 18 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
8502 170020 385449.233519
8503 170040 385537.351705
8504 170060 385625.471916
8505 170080 385713.594151
8506 170100 385801.718411
8507 170120 385889.844693
8508 170140 385977.973000
8509 170160 386066.103329
8510 170180 386154.235681
8511 170200 386242.370055
8512 170220 386330.506452
8513 170240 386418.644870
8514 170260 386506.785310
8515 170280 386594.927771
8516 170300 386683.072254
8517 170320 386771.218757
8518 170340 386859.367280
8519 170360 386947.517823
8520 170380 387035.670387
8521 170400 387123.824969
8522 170420 387211.981572
8523 170440 387300.140192
8524 170460 387388.300832
8525 170480 387476.463490
8526 170500 387564.628166
8527 170520 387652.794860
8528 170540 387740.963571
8529 170560 387829.134299
8530 170580 387917.307045
8531 170600 388005.481807
8532 170620 388093.658585
8533 170640 388181.837379
8534 170660 388270.018189
8535 170680 388358.201014
8536 170700 388446.385855
8537 170720 388534.572710
8538 170740 388622.761580
8539 170760 388710.952464
8540 170780 388799.145362
8541 170800 388887.340273
8542 170820 388975.537198
8543 170840 389063.736136
8544 170860 389151.937087
8545 170880 389240.140051
8546 170900 389328.345026
8547 170920 389416.552014
8548 170940 389504.761013
8549 170960 389592.972024
8550 170980 389681.185045
8551 171000 389769.400078
8552 171020 389857.617120
8553 171040 389945.836173
8554 171060 390034.057236
8555 171080 390122.280308
8556 171100 390210.505390
8557 171120 390298.732481
8558 171140 390386.961580
8559 171160 390475.192688
8560 171180 390563.425804
8561 171200 390651.660928
8562 171220 390739.898059
8563 171240 390828.137198
8564 171260 390916.378343
8565 171280 391004.621496
8566 171300 391092.866654
8567 171320 391181.113819
8568 171340 391269.362990
8569 171360 391357.614166
8570 171380 391445.867347
8571 171400 391534.122534
8572 171420 391622.379724
8573 171440 391710.638920
8574 171460 391798.900119
8575 171480 391887.163322
8576 171500 391975.428529
8577 171520 392063.695739
8578 171540 392151.964952
8579 171560 392240.236167
8580 171580 392328.509385
8581 171600 392416.784605
8582 171620 392505.061826
8583 171640 392593.341050
8584 171660 392681.622274
8585 171680 392769.905499
8586 171700 392858.190725
8587 171720 392946.477951
8588 171740 393034.767177
8589 171760 393123.058403
8590 171780 393211.351628
8591 171800 393299.646853
8592 171820 393387.944076
8593 171840 393476.243298
8594 171860 393564.544519
8595 171880 393652.847737
8596 171900 393741.152953
8597 171920 393829.460166
8598 171940 393917.769377
8599 171960 394006.080585
8600 171980 394094.393789
8601 172000 394182.708989
8602 172020 394271.026186
8603 172040 394359.345378
8604 172060 394447.666565
8605 172080 394535.989748
8606 172100 394624.314926
8607 172120 394712.642098
8608 172140 394800.971264
8609 172160 394889.302425
8610 172180 394977.635579
8611 172200 395065.970726
8612 172220 395154.307867
8613 172240 395242.647001
8614 172260 395330.988127
8615 172280 395419.331245
8616 172300 395507.676356
8617 172320 395596.023458
8618 172340 395684.372551
8619 172360 395772.723636
8620 172380 395861.076711
8621 172400 395949.431778
8622 172420 396037.788834
8623 172440 396126.147880
8624 172460 396214.508916
8625 172480 396302.871942
8626 172500 396391.236957
8627 172520 396479.603960
8628 172540 396567.972952
8629 172560 396656.343933
8630 172580 396744.716901
8631 172600 396833.091857
8632 172620 396921.468801
8633 172640 397009.847731
8634 172660 397098.228649
8635 172680 397186.611553
8636 172700 397274.996443
8637 172720 397363.383320
8638 172740 397451.772182
8639 172760 397540.163029
8640 172780 397628.555862
8641 172800 397716.950680
8642 172820 397805.347482
8643 172840 397893.746268
8644 172860 397982.147039
8645 172880 398070.549793
8646 172900 398158.954530
8647 172920 398247.361251
8648 172940 398335.769955
8649 172960 398424.180641
8650 172980 398512.593310
8651 173000 398601.007961
8652 173020 398689.424593
8653 173040 398777.843207
8654 173060 398866.263802
8655 173080 398954.686378
8656 173100 399043.110934
8657 173120 399131.537471
8658 173140 399219.965988
8659 173160 399308.396485
8660 173180 399396.828961
8661 173200 399485.263417
8662 173220 399573.699851
8663 173240 399662.138264
8664 173260 399750.578655
8665 173280 399839.021025
8666 173300 399927.465372
8667 173320 400015.911697
8668 173340 400104.359998
8669 173360 400192.810277
8670 173380 400281.262533
8671 173400 400369.716765
8672 173420 400458.172973
8673 173440 400546.631157
8674 173460 400635.091316
8675 173480 400723.553451
8676 173500 400812.017560
8677 173520 400900.483644
8678 173540 400988.951703
8679 173560 401077.421736
8680 173580 401165.893743
8681 173600 401254.367723
8682 173620 401342.843676
8683 173640 401431.321603
8684 173660 401519.801502
8685 173680 401608.283374
8686 173700 401696.767218
8687 173720 401785.253033
8688 173740 401873.740821
8689 173760 401962.230579
8690 173780 402050.722309
8691 173800 402139.216009
8692 173820 402227.711680
8693 173840 402316.209321
8694 173860 402404.708932
8695 173880 402493.210513
8696 173900 402581.714063
8697 173920 402670.219582
8698 173940 402758.727070
8699 173960 402847.236526
8700 173980 402935.747951
8701 174000 403024.261344
8702 174020 403112.776704
8703 174040 403201.294032
8704 174060 403289.813327
8705 174080 403378.334588
8706 174100 403466.857816
8707 174120 403555.383011
8708 174140 403643.910171
8709 174160 403732.439298
8710 174180 403820.970389
8711 174200 403909.503446
8712 174220 403998.038468
8713 174240 404086.575454
8714 174260 404175.114405
8715 174280 404263.655320
8716 174300 404352.198198
8717 174320 404440.743040
8718 174340 404529.289845
8719 174360 404617.838614
8720 174380 404706.389344
8721 174400 404794.942038
8722 174420 404883.496693
8723 174440 404972.053310
8724 174460 405060.611889
8725 174480 405149.172429
8726 174500 405237.734930
8727 174520 405326.299391
8728 174540 405414.865813
8729 174560 405503.434196
8730 174580 405592.004538
8731 174600 405680.576839
8732 174620 405769.151100
8733 174640 405857.727321
8734 174660 405946.305499
8735 174680 406034.885637
8736 174700 406123.467732
8737 174720 406212.051786
8738 174740 406300.637797
8739 174760 406389.225766
8740 174780 406477.815691
8741 174800 406566.407574
8742 174820 406655.001413
8743 174840 406743.597208
8744 174860 406832.194960
8745 174880 406920.794667
8746 174900 407009.396329
8747 174920 407097.999947
8748 174940 407186.605520
8749 174960 407275.213047
8750 174980 407363.822529
8751 175000 407452.433964
8752 175020 407541.047354
8753 175040 407629.662697
8754 175060 407718.279993
8755 175080 407806.899242
8756 175100 407895.520444
8757 175120 407984.143599
8758 175140 408072.768705
8759 175160 408161.395763
8760 175180 408250.024773
8761 175200 408338.655734
8762 175220 408427.288647
8763 175240 408515.923510
8764 175260 408604.560323
8765 175280 408693.199087
8766 175300 408781.839801
8767 175320 408870.482464
8768 175340 408959.127077
8769 175360 409047.773639
8770 175380 409136.422149
8771 175400 409225.072609
8772 175420 409313.725016
8773 175440 409402.379372
8774 175460 409491.035675
8775 175480 409579.693926
8776 175500 409668.354124
8777 175520 409757.016269
8778 175540 409845.680361
8779 175560 409934.346399
8780 175580 410023.014383
8781 175600 410111.684313
8782 175620 410200.356188
8783 175640 410289.030009
8784 175660 410377.705774
8785 175680 410466.383485
8786 175700 410555.063140
8787 175720 410643.744739
8788 175740 410732.428282
8789 175760 410821.113769
8790 175780 410909.801199
8791 175800 410998.490572
8792 175820 411087.181888
8793 175840 411175.875146
8794 175860 411264.570347
8795 175880 411353.267490
8796 175900 411441.966574
8797 175920 411530.667600
8798 175940 411619.370567
8799 175960 411708.075475
8800 175980 411796.782324
8801 176000 411885.491113
8802 176020 411974.201842
8803 176040 412062.914511
8804 176060 412151.629120
8805 176080 412240.345667
8806 176100 412329.064154
8807 176120 412417.784580
8808 176140 412506.506944
8809 176160 412595.231246
8810 176180 412683.957486
8811 176200 412772.685664
8812 176220 412861.415779
8813 176240 412950.147831
8814 176260 413038.881820
8815 176280 413127.617746
8816 176300 413216.355608
8817 176320 413305.095406
8818 176340 413393.837139
8819 176360 413482.580809
8820 176380 413571.326413
8821 176400 413660.073952
8822 176420 413748.823426
8823 176440 413837.574835
8824 176460 413926.328177
8825 176480 414015.083453
8826 176500 414103.840663
8827 176520 414192.599807
8828 176540 414281.360883
8829 176560 414370.123892
8830 176580 414458.888833
8831 176600 414547.655707
8832 176620 414636.424513
8833 176640 414725.195250
8834 176660 414813.967919
8835 176680 414902.742519
8836 176700 414991.519050
8837 176720 415080.297512
8838 176740 415169.077903
8839 176760 415257.860225
8840 176780 415346.644477
8841 176800 415435.430658
8842 176820 415524.218769
8843 176840 415613.008808
8844 176860 415701.800777
8845 176880 415790.594673
8846 176900 415879.390498
8847 176920 415968.188251
8848 176940 416056.987931
8849 176960 416145.789539
8850 176980 416234.593074
8851 177000 416323.398536
8852 177020 416412.205924
8853 177040 416501.015239
8854 177060 416589.826479
8855 177080 416678.639646
8856 177100 416767.454738
8857 177120 416856.271755
8858 177140 416945.090697
8859 177160 417033.911564
8860 177180 417122.734355
8861 177200 417211.559070
8862 177220 417300.385710
8863 177240 417389.214273
8864 177260 417478.044759
8865 177280 417566.877168
8866 177300 417655.711500
8867 177320 417744.547755
8868 177340 417833.385932
8869 177360 417922.226031
8870 177380 418011.068052
8871 177400 418099.911994
8872 177420 418188.757858
8873 177440 418277.605642
8874 177460 418366.455347
8875 177480 418455.306973
8876 177500 418544.160518
8877 177520 418633.015984
8878 177540 418721.873369
8879 177560 418810.732673
8880 177580 418899.593897
8881 177600 418988.457039
8882 177620 419077.322100
8883 177640 419166.189079
8884 177660 419255.057977
8885 177680 419343.928791
8886 177700 419432.801524
8887 177720 419521.676174
8888 177740 419610.552740
8889 177760 419699.431223
8890 177780 419788.311623
8891 177800 419877.193939
8892 177820 419966.078170
8893 177840 420054.964318
8894 177860 420143.852380
8895 177880 420232.742358
8896 177900 420321.634251
8897 177920 420410.528058
8898 177940 420499.423779
8899 177960 420588.321415
8900 177980 420677.220964
8901 178000 420766.122426
8902 178020 420855.025802
8903 178040 420943.931091
8904 178060 421032.838293
8905 178080 421121.747407
8906 178100 421210.658433
8907 178120 421299.571371
8908 178140 421388.486221
8909 178160 421477.402982
8910 178180 421566.321654
8911 178200 421655.242237
8912 178220 421744.164730
8913 178240 421833.089134
8914 178260 421922.015448
8915 178280 422010.943672
8916 178300 422099.873805
8917 178320 422188.805848
8918 178340 422277.739799
8919 178360 422366.675659
8920 178380 422455.613428
8921 178400 422544.553105
8922 178420 422633.494690
8923 178440 422722.438182
8924 178460 422811.383582
8925 178480 422900.330889
8926 178500 422989.280103
8927 178520 423078.231223
8928 178540 423167.184250
8929 178560 423256.139183
8930 178580 423345.096022
8931 178600 423434.054767
8932 178620 423523.015416
8933 178640 423611.977971
8934 178660 423700.942430
8935 178680 423789.908794
8936 178700 423878.877063
8937 178720 423967.847235
8938 178740 424056.819311
8939 178760 424145.793290
8940 178780 424234.769173
8941 178800 424323.746958
8942 178820 424412.726647
8943 178840 424501.708237
8944 178860 424590.691730
8945 178880 424679.677125
8946 178900 424768.664421
8947 178920 424857.653618
8948 178940 424946.644717
8949 178960 425035.637717
8950 178980 425124.632617
8951 179000 425213.629417
8952 179020 425302.628118
8953 179040 425391.628718
8954 179060 425480.631218
8955 179080 425569.635617
8956 179100 425658.641915
8957 179120 425747.650112
8958 179140 425836.660207
8959 179160 425925.672201
8960 179180 426014.686092
8961 179200 426103.701882
8962 179220 426192.719568
8963 179240 426281.739152
8964 179260 426370.760633
8965 179280 426459.784010
8966 179300 426548.809284
8967 179320 426637.836454
8968 179340 426726.865520
8969 179360 426815.896481
8970 179380 426904.929338
8971 179400 426993.964090
8972 179420 427083.000736
8973 179440 427172.039278
8974 179460 427261.079713
8975 179480 427350.122043
8976 179500 427439.166266
8977 179520 427528.212383
8978 179540 427617.260393
8979 179560 427706.310296
8980 179580 427795.362092
8981 179600 427884.415781
8982 179620 427973.471361
8983 179640 428062.528834
8984 179660 428151.588198
8985 179680 428240.649454
8986 179700 428329.712601
8987 179720 428418.777639
8988 179740 428507.844567
8989 179760 428596.913386
8990 179780 428685.984095
8991 179800 428775.056694
8992 179820 428864.131183
8993 179840 428953.207561
8994 179860 429042.285828
8995 179880 429131.365984
8996 179900 429220.448029
8997 179920 429309.531962
8998 179940 429398.617783
8999 179960 429487.705491
9000 179980 429576.795088
9001 180000 429665.886572

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