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 5 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
2002 40020 -117382.473775
2003 40040 -117325.349782
2004 40060 -117268.212143
2005 40080 -117211.060869
2006 40100 -117153.895969
2007 40120 -117096.717452
2008 40140 -117039.525329
2009 40160 -116982.319609
2010 40180 -116925.100301
2011 40200 -116867.867415
2012 40220 -116810.620960
2013 40240 -116753.360946
2014 40260 -116696.087383
2015 40280 -116638.800279
2016 40300 -116581.499645
2017 40320 -116524.185490
2018 40340 -116466.857823
2019 40360 -116409.516653
2020 40380 -116352.161991
2021 40400 -116294.793845
2022 40420 -116237.412226
2023 40440 -116180.017141
2024 40460 -116122.608602
2025 40480 -116065.186616
2026 40500 -116007.751194
2027 40520 -115950.302345
2028 40540 -115892.840078
2029 40560 -115835.364402
2030 40580 -115777.875327
2031 40600 -115720.372862
2032 40620 -115662.857017
2033 40640 -115605.327800
2034 40660 -115547.785222
2035 40680 -115490.229290
2036 40700 -115432.660015
2037 40720 -115375.077405
2038 40740 -115317.481470
2039 40760 -115259.872220
2040 40780 -115202.249662
2041 40800 -115144.613808
2042 40820 -115086.964664
2043 40840 -115029.302242
2044 40860 -114971.626549
2045 40880 -114913.937596
2046 40900 -114856.235391
2047 40920 -114798.519943
2048 40940 -114740.791261
2049 40960 -114683.049356
2050 40980 -114625.294234
2051 41000 -114567.525907
2052 41020 -114509.744382
2053 41040 -114451.949669
2054 41060 -114394.141777
2055 41080 -114336.320715
2056 41100 -114278.486492
2057 41120 -114220.639116
2058 41140 -114162.778598
2059 41160 -114104.904946
2060 41180 -114047.018168
2061 41200 -113989.118274
2062 41220 -113931.205273
2063 41240 -113873.279174
2064 41260 -113815.339986
2065 41280 -113757.387717
2066 41300 -113699.422376
2067 41320 -113641.443973
2068 41340 -113583.452517
2069 41360 -113525.448015
2070 41380 -113467.430478
2071 41400 -113409.399913
2072 41420 -113351.356330
2073 41440 -113293.299738
2074 41460 -113235.230145
2075 41480 -113177.147561
2076 41500 -113119.051993
2077 41520 -113060.943451
2078 41540 -113002.821944
2079 41560 -112944.687480
2080 41580 -112886.540068
2081 41600 -112828.379718
2082 41620 -112770.206436
2083 41640 -112712.020234
2084 41660 -112653.821118
2085 41680 -112595.609098
2086 41700 -112537.384182
2087 41720 -112479.146380
2088 41740 -112420.895699
2089 41760 -112362.632149
2090 41780 -112304.355739
2091 41800 -112246.066475
2092 41820 -112187.764369
2093 41840 -112129.449427
2094 41860 -112071.121660
2095 41880 -112012.781074
2096 41900 -111954.427679
2097 41920 -111896.061484
2098 41940 -111837.682497
2099 41960 -111779.290726
2100 41980 -111720.886181
2101 42000 -111662.468869
2102 42020 -111604.038800
2103 42040 -111545.595981
2104 42060 -111487.140422
2105 42080 -111428.672130
2106 42100 -111370.191115
2107 42120 -111311.697384
2108 42140 -111253.190947
2109 42160 -111194.671811
2110 42180 -111136.139985
2111 42200 -111077.595478
2112 42220 -111019.038298
2113 42240 -110960.468454
2114 42260 -110901.885953
2115 42280 -110843.290804
2116 42300 -110784.683016
2117 42320 -110726.062598
2118 42340 -110667.429556
2119 42360 -110608.783901
2120 42380 -110550.125639
2121 42400 -110491.454780
2122 42420 -110432.771331
2123 42440 -110374.075302
2124 42460 -110315.366700
2125 42480 -110256.645534
2126 42500 -110197.911812
2127 42520 -110139.165543
2128 42540 -110080.406733
2129 42560 -110021.635393
2130 42580 -109962.851530
2131 42600 -109904.055152
2132 42620 -109845.246268
2133 42640 -109786.424885
2134 42660 -109727.591013
2135 42680 -109668.744659
2136 42700 -109609.885831
2137 42720 -109551.014538
2138 42740 -109492.130787
2139 42760 -109433.234588
2140 42780 -109374.325948
2141 42800 -109315.404875
2142 42820 -109256.471377
2143 42840 -109197.525463
2144 42860 -109138.567141
2145 42880 -109079.596418
2146 42900 -109020.613303
2147 42920 -108961.617805
2148 42940 -108902.609930
2149 42960 -108843.589687
2150 42980 -108784.557085
2151 43000 -108725.512131
2152 43020 -108666.454833
2153 43040 -108607.385199
2154 43060 -108548.303238
2155 43080 -108489.208957
2156 43100 -108430.102365
2157 43120 -108370.983469
2158 43140 -108311.852277
2159 43160 -108252.708798
2160 43180 -108193.553039
2161 43200 -108134.385008
2162 43220 -108075.204714
2163 43240 -108016.012163
2164 43260 -107956.807365
2165 43280 -107897.590327
2166 43300 -107838.361057
2167 43320 -107779.119562
2168 43340 -107719.865852
2169 43360 -107660.599933
2170 43380 -107601.321814
2171 43400 -107542.031502
2172 43420 -107482.729005
2173 43440 -107423.414331
2174 43460 -107364.087489
2175 43480 -107304.748485
2176 43500 -107245.397328
2177 43520 -107186.034025
2178 43540 -107126.658585
2179 43560 -107067.271014
2180 43580 -107007.871321
2181 43600 -106948.459514
2182 43620 -106889.035601
2183 43640 -106829.599588
2184 43660 -106770.151485
2185 43680 -106710.691298
2186 43700 -106651.219035
2187 43720 -106591.734705
2188 43740 -106532.238314
2189 43760 -106472.729871
2190 43780 -106413.209384
2191 43800 -106353.676859
2192 43820 -106294.132305
2193 43840 -106234.575729
2194 43860 -106175.007139
2195 43880 -106115.426542
2196 43900 -106055.833947
2197 43920 -105996.229361
2198 43940 -105936.612791
2199 43960 -105876.984246
2200 43980 -105817.343732
2201 44000 -105757.691258
2202 44020 -105698.026831
2203 44040 -105638.350458
2204 44060 -105578.662148
2205 44080 -105518.961907
2206 44100 -105459.249743
2207 44120 -105399.525664
2208 44140 -105339.789678
2209 44160 -105280.041792
2210 44180 -105220.282013
2211 44200 -105160.510349
2212 44220 -105100.726807
2213 44240 -105040.931396
2214 44260 -104981.124122
2215 44280 -104921.304993
2216 44300 -104861.474016
2217 44320 -104801.631199
2218 44340 -104741.776550
2219 44360 -104681.910075
2220 44380 -104622.031783
2221 44400 -104562.141680
2222 44420 -104502.239775
2223 44440 -104442.326074
2224 44460 -104382.400585
2225 44480 -104322.463316
2226 44500 -104262.514273
2227 44520 -104202.553464
2228 44540 -104142.580897
2229 44560 -104082.596579
2230 44580 -104022.600517
2231 44600 -103962.592719
2232 44620 -103902.573191
2233 44640 -103842.541942
2234 44660 -103782.498979
2235 44680 -103722.444308
2236 44700 -103662.377938
2237 44720 -103602.299875
2238 44740 -103542.210127
2239 44760 -103482.108701
2240 44780 -103421.995605
2241 44800 -103361.870845
2242 44820 -103301.734430
2243 44840 -103241.586365
2244 44860 -103181.426659
2245 44880 -103121.255319
2246 44900 -103061.072351
2247 44920 -103000.877764
2248 44940 -102940.671564
2249 44960 -102880.453759
2250 44980 -102820.224355
2251 45000 -102759.983360
2252 45020 -102699.730782
2253 45040 -102639.466627
2254 45060 -102579.190902
2255 45080 -102518.903615
2256 45100 -102458.604772
2257 45120 -102398.294382
2258 45140 -102337.972451
2259 45160 -102277.638986
2260 45180 -102217.293994
2261 45200 -102156.937483
2262 45220 -102096.569459
2263 45240 -102036.189930
2264 45260 -101975.798902
2265 45280 -101915.396384
2266 45300 -101854.982381
2267 45320 -101794.556901
2268 45340 -101734.119951
2269 45360 -101673.671538
2270 45380 -101613.211670
2271 45400 -101552.740352
2272 45420 -101492.257593
2273 45440 -101431.763398
2274 45460 -101371.257776
2275 45480 -101310.740733
2276 45500 -101250.212277
2277 45520 -101189.672413
2278 45540 -101129.121150
2279 45560 -101068.558493
2280 45580 -101007.984451
2281 45600 -100947.399030
2282 45620 -100886.802237
2283 45640 -100826.194079
2284 45660 -100765.574562
2285 45680 -100704.943695
2286 45700 -100644.301483
2287 45720 -100583.647934
2288 45740 -100522.983054
2289 45760 -100462.306851
2290 45780 -100401.619331
2291 45800 -100340.920501
2292 45820 -100280.210368
2293 45840 -100219.488940
2294 45860 -100158.756222
2295 45880 -100098.012221
2296 45900 -100037.256946
2297 45920 -99976.490401
2298 45940 -99915.712595
2299 45960 -99854.923534
2300 45980 -99794.123224
2301 46000 -99733.311673
2302 46020 -99672.488888
2303 46040 -99611.654875
2304 46060 -99550.809640
2305 46080 -99489.953192
2306 46100 -99429.085536
2307 46120 -99368.206679
2308 46140 -99307.316629
2309 46160 -99246.415391
2310 46180 -99185.502973
2311 46200 -99124.579381
2312 46220 -99063.644622
2313 46240 -99002.698703
2314 46260 -98941.741630
2315 46280 -98880.773411
2316 46300 -98819.794051
2317 46320 -98758.803558
2318 46340 -98697.801938
2319 46360 -98636.789198
2320 46380 -98575.765345
2321 46400 -98514.730385
2322 46420 -98453.684324
2323 46440 -98392.627170
2324 46460 -98331.558930
2325 46480 -98270.479609
2326 46500 -98209.389215
2327 46520 -98148.287754
2328 46540 -98087.175232
2329 46560 -98026.051657
2330 46580 -97964.917035
2331 46600 -97903.771372
2332 46620 -97842.614675
2333 46640 -97781.446951
2334 46660 -97720.268206
2335 46680 -97659.078446
2336 46700 -97597.877680
2337 46720 -97536.665912
2338 46740 -97475.443149
2339 46760 -97414.209398
2340 46780 -97352.964666
2341 46800 -97291.708959
2342 46820 -97230.442284
2343 46840 -97169.164646
2344 46860 -97107.876053
2345 46880 -97046.576511
2346 46900 -96985.266026
2347 46920 -96923.944606
2348 46940 -96862.612256
2349 46960 -96801.268983
2350 46980 -96739.914793
2351 47000 -96678.549693
2352 47020 -96617.173690
2353 47040 -96555.786789
2354 47060 -96494.388997
2355 47080 -96432.980321
2356 47100 -96371.560767
2357 47120 -96310.130342
2358 47140 -96248.689051
2359 47160 -96187.236901
2360 47180 -96125.773900
2361 47200 -96064.300052
2362 47220 -96002.815364
2363 47240 -95941.319843
2364 47260 -95879.813496
2365 47280 -95818.296328
2366 47300 -95756.768345
2367 47320 -95695.229555
2368 47340 -95633.679964
2369 47360 -95572.119577
2370 47380 -95510.548401
2371 47400 -95448.966443
2372 47420 -95387.373709
2373 47440 -95325.770205
2374 47460 -95264.155937
2375 47480 -95202.530912
2376 47500 -95140.895136
2377 47520 -95079.248615
2378 47540 -95017.591356
2379 47560 -94955.923364
2380 47580 -94894.244647
2381 47600 -94832.555210
2382 47620 -94770.855059
2383 47640 -94709.144201
2384 47660 -94647.422643
2385 47680 -94585.690389
2386 47700 -94523.947448
2387 47720 -94462.193823
2388 47740 -94400.429523
2389 47760 -94338.654553
2390 47780 -94276.868919
2391 47800 -94215.072627
2392 47820 -94153.265685
2393 47840 -94091.448097
2394 47860 -94029.619870
2395 47880 -93967.781010
2396 47900 -93905.931524
2397 47920 -93844.071417
2398 47940 -93782.200696
2399 47960 -93720.319366
2400 47980 -93658.427435
2401 48000 -93596.524907
2402 48020 -93534.611790
2403 48040 -93472.688088
2404 48060 -93410.753810
2405 48080 -93348.808959
2406 48100 -93286.853543
2407 48120 -93224.887568
2408 48140 -93162.911040
2409 48160 -93100.923964
2410 48180 -93038.926347
2411 48200 -92976.918195
2412 48220 -92914.899514
2413 48240 -92852.870310
2414 48260 -92790.830589
2415 48280 -92728.780357
2416 48300 -92666.719621
2417 48320 -92604.648385
2418 48340 -92542.566657
2419 48360 -92480.474442
2420 48380 -92418.371746
2421 48400 -92356.258575
2422 48420 -92294.134935
2423 48440 -92232.000833
2424 48460 -92169.856273
2425 48480 -92107.701263
2426 48500 -92045.535808
2427 48520 -91983.359914
2428 48540 -91921.173587
2429 48560 -91858.976833
2430 48580 -91796.769658
2431 48600 -91734.552067
2432 48620 -91672.324068
2433 48640 -91610.085665
2434 48660 -91547.836865
2435 48680 -91485.577673
2436 48700 -91423.308096
2437 48720 -91361.028139
2438 48740 -91298.737808
2439 48760 -91236.437109
2440 48780 -91174.126049
2441 48800 -91111.804632
2442 48820 -91049.472865
2443 48840 -90987.130754
2444 48860 -90924.778304
2445 48880 -90862.415522
2446 48900 -90800.042413
2447 48920 -90737.658983
2448 48940 -90675.265237
2449 48960 -90612.861183
2450 48980 -90550.446825
2451 49000 -90488.022169
2452 49020 -90425.587221
2453 49040 -90363.141988
2454 49060 -90300.686474
2455 49080 -90238.220685
2456 49100 -90175.744628
2457 49120 -90113.258309
2458 49140 -90050.761732
2459 49160 -89988.254903
2460 49180 -89925.737830
2461 49200 -89863.210516
2462 49220 -89800.672969
2463 49240 -89738.125193
2464 49260 -89675.567194
2465 49280 -89612.998979
2466 49300 -89550.420553
2467 49320 -89487.831921
2468 49340 -89425.233090
2469 49360 -89362.624065
2470 49380 -89300.004851
2471 49400 -89237.375455
2472 49420 -89174.735882
2473 49440 -89112.086139
2474 49460 -89049.426229
2475 49480 -88986.756160
2476 49500 -88924.075937
2477 49520 -88861.385566
2478 49540 -88798.685051
2479 49560 -88735.974400
2480 49580 -88673.253617
2481 49600 -88610.522708
2482 49620 -88547.781680
2483 49640 -88485.030536
2484 49660 -88422.269284
2485 49680 -88359.497929
2486 49700 -88296.716476
2487 49720 -88233.924931
2488 49740 -88171.123299
2489 49760 -88108.311587
2490 49780 -88045.489799
2491 49800 -87982.657942
2492 49820 -87919.816020
2493 49840 -87856.964040
2494 49860 -87794.102008
2495 49880 -87731.229928
2496 49900 -87668.347806
2497 49920 -87605.455648
2498 49940 -87542.553459
2499 49960 -87479.641245
2500 49980 -87416.719012
2501 50000 -87353.786764

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