Current task: —

E-002-first-zeros.py

Experiments: E-002 · script updated 08-17-2026

E-002-zeros-first-10000.csv — 310.4 KB, updated 08-17-2026

← prev page 15 of 20 · 500/page · 10000 rows next →
# ngamma_n
7002 7001 7265.962856285730425838365
7003 7002 7266.825071623350184688554
7004 7003 7267.022572810923249049979
7005 7004 7267.851161907388025441739
7006 7005 7269.281796531018220073296
7007 7006 7270.665196022362393679354
7008 7007 7271.162578225273133176604
7009 7008 7272.293916094605082827463
7010 7009 7272.756819678747073989472
7011 7010 7273.701234074715900567847
7012 7011 7274.639386093656458108059
7013 7012 7275.692946628287775442351
7014 7013 7276.188510979781822820454
7015 7014 7277.313417506350011730332
7016 7015 7277.911194920978544607525
7017 7016 7279.226323515833416739917
7018 7017 7279.768521282346233808039
7019 7018 7281.316094067057101992481
7020 7019 7282.176167149542507676168
7021 7020 7282.817681698420671027602
7022 7021 7283.495775763902552397189
7023 7022 7284.0236978972730477691
7024 7023 7285.277302369637128835807
7025 7024 7286.139694204905831124207
7026 7025 7286.779238865985828163611
7027 7026 7288.267170428100978003182
7028 7027 7289.103758080980736402286
7029 7028 7289.940276827100235646753
7030 7029 7290.821429929111279319383
7031 7030 7291.29004357574896657398
7032 7031 7292.741249445308596368884
7033 7032 7293.403109651341221108233
7034 7033 7294.204147964223233267898
7035 7034 7295.048894052715275701476
7036 7035 7295.564849559881398992491
7037 7036 7296.571619042983888130308
7038 7037 7298.368684315504602304457
7039 7038 7299.138848601880261484714
7040 7039 7299.336571426263320006655
7041 7040 7300.763476874868297675678
7042 7041 7301.581317104950424209411
7043 7042 7301.848557608593614591575
7044 7043 7302.917875819657265136454
7045 7044 7303.843900682814064180181
7046 7045 7305.060287115027131041382
7047 7046 7305.81816157603400466108
7048 7047 7306.637205578428387127106
7049 7048 7307.660752633696008529375
7050 7049 7308.671664974055799648843
7051 7050 7309.497903971277161652076
7052 7051 7310.501357045358307444913
7053 7052 7311.190951720799514080265
7054 7053 7311.881145968618934921569
7055 7054 7312.724372391775215874088
7056 7055 7313.555046083626767562659
7057 7056 7314.449131441170571386485
7058 7057 7315.755628547018349158745
7059 7058 7317.100250555245665362207
7060 7059 7317.553738653384640218056
7061 7060 7318.351002510428594160946
7062 7061 7318.871998937910655270094
7063 7062 7319.896757099853641876324
7064 7063 7321.233781570092830227255
7065 7064 7321.717373427289606437279
7066 7065 7322.568751053077915200438
7067 7066 7323.243983122767672892033
7068 7067 7324.849333141856509673237
7069 7068 7325.226115149934923090422
7070 7069 7326.444102995292468808746
7071 7070 7327.534497970134863705956
7072 7071 7328.283514383425177515278
7073 7072 7328.861171711708020379323
7074 7073 7329.815578232490447790919
7075 7074 7330.586839533580275299798
7076 7075 7330.970858435755318792725
7077 7076 7332.652130477497609658357
7078 7077 7333.517033387612336019716
7079 7078 7334.639105970603126068456
7080 7079 7335.193963690995500536703
7081 7080 7336.016820436064203488521
7082 7081 7337.312223967157482777072
7083 7082 7337.649201460033123598291
7084 7083 7338.621251438964497619192
7085 7084 7339.763136524200772065826
7086 7085 7340.495964530858441116747
7087 7086 7341.172411124238111707107
7088 7087 7341.781448952951327102261
7089 7088 7343.507522665944163526653
7090 7089 7344.429407193065457155713
7091 7090 7345.413384428055544149387
7092 7091 7345.737188186168350015066
7093 7092 7346.698927085315089508391
7094 7093 7347.601440600781153653007
7095 7094 7348.226470588923094624164
7096 7095 7349.24977762881870154721
7097 7096 7350.347618713708219419933
7098 7097 7350.973256492759165253112
7099 7098 7352.631847583570032761104
7100 7099 7352.880430233791917483614
7101 7100 7353.913947828911691922234
7102 7101 7354.584625580227641599485
7103 7102 7356.076801101874458613203
7104 7103 7356.71390153703541977255
7105 7104 7357.298064962759905567036
7106 7105 7357.829927024958913009852
7107 7106 7359.022424060840259339528
7108 7107 7359.818833444008357428445
7109 7108 7361.267013426217842891349
7110 7109 7362.05813443122856816341
7111 7110 7363.102591149028470739943
7112 7111 7363.822093867508893236596
7113 7112 7364.469761389726229405171
7114 7113 7365.12005991044137604558
7115 7114 7366.176826462235344939385
7116 7115 7367.444805267362586995852
7117 7116 7367.716583625250539703903
7118 7117 7369.211235568974283400825
7119 7118 7369.53261363158859785459
7120 7119 7370.778296043783205148168
7121 7120 7371.987960977816102732237
7122 7121 7372.805047996384431371908
7123 7122 7373.424035167817824410782
7124 7123 7374.349391958722387603327
7125 7124 7375.199243762267915500422
7126 7125 7375.878151643688935722328
7127 7126 7376.873649474445420756326
7128 7127 7377.190089316885776702256
7129 7128 7379.332785005437798852532
7130 7129 7379.97960305297001743652
7131 7130 7380.464011573217246397752
7132 7131 7381.536932090845833017232
7133 7132 7382.222713356686497953225
7134 7133 7383.173523724594820140595
7135 7134 7384.202396205880081704025
7136 7135 7384.924513067149952468021
7137 7136 7385.752633651786959632919
7138 7137 7386.461552514135297793149
7139 7138 7387.542420641697263856791
7140 7139 7388.629535056729806573127
7141 7140 7389.584509291652398878149
7142 7141 7390.664177739965680684256
7143 7142 7391.440259727915676236724
7144 7143 7392.160733367933975895405
7145 7144 7392.988605528528395612195
7146 7145 7393.173269331163408867858
7147 7146 7394.711617877432209773998
7148 7147 7395.693962379837779998449
7149 7148 7396.403273585961691027522
7150 7149 7397.531933665013403860031
7151 7150 7398.751920761657179477798
7152 7151 7399.220386820145566129749
7153 7152 7399.828819540750104141317
7154 7153 7401.354181203370289682694
7155 7154 7401.670669618894287793727
7156 7155 7403.018090817923481455411
7157 7156 7403.448923018043834200092
7158 7157 7404.103468670983684070743
7159 7158 7405.071527890625336518224
7160 7159 7406.434875899130835246785
7161 7160 7407.782772520035335433673
7162 7161 7408.318442247684754666972
7163 7162 7408.961023091149374354811
7164 7163 7409.697910099988901549521
7165 7164 7410.875016639208371852939
7166 7165 7411.475578801157833130452
7167 7166 7412.213344651957668830719
7168 7167 7413.328582877763198529613
7169 7168 7414.418814788438288698287
7170 7169 7415.18065015704555626033
7171 7170 7416.269504358515811868804
7172 7171 7416.713391716671162192253
7173 7172 7418.310509223290436967465
7174 7173 7418.988098353758021811299
7175 7174 7419.537617023206762724814
7176 7175 7420.415913275070822032929
7177 7176 7421.420781813852902728309
7178 7177 7421.806962622241659046187
7179 7178 7422.910687407876036752307
7180 7179 7424.220735433382475013523
7181 7180 7425.306205763072387950165
7182 7181 7426.042615765489458064169
7183 7182 7427.010358315736622728119
7184 7183 7427.61888217224088248743
7185 7184 7428.124246616228754627855
7186 7185 7429.350889131061105350627
7187 7186 7430.5553688948598136442
7188 7187 7431.156635122250530927296
7189 7188 7431.634303466920622692661
7190 7189 7432.740669966663169448269
7191 7190 7434.041575198198332452905
7192 7191 7435.059191589477996769375
7193 7192 7435.590441587655234259349
7194 7193 7436.766516776394436176269
7195 7194 7437.658181522263560917074
7196 7195 7438.12599504293822062318
7197 7196 7438.872215940764819608698
7198 7197 7439.737648719435252954264
7199 7198 7440.703121048362775762338
7200 7199 7441.96932338923160241809
7201 7200 7443.171160862861014030325
7202 7201 7443.628394354244091403323
7203 7202 7444.423866228738812196922
7204 7203 7445.518979786399835818064
7205 7204 7446.192112312270061348451
7206 7205 7447.470379601740188309269
7207 7206 7447.915999950696172335044
7208 7207 7448.578846008307472558256
7209 7208 7450.026851981019403052211
7210 7209 7450.313414658015021852892
7211 7210 7451.287377006888543481113
7212 7211 7453.156333014424156857683
7213 7212 7453.562255596974916590541
7214 7213 7454.501150895424585067033
7215 7214 7455.111599984896281354573
7216 7215 7455.756248182660499694709
7217 7216 7456.879264173984865474397
7218 7217 7457.555015683983027277889
7219 7218 7458.758896547601961142207
7220 7219 7459.317916595858025070637
7221 7220 7460.742319218625349081935
7222 7221 7461.412836776340541521824
7223 7222 7462.345119229532087408511
7224 7223 7463.241034353370796998786
7225 7224 7463.953428492880504501651
7226 7225 7465.235332546496178727004
7227 7226 7465.873648618118889695003
7228 7227 7466.509567399981599685718
7229 7228 7467.236892002760991399514
7230 7229 7467.893516230214783151051
7231 7230 7469.74231277572060914711
7232 7231 7470.410694722724031713602
7233 7232 7471.316153957136808768312
7234 7233 7472.216337834579598657615
7235 7234 7472.938452470044806957875
7236 7235 7473.801923221800201404659
7237 7236 7474.31837556098658007541
7238 7237 7475.457148465555493780247
7239 7238 7476.661685380833510108036
7240 7239 7477.126117162264961792091
7241 7240 7477.990220376344812903471
7242 7241 7479.360803879442271820007
7243 7242 7479.826490146604122632168
7244 7243 7481.270585133406120668127
7245 7244 7482.088353049577709046122
7246 7245 7482.760970559226408652807
7247 7246 7483.222684506732783256841
7248 7247 7484.435406371245882189405
7249 7248 7485.087260837081238577323
7250 7249 7485.836110097768982266797
7251 7250 7486.980574712563132691576
7252 7251 7488.341398400302638447354
7253 7252 7489.410793262698826948502
7254 7253 7489.801649959827976689675
7255 7254 7490.288466891315745374499
7256 7255 7491.480237437946742721192
7257 7256 7492.87117701094658366354
7258 7257 7493.000605946223722583793
7259 7258 7494.155593665298991217584
7260 7259 7494.893354720954617006599
7261 7260 7495.620535550989495331381
7262 7261 7496.903234041265436847912
7263 7262 7497.876666871169405678326
7264 7263 7499.018375212885305176044
7265 7264 7499.635017044756982192725
7266 7265 7500.520758701277019637178
7267 7266 7501.394356540355174080908
7268 7267 7501.889601165814580332121
7269 7268 7502.606128496650192893355
7270 7269 7503.815822095972240798501
7271 7270 7505.007627511302185422641
7272 7271 7505.855760749127102917379
7273 7272 7506.4587778442488232479
7274 7273 7507.881582709907876081645
7275 7274 7508.325357727524731090278
7276 7275 7509.36285797248792752741
7277 7276 7510.062014246713988978162
7278 7277 7511.268152095430295920217
7279 7278 7511.831550094300016093715
7280 7279 7512.639108892178797878159
7281 7280 7513.256478602329517953943
7282 7281 7514.327458196641650421608
7283 7282 7516.017338757152935858657
7284 7283 7516.682865383154419164785
7285 7284 7517.316546882907393634245
7286 7285 7518.233922044484548529665
7287 7286 7518.988255293477437859909
7288 7287 7519.483808585253547372663
7289 7288 7521.095478308028223922218
7290 7289 7521.418960158709423093082
7291 7290 7522.23595594090026723703
7292 7291 7523.583809962573676566051
7293 7292 7524.576063140947031560946
7294 7293 7525.117755066564482271084
7295 7294 7526.077888669459256673785
7296 7295 7527.339243900151827794985
7297 7296 7528.255945298981904693998
7298 7297 7528.618824834709755725785
7299 7298 7529.572439683574495871864
7300 7299 7530.024518136625101719415
7301 7300 7531.443037755095599093485
7302 7301 7531.918476003772679290952
7303 7302 7533.701788860477887536102
7304 7303 7534.196176756290840934869
7305 7304 7535.269416746331117322336
7306 7305 7535.795879638116309489975
7307 7306 7536.852140836628031889472
7308 7307 7537.312581103595125673445
7309 7308 7538.513844107824489426829
7310 7309 7539.507181192063108875114
7311 7310 7540.227539900590182996344
7312 7311 7540.952212400233503607846
7313 7312 7541.719927233003954428543
7314 7313 7543.27408681060413234067
7315 7314 7544.143089597874020440753
7316 7315 7545.017282211273549768857
7317 7316 7545.469645335592324132304
7318 7317 7546.619778438462273517101
7319 7318 7547.346464375364075455226
7320 7319 7548.163928908409212916697
7321 7320 7548.467009257108447356372
7322 7321 7550.120472174725836334514
7323 7322 7551.093890396879284391479
7324 7323 7552.050977943308287753295
7325 7324 7552.915722719904331474183
7326 7325 7553.422599595428144353752
7327 7326 7554.415064430765764782134
7328 7327 7555.636986998434110980147
7329 7328 7556.215633320349496940274
7330 7329 7557.123848469489221596342
7331 7330 7557.731650015266580737209
7332 7331 7558.61869314490848428805
7333 7332 7559.643376318825209781396
7334 7333 7560.829820023239967471604
7335 7334 7561.658959993991355611088
7336 7335 7563.18281443762766103714
7337 7336 7563.520415699232741405218
7338 7337 7563.769301891219881043698
7339 7338 7564.960243676845744017286
7340 7339 7565.732853403864780349648
7341 7340 7566.845322430019350954391
7342 7341 7567.866531115936457128643
7343 7342 7568.289067602235025520143
7344 7343 7569.797165105977979193445
7345 7344 7570.547137990415853218847
7346 7345 7571.281289377956611479621
7347 7346 7572.278993977846617981185
7348 7347 7573.255184306472245964134
7349 7348 7574.04680204844820789913
7350 7349 7574.749888838462338168609
7351 7350 7575.696668164665144318653
7352 7351 7576.268605073816272951201
7353 7352 7576.905770590952376800337
7354 7353 7578.917486664980541744989
7355 7354 7579.597757316370979854043
7356 7355 7580.280088977226210362513
7357 7356 7580.959830819929112068924
7358 7357 7582.031705549502287524004
7359 7358 7582.802983860871466594029
7360 7359 7583.462734774582125957924
7361 7360 7584.486959736256362491242
7362 7361 7585.469517629117947942225
7363 7362 7586.234994584177271235493
7364 7363 7587.283239491649158878755
7365 7364 7587.890350603440194526433
7366 7365 7589.356254115857285823284
7367 7366 7590.120871486676802837054
7368 7367 7590.918224866148663468421
7369 7368 7591.966193812054308603466
7370 7369 7592.269712605830106360572
7371 7370 7593.098313959197637430841
7372 7371 7594.102742542237735401204
7373 7372 7595.077658168319632537987
7374 7373 7596.016212837787818208863
7375 7374 7597.414985716674184017456
7376 7375 7598.007882857832747009363
7377 7376 7598.982709953076319671231
7378 7377 7599.565154718348067712328
7379 7378 7600.130858727205791938523
7380 7379 7601.751366014514473666215
7381 7380 7602.405163470408841780254
7382 7381 7603.022366327148150365015
7383 7382 7603.560678579999710349447
7384 7383 7604.831196490887741558374
7385 7384 7605.857934326610778176843
7386 7385 7606.994882980089870273915
7387 7386 7608.02135412268464458616
7388 7387 7608.420807870141017375605
7389 7388 7609.673607809897104059222
7390 7389 7610.066214264622047545827
7391 7390 7610.854490320338829840803
7392 7391 7611.794530221127641004584
7393 7392 7612.682249514443941397105
7394 7393 7613.949125482984284409551
7395 7394 7614.911019080955606889889
7396 7395 7615.589706732948507625794
7397 7396 7616.361441789906642697921
7398 7397 7617.490687417529440383512
7399 7398 7618.506225529719278433727
7400 7399 7619.109221400457056567524
7401 7400 7619.74944183342033197603
7402 7401 7620.983924855111797211961
7403 7402 7621.693574971434539229488
7404 7403 7622.017492708766276081222
7405 7404 7623.4232985455932342269
7406 7405 7624.987382547289350556213
7407 7406 7625.594493501390940917125
7408 7407 7626.265292758522939904744
7409 7408 7627.127213556263907982367
7410 7409 7627.690979947768927615502
7411 7410 7628.742026441597760408531
7412 7411 7629.642702477912836758214
7413 7412 7630.569927977194936764735
7414 7413 7631.506758032182373200919
7415 7414 7632.009099304118127588226
7416 7415 7633.651861591744363861946
7417 7416 7634.312300238634041392011
7418 7417 7634.77178800081249869111
7419 7418 7636.387151486738377597809
7420 7419 7636.82298939939534759023
7421 7420 7637.940366202656175094017
7422 7421 7638.237099967603795159859
7423 7422 7639.03929491068801606839
7424 7423 7639.934790875170681103124
7425 7424 7641.505667573557136941601
7426 7425 7642.166837363396411637479
7427 7426 7643.295177167179039051704
7428 7427 7644.035703917745626767093
7429 7428 7644.927813313910344241562
7430 7429 7645.331599328179891317727
7431 7430 7646.560905687084503150298
7432 7431 7647.399804109449757489055
7433 7432 7648.197821584823423761336
7434 7433 7649.21036891410397877427
7435 7434 7649.787924743955314398134
7436 7435 7650.778131570510468451691
7437 7436 7651.918000850130213887414
7438 7437 7653.356680957865957558534
7439 7438 7653.70281498644487266645
7440 7439 7654.580638876738525422381
7441 7440 7655.121494572614321818853
7442 7441 7656.261966851359120835782
7443 7442 7656.956407644797437168282
7444 7443 7657.717933644821738698028
7445 7444 7658.652286327494611691982
7446 7445 7660.264422520262253274577
7447 7446 7660.874842474168023419528
7448 7447 7661.578687879151758572675
7449 7448 7662.331833437668217558125
7450 7449 7663.456194163918995424802
7451 7450 7664.203009254391862502666
7452 7451 7665.444059487939183146746
7453 7452 7665.801809429017324387924
7454 7453 7666.502822823470848864891
7455 7454 7667.549329156073104945431
7456 7455 7668.365665795743934648345
7457 7456 7669.936029946729274183989
7458 7457 7670.581042533543230095329
7459 7458 7671.447129920533693208874
7460 7459 7672.450691456603432703579
7461 7460 7673.103534095298166003624
7462 7461 7673.740632528100958224627
7463 7462 7674.241511064689966271571
7464 7463 7676.061473908754227927443
7465 7464 7676.404517064156978750202
7466 7465 7677.306367425822467274348
7467 7466 7678.489609005653850841089
7468 7467 7679.283816647054637062956
7469 7468 7680.369729689470264732783
7470 7469 7681.049611798072244771185
7471 7470 7681.945482259358269763658
7472 7471 7683.01816736395613613168
7473 7472 7683.59396487636259000295
7474 7473 7684.205667991135766026686
7475 7474 7685.305556834081107176721
7476 7475 7685.782993532922828186218
7477 7476 7687.513293015229245110174
7478 7477 7688.591692890071840321913
7479 7478 7689.156619857496179877607
7480 7479 7689.858001083120885340493
7481 7480 7690.429650782193157529389
7482 7481 7691.802176533043543837748
7483 7482 7692.342743388696256125786
7484 7483 7693.479401398161833190115
7485 7484 7693.89700596097979110209
7486 7485 7695.112272417748508678057
7487 7486 7696.136385041082438525119
7488 7487 7696.779476828299612155871
7489 7488 7697.898469111742158086425
7490 7489 7699.071025944231010177055
7491 7490 7700.036047546039263505108
7492 7491 7700.216724379954644693109
7493 7492 7701.157954572198021580407
7494 7493 7702.194731381937569855174
7495 7494 7702.589229875584176817986
7496 7495 7703.831003124176732072125
7497 7496 7705.213166786040930602515
7498 7497 7705.70321688798584926565
7499 7498 7706.96219619127969151869
7500 7499 7707.736760360777352591718
7501 7500 7708.22097263206162792013

E-002-zeros-first-10000.json — 712 bytes, updated 08-17-2026

JSON sidecar (click to expand)
{
  "experiment": "E-002",
  "task": "0.6a",
  "description": "First 10000 nontrivial zero ordinates via mpmath.zetazero (multiprocess)",
  "script": "research/numerics/scripts/E-002-first-zeros.py",
  "parameters": {
    "n_zeros": 10000,
    "dps": 25,
    "workers": 15
  },
  "checks": {
    "strictly_monotone": true,
    "gamma_1_matches_known": true,
    "riemann_von_mangoldt_abs_error": "0.3207309991"
  },
  "gap_statistics": {
    "min_gap": "0.03769849773",
    "max_gap": "6.887314497",
    "mean_gap": "0.9864634392",
    "local_mean_spacing_at_end": "0.8536743703"
  },
  "elapsed_seconds": 0.0,
  "timestamp_utc": "2026-08-17T20:09:20.100449+00:00",
  "row_count": 10000
}

Source code

Python script (click to expand)
"""E-002 — Task 0.6a: first 10^4 nontrivial zero ordinates of zeta.

Computes γ_n = Im(ρ_n) for n = 1..N via mpmath.zetazero at dps 25.
Parallel: multiprocessing over contiguous n-blocks (zetazero(n) is
independent per n); each worker writes its own part file with per-row
flush (crash-safe), main merges. Resumable: existing complete part files
are skipped.

Sanity checks: strict monotonicity; γ_1 = 14.134725141734693790…;
Riemann–von Mangoldt N(T) agreement at T = γ_N.

Outputs: research/numerics/data/E-002-zeros-first-10000.csv (+ .json)
Parts:   research/numerics/data/E-002-parts/part-NNN.csv
Cached:  does not recompute if final CSV is complete (use --force).
"""
import json
import os
import sys
import time
from datetime import datetime, timezone
from multiprocessing import Pool
from pathlib import Path

import mpmath as mp
import numpy as np

REPO = Path(__file__).resolve().parents[3]
DATA = REPO / "research" / "numerics" / "data"
PARTS = DATA / "E-002-parts"
N_ZEROS = 10_000
DPS = 25
N_WORKERS = min(15, os.cpu_count() or 4)  # leave one core for the OS

CSV = DATA / "E-002-zeros-first-10000.csv"
JSON = DATA / "E-002-zeros-first-10000.json"


def block_bounds(n_blocks: int):
    bounds = []
    per = N_ZEROS // n_blocks
    lo = 1
    for b in range(n_blocks):
        hi = N_ZEROS if b == n_blocks - 1 else lo + per - 1
        bounds.append((lo, hi))
        lo = hi + 1
    return bounds


def part_path(lo: int) -> Path:
    return PARTS / f"part-{lo:05d}.csv"


def compute_block(lo: int, hi: int) -> str:
    mp.mp.dps = DPS
    p = part_path(lo)
    tmp = p.with_suffix(".tmp")
    with tmp.open("w", encoding="utf-8", newline="") as f:
        for n in range(lo, hi + 1):
            g = mp.im(mp.zetazero(n))
            f.write(f"{n},{mp.nstr(g, DPS)}\n")
            f.flush()  # crash-safe: no buffered loss on kill
    os.replace(tmp, p)  # atomic: complete parts only
    return str(p)


def part_complete(lo: int, hi: int) -> bool:
    p = part_path(lo)
    if not p.exists():
        return False
    with p.open(encoding="utf-8") as f:
        return sum(1 for _ in f) == hi - lo + 1


def main() -> int:
    force = "--force" in sys.argv
    if CSV.exists() and JSON.exists() and not force:
        with CSV.open(encoding="utf-8") as f:
            if sum(1 for _ in f) - 1 >= N_ZEROS:
                print(f"cached: {CSV} complete (use --force to recompute)")
                return 0
    DATA.mkdir(parents=True, exist_ok=True)
    PARTS.mkdir(parents=True, exist_ok=True)

    blocks = block_bounds(N_WORKERS)
    todo = [(lo, hi) for lo, hi in blocks
            if force or not part_complete(lo, hi)]
    print(f"blocks: {len(blocks)} total, {len(todo)} to compute "
          f"({N_WORKERS} workers)")

    t0 = time.time()
    if todo:
        with Pool(N_WORKERS) as pool:
            for i, path in enumerate(pool.starmap(compute_block, todo), 1):
                print(f"  part done {i}/{len(todo)}: {Path(path).name} "
                      f"({time.time()-t0:.0f}s)", flush=True)

    # merge
    rows = []
    for lo, hi in blocks:
        with part_path(lo).open(encoding="utf-8") as f:
            rows.extend(f.read().strip().splitlines())
    rows.sort(key=lambda r: int(r.split(",", 1)[0]))
    with CSV.open("w", encoding="utf-8", newline="") as f:
        f.write("n,gamma_n\n")
        f.write("\n".join(rows) + "\n")
    elapsed = time.time() - t0

    # sanity checks
    mp.mp.dps = DPS
    # full-precision values straight from the CSV text (not float64 reload)
    with CSV.open(encoding="utf-8") as f:
        next(f)
        gammas = [mp.mpf(line.split(",", 1)[1]) for line in f]
    mono = all(gammas[i] < gammas[i + 1] for i in range(len(gammas) - 1))
    g1_known = mp.mpf("14.134725141734693790457251983562470270784257115699")
    g1_ok = abs(gammas[0] - g1_known) < mp.mpf("1e-20")
    T = gammas[-1]
    rvm = (T / (2 * mp.pi)) * (mp.log(T / (2 * mp.pi)) - 1) + mp.mpf("0.875")
    rvm_err = abs(N_ZEROS - rvm)
    gaps = [gammas[i + 1] - gammas[i] for i in range(len(gammas) - 1)]
    stats = {
        "min_gap": mp.nstr(min(gaps), 10),
        "max_gap": mp.nstr(max(gaps), 10),
        "mean_gap": mp.nstr(sum(gaps) / len(gaps), 10),
        "local_mean_spacing_at_end": mp.nstr(2 * mp.pi / mp.log(T / (2 * mp.pi)), 10),
    }
    print(f"monotone: {mono} | g1 ok: {g1_ok} | RvM err: "
          f"{mp.nstr(rvm_err, 5)} (should be << log T = "
          f"{mp.nstr(mp.log(T), 3)})")
    print("gap stats:", stats)

    meta = {
        "experiment": "E-002",
        "task": "0.6a",
        "description": f"First {N_ZEROS} nontrivial zero ordinates via "
                       "mpmath.zetazero (multiprocess)",
        "script": "research/numerics/scripts/E-002-first-zeros.py",
        "parameters": {"n_zeros": N_ZEROS, "dps": DPS,
                       "workers": N_WORKERS},
        "checks": {
            "strictly_monotone": bool(mono),
            "gamma_1_matches_known": bool(g1_ok),
            "riemann_von_mangoldt_abs_error": mp.nstr(rvm_err, 10),
        },
        "gap_statistics": stats,
        "elapsed_seconds": round(elapsed, 1),
        "timestamp_utc": datetime.now(timezone.utc).isoformat(),
        "row_count": N_ZEROS,
    }
    JSON.write_text(json.dumps(meta, indent=2), encoding="utf-8")
    ok = mono and g1_ok and rvm_err < 2 * mp.log(T)
    print(f"wrote {CSV.name}, {JSON.name} in {elapsed:.0f}s — "
          f"{'ALL CHECKS PASS' if ok else 'CHECK FAILURE'}")
    return 0 if ok else 1


if __name__ == "__main__":
    raise SystemExit(main())