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 9 of 40 · 500/page · 20000 rows next →
# nmargin_tilde
4002 80020 16093.955375
4003 80040 16167.718858
4004 80060 16241.487644
4005 80080 16315.261731
4006 80100 16389.041117
4007 80120 16462.825801
4008 80140 16536.615780
4009 80160 16610.411054
4010 80180 16684.211620
4011 80200 16758.017477
4012 80220 16831.828622
4013 80240 16905.645055
4014 80260 16979.466773
4015 80280 17053.293775
4016 80300 17127.126058
4017 80320 17200.963622
4018 80340 17274.806464
4019 80360 17348.654583
4020 80380 17422.507977
4021 80400 17496.366644
4022 80420 17570.230583
4023 80440 17644.099791
4024 80460 17717.974268
4025 80480 17791.854010
4026 80500 17865.739018
4027 80520 17939.629288
4028 80540 18013.524819
4029 80560 18087.425610
4030 80580 18161.331658
4031 80600 18235.242963
4032 80620 18309.159521
4033 80640 18383.081333
4034 80660 18457.008394
4035 80680 18530.940706
4036 80700 18604.878264
4037 80720 18678.821068
4038 80740 18752.769116
4039 80760 18826.722406
4040 80780 18900.680937
4041 80800 18974.644706
4042 80820 19048.613713
4043 80840 19122.587955
4044 80860 19196.567431
4045 80880 19270.552138
4046 80900 19344.542076
4047 80920 19418.537243
4048 80940 19492.537636
4049 80960 19566.543254
4050 80980 19640.554096
4051 81000 19714.570160
4052 81020 19788.591443
4053 81040 19862.617945
4054 81060 19936.649664
4055 81080 20010.686597
4056 81100 20084.728744
4057 81120 20158.776102
4058 81140 20232.828670
4059 81160 20306.886447
4060 81180 20380.949429
4061 81200 20455.017617
4062 81220 20529.091008
4063 81240 20603.169600
4064 81260 20677.253391
4065 81280 20751.342381
4066 81300 20825.436567
4067 81320 20899.535948
4068 81340 20973.640521
4069 81360 21047.750286
4070 81380 21121.865241
4071 81400 21195.985383
4072 81420 21270.110712
4073 81440 21344.241225
4074 81460 21418.376921
4075 81480 21492.517798
4076 81500 21566.663855
4077 81520 21640.815090
4078 81540 21714.971501
4079 81560 21789.133086
4080 81580 21863.299844
4081 81600 21937.471773
4082 81620 22011.648872
4083 81640 22085.831138
4084 81660 22160.018571
4085 81680 22234.211168
4086 81700 22308.408928
4087 81720 22382.611849
4088 81740 22456.819930
4089 81760 22531.033168
4090 81780 22605.251563
4091 81800 22679.475112
4092 81820 22753.703813
4093 81840 22827.937666
4094 81860 22902.176669
4095 81880 22976.420819
4096 81900 23050.670116
4097 81920 23124.924557
4098 81940 23199.184141
4099 81960 23273.448866
4100 81980 23347.718731
4101 82000 23421.993733
4102 82020 23496.273872
4103 82040 23570.559146
4104 82060 23644.849552
4105 82080 23719.145090
4106 82100 23793.445757
4107 82120 23867.751553
4108 82140 23942.062475
4109 82160 24016.378521
4110 82180 24090.699691
4111 82200 24165.025982
4112 82220 24239.357393
4113 82240 24313.693922
4114 82260 24388.035568
4115 82280 24462.382328
4116 82300 24536.734202
4117 82320 24611.091188
4118 82340 24685.453283
4119 82360 24759.820487
4120 82380 24834.192797
4121 82400 24908.570213
4122 82420 24982.952731
4123 82440 25057.340352
4124 82460 25131.733073
4125 82480 25206.130893
4126 82500 25280.533809
4127 82520 25354.941821
4128 82540 25429.354926
4129 82560 25503.773124
4130 82580 25578.196411
4131 82600 25652.624788
4132 82620 25727.058252
4133 82640 25801.496801
4134 82660 25875.940435
4135 82680 25950.389150
4136 82700 26024.842947
4137 82720 26099.301822
4138 82740 26173.765775
4139 82760 26248.234804
4140 82780 26322.708907
4141 82800 26397.188082
4142 82820 26471.672329
4143 82840 26546.161645
4144 82860 26620.656028
4145 82880 26695.155478
4146 82900 26769.659993
4147 82920 26844.169570
4148 82940 26918.684209
4149 82960 26993.203908
4150 82980 27067.728664
4151 83000 27142.258477
4152 83020 27216.793345
4153 83040 27291.333267
4154 83060 27365.878240
4155 83080 27440.428263
4156 83100 27514.983335
4157 83120 27589.543454
4158 83140 27664.108618
4159 83160 27738.678825
4160 83180 27813.254075
4161 83200 27887.834366
4162 83220 27962.419695
4163 83240 28037.010062
4164 83260 28111.605464
4165 83280 28186.205901
4166 83300 28260.811370
4167 83320 28335.421870
4168 83340 28410.037400
4169 83360 28484.657957
4170 83380 28559.283540
4171 83400 28633.914149
4172 83420 28708.549780
4173 83440 28783.190432
4174 83460 28857.836105
4175 83480 28932.486796
4176 83500 29007.142503
4177 83520 29081.803226
4178 83540 29156.468962
4179 83560 29231.139711
4180 83580 29305.815469
4181 83600 29380.496237
4182 83620 29455.182011
4183 83640 29529.872792
4184 83660 29604.568576
4185 83680 29679.269363
4186 83700 29753.975151
4187 83720 29828.685938
4188 83740 29903.401723
4189 83760 29978.122505
4190 83780 30052.848280
4191 83800 30127.579050
4192 83820 30202.314810
4193 83840 30277.055561
4194 83860 30351.801300
4195 83880 30426.552025
4196 83900 30501.307736
4197 83920 30576.068431
4198 83940 30650.834108
4199 83960 30725.604766
4200 83980 30800.380402
4201 84000 30875.161016
4202 84020 30949.946606
4203 84040 31024.737170
4204 84060 31099.532707
4205 84080 31174.333216
4206 84100 31249.138694
4207 84120 31323.949140
4208 84140 31398.764552
4209 84160 31473.584930
4210 84180 31548.410271
4211 84200 31623.240574
4212 84220 31698.075838
4213 84240 31772.916060
4214 84260 31847.761240
4215 84280 31922.611375
4216 84300 31997.466464
4217 84320 32072.326506
4218 84340 32147.191500
4219 84360 32222.061442
4220 84380 32296.936333
4221 84400 32371.816171
4222 84420 32446.700953
4223 84440 32521.590678
4224 84460 32596.485346
4225 84480 32671.384953
4226 84500 32746.289500
4227 84520 32821.198984
4228 84540 32896.113403
4229 84560 32971.032757
4230 84580 33045.957043
4231 84600 33120.886261
4232 84620 33195.820408
4233 84640 33270.759483
4234 84660 33345.703484
4235 84680 33420.652411
4236 84700 33495.606261
4237 84720 33570.565032
4238 84740 33645.528725
4239 84760 33720.497336
4240 84780 33795.470864
4241 84800 33870.449309
4242 84820 33945.432668
4243 84840 34020.420939
4244 84860 34095.414122
4245 84880 34170.412214
4246 84900 34245.415215
4247 84920 34320.423122
4248 84940 34395.435935
4249 84960 34470.453651
4250 84980 34545.476269
4251 85000 34620.503788
4252 85020 34695.536206
4253 85040 34770.573522
4254 85060 34845.615734
4255 85080 34920.662840
4256 85100 34995.714840
4257 85120 35070.771731
4258 85140 35145.833512
4259 85160 35220.900182
4260 85180 35295.971738
4261 85200 35371.048181
4262 85220 35446.129507
4263 85240 35521.215716
4264 85260 35596.306805
4265 85280 35671.402775
4266 85300 35746.503622
4267 85320 35821.609346
4268 85340 35896.719945
4269 85360 35971.835417
4270 85380 36046.955761
4271 85400 36122.080976
4272 85420 36197.211060
4273 85440 36272.346011
4274 85460 36347.485829
4275 85480 36422.630511
4276 85500 36497.780056
4277 85520 36572.934462
4278 85540 36648.093729
4279 85560 36723.257854
4280 85580 36798.426836
4281 85600 36873.600673
4282 85620 36948.779365
4283 85640 37023.962910
4284 85660 37099.151305
4285 85680 37174.344550
4286 85700 37249.542644
4287 85720 37324.745583
4288 85740 37399.953369
4289 85760 37475.165997
4290 85780 37550.383468
4291 85800 37625.605780
4292 85820 37700.832931
4293 85840 37776.064920
4294 85860 37851.301745
4295 85880 37926.543404
4296 85900 38001.789897
4297 85920 38077.041222
4298 85940 38152.297378
4299 85960 38227.558362
4300 85980 38302.824174
4301 86000 38378.094811
4302 86020 38453.370273
4303 86040 38528.650558
4304 86060 38603.935665
4305 86080 38679.225591
4306 86100 38754.520337
4307 86120 38829.819899
4308 86140 38905.124277
4309 86160 38980.433469
4310 86180 39055.747474
4311 86200 39131.066291
4312 86220 39206.389917
4313 86240 39281.718351
4314 86260 39357.051592
4315 86280 39432.389639
4316 86300 39507.732490
4317 86320 39583.080143
4318 86340 39658.432597
4319 86360 39733.789850
4320 86380 39809.151902
4321 86400 39884.518751
4322 86420 39959.890394
4323 86440 40035.266832
4324 86460 40110.648061
4325 86480 40186.034082
4326 86500 40261.424892
4327 86520 40336.820490
4328 86540 40412.220874
4329 86560 40487.626043
4330 86580 40563.035996
4331 86600 40638.450732
4332 86620 40713.870247
4333 86640 40789.294542
4334 86660 40864.723615
4335 86680 40940.157464
4336 86700 41015.596088
4337 86720 41091.039486
4338 86740 41166.487655
4339 86760 41241.940595
4340 86780 41317.398304
4341 86800 41392.860781
4342 86820 41468.328024
4343 86840 41543.800032
4344 86860 41619.276804
4345 86880 41694.758337
4346 86900 41770.244631
4347 86920 41845.735683
4348 86940 41921.231494
4349 86960 41996.732060
4350 86980 42072.237382
4351 87000 42147.747457
4352 87020 42223.262283
4353 87040 42298.781860
4354 87060 42374.306186
4355 87080 42449.835260
4356 87100 42525.369080
4357 87120 42600.907644
4358 87140 42676.450952
4359 87160 42751.999002
4360 87180 42827.551792
4361 87200 42903.109321
4362 87220 42978.671588
4363 87240 43054.238591
4364 87260 43129.810329
4365 87280 43205.386800
4366 87300 43280.968003
4367 87320 43356.553937
4368 87340 43432.144600
4369 87360 43507.739990
4370 87380 43583.340107
4371 87400 43658.944948
4372 87420 43734.554513
4373 87440 43810.168800
4374 87460 43885.787807
4375 87480 43961.411534
4376 87500 44037.039978
4377 87520 44112.673139
4378 87540 44188.311014
4379 87560 44263.953604
4380 87580 44339.600905
4381 87600 44415.252917
4382 87620 44490.909638
4383 87640 44566.571067
4384 87660 44642.237203
4385 87680 44717.908043
4386 87700 44793.583588
4387 87720 44869.263834
4388 87740 44944.948782
4389 87760 45020.638429
4390 87780 45096.332774
4391 87800 45172.031815
4392 87820 45247.735552
4393 87840 45323.443983
4394 87860 45399.157106
4395 87880 45474.874920
4396 87900 45550.597424
4397 87920 45626.324616
4398 87940 45702.056495
4399 87960 45777.793059
4400 87980 45853.534308
4401 88000 45929.280239
4402 88020 46005.030851
4403 88040 46080.786144
4404 88060 46156.546114
4405 88080 46232.310762
4406 88100 46308.080086
4407 88120 46383.854084
4408 88140 46459.632755
4409 88160 46535.416097
4410 88180 46611.204110
4411 88200 46686.996791
4412 88220 46762.794140
4413 88240 46838.596155
4414 88260 46914.402834
4415 88280 46990.214177
4416 88300 47066.030181
4417 88320 47141.850846
4418 88340 47217.676170
4419 88360 47293.506152
4420 88380 47369.340790
4421 88400 47445.180083
4422 88420 47521.024029
4423 88440 47596.872628
4424 88460 47672.725877
4425 88480 47748.583776
4426 88500 47824.446324
4427 88520 47900.313517
4428 88540 47976.185356
4429 88560 48052.061839
4430 88580 48127.942965
4431 88600 48203.828732
4432 88620 48279.719138
4433 88640 48355.614183
4434 88660 48431.513866
4435 88680 48507.418183
4436 88700 48583.327136
4437 88720 48659.240721
4438 88740 48735.158938
4439 88760 48811.081785
4440 88780 48887.009261
4441 88800 48962.941364
4442 88820 49038.878094
4443 88840 49114.819448
4444 88860 49190.765426
4445 88880 49266.716026
4446 88900 49342.671247
4447 88920 49418.631087
4448 88940 49494.595545
4449 88960 49570.564620
4450 88980 49646.538310
4451 89000 49722.516614
4452 89020 49798.499530
4453 89040 49874.487058
4454 89060 49950.479195
4455 89080 50026.475941
4456 89100 50102.477294
4457 89120 50178.483253
4458 89140 50254.493817
4459 89160 50330.508983
4460 89180 50406.528751
4461 89200 50482.553120
4462 89220 50558.582088
4463 89240 50634.615653
4464 89260 50710.653815
4465 89280 50786.696571
4466 89300 50862.743922
4467 89320 50938.795865
4468 89340 51014.852398
4469 89360 51090.913522
4470 89380 51166.979233
4471 89400 51243.049532
4472 89420 51319.124416
4473 89440 51395.203884
4474 89460 51471.287935
4475 89480 51547.376568
4476 89500 51623.469781
4477 89520 51699.567573
4478 89540 51775.669943
4479 89560 51851.776889
4480 89580 51927.888409
4481 89600 52004.004504
4482 89620 52080.125170
4483 89640 52156.250407
4484 89660 52232.380214
4485 89680 52308.514589
4486 89700 52384.653531
4487 89720 52460.797039
4488 89740 52536.945111
4489 89760 52613.097745
4490 89780 52689.254942
4491 89800 52765.416698
4492 89820 52841.583014
4493 89840 52917.753887
4494 89860 52993.929316
4495 89880 53070.109300
4496 89900 53146.293838
4497 89920 53222.482928
4498 89940 53298.676569
4499 89960 53374.874760
4500 89980 53451.077499
4501 90000 53527.284785

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