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 13 of 20 · 500/page · 10000 rows next →
# ngamma_n
6002 6001 6366.671353345361424043665
6003 6002 6367.958813533014683606677
6004 6003 6368.438094219739437846784
6005 6004 6369.245882999161260488227
6006 6005 6369.770229023833336162843
6007 6006 6370.898050447910822287736
6008 6007 6372.415682393795277333579
6009 6008 6373.173152452142145875621
6010 6009 6374.053534358543126366858
6011 6010 6375.032404908860483046297
6012 6011 6375.599195635544081659462
6013 6012 6376.764549170062526955947
6014 6013 6377.511439944205574328358
6015 6014 6378.550145730094809378052
6016 6015 6379.246624188774805113775
6017 6016 6379.959409795578899795606
6018 6017 6381.143665232173580816394
6019 6018 6381.848039061530956521921
6020 6019 6383.410238912067498918017
6021 6020 6384.459219016481777620276
6022 6021 6384.920488511157782489996
6023 6022 6385.57820350812593868613
6024 6023 6386.357077118747839791112
6025 6024 6387.528294105803732639907
6026 6025 6388.197850516724536284829
6027 6026 6389.360853368250931541098
6028 6027 6390.006152212628571675579
6029 6028 6391.686645483916793870449
6030 6029 6392.187328677613410415003
6031 6030 6392.718575157853163115444
6032 6031 6394.065073885532055817129
6033 6032 6395.031740700798242263188
6034 6033 6395.668869607560350222506
6035 6034 6396.729259797332919624863
6036 6035 6397.361130692520493118079
6037 6036 6397.786081170897035537167
6038 6037 6399.176640347329416090415
6039 6038 6400.746238657757721502045
6040 6039 6401.323625925219883585188
6041 6040 6402.175290622142466589572
6042 6041 6403.110886587122267792992
6043 6042 6403.861397515233267998039
6044 6043 6404.767039730848564776754
6045 6044 6405.178961948583762285284
6046 6045 6406.74828385947906743149
6047 6046 6407.61295281862051340543
6048 6047 6408.077160917846822667821
6049 6048 6409.279021189901117343319
6050 6049 6410.353801335843156185769
6051 6050 6411.384469328819870557963
6052 6051 6412.247558440064533014445
6053 6052 6413.0404200587980457298
6054 6053 6413.833451375073185710343
6055 6054 6414.570290068342803031114
6056 6055 6415.462076135825069083272
6057 6056 6416.17590896068547183927
6058 6057 6417.378052856020880831767
6059 6058 6418.792599643247888029496
6060 6059 6419.69202286110241579471
6061 6060 6420.182578627688254466559
6062 6061 6421.255935827854276589841
6063 6062 6421.491228644308911455118
6064 6063 6423.41448617672950206168
6065 6064 6423.764508953828938088571
6066 6065 6424.401461601265353716479
6067 6066 6425.399747335204854331286
6068 6067 6426.480014181574981383485
6069 6068 6427.401528361016960064606
6070 6069 6428.587583738724528074754
6071 6070 6429.468848692722881320446
6072 6071 6430.694571981495006693082
6073 6072 6430.918186133596075459758
6074 6073 6431.981683244139887682676
6075 6074 6432.433303080168638469244
6076 6075 6433.622387485807578728402
6077 6076 6434.514944024420730191218
6078 6077 6435.774652679148520790756
6079 6078 6436.905185937703858712866
6080 6079 6437.123406603307296667459
6081 6080 6438.740481004520417110747
6082 6081 6439.140618634673134465334
6083 6082 6440.125226420810110565721
6084 6083 6441.140573842962555865479
6085 6084 6441.894099406383302656517
6086 6085 6442.897533673153230527855
6087 6086 6443.565266180883024089478
6088 6087 6443.978372087088441979022
6089 6088 6445.971515283606789670202
6090 6089 6447.022174123041568812108
6091 6090 6447.474618171753579654596
6092 6091 6448.246132866305740677297
6093 6092 6449.332054723968976675845
6094 6093 6449.896208786239332513336
6095 6094 6450.770449031410653905281
6096 6095 6451.96507277446942244101
6097 6096 6452.616809388042463744423
6098 6097 6453.681785667650826079099
6099 6098 6454.861307375188520520665
6100 6099 6455.690820622381995171408
6101 6100 6456.243758468239422331266
6102 6101 6457.653867882111396578083
6103 6102 6458.658611072352056851137
6104 6103 6459.067827430399617446658
6105 6104 6459.952831320823704233433
6106 6105 6460.534639476212205713096
6107 6106 6461.614784191283541384937
6108 6107 6462.852814105798443688312
6109 6108 6463.724097145994532060439
6110 6109 6465.143720813163052803081
6111 6110 6465.743873966872537666105
6112 6111 6466.29573370045704236807
6113 6112 6467.193447823703071356965
6114 6113 6468.092790956416076326102
6115 6114 6469.13112519051068145282
6116 6115 6470.197357327963050919696
6117 6116 6470.701077816671190153762
6118 6117 6471.560457479093344829598
6119 6118 6472.780201590247656186391
6120 6119 6473.798648696707054279102
6121 6120 6475.021493493020818960124
6122 6121 6475.727754605961955342411
6123 6122 6476.113123922475265844805
6124 6123 6477.481705763072629091249
6125 6124 6478.027176624626376606285
6126 6125 6478.831342932714104242697
6127 6126 6479.431139218032926513277
6128 6127 6481.273679157492809066508
6129 6128 6482.002790371315400100909
6130 6129 6483.006704609867431727122
6131 6130 6483.45018979424566809184
6132 6131 6484.519323277323860277637
6133 6132 6485.713209326583412622282
6134 6133 6486.163374261582699002025
6135 6134 6487.445215262415743448406
6136 6135 6487.830216813242214510026
6137 6136 6488.926620780881315211359
6138 6137 6489.622575931016999621281
6139 6138 6490.906097872482926005423
6140 6139 6492.190210433448301029761
6141 6140 6492.813486515120289631144
6142 6141 6494.004710693342287935655
6143 6142 6494.622125318580358939526
6144 6143 6494.866454095690876934337
6145 6144 6496.007974724864466058215
6146 6145 6497.27930827757064906718
6147 6146 6498.038769460500676695066
6148 6147 6498.834863257906309160629
6149 6148 6500.031689480680051882774
6150 6149 6501.207453991779785792521
6151 6150 6501.66518435213694506332
6152 6151 6502.566972220884626823699
6153 6152 6503.701543493511297749057
6154 6153 6504.732509796223354690686
6155 6154 6505.408729994132477228817
6156 6155 6505.667900631896612114664
6157 6156 6507.137020076430888150983
6158 6157 6507.477752627870797739618
6159 6158 6509.618252802300380090193
6160 6159 6510.058208138934536733779
6161 6160 6510.892054060107106316017
6162 6161 6511.726223192474062750477
6163 6162 6512.566938401199879908526
6164 6163 6513.360945148274204080765
6165 6164 6514.382624269534249631602
6166 6165 6515.052647859496398127314
6167 6166 6516.171290289174179264486
6168 6167 6517.240330844650423525847
6169 6168 6517.861387846916315813208
6170 6169 6518.808197450836873827724
6171 6170 6520.320492651004059240565
6172 6171 6520.909964939857657544408
6173 6172 6521.788872386337834917928
6174 6173 6522.371597080945186712475
6175 6174 6523.377319126218735663118
6176 6175 6524.089123052959289596052
6177 6176 6524.898764044254781140437
6178 6177 6526.082562690724252412499
6179 6178 6527.431766363988799392645
6180 6179 6528.187904465222229883965
6181 6180 6529.103609831716260814904
6182 6181 6529.761023940341150163592
6183 6182 6530.42767175575618299944
6184 6183 6531.598707501850635662802
6185 6184 6532.693567137808111116329
6186 6185 6533.491429406026904313526
6187 6186 6533.871387072464251311318
6188 6187 6534.762937012053292279293
6189 6188 6536.470053698357899347488
6190 6189 6537.054650213740264780453
6191 6190 6538.142600402396599285862
6192 6191 6539.169984547960272350865
6193 6192 6539.72496098489846511953
6194 6193 6540.638906760232297601307
6195 6194 6541.354659155190316552323
6196 6195 6541.86239458309759665085
6197 6196 6543.517657049525190307081
6198 6197 6544.117508866735991242383
6199 6198 6545.406761305511317930161
6200 6199 6546.203853143526757654197
6201 6200 6546.926187186619105879135
6202 6201 6547.849360757134956928212
6203 6202 6549.129863100256038989836
6204 6203 6549.691789353554554080761
6205 6204 6550.283449195851965903047
6206 6205 6551.606750606022885378688
6207 6206 6552.137913651264489877076
6208 6207 6552.822686785684069590112
6209 6208 6554.188696830806650401254
6210 6209 6555.776866674192585931473
6211 6210 6556.290164157591708536135
6212 6211 6556.932787603161003021925
6213 6212 6557.550866183959278842527
6214 6213 6558.710265696090958411795
6215 6214 6559.459473093697398730157
6216 6215 6560.485236248453851356009
6217 6216 6561.246375942028388529028
6218 6217 6562.260958255342889226672
6219 6218 6563.369421995659979696685
6220 6219 6564.166004197383188149629
6221 6220 6565.225896725426339287716
6222 6221 6565.916463678861602936382
6223 6222 6567.222123704213833505231
6224 6223 6567.810942958576117206538
6225 6224 6568.585110673608741590183
6226 6225 6569.319354206848405752012
6227 6226 6569.866289055112532484458
6228 6227 6571.349397080133331679897
6229 6228 6572.768540538470061939809
6230 6229 6573.166263739421396648862
6231 6230 6574.23008464536764972101
6232 6231 6575.279364268423755061319
6233 6232 6575.921041736286156123119
6234 6233 6576.290007732859411696913
6235 6234 6577.84244472739352769222
6236 6235 6578.66834054497910938544
6237 6236 6579.281726766580351184105
6238 6237 6580.253132475486986297181
6239 6238 6581.106726792464198508134
6240 6239 6582.366235017422402103328
6241 6240 6583.647989893458266864931
6242 6241 6584.025065236713674143548
6243 6242 6585.15214925911586021001
6244 6243 6585.76606574925330147293
6245 6244 6586.365117607648683691936
6246 6245 6587.67993501904603309963
6247 6246 6588.133534515000023429778
6248 6247 6589.210210194637361826526
6249 6248 6590.863205277395462127199
6250 6249 6591.491048592958149927466
6251 6250 6592.144011228696277901219
6252 6251 6592.845950010057018369935
6253 6252 6594.035062429382218503045
6254 6253 6595.182141381570587384128
6255 6254 6595.672779583989083248967
6256 6255 6596.500204522654024231893
6257 6256 6597.265170319666012148673
6258 6257 6598.340695483692917390574
6259 6258 6599.176046768407733055941
6260 6259 6600.753780454660541360517
6261 6260 6601.347457984375360599999
6262 6261 6602.390527988640125968896
6263 6262 6602.977753481656713051573
6264 6263 6603.897138837148296885248
6265 6264 6604.427167139000244130093
6266 6265 6605.399554340270634154056
6267 6266 6606.694580788018305136735
6268 6267 6607.765474189113708455647
6269 6268 6607.967781789132745462814
6270 6269 6609.741917966225346152503
6271 6270 6610.094415677309120256933
6272 6271 6611.386797395995561930023
6273 6272 6612.007975267009756520257
6274 6273 6612.907977501809397040214
6275 6274 6614.103829390387868302355
6276 6275 6614.525354351744778253463
6277 6276 6615.245604673416848274923
6278 6277 6616.001321093093802857847
6279 6278 6617.823120341630444325833
6280 6279 6618.582598754258417942193
6281 6280 6619.598203880315848087602
6282 6281 6620.243653081768939408675
6283 6282 6620.801846220445418157221
6284 6283 6621.897593444352850674215
6285 6284 6622.896150263723238417487
6286 6285 6623.574968353803824221298
6287 6286 6624.663719462918326760587
6288 6287 6625.250125790551209532924
6289 6288 6626.636287300496303810875
6290 6289 6627.460241761985331555728
6291 6290 6628.061836652559259725215
6292 6291 6629.891281103415527153648
6293 6292 6630.110418429952930703224
6294 6293 6631.038268216502148694175
6295 6294 6631.547698183336692897336
6296 6295 6632.548656711797377311949
6297 6296 6633.48400202072731242018
6298 6297 6634.352598134559372051021
6299 6298 6635.696775490745872128322
6300 6299 6636.654287338266203341832
6301 6300 6637.625363681343772683126
6302 6301 6638.090473850530320181561
6303 6302 6639.075753370515833884153
6304 6303 6639.859562435562389737872
6305 6304 6641.055120832440537495166
6306 6305 6641.786228641866041104754
6307 6306 6642.644283633712492250592
6308 6307 6643.292547542332942691744
6309 6308 6644.11990286844342794215
6310 6309 6645.918402372157220363572
6311 6310 6646.61179553847692616365
6312 6311 6647.322423863212770213748
6313 6312 6648.077919597346856684246
6314 6313 6649.384089933557217783669
6315 6314 6649.647351976543205296305
6316 6315 6650.383134979861011807333
6317 6316 6651.54513943376441251424
6318 6317 6652.583661009993449025507
6319 6318 6653.941240679172462406398
6320 6319 6654.366268486230880080486
6321 6320 6655.334573448509635876458
6322 6321 6656.446114677313193013623
6323 6322 6657.053755492811346689375
6324 6323 6658.335707229374759429551
6325 6324 6659.055077831643344376997
6326 6325 6659.52184232074763971207
6327 6326 6660.503555598670573876336
6328 6327 6661.461648933372220394007
6329 6328 6662.34672063163879262335
6330 6329 6663.719022678308470169439
6331 6330 6664.872916950475617243433
6332 6331 6665.432916953979205554975
6333 6332 6666.236097925817492378157
6334 6333 6666.808353082496453560557
6335 6334 6667.616350899313029851457
6336 6335 6669.097362269837571762272
6337 6336 6669.810009517607377143845
6338 6337 6670.175702313964530903226
6339 6338 6671.713778808945341958604
6340 6339 6672.52646539513196371908
6341 6340 6673.539418182129458581752
6342 6341 6674.254359553938292440199
6343 6342 6675.608127235226302827097
6344 6343 6676.021079514865380950443
6345 6344 6677.034062070678164792516
6346 6345 6677.773602313434796236988
6347 6346 6678.438197868944262587857
6348 6347 6679.147300422944390846407
6349 6348 6680.890098038188466922522
6350 6349 6681.885127241568576084659
6351 6350 6682.56564030669912626718
6352 6351 6683.184617811499675208655
6353 6352 6684.32308714498299791488
6354 6353 6685.084637365415992217098
6355 6354 6685.936244319487324881695
6356 6355 6686.656349751517539012902
6357 6356 6688.040741920755122039412
6358 6357 6688.50350213519319360848
6359 6358 6689.259935461762110317337
6360 6359 6690.508707528538464991815
6361 6360 6691.704920009254843555762
6362 6361 6692.64754125474919421891
6363 6362 6693.499651871101691021646
6364 6363 6693.981516036087729137519
6365 6364 6694.823702884915021330827
6366 6365 6695.938981836288821680688
6367 6366 6696.272310646920029171747
6368 6367 6697.779004686451685941074
6369 6368 6698.50767962290520853189
6370 6369 6699.761639218128279456087
6371 6370 6700.87136818145374113867
6372 6371 6701.375798236871544139646
6373 6372 6701.784678330473056665745
6374 6373 6703.336806677939987331896
6375 6374 6704.270589493424994442809
6376 6375 6704.873686015397016024228
6377 6376 6705.640106165690509707719
6378 6377 6706.214075997798149736029
6379 6378 6707.535168632613871650513
6380 6379 6708.721048689681165972143
6381 6380 6709.72699169926488730861
6382 6381 6710.545176389561913248809
6383 6382 6711.503024657997161672384
6384 6383 6712.08990386812218885258
6385 6384 6712.731759929546332370334
6386 6385 6713.825345385445995691837
6387 6386 6714.552463890872704779522
6388 6387 6715.865576387474949010094
6389 6388 6716.558365972571729200159
6390 6389 6717.809675011431266750734
6391 6390 6718.186519712513916409414
6392 6391 6719.559687205051936607058
6393 6392 6720.626196173092866124773
6394 6393 6721.043429319701700159256
6395 6394 6722.047668249347597020188
6396 6395 6722.914170254797079255649
6397 6396 6723.649784945099889200815
6398 6397 6724.57328441851183613333
6399 6398 6725.062801240417049298233
6400 6399 6727.203484213404062511635
6401 6400 6727.861353028848182556755
6402 6401 6728.191087298997566737855
6403 6402 6729.486019096450881267595
6404 6403 6729.895237293208604272276
6405 6404 6730.934946661614585471722
6406 6405 6731.961248879775819856248
6407 6406 6733.013197272611141043779
6408 6407 6733.352651970028390788868
6409 6408 6734.49141133363666266086
6410 6409 6735.744523774782003484997
6411 6410 6736.409605357799291284116
6412 6411 6737.651227900498382902738
6413 6412 6738.297181091919082992339
6414 6413 6739.552413812180720816886
6415 6414 6740.261721734861135812099
6416 6415 6740.457697493020143147924
6417 6416 6741.366527617479605164352
6418 6417 6742.674048332693447913422
6419 6418 6743.672183245423916776684
6420 6419 6744.725146506183853074711
6421 6420 6745.670849832026453706084
6422 6421 6746.593080879846614749184
6423 6422 6747.242437890560569040487
6424 6423 6748.029172419816689359305
6425 6424 6749.031010237307091294181
6426 6425 6750.21368534222245600297
6427 6426 6750.601759539744663442882
6428 6427 6751.786325711448180641784
6429 6428 6752.178020361104664319629
6430 6429 6753.43690475714266266621
6431 6430 6754.800870274663560729911
6432 6431 6755.929060721253845734328
6433 6432 6756.349056164564972445225
6434 6433 6756.987912268812942230967
6435 6434 6757.968818185654720324387
6436 6435 6759.040586961104749326648
6437 6436 6759.501932128259026160995
6438 6437 6760.462459400594763555959
6439 6438 6761.720180324828193423653
6440 6439 6762.871493911747016513895
6441 6440 6763.550805103910999888903
6442 6441 6764.315430966511304556996
6443 6442 6765.177507003465537536095
6444 6443 6766.626418343841652528279
6445 6444 6767.055387842126734255949
6446 6445 6767.826497444045622221699
6447 6446 6768.762729472866056368643
6448 6447 6769.585676837071952234692
6449 6448 6770.093879396388277540382
6450 6449 6771.955148424854677350097
6451 6450 6772.495692995084200294782
6452 6451 6773.74038304948113232239
6453 6452 6774.572946802576487770475
6454 6453 6774.99384010807015742114
6455 6454 6776.14668500243989934424
6456 6455 6776.359235997386577486878
6457 6456 6778.094859514306824589539
6458 6457 6778.684172078836788787339
6459 6458 6779.586018071240762023576
6460 6459 6780.21753710773054885942
6461 6460 6781.893987624381506299157
6462 6461 6782.353593658482034685236
6463 6462 6783.35303659247913766821
6464 6463 6784.369341123243433921132
6465 6464 6785.226455746954204131694
6466 6465 6785.78341536400198631929
6467 6466 6786.860012200988476772523
6468 6467 6787.190723306275850312339
6469 6468 6788.359287917739126642441
6470 6469 6789.795642994313058018471
6471 6470 6791.028915455409257057618
6472 6471 6791.376409715538111161549
6473 6472 6792.19669898165528107932
6474 6473 6793.061593444636023624761
6475 6474 6794.0966238441726797338
6476 6475 6795.007815668104988353359
6477 6476 6795.896919249778716355232
6478 6477 6796.295555003895799939137
6479 6478 6797.774135880902573258328
6480 6479 6798.366625614905455530389
6481 6480 6799.273322354985476572987
6482 6481 6800.772051417368809073634
6483 6482 6801.656988280415670246017
6484 6483 6802.224132415900248370559
6485 6484 6802.957130339654625849055
6486 6485 6803.90595948059252730762
6487 6486 6804.369622404881331678235
6488 6487 6805.731785578891033594163
6489 6488 6806.401467743143591086741
6490 6489 6807.689586081386919160897
6491 6490 6808.690301596814086007991
6492 6491 6809.403080163782453274495
6493 6492 6810.366331181320559173667
6494 6493 6811.157036390080747422399
6495 6494 6811.850764837749860844976
6496 6495 6813.242160313709271536757
6497 6496 6813.937310608287777888292
6498 6497 6814.462465953229768721676
6499 6498 6815.081096307120816080165
6500 6499 6816.335338647445576803847
6501 6500 6817.957478321912094698182

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