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 3 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
1002 20020 -165270.744973
1003 20040 -165235.760490
1004 20060 -165200.738565
1005 20080 -165165.679253
1006 20100 -165130.582611
1007 20120 -165095.448695
1008 20140 -165060.277560
1009 20160 -165025.069263
1010 20180 -164989.823858
1011 20200 -164954.541402
1012 20220 -164919.221948
1013 20240 -164883.865553
1014 20260 -164848.472272
1015 20280 -164813.042159
1016 20300 -164777.575268
1017 20320 -164742.071655
1018 20340 -164706.531373
1019 20360 -164670.954478
1020 20380 -164635.341022
1021 20400 -164599.691061
1022 20420 -164564.004648
1023 20440 -164528.281836
1024 20460 -164492.522679
1025 20480 -164456.727231
1026 20500 -164420.895545
1027 20520 -164385.027674
1028 20540 -164349.123671
1029 20560 -164313.183589
1030 20580 -164277.207481
1031 20600 -164241.195399
1032 20620 -164205.147396
1033 20640 -164169.063524
1034 20660 -164132.943835
1035 20680 -164096.788382
1036 20700 -164060.597217
1037 20720 -164024.370390
1038 20740 -163988.107955
1039 20760 -163951.809962
1040 20780 -163915.476463
1041 20800 -163879.107510
1042 20820 -163842.703153
1043 20840 -163806.263443
1044 20860 -163769.788433
1045 20880 -163733.278171
1046 20900 -163696.732709
1047 20920 -163660.152098
1048 20940 -163623.536388
1049 20960 -163586.885629
1050 20980 -163550.199872
1051 21000 -163513.479166
1052 21020 -163476.723561
1053 21040 -163439.933108
1054 21060 -163403.107856
1055 21080 -163366.247854
1056 21100 -163329.353152
1057 21120 -163292.423799
1058 21140 -163255.459845
1059 21160 -163218.461338
1060 21180 -163181.428328
1061 21200 -163144.360863
1062 21220 -163107.258992
1063 21240 -163070.122764
1064 21260 -163032.952227
1065 21280 -162995.747429
1066 21300 -162958.508419
1067 21320 -162921.235245
1068 21340 -162883.927955
1069 21360 -162846.586596
1070 21380 -162809.211217
1071 21400 -162771.801865
1072 21420 -162734.358588
1073 21440 -162696.881433
1074 21460 -162659.370448
1075 21480 -162621.825679
1076 21500 -162584.247174
1077 21520 -162546.634980
1078 21540 -162508.989143
1079 21560 -162471.309711
1080 21580 -162433.596730
1081 21600 -162395.850246
1082 21620 -162358.070306
1083 21640 -162320.256956
1084 21660 -162282.410243
1085 21680 -162244.530212
1086 21700 -162206.616910
1087 21720 -162168.670382
1088 21740 -162130.690674
1089 21760 -162092.677832
1090 21780 -162054.631901
1091 21800 -162016.552926
1092 21820 -161978.440954
1093 21840 -161940.296029
1094 21860 -161902.118196
1095 21880 -161863.907501
1096 21900 -161825.663987
1097 21920 -161787.387701
1098 21940 -161749.078686
1099 21960 -161710.736988
1100 21980 -161672.362650
1101 22000 -161633.955717
1102 22020 -161595.516234
1103 22040 -161557.044244
1104 22060 -161518.539792
1105 22080 -161480.002921
1106 22100 -161441.433675
1107 22120 -161402.832098
1108 22140 -161364.198234
1109 22160 -161325.532127
1110 22180 -161286.833819
1111 22200 -161248.103354
1112 22220 -161209.340775
1113 22240 -161170.546125
1114 22260 -161131.719448
1115 22280 -161092.860786
1116 22300 -161053.970183
1117 22320 -161015.047680
1118 22340 -160976.093321
1119 22360 -160937.107148
1120 22380 -160898.089203
1121 22400 -160859.039529
1122 22420 -160819.958168
1123 22440 -160780.845163
1124 22460 -160741.700555
1125 22480 -160702.524386
1126 22500 -160663.316697
1127 22520 -160624.077532
1128 22540 -160584.806932
1129 22560 -160545.504937
1130 22580 -160506.171590
1131 22600 -160466.806932
1132 22620 -160427.411004
1133 22640 -160387.983847
1134 22660 -160348.525503
1135 22680 -160309.036012
1136 22700 -160269.515415
1137 22720 -160229.963754
1138 22740 -160190.381069
1139 22760 -160150.767400
1140 22780 -160111.122788
1141 22800 -160071.447274
1142 22820 -160031.740898
1143 22840 -159992.003699
1144 22860 -159952.235719
1145 22880 -159912.436998
1146 22900 -159872.607574
1147 22920 -159832.747489
1148 22940 -159792.856782
1149 22960 -159752.935493
1150 22980 -159712.983661
1151 23000 -159673.001326
1152 23020 -159632.988528
1153 23040 -159592.945305
1154 23060 -159552.871697
1155 23080 -159512.767744
1156 23100 -159472.633484
1157 23120 -159432.468956
1158 23140 -159392.274199
1159 23160 -159352.049252
1160 23180 -159311.794155
1161 23200 -159271.508945
1162 23220 -159231.193660
1163 23240 -159190.848341
1164 23260 -159150.473024
1165 23280 -159110.067749
1166 23300 -159069.632553
1167 23320 -159029.167475
1168 23340 -158988.672553
1169 23360 -158948.147824
1170 23380 -158907.593327
1171 23400 -158867.009100
1172 23420 -158826.395180
1173 23440 -158785.751604
1174 23460 -158745.078411
1175 23480 -158704.375638
1176 23500 -158663.643322
1177 23520 -158622.881501
1178 23540 -158582.090211
1179 23560 -158541.269491
1180 23580 -158500.419377
1181 23600 -158459.539906
1182 23620 -158418.631114
1183 23640 -158377.693040
1184 23660 -158336.725719
1185 23680 -158295.729188
1186 23700 -158254.703485
1187 23720 -158213.648644
1188 23740 -158172.564704
1189 23760 -158131.451699
1190 23780 -158090.309667
1191 23800 -158049.138644
1192 23820 -158007.938665
1193 23840 -157966.709767
1194 23860 -157925.451986
1195 23880 -157884.165357
1196 23900 -157842.849917
1197 23920 -157801.505701
1198 23940 -157760.132745
1199 23960 -157718.731084
1200 23980 -157677.300754
1201 24000 -157635.841790
1202 24020 -157594.354228
1203 24040 -157552.838103
1204 24060 -157511.293450
1205 24080 -157469.720305
1206 24100 -157428.118701
1207 24120 -157386.488675
1208 24140 -157344.830261
1209 24160 -157303.143494
1210 24180 -157261.428409
1211 24200 -157219.685040
1212 24220 -157177.913422
1213 24240 -157136.113589
1214 24260 -157094.285577
1215 24280 -157052.429419
1216 24300 -157010.545149
1217 24320 -156968.632803
1218 24340 -156926.692413
1219 24360 -156884.724015
1220 24380 -156842.727642
1221 24400 -156800.703328
1222 24420 -156758.651107
1223 24440 -156716.571012
1224 24460 -156674.463078
1225 24480 -156632.327339
1226 24500 -156590.163827
1227 24520 -156547.972576
1228 24540 -156505.753620
1229 24560 -156463.506993
1230 24580 -156421.232726
1231 24600 -156378.930854
1232 24620 -156336.601411
1233 24640 -156294.244428
1234 24660 -156251.859938
1235 24680 -156209.447976
1236 24700 -156167.008574
1237 24720 -156124.541764
1238 24740 -156082.047580
1239 24760 -156039.526054
1240 24780 -155996.977218
1241 24800 -155954.401106
1242 24820 -155911.797749
1243 24840 -155869.167181
1244 24860 -155826.509433
1245 24880 -155783.824537
1246 24900 -155741.112527
1247 24920 -155698.373434
1248 24940 -155655.607290
1249 24960 -155612.814128
1250 24980 -155569.993978
1251 25000 -155527.146874
1252 25020 -155484.272847
1253 25040 -155441.371928
1254 25060 -155398.444149
1255 25080 -155355.489543
1256 25100 -155312.508140
1257 25120 -155269.499972
1258 25140 -155226.465071
1259 25160 -155183.403467
1260 25180 -155140.315193
1261 25200 -155097.200279
1262 25220 -155054.058756
1263 25240 -155010.890656
1264 25260 -154967.696010
1265 25280 -154924.474848
1266 25300 -154881.227202
1267 25320 -154837.953103
1268 25340 -154794.652581
1269 25360 -154751.325666
1270 25380 -154707.972391
1271 25400 -154664.592784
1272 25420 -154621.186878
1273 25440 -154577.754702
1274 25460 -154534.296286
1275 25480 -154490.811662
1276 25500 -154447.300859
1277 25520 -154403.763908
1278 25540 -154360.200838
1279 25560 -154316.611681
1280 25580 -154272.996465
1281 25600 -154229.355221
1282 25620 -154185.687980
1283 25640 -154141.994770
1284 25660 -154098.275622
1285 25680 -154054.530565
1286 25700 -154010.759629
1287 25720 -153966.962844
1288 25740 -153923.140239
1289 25760 -153879.291844
1290 25780 -153835.417689
1291 25800 -153791.517802
1292 25820 -153747.592213
1293 25840 -153703.640951
1294 25860 -153659.664046
1295 25880 -153615.661527
1296 25900 -153571.633423
1297 25920 -153527.579762
1298 25940 -153483.500574
1299 25960 -153439.395889
1300 25980 -153395.265733
1301 26000 -153351.110138
1302 26020 -153306.929131
1303 26040 -153262.722740
1304 26060 -153218.490996
1305 26080 -153174.233925
1306 26100 -153129.951558
1307 26120 -153085.643922
1308 26140 -153041.311045
1309 26160 -152996.952957
1310 26180 -152952.569685
1311 26200 -152908.161258
1312 26220 -152863.727704
1313 26240 -152819.269051
1314 26260 -152774.785327
1315 26280 -152730.276560
1316 26300 -152685.742778
1317 26320 -152641.184010
1318 26340 -152596.600282
1319 26360 -152551.991624
1320 26380 -152507.358061
1321 26400 -152462.699624
1322 26420 -152418.016338
1323 26440 -152373.308232
1324 26460 -152328.575333
1325 26480 -152283.817669
1326 26500 -152239.035266
1327 26520 -152194.228154
1328 26540 -152149.396358
1329 26560 -152104.539906
1330 26580 -152059.658826
1331 26600 -152014.753144
1332 26620 -151969.822888
1333 26640 -151924.868085
1334 26660 -151879.888762
1335 26680 -151834.884945
1336 26700 -151789.856662
1337 26720 -151744.803940
1338 26740 -151699.726805
1339 26760 -151654.625284
1340 26780 -151609.499404
1341 26800 -151564.349192
1342 26820 -151519.174674
1343 26840 -151473.975877
1344 26860 -151428.752827
1345 26880 -151383.505550
1346 26900 -151338.234074
1347 26920 -151292.938424
1348 26940 -151247.618628
1349 26960 -151202.274710
1350 26980 -151156.906698
1351 27000 -151111.514617
1352 27020 -151066.098493
1353 27040 -151020.658354
1354 27060 -150975.194224
1355 27080 -150929.706130
1356 27100 -150884.194097
1357 27120 -150838.658152
1358 27140 -150793.098319
1359 27160 -150747.514626
1360 27180 -150701.907098
1361 27200 -150656.275760
1362 27220 -150610.620638
1363 27240 -150564.941758
1364 27260 -150519.239145
1365 27280 -150473.512825
1366 27300 -150427.762822
1367 27320 -150381.989164
1368 27340 -150336.191874
1369 27360 -150290.370978
1370 27380 -150244.526501
1371 27400 -150198.658469
1372 27420 -150152.766906
1373 27440 -150106.851839
1374 27460 -150060.913291
1375 27480 -150014.951288
1376 27500 -149968.965855
1377 27520 -149922.957016
1378 27540 -149876.924798
1379 27560 -149830.869223
1380 27580 -149784.790318
1381 27600 -149738.688107
1382 27620 -149692.562614
1383 27640 -149646.413865
1384 27660 -149600.241883
1385 27680 -149554.046694
1386 27700 -149507.828322
1387 27720 -149461.586791
1388 27740 -149415.322126
1389 27760 -149369.034351
1390 27780 -149322.723491
1391 27800 -149276.389569
1392 27820 -149230.032611
1393 27840 -149183.652639
1394 27860 -149137.249679
1395 27880 -149090.823754
1396 27900 -149044.374889
1397 27920 -148997.903107
1398 27940 -148951.408433
1399 27960 -148904.890890
1400 27980 -148858.350502
1401 28000 -148811.787294
1402 28020 -148765.201288
1403 28040 -148718.592509
1404 28060 -148671.960981
1405 28080 -148625.306726
1406 28100 -148578.629769
1407 28120 -148531.930134
1408 28140 -148485.207843
1409 28160 -148438.462920
1410 28180 -148391.695389
1411 28200 -148344.905273
1412 28220 -148298.092596
1413 28240 -148251.257380
1414 28260 -148204.399650
1415 28280 -148157.519428
1416 28300 -148110.616737
1417 28320 -148063.691601
1418 28340 -148016.744043
1419 28360 -147969.774085
1420 28380 -147922.781752
1421 28400 -147875.767065
1422 28420 -147828.730048
1423 28440 -147781.670724
1424 28460 -147734.589116
1425 28480 -147687.485246
1426 28500 -147640.359137
1427 28520 -147593.210812
1428 28540 -147546.040294
1429 28560 -147498.847605
1430 28580 -147451.632768
1431 28600 -147404.395805
1432 28620 -147357.136740
1433 28640 -147309.855594
1434 28660 -147262.552390
1435 28680 -147215.227150
1436 28700 -147167.879897
1437 28720 -147120.510654
1438 28740 -147073.119441
1439 28760 -147025.706283
1440 28780 -146978.271200
1441 28800 -146930.814216
1442 28820 -146883.335352
1443 28840 -146835.834630
1444 28860 -146788.312072
1445 28880 -146740.767701
1446 28900 -146693.201538
1447 28920 -146645.613606
1448 28940 -146598.003926
1449 28960 -146550.372520
1450 28980 -146502.719410
1451 29000 -146455.044618
1452 29020 -146407.348165
1453 29040 -146359.630073
1454 29060 -146311.890365
1455 29080 -146264.129061
1456 29100 -146216.346183
1457 29120 -146168.541753
1458 29140 -146120.715792
1459 29160 -146072.868321
1460 29180 -146024.999363
1461 29200 -145977.108939
1462 29220 -145929.197069
1463 29240 -145881.263776
1464 29260 -145833.309081
1465 29280 -145785.333004
1466 29300 -145737.335567
1467 29320 -145689.316792
1468 29340 -145641.276699
1469 29360 -145593.215310
1470 29380 -145545.132645
1471 29400 -145497.028726
1472 29420 -145448.903573
1473 29440 -145400.757209
1474 29460 -145352.589653
1475 29480 -145304.400926
1476 29500 -145256.191050
1477 29520 -145207.960045
1478 29540 -145159.707931
1479 29560 -145111.434731
1480 29580 -145063.140464
1481 29600 -145014.825151
1482 29620 -144966.488813
1483 29640 -144918.131470
1484 29660 -144869.753143
1485 29680 -144821.353853
1486 29700 -144772.933620
1487 29720 -144724.492464
1488 29740 -144676.030406
1489 29760 -144627.547466
1490 29780 -144579.043665
1491 29800 -144530.519023
1492 29820 -144481.973561
1493 29840 -144433.407298
1494 29860 -144384.820254
1495 29880 -144336.212451
1496 29900 -144287.583908
1497 29920 -144238.934645
1498 29940 -144190.264682
1499 29960 -144141.574040
1500 29980 -144092.862738
1501 30000 -144044.130796

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