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 4 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
1502 30020 -143995.378235
1503 30040 -143946.605074
1504 30060 -143897.811334
1505 30080 -143848.997033
1506 30100 -143800.162192
1507 30120 -143751.306831
1508 30140 -143702.430969
1509 30160 -143653.534626
1510 30180 -143604.617822
1511 30200 -143555.680576
1512 30220 -143506.722909
1513 30240 -143457.744839
1514 30260 -143408.746386
1515 30280 -143359.727570
1516 30300 -143310.688410
1517 30320 -143261.628926
1518 30340 -143212.549136
1519 30360 -143163.449061
1520 30380 -143114.328720
1521 30400 -143065.188132
1522 30420 -143016.027317
1523 30440 -142966.846293
1524 30460 -142917.645080
1525 30480 -142868.423697
1526 30500 -142819.182163
1527 30520 -142769.920498
1528 30540 -142720.638720
1529 30560 -142671.336848
1530 30580 -142622.014902
1531 30600 -142572.672901
1532 30620 -142523.310864
1533 30640 -142473.928808
1534 30660 -142424.526754
1535 30680 -142375.104721
1536 30700 -142325.662726
1537 30720 -142276.200790
1538 30740 -142226.718930
1539 30760 -142177.217166
1540 30780 -142127.695516
1541 30800 -142078.153998
1542 30820 -142028.592633
1543 30840 -141979.011437
1544 30860 -141929.410430
1545 30880 -141879.789631
1546 30900 -141830.149057
1547 30920 -141780.488728
1548 30940 -141730.808661
1549 30960 -141681.108876
1550 30980 -141631.389391
1551 31000 -141581.650223
1552 31020 -141531.891393
1553 31040 -141482.112916
1554 31060 -141432.314813
1555 31080 -141382.497102
1556 31100 -141332.659799
1557 31120 -141282.802925
1558 31140 -141232.926497
1559 31160 -141183.030532
1560 31180 -141133.115050
1561 31200 -141083.180068
1562 31220 -141033.225605
1563 31240 -140983.251678
1564 31260 -140933.258305
1565 31280 -140883.245504
1566 31300 -140833.213294
1567 31320 -140783.161692
1568 31340 -140733.090716
1569 31360 -140683.000385
1570 31380 -140632.890714
1571 31400 -140582.761724
1572 31420 -140532.613430
1573 31440 -140482.445852
1574 31460 -140432.259007
1575 31480 -140382.052912
1576 31500 -140331.827585
1577 31520 -140281.583043
1578 31540 -140231.319305
1579 31560 -140181.036388
1580 31580 -140130.734310
1581 31600 -140080.413087
1582 31620 -140030.072738
1583 31640 -139979.713279
1584 31660 -139929.334729
1585 31680 -139878.937105
1586 31700 -139828.520423
1587 31720 -139778.084702
1588 31740 -139727.629959
1589 31760 -139677.156210
1590 31780 -139626.663474
1591 31800 -139576.151768
1592 31820 -139525.621108
1593 31840 -139475.071512
1594 31860 -139424.502997
1595 31880 -139373.915580
1596 31900 -139323.309278
1597 31920 -139272.684109
1598 31940 -139222.040089
1599 31960 -139171.377235
1600 31980 -139120.695565
1601 32000 -139069.995095
1602 32020 -139019.275842
1603 32040 -138968.537823
1604 32060 -138917.781056
1605 32080 -138867.005556
1606 32100 -138816.211341
1607 32120 -138765.398427
1608 32140 -138714.566832
1609 32160 -138663.716572
1610 32180 -138612.847663
1611 32200 -138561.960123
1612 32220 -138511.053968
1613 32240 -138460.129214
1614 32260 -138409.185879
1615 32280 -138358.223979
1616 32300 -138307.243531
1617 32320 -138256.244550
1618 32340 -138205.227054
1619 32360 -138154.191059
1620 32380 -138103.136581
1621 32400 -138052.063638
1622 32420 -138000.972244
1623 32440 -137949.862418
1624 32460 -137898.734174
1625 32480 -137847.587530
1626 32500 -137796.422501
1627 32520 -137745.239105
1628 32540 -137694.037356
1629 32560 -137642.817273
1630 32580 -137591.578869
1631 32600 -137540.322163
1632 32620 -137489.047169
1633 32640 -137437.753905
1634 32660 -137386.442386
1635 32680 -137335.112628
1636 32700 -137283.764648
1637 32720 -137232.398461
1638 32740 -137181.014083
1639 32760 -137129.611530
1640 32780 -137078.190819
1641 32800 -137026.751965
1642 32820 -136975.294985
1643 32840 -136923.819893
1644 32860 -136872.326706
1645 32880 -136820.815440
1646 32900 -136769.286110
1647 32920 -136717.738733
1648 32940 -136666.173324
1649 32960 -136614.589898
1650 32980 -136562.988472
1651 33000 -136511.369061
1652 33020 -136459.731681
1653 33040 -136408.076348
1654 33060 -136356.403076
1655 33080 -136304.711882
1656 33100 -136253.002782
1657 33120 -136201.275790
1658 33140 -136149.530922
1659 33160 -136097.768195
1660 33180 -136045.987622
1661 33200 -135994.189220
1662 33220 -135942.373005
1663 33240 -135890.538991
1664 33260 -135838.687193
1665 33280 -135786.817628
1666 33300 -135734.930311
1667 33320 -135683.025257
1668 33340 -135631.102480
1669 33360 -135579.161997
1670 33380 -135527.203823
1671 33400 -135475.227973
1672 33420 -135423.234462
1673 33440 -135371.223304
1674 33460 -135319.194517
1675 33480 -135267.148114
1676 33500 -135215.084110
1677 33520 -135163.002521
1678 33540 -135110.903362
1679 33560 -135058.786648
1680 33580 -135006.652393
1681 33600 -134954.500613
1682 33620 -134902.331323
1683 33640 -134850.144537
1684 33660 -134797.940271
1685 33680 -134745.718540
1686 33700 -134693.479358
1687 33720 -134641.222740
1688 33740 -134588.948701
1689 33760 -134536.657256
1690 33780 -134484.348419
1691 33800 -134432.022206
1692 33820 -134379.678631
1693 33840 -134327.317709
1694 33860 -134274.939454
1695 33880 -134222.543881
1696 33900 -134170.131006
1697 33920 -134117.700841
1698 33940 -134065.253403
1699 33960 -134012.788705
1700 33980 -133960.306763
1701 34000 -133907.807591
1702 34020 -133855.291202
1703 34040 -133802.757613
1704 34060 -133750.206837
1705 34080 -133697.638888
1706 34100 -133645.053782
1707 34120 -133592.451532
1708 34140 -133539.832153
1709 34160 -133487.195659
1710 34180 -133434.542066
1711 34200 -133381.871386
1712 34220 -133329.183634
1713 34240 -133276.478825
1714 34260 -133223.756973
1715 34280 -133171.018092
1716 34300 -133118.262196
1717 34320 -133065.489300
1718 34340 -133012.699418
1719 34360 -132959.892563
1720 34380 -132907.068751
1721 34400 -132854.227994
1722 34420 -132801.370308
1723 34440 -132748.495706
1724 34460 -132695.604202
1725 34480 -132642.695811
1726 34500 -132589.770546
1727 34520 -132536.828422
1728 34540 -132483.869452
1729 34560 -132430.893650
1730 34580 -132377.901030
1731 34600 -132324.891607
1732 34620 -132271.865394
1733 34640 -132218.822405
1734 34660 -132165.762653
1735 34680 -132112.686153
1736 34700 -132059.592918
1737 34720 -132006.482963
1738 34740 -131953.356301
1739 34760 -131900.212945
1740 34780 -131847.052910
1741 34800 -131793.876209
1742 34820 -131740.682856
1743 34840 -131687.472865
1744 34860 -131634.246248
1745 34880 -131581.003021
1746 34900 -131527.743196
1747 34920 -131474.466787
1748 34940 -131421.173807
1749 34960 -131367.864271
1750 34980 -131314.538191
1751 35000 -131261.195582
1752 35020 -131207.836456
1753 35040 -131154.460827
1754 35060 -131101.068709
1755 35080 -131047.660116
1756 35100 -130994.235059
1757 35120 -130940.793554
1758 35140 -130887.335612
1759 35160 -130833.861249
1760 35180 -130780.370476
1761 35200 -130726.863307
1762 35220 -130673.339757
1763 35240 -130619.799837
1764 35260 -130566.243561
1765 35280 -130512.670942
1766 35300 -130459.081994
1767 35320 -130405.476730
1768 35340 -130351.855163
1769 35360 -130298.217306
1770 35380 -130244.563172
1771 35400 -130190.892775
1772 35420 -130137.206127
1773 35440 -130083.503242
1774 35460 -130029.784133
1775 35480 -129976.048812
1776 35500 -129922.297293
1777 35520 -129868.529589
1778 35540 -129814.745713
1779 35560 -129760.945678
1780 35580 -129707.129496
1781 35600 -129653.297181
1782 35620 -129599.448746
1783 35640 -129545.584203
1784 35660 -129491.703566
1785 35680 -129437.806847
1786 35700 -129383.894060
1787 35720 -129329.965216
1788 35740 -129276.020329
1789 35760 -129222.059412
1790 35780 -129168.082477
1791 35800 -129114.089537
1792 35820 -129060.080606
1793 35840 -129006.055694
1794 35860 -128952.014817
1795 35880 -128897.957985
1796 35900 -128843.885212
1797 35920 -128789.796510
1798 35940 -128735.691893
1799 35960 -128681.571372
1800 35980 -128627.434960
1801 36000 -128573.282670
1802 36020 -128519.114515
1803 36040 -128464.930506
1804 36060 -128410.730657
1805 36080 -128356.514980
1806 36100 -128302.283488
1807 36120 -128248.036192
1808 36140 -128193.773106
1809 36160 -128139.494242
1810 36180 -128085.199612
1811 36200 -128030.889229
1812 36220 -127976.563105
1813 36240 -127922.221252
1814 36260 -127867.863683
1815 36280 -127813.490411
1816 36300 -127759.101447
1817 36320 -127704.696804
1818 36340 -127650.276493
1819 36360 -127595.840529
1820 36380 -127541.388922
1821 36400 -127486.921684
1822 36420 -127432.438829
1823 36440 -127377.940369
1824 36460 -127323.426314
1825 36480 -127268.896679
1826 36500 -127214.351474
1827 36520 -127159.790712
1828 36540 -127105.214405
1829 36560 -127050.622566
1830 36580 -126996.015206
1831 36600 -126941.392337
1832 36620 -126886.753971
1833 36640 -126832.100121
1834 36660 -126777.430799
1835 36680 -126722.746015
1836 36700 -126668.045784
1837 36720 -126613.330116
1838 36740 -126558.599023
1839 36760 -126503.852517
1840 36780 -126449.090611
1841 36800 -126394.313316
1842 36820 -126339.520644
1843 36840 -126284.712607
1844 36860 -126229.889217
1845 36880 -126175.050485
1846 36900 -126120.196424
1847 36920 -126065.327045
1848 36940 -126010.442360
1849 36960 -125955.542381
1850 36980 -125900.627119
1851 37000 -125845.696587
1852 37020 -125790.750796
1853 37040 -125735.789757
1854 37060 -125680.813484
1855 37080 -125625.821986
1856 37100 -125570.815276
1857 37120 -125515.793366
1858 37140 -125460.756266
1859 37160 -125405.703990
1860 37180 -125350.636548
1861 37200 -125295.553951
1862 37220 -125240.456212
1863 37240 -125185.343343
1864 37260 -125130.215353
1865 37280 -125075.072256
1866 37300 -125019.914063
1867 37320 -124964.740784
1868 37340 -124909.552433
1869 37360 -124854.349019
1870 37380 -124799.130555
1871 37400 -124743.897051
1872 37420 -124688.648520
1873 37440 -124633.384973
1874 37460 -124578.106421
1875 37480 -124522.812875
1876 37500 -124467.504347
1877 37520 -124412.180849
1878 37540 -124356.842391
1879 37560 -124301.488985
1880 37580 -124246.120641
1881 37600 -124190.737373
1882 37620 -124135.339190
1883 37640 -124079.926103
1884 37660 -124024.498125
1885 37680 -123969.055267
1886 37700 -123913.597539
1887 37720 -123858.124952
1888 37740 -123802.637519
1889 37760 -123747.135250
1890 37780 -123691.618156
1891 37800 -123636.086248
1892 37820 -123580.539538
1893 37840 -123524.978036
1894 37860 -123469.401754
1895 37880 -123413.810703
1896 37900 -123358.204893
1897 37920 -123302.584337
1898 37940 -123246.949044
1899 37960 -123191.299026
1900 37980 -123135.634294
1901 38000 -123079.954858
1902 38020 -123024.260731
1903 38040 -122968.551922
1904 38060 -122912.828443
1905 38080 -122857.090305
1906 38100 -122801.337518
1907 38120 -122745.570094
1908 38140 -122689.788043
1909 38160 -122633.991376
1910 38180 -122578.180104
1911 38200 -122522.354238
1912 38220 -122466.513789
1913 38240 -122410.658767
1914 38260 -122354.789184
1915 38280 -122298.905049
1916 38300 -122243.006375
1917 38320 -122187.093171
1918 38340 -122131.165448
1919 38360 -122075.223218
1920 38380 -122019.266490
1921 38400 -121963.295276
1922 38420 -121907.309585
1923 38440 -121851.309430
1924 38460 -121795.294820
1925 38480 -121739.265767
1926 38500 -121683.222280
1927 38520 -121627.164370
1928 38540 -121571.092049
1929 38560 -121515.005325
1930 38580 -121458.904212
1931 38600 -121402.788717
1932 38620 -121346.658853
1933 38640 -121290.514630
1934 38660 -121234.356058
1935 38680 -121178.183148
1936 38700 -121121.995910
1937 38720 -121065.794354
1938 38740 -121009.578492
1939 38760 -120953.348334
1940 38780 -120897.103890
1941 38800 -120840.845170
1942 38820 -120784.572185
1943 38840 -120728.284945
1944 38860 -120671.983461
1945 38880 -120615.667744
1946 38900 -120559.337802
1947 38920 -120502.993648
1948 38940 -120446.635290
1949 38960 -120390.262740
1950 38980 -120333.876007
1951 39000 -120277.475103
1952 39020 -120221.060037
1953 39040 -120164.630819
1954 39060 -120108.187460
1955 39080 -120051.729970
1956 39100 -119995.258359
1957 39120 -119938.772638
1958 39140 -119882.272816
1959 39160 -119825.758904
1960 39180 -119769.230913
1961 39200 -119712.688851
1962 39220 -119656.132730
1963 39240 -119599.562559
1964 39260 -119542.978348
1965 39280 -119486.380108
1966 39300 -119429.767849
1967 39320 -119373.141581
1968 39340 -119316.501313
1969 39360 -119259.847057
1970 39380 -119203.178821
1971 39400 -119146.496617
1972 39420 -119089.800453
1973 39440 -119033.090341
1974 39460 -118976.366289
1975 39480 -118919.628309
1976 39500 -118862.876409
1977 39520 -118806.110601
1978 39540 -118749.330893
1979 39560 -118692.537296
1980 39580 -118635.729819
1981 39600 -118578.908473
1982 39620 -118522.073268
1983 39640 -118465.224213
1984 39660 -118408.361318
1985 39680 -118351.484593
1986 39700 -118294.594048
1987 39720 -118237.689693
1988 39740 -118180.771537
1989 39760 -118123.839591
1990 39780 -118066.893864
1991 39800 -118009.934366
1992 39820 -117952.961106
1993 39840 -117895.974095
1994 39860 -117838.973342
1995 39880 -117781.958856
1996 39900 -117724.930649
1997 39920 -117667.888728
1998 39940 -117610.833105
1999 39960 -117553.763788
2000 39980 -117496.680788
2001 40000 -117439.584114

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