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 3 of 20 · 500/page · 10000 rows next →
# ngamma_n
1002 1001 1420.416526323751136034375
1003 1002 1421.850567187048653910707
1004 1003 1422.461310987507366496379
1005 1004 1424.463045669579022246795
1006 1005 1425.87346924499659107929
1007 1006 1426.645979682120039380197
1008 1007 1427.365671109426682028961
1009 1008 1428.592305875978768705861
1010 1009 1429.650477276191545764898
1011 1010 1431.218313672751658422363
1012 1011 1432.049740893313600726956
1013 1012 1433.821940737065160513138
1014 1013 1434.584942168260123966069
1015 1014 1435.692907383419277383953
1016 1015 1437.226721623801248684463
1017 1016 1438.006284841722401518352
1018 1017 1438.949552746882798976179
1019 1018 1439.622793078163983973975
1020 1019 1441.960987504861836180539
1021 1020 1442.911059580896858867879
1022 1021 1444.041930706366562243066
1023 1022 1445.072278459201045744067
1024 1023 1445.830084779710020783356
1025 1024 1447.226227099975794392216
1026 1025 1448.323853515725453517684
1027 1026 1449.488771280731257902871
1028 1027 1450.773561858297330089907
1029 1028 1451.835297999393383264246
1030 1029 1453.737596757102226254609
1031 1030 1454.22601126022627961803
1032 1031 1455.312091239819668355062
1033 1032 1456.167797608387255558047
1034 1033 1457.539001668411230439853
1035 1034 1458.393777368687248897353
1036 1035 1460.688270535419103886417
1037 1036 1461.245443345159955929938
1038 1037 1462.266123265787259537551
1039 1038 1463.286891190427541263051
1040 1039 1464.696903297876409962361
1041 1040 1465.889557614085268159057
1042 1041 1466.505621107887723368923
1043 1042 1467.703989586071013401827
1044 1043 1469.347649878269645799291
1045 1044 1470.966589127164967200424
1046 1045 1471.388764527106594515569
1047 1046 1473.020132324185711143723
1048 1047 1473.745649185746533474087
1049 1048 1474.203221565698878785627
1050 1049 1476.09212703824092070257
1051 1050 1477.435191147500117405005
1052 1051 1478.441395973412948585008
1053 1052 1479.759918706490077675396
1054 1053 1480.766879017982257679543
1055 1054 1481.964684209802309575731
1056 1055 1483.032959958071480650362
1057 1056 1484.143580881755407774917
1058 1057 1484.817883231203726576635
1059 1058 1486.171349027557139928372
1060 1059 1488.116337976228270527027
1061 1060 1489.252466946430123072028
1062 1061 1489.970892204678885758734
1063 1062 1490.670693814603265610718
1064 1063 1492.180090544016411448622
1065 1064 1493.330835421270217760647
1066 1065 1494.155368613688803742654
1067 1066 1495.768832978941731640262
1068 1067 1497.065505571710063707658
1069 1068 1497.747360933121155702567
1070 1069 1499.640824746619819727063
1071 1070 1500.351951516603164877266
1072 1071 1501.119324922131586755267
1073 1072 1502.346063292399062924653
1074 1073 1503.090933126680493369499
1075 1074 1505.261529654671910926654
1076 1075 1506.152986138113179314532
1077 1076 1507.407505163830322280238
1078 1077 1508.2530310295422753053
1079 1078 1509.280419363223243290159
1080 1079 1510.391797446473538038311
1081 1080 1511.92300545900211118846
1082 1081 1512.589764705458127802798
1083 1082 1513.589765539918677586756
1084 1083 1515.708343586873929897339
1085 1084 1516.435989718758455005481
1086 1085 1517.719806254130186785136
1087 1086 1518.414791487253691070493
1088 1087 1519.74100949390682086283
1089 1088 1520.273622220356154270041
1090 1089 1521.901909065460911395428
1091 1090 1523.486047149258880136595
1092 1091 1524.724892160622186989842
1093 1092 1525.227837233791800071451
1094 1093 1526.552311910387456833343
1095 1094 1528.040930429297572159721
1096 1095 1529.034456728701310627987
1097 1096 1529.369975365194524165597
1098 1097 1531.020742970222322575867
1099 1098 1532.222326939392069528773
1100 1099 1533.886977913201592096683
1101 1100 1535.042277471206664585291
1102 1101 1535.769502395248204327719
1103 1102 1536.62070182402987189828
1104 1103 1537.651062167944922464754
1105 1104 1539.302854855583229427846
1106 1105 1540.030270139506368973723
1107 1106 1541.742248762789003493587
1108 1107 1542.496522922766279604769
1109 1108 1544.118670054520289895368
1110 1109 1544.834608227519480110203
1111 1110 1546.091197786313297886145
1112 1111 1547.297581121406901368
1113 1112 1547.806563801857567812332
1114 1113 1548.871348178725372883928
1115 1114 1551.273845326404526567957
1116 1115 1552.006872837670069396825
1117 1116 1552.736105329803855130255
1118 1117 1554.156519109657777788806
1119 1118 1554.921285164991869748802
1120 1119 1556.162987497552752345745
1121 1120 1557.394507017690490987832
1122 1121 1558.339152852351962786386
1123 1122 1559.781154390710235255259
1124 1123 1560.876475777809452139941
1125 1124 1562.410153180194439680536
1126 1125 1563.385400958495537267918
1127 1126 1564.17794046043167482059
1128 1127 1564.915788262260135930226
1129 1128 1566.266415601551516737196
1130 1129 1567.62345071721810545667
1131 1130 1569.022477804374074528561
1132 1131 1570.509277866920837750154
1133 1132 1571.045381485538185056936
1134 1133 1571.845352088045338365385
1135 1134 1573.806563330271403834713
1136 1135 1574.230915429863777755374
1137 1136 1575.638154952016551704401
1138 1137 1576.161352363424377561327
1139 1138 1578.118826945782786074641
1140 1139 1579.514055067740677248002
1141 1140 1580.372081625471549375071
1142 1141 1581.363551773001820393001
1143 1142 1582.329486944147176256569
1144 1143 1583.394693435421748433184
1145 1144 1584.234848066376210517872
1146 1145 1586.293210750337776065599
1147 1146 1587.004342107041149829095
1148 1147 1588.163404028904790148031
1149 1148 1589.357945949557727776031
1150 1149 1590.835904321394104771306
1151 1150 1591.293884373572356231406
1152 1151 1592.637167039234918473436
1153 1152 1593.584808188861926335471
1154 1153 1594.442689655690523961913
1155 1154 1596.484492409654675246699
1156 1155 1597.715895944423128646337
1157 1156 1598.420798549670449745762
1158 1157 1599.619348950462806910981
1159 1158 1600.048044903407311117641
1160 1159 1601.911946228582195319049
1161 1160 1602.815404793726602517536
1162 1161 1603.655202996124079668404
1163 1162 1605.521646646623348704333
1164 1163 1606.293418126574223498512
1165 1164 1607.556905211982879540601
1166 1165 1608.836295305010015548217
1167 1166 1610.003264190037944310471
1168 1167 1610.253823162574488807568
1169 1168 1611.437141269554780419202
1170 1169 1613.078855451027423513523
1171 1170 1614.710627852161491739637
1172 1171 1615.574608718972008759901
1173 1172 1616.398394841583644176829
1174 1173 1617.734684840985208560999
1175 1174 1618.537517831977547528321
1176 1175 1619.952501261128849053361
1177 1176 1620.774310821388562418885
1178 1177 1622.098751698022960734552
1179 1178 1622.977767699475580047234
1180 1179 1625.021856657962789849855
1181 1180 1625.98702016362117224155
1182 1181 1626.399919311635551920494
1183 1182 1627.755441276315744955156
1184 1183 1628.715316856763230191985
1185 1184 1629.658668954947761462749
1186 1185 1631.194814551515752982858
1187 1186 1632.798183570708816965553
1188 1187 1633.512516889737263158085
1189 1188 1634.516822662067080706424
1190 1189 1635.718366326213799525579
1191 1190 1637.089190173370945876389
1192 1191 1637.994643586012752332016
1193 1192 1638.599658304213882696397
1194 1193 1639.821235729830195521376
1195 1194 1641.89981900850457703943
1196 1195 1642.489779822378073057345
1197 1196 1644.152065959737679196727
1198 1197 1644.713745774667882876164
1199 1198 1645.573760362766078582487
1200 1199 1646.624866593178890765821
1201 1200 1648.270598222531697807583
1202 1201 1649.118535409240123292286
1203 1202 1650.416988983048381149984
1204 1203 1651.732693341395981036998
1205 1204 1652.671065899601207082319
1206 1205 1654.205896759371166943082
1207 1206 1654.726652393321786381752
1208 1207 1655.822775676771767318207
1209 1208 1657.114236399763082353707
1210 1209 1657.567101179321441112896
1211 1210 1660.019980337998945424469
1212 1211 1660.860056833300810301496
1213 1212 1661.836892884096688304723
1214 1213 1662.377202549280083467248
1215 1214 1664.057265418110030617261
1216 1215 1664.968004486365083806975
1217 1216 1665.877640414486212330961
1218 1217 1667.241125051711277139387
1219 1218 1668.36822932740186265219
1220 1219 1669.669728452399209150018
1221 1220 1671.047182433303181979264
1222 1221 1671.984259333726273942437
1223 1222 1672.963370830781056597758
1224 1223 1673.687445333905250511074
1225 1224 1674.648462097009754796137
1226 1225 1676.362486323950475216756
1227 1226 1677.691227141526503618624
1228 1227 1678.630368091063650393493
1229 1228 1680.077946716809494439835
1230 1229 1680.504770112847052080567
1231 1230 1681.812320174266013360627
1232 1231 1683.273289260666770470468
1233 1232 1684.171656837064291579029
1234 1233 1684.558863252537241861382
1235 1234 1686.421121947838197593277
1236 1235 1688.08014269317658843674
1237 1236 1688.933868509784624056562
1238 1237 1689.703154256179788865819
1239 1238 1691.051559916893075944593
1240 1239 1691.515192892035152299187
1241 1240 1693.053020930197146867153
1242 1241 1694.017564652607856866831
1243 1242 1695.832554474187265513088
1244 1243 1696.654997439785656348972
1245 1244 1697.342514286564009349295
1246 1245 1699.229547187643018792872
1247 1246 1699.966817266863858564388
1248 1247 1700.820303245006238733439
1249 1248 1701.825550997047417233554
1250 1249 1702.923249764490519399324
1251 1250 1704.291412426679760281344
1252 1251 1706.256032431560377055488
1253 1252 1706.615665035026012470105
1254 1253 1707.912312493324514939295
1255 1254 1708.512116178403088250827
1256 1255 1709.780842298580484923408
1257 1256 1711.137603258592841272861
1258 1257 1712.155397654322368843191
1259 1258 1713.055341727513109628707
1260 1259 1714.717145255494530380907
1261 1260 1715.825283039820567835619
1262 1261 1716.769983717394902744362
1263 1262 1717.974485066158528153116
1264 1263 1718.954152498583751996121
1265 1264 1719.724469321831035110477
1266 1265 1720.498070947586531810458
1267 1266 1722.844661739915648825987
1268 1267 1723.532822631259873601001
1269 1268 1724.733958737658224911768
1270 1269 1725.638628019973830653353
1271 1270 1726.605700739885404462597
1272 1271 1728.166506760965425040579
1273 1272 1728.644486480371988396949
1274 1273 1730.023872544779144422568
1275 1274 1731.014193761857181783075
1276 1275 1732.430169859256836542029
1277 1276 1733.840825021430013404403
1278 1277 1735.175466021101098339878
1279 1278 1735.624715342870632327564
1280 1279 1736.305662733237988887385
1281 1280 1737.893884786928548284184
1282 1281 1738.783237588816054261497
1283 1282 1740.169115680140548587294
1284 1283 1741.779167808727257289366
1285 1284 1742.467680720782010198986
1286 1285 1743.426436858721626521508
1287 1286 1744.721511937699789776716
1288 1287 1746.097498595632694981089
1289 1288 1746.595456627128205571698
1290 1289 1747.781695527752417747951
1291 1290 1748.563987381080216827565
1292 1291 1750.82281848983910049697
1293 1292 1751.617794946251114836818
1294 1293 1752.511511140665935993366
1295 1294 1753.66135524313953815192
1296 1295 1754.763369874252878074452
1297 1296 1755.169694068142685182724
1298 1297 1757.046518460723108432761
1299 1298 1757.984077032818179991453
1300 1299 1759.240085646681894957163
1301 1300 1760.215166242762324185108
1302 1301 1761.854899938728070380092
1303 1302 1762.497688870660621630554
1304 1303 1763.719121496287047263667
1305 1304 1764.591476849091958354746
1306 1305 1765.400493991783835727809
1307 1306 1766.676243599477873545201
1308 1307 1768.295971136341381198622
1309 1308 1769.940952051635838334389
1310 1309 1770.243677312197348192617
1311 1310 1771.212944983546526725935
1312 1311 1772.328000363591359307656
1313 1312 1773.89491551070346181188
1314 1313 1774.660430990023590107677
1315 1314 1775.341987573747291026906
1316 1315 1777.255860224057987062985
1317 1316 1778.041734762249298116558
1318 1317 1779.552270809178961606809
1319 1318 1780.665228492998657232798
1320 1319 1781.355637722819562971967
1321 1320 1782.439067320020181451752
1322 1321 1783.08482951994648471148
1323 1322 1784.60794639661266486885
1324 1323 1786.342201179342528821326
1325 1324 1787.049273086816266390257
1326 1325 1788.215123479632823247643
1327 1326 1789.242179963684720140864
1328 1327 1790.449562369783540465519
1329 1328 1791.254409818795450149148
1330 1329 1792.616102735198182735946
1331 1330 1793.525390652409514822063
1332 1331 1794.178482007255591198751
1333 1332 1796.465140537430813751114
1334 1333 1797.376335671136769855691
1335 1334 1798.147067458075746926823
1336 1335 1799.231647209737400400065
1337 1336 1800.024724019739154568118
1338 1337 1801.309636945287992131077
1339 1338 1802.301283491450569858836
1340 1339 1803.796843813365957725243
1341 1340 1804.90416097481201544791
1342 1341 1806.289667019497781635011
1343 1342 1806.578391750963925581049
1344 1343 1808.714431865474890356508
1345 1344 1809.119273788287333095647
1346 1345 1810.108892987985804546815
1347 1346 1810.873719158854715653483
1348 1347 1812.420077002105519026847
1349 1348 1814.024140347615513423617
1350 1349 1814.973082363495849025906
1351 1350 1816.338611219674637287878
1352 1351 1816.758023365350853184435
1353 1352 1817.710608563342472647764
1354 1353 1819.260334099488250564022
1355 1354 1820.187882186811219183601
1356 1355 1821.305708365203909060316
1357 1356 1822.427671440302586928808
1358 1357 1823.766265895773287956296
1359 1358 1825.213676893013383353733
1360 1359 1825.915683614928409365477
1361 1360 1826.795455271492655557559
1362 1361 1828.211270499973141933934
1363 1362 1828.621091758031140727573
1364 1363 1829.832529709939702045809
1365 1364 1831.936379901815210814258
1366 1365 1832.984940243731554247654
1367 1366 1833.273239032730321520861
1368 1367 1834.721559748608499026127
1369 1368 1835.883754437692548567062
1370 1369 1836.827672515957489640815
1371 1370 1838.086943305644553436013
1372 1371 1838.6402887076507410708
1373 1372 1840.195563473357363106728
1374 1373 1841.478582570643394257082
1375 1374 1842.875955278667221445727
1376 1375 1843.771057743069120456561
1377 1376 1844.759043650095888927069
1378 1377 1845.417534146424529184836
1379 1378 1846.353253420516416602189
1380 1379 1848.330980622383731433415
1381 1380 1848.722760910890866404391
1382 1381 1850.601184047651463659879
1383 1382 1851.400361994589779203914
1384 1383 1852.342204733386277236303
1385 1384 1853.519342920989503777938
1386 1385 1854.855632115986727770019
1387 1386 1855.592934937055467317871
1388 1387 1856.389179153523854467584
1389 1388 1857.498074814880186030132
1390 1389 1859.495271568794459978385
1391 1390 1860.541388109336813481347
1392 1391 1861.379671547232853462528
1393 1392 1862.121464928944214881547
1394 1393 1863.425464845096486006563
1395 1394 1864.353981335746251375531
1396 1395 1865.367433794057890105678
1397 1396 1866.836547018608191339929
1398 1397 1868.085190998609224366009
1399 1398 1868.706745684408117519671
1400 1399 1870.421471768310790151709
1401 1400 1871.41604309840714532602
1402 1401 1872.441566428192717588509
1403 1402 1872.865667637967680009892
1404 1403 1874.508361412660135338419
1405 1404 1874.913774010039541468588
1406 1405 1877.09506416733977461244
1407 1406 1878.022251482753471098902
1408 1407 1879.153303090461328571737
1409 1408 1880.082325418994379763301
1410 1409 1880.611766479656867414168
1411 1410 1882.321974797384684057812
1412 1411 1883.408724269518366030718
1413 1412 1884.005778349667142356788
1414 1413 1885.198075130258122876007
1415 1414 1887.053894806890124232468
1416 1415 1887.808841416832129527162
1417 1416 1888.93818263657945499955
1418 1417 1890.348128614244545597396
1419 1418 1890.612128587933260930814
1420 1419 1891.678510539728787851251
1421 1420 1892.8677013357911153411
1422 1421 1894.558537572429687187311
1423 1422 1895.69715565358456329659
1424 1423 1896.585494347168901175289
1425 1424 1897.513692859711974093951
1426 1425 1898.829372818679482109816
1427 1426 1900.006144829143996610552
1428 1427 1900.571884272414833831619
1429 1428 1901.891305750600065080568
1430 1429 1902.805059206680062983354
1431 1430 1904.089325323351742088979
1432 1431 1906.102756198181956502047
1433 1432 1906.597678003766215393604
1434 1433 1907.332780123909926346037
1435 1434 1908.433063045051752229753
1436 1435 1909.465930025982380253956
1437 1436 1910.733659615891596477795
1438 1437 1911.704690943172158628322
1439 1438 1913.18248977588307681364
1440 1439 1914.352300051674052677269
1441 1440 1915.054629333347218570916
1442 1441 1916.606371839519353790415
1443 1442 1917.344704041566345522915
1444 1443 1918.786498909856788986721
1445 1444 1919.20777839780523826397
1446 1445 1919.937457371217203896594
1447 1446 1922.101625621993703442189
1448 1447 1923.28083793641744205753
1449 1448 1924.05583110144084951951
1450 1449 1925.231987975406529411983
1451 1450 1926.211583079894078458363
1452 1451 1926.820092794871576744617
1453 1452 1928.417518549519447858834
1454 1453 1929.487560180576489987259
1455 1454 1930.258387180387325797027
1456 1455 1931.760069436524614011378
1457 1456 1932.875754549946917778837
1458 1457 1934.416436369151903416413
1459 1458 1934.907943434365697510018
1460 1459 1935.924848803745694844527
1461 1460 1936.873093814278902386711
1462 1461 1937.968633498019957719648
1463 1462 1939.050029150544125716814
1464 1463 1940.977326705859935993002
1465 1464 1941.822862215780232950893
1466 1465 1942.633568692246150914573
1467 1466 1943.367947449252749107007
1468 1467 1945.153796306367959584251
1469 1468 1945.922716949483327186313
1470 1469 1946.60994536187741031128
1471 1470 1947.917047737703604079914
1472 1471 1949.03003007360655073693
1473 1472 1950.74320155286315859843
1474 1473 1951.536695873054910398385
1475 1474 1952.85012921186575327612
1476 1475 1953.448556325135770052821
1477 1476 1954.418588175214116790112
1478 1477 1955.315809283718388686037
1479 1478 1956.848164578215508554637
1480 1479 1958.314403555120358564965
1481 1480 1958.85188346319481384647
1482 1481 1960.418845269381796764848
1483 1482 1961.3592778800143795083
1484 1483 1962.23357184857979807258
1485 1484 1963.621184573202069079436
1486 1485 1964.357390938095597209784
1487 1486 1965.377829505103857030394
1488 1487 1966.117658574074526474161
1489 1488 1968.471602019420441852811
1490 1489 1969.047617546527828615055
1491 1490 1970.305009517033761407286
1492 1491 1970.855547579945944308915
1493 1492 1971.970312804811386640255
1494 1493 1973.182663405938679691731
1495 1494 1974.347201910120085258705
1496 1495 1975.080610302266993556028
1497 1496 1977.173943698039879018377
1498 1497 1977.271446199746510741697
1499 1498 1978.801448167731529631539
1500 1499 1980.37177228705133692713
1501 1500 1980.910043091024233255044

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