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 12 of 20 · 500/page · 10000 rows next →
# ngamma_n
5502 5501 5910.297428639246118532356
5503 5502 5911.489176576974486494803
5504 5503 5912.332412220923777498716
5505 5504 5912.93529661250529463175
5506 5505 5914.115666541656472070598
5507 5506 5915.019576754144383606038
5508 5507 5916.088332580690013019257
5509 5508 5916.441169127997579591711
5510 5509 5917.380890968155200207621
5511 5510 5917.975417960736669535617
5512 5511 5920.055550869004545366877
5513 5512 5920.538476511501067785348
5514 5513 5921.438418562954292963355
5515 5514 5922.552080087763753750457
5516 5515 5923.106480527551745513962
5517 5516 5924.023918205912250391419
5518 5517 5924.612567997041964535407
5519 5518 5925.982652112324126508003
5520 5519 5926.86780689763150629097
5521 5520 5927.479356433868603789345
5522 5521 5928.899161984593494231146
5523 5522 5929.345382897492492081268
5524 5523 5930.860362894445147312173
5525 5524 5931.570134864405308022095
5526 5525 5932.736065547437876631361
5527 5526 5933.033536559582047288518
5528 5527 5933.987898043518446260899
5529 5528 5934.829981307314893964504
5530 5529 5935.948347327593923962034
5531 5530 5936.465147329213855890505
5532 5531 5938.287679988199271866172
5533 5532 5939.265303266807171158181
5534 5533 5939.695838711395468074725
5535 5534 5940.379099853132093793997
5536 5535 5941.441894804406140524831
5537 5536 5942.467736153845577130112
5538 5537 5943.543979174501539699718
5539 5538 5944.13024662425800976667
5540 5539 5944.725413371057810298633
5541 5540 5946.14333199071051650675
5542 5541 5946.820062652999829045935
5543 5542 5948.301613869440054304056
5544 5543 5949.142426312635388881512
5545 5544 5949.777706351522475261177
5546 5545 5950.989084392992790030602
5547 5546 5951.430121674386412507297
5548 5547 5952.261902584627730395708
5549 5548 5952.902618768109362060845
5550 5549 5954.465995760656197572358
5551 5550 5955.342138476738498566354
5552 5551 5956.365914060978522958851
5553 5552 5957.027692949344674177001
5554 5553 5958.332640101391825507474
5555 5554 5958.866457495425007628822
5556 5555 5959.876516604980236971356
5557 5556 5960.740693076100246887534
5558 5557 5961.788662547501495820587
5559 5558 5962.574245885660007370788
5560 5559 5962.943559513120417371533
5561 5560 5964.146533459619874102106
5562 5561 5965.736509167636371310779
5563 5562 5966.619515143618021427765
5564 5563 5967.433133231373155360058
5565 5564 5968.178918743095247575719
5566 5565 5968.735878784985767163721
5567 5566 5969.779680206670108432442
5568 5567 5970.844216766736223650668
5569 5568 5971.604971542721230147664
5570 5569 5972.485368405060761185116
5571 5570 5973.620902248292101077068
5572 5571 5974.886211179463757141001
5573 5572 5975.356163229908470858586
5574 5573 5976.141901892539937529053
5575 5574 5978.026590419289768780305
5576 5575 5978.139309725790062811665
5577 5576 5978.832670352795680398052
5578 5577 5979.862288578085496534765
5579 5578 5980.592613333379713768247
5580 5579 5981.506260799348249891513
5581 5580 5982.914976763731777780506
5582 5581 5984.012615640010910903479
5583 5582 5984.792817506801592649579
5584 5583 5985.669034669888019629396
5585 5584 5986.4191452050762899188
5586 5585 5987.055919517702678447129
5587 5586 5988.313841463135190181791
5588 5587 5988.973948250782740647756
5589 5588 5990.294284873586110018503
5590 5589 5990.809755142914262251229
5591 5590 5991.472985430085497577077
5592 5591 5993.084653614646440417076
5593 5592 5994.057233174675006723627
5594 5593 5995.024532494481209144074
5595 5594 5995.409540651148099574757
5596 5595 5996.609465538453866655625
5597 5596 5997.392505688815814842397
5598 5597 5998.052919752655547981851
5599 5598 5998.734794943291395085923
5600 5599 6000.121020998374398242438
5601 5600 6001.495519089924949147504
5602 5601 6002.154589633411581469066
5603 5602 6002.914838345618660044322
5604 5603 6003.878519365193319554118
5605 5604 6004.591820724887783124492
5606 5605 6005.855784942334063607354
5607 5606 6006.678028614962485021742
5608 5607 6007.325565907606133666592
5609 5608 6007.978287457788154404299
5610 5609 6009.20454037958643036475
5611 5610 6010.190820410438061199944
5612 5611 6011.253025428469748140463
5613 5612 6012.65112263533907952398
5614 5613 6013.047245645551296276037
5615 5614 6014.042373169796768536828
5616 5615 6014.663869379400772318478
5617 5616 6015.161467300141288421226
5618 5617 6016.736803703802709105802
5619 5618 6017.530542899120923821839
5620 5619 6018.180474529548380788857
5621 5620 6019.650285835952248112756
5622 5621 6020.48547716546745758402
5623 5622 6021.078533684980212731308
5624 5623 6022.496991537044644002841
5625 5624 6022.866086750984914575913
5626 5625 6024.235928621511194810085
5627 5626 6024.765822154941554465631
5628 5627 6025.652989058804266580461
5629 5628 6026.328429368197704406023
5630 5629 6027.149989355024829533913
5631 5630 6029.083879336239010355713
5632 5631 6029.871336490612924495199
5633 5632 6030.366565545267206179682
5634 5633 6031.190552493812445299458
5635 5634 6032.274114806583767068247
5636 5635 6033.146731331337611207695
5637 5636 6033.64497720837344364119
5638 5637 6034.942132629864696860966
5639 5638 6035.782357605260268143246
5640 5639 6036.735104464168221546657
5641 5640 6037.621814970688771358615
5642 5641 6038.620819010113696174254
5643 5642 6039.780188462111087175716
5644 5643 6040.747929474347735275926
5645 5644 6041.398240993254923855177
5646 5645 6042.397652237235167301378
5647 5646 6042.668644064463009805447
5648 5647 6043.995010268979583331289
5649 5648 6044.552572123936447633859
5650 5649 6046.181521954205143328526
5651 5650 6046.796932396247279023399
5652 5651 6048.263607361397851746512
5653 5652 6048.952645864481554597648
5654 5653 6049.241142991617681342145
5655 5654 6050.246128122275047045831
5656 5655 6051.626971033905295497066
5657 5656 6052.43973929370899498599
5658 5657 6053.067413924323484897176
5659 5658 6053.778846036457766245038
5660 5659 6054.804164558045311285087
5661 5660 6056.260886232179706718446
5662 5661 6057.072842116193979147367
5663 5662 6058.00087627065018033175
5664 5663 6059.1344937857585824589
5665 5664 6059.466828728352247359558
5666 5665 6060.341627593010384681421
5667 5666 6061.493619822284428289643
5668 5667 6061.793911747667375030325
5669 5668 6063.253687207729857485196
5670 5669 6064.593399932610514649347
5671 5670 6065.104446594213095877825
5672 5671 6066.142573932623411074312
5673 5672 6066.829934378909977725237
5674 5673 6068.165352787178424079309
5675 5674 6068.884377847925849942761
5676 5675 6069.569709881499908973275
5677 5676 6070.456730948586473973493
5678 5677 6071.607124379687053861959
5679 5678 6071.987031737128093498993
5680 5679 6072.986930281585092310381
5681 5680 6074.835751881022211828369
5682 5681 6075.456209880471805891716
5683 5682 6076.319580410927648384651
5684 5683 6076.896595428756527900231
5685 5684 6077.923525597853783609354
5686 5685 6078.464257000358784496569
5687 5686 6079.7253725148243797695
5688 5687 6080.817594639934868188861
5689 5688 6081.177170652933892961613
5690 5689 6082.50108370697757357294
5691 5690 6083.644016757932694657663
5692 5691 6084.383007365660920365833
5693 5692 6085.230905162356115883081
5694 5693 6086.325556912578516777475
5695 5694 6087.278392364372645258808
5696 5695 6088.144768071507194160101
5697 5696 6088.537541404678286308287
5698 5697 6089.128616019717220693059
5699 5698 6090.71715310707747946382
5700 5699 6091.689881768494912349327
5701 5700 6093.192335325567517799014
5702 5701 6093.283426817677733127603
5703 5702 6094.550261329978041582003
5704 5703 6095.331193379996965078722
5705 5704 6095.911728318065476671969
5706 5705 6097.096728489390064447267
5707 5706 6098.071498010461451623264
5708 5707 6098.786888080899295824587
5709 5708 6099.667065247016674700586
5710 5709 6100.713939634763281918004
5711 5710 6101.542636010731527203091
5712 5711 6103.11106205634282335398
5713 5712 6103.890836007713371613938
5714 5713 6104.369986546026122172359
5715 5714 6105.080112318568317659819
5716 5715 6106.427937948077785472041
5717 5716 6106.698870787320148351154
5718 5717 6107.888398279542395604613
5719 5718 6108.683780716910883326509
5720 5719 6110.531011475981902602432
5721 5720 6110.830996154773429290586
5722 5721 6111.844532847507673288333
5723 5722 6112.464435384833018859023
5724 5723 6113.552617473988230813832
5725 5724 6114.761891753269902230213
5726 5725 6115.274791543812193783141
5727 5726 6116.16749593062941590614
5728 5727 6117.090753291097079784351
5729 5728 6117.552359427716710983812
5730 5729 6119.215997842411625924736
5731 5730 6120.281534697360683034416
5732 5731 6120.933301686410976016383
5733 5732 6122.09439875850355329516
5734 5733 6122.857424919649677858881
5735 5734 6123.356607972827526055504
5736 5735 6124.138883220781073825308
5737 5736 6125.172619880176128288571
5738 5737 6126.568586519307376488418
5739 5738 6127.130221394032243611453
5740 5739 6128.046863129756694762316
5741 5740 6129.26875154801351087188
5742 5741 6130.291606464611255266012
5743 5742 6130.686768649261289096597
5744 5743 6132.121687397098473468265
5745 5744 6132.762353486791185964552
5746 5745 6133.489892704202552012906
5747 5746 6134.455051667965093678123
5748 5747 6135.143074922048810884565
5749 5748 6135.892613200648426736061
5750 5749 6137.781389320129082233523
5751 5750 6138.445601390254319204479
5752 5751 6139.589346958781660513923
5753 5752 6139.81323983382586076329
5754 5753 6140.675863382833775707015
5755 5754 6141.872358756231454527424
5756 5755 6142.911451640284748056132
5757 5756 6143.356666103172837357107
5758 5757 6144.405867207821494553569
5759 5758 6145.50536404389026139853
5760 5759 6146.604329604662559738189
5761 5760 6147.070023447599011416152
5762 5761 6148.593113945611024538565
5763 5762 6149.39892523007550159151
5764 5763 6150.27537410434017387015
5765 5764 6150.879887870594664179501
5766 5765 6151.572502081302249277557
5767 5766 6152.585599027227552121695
5768 5767 6153.326365653243776673647
5769 5768 6154.805638423514126474301
5770 5769 6155.704809901577576141088
5771 5770 6156.737464494589812264814
5772 5771 6157.381128649895637849398
5773 5772 6158.397686173142676134441
5774 5773 6159.096947190147221007465
5775 5774 6159.829468995751324190308
5776 5775 6161.429368945598253251375
5777 5776 6161.827253696845165926754
5778 5777 6162.415562412440462142
5779 5778 6163.378477444262907414916
5780 5779 6164.77322051761087728081
5781 5780 6166.20051343459717235463
5782 5781 6166.48304899403078110056
5783 5782 6167.464531359393705301398
5784 5783 6168.379809680246988887564
5785 5784 6169.394736467650740890785
5786 5785 6169.538152648448951805981
5787 5786 6170.8200081090755564471
5788 5787 6171.920474771537950835092
5789 5788 6172.839930458118756665442
5790 5789 6174.235069962361212032654
5791 5790 6174.747542413266487368144
5792 5791 6175.309013705466202534556
5793 5792 6176.744162202786075605758
5794 5793 6177.630404449607687190346
5795 5794 6178.410285632124583663284
5796 5795 6179.094486917628065861994
5797 5796 6179.764681614095670946034
5798 5797 6181.012825755287161887183
5799 5798 6181.678420746651563134654
5800 5799 6183.062480334703978667785
5801 5800 6184.336316582487731672272
5802 5801 6185.079974864195634102861
5803 5802 6185.460103700484071046023
5804 5803 6186.457283968078469376193
5805 5804 6187.126750723331392003293
5806 5805 6188.458683360364819828546
5807 5806 6189.118029681645703748417
5808 5807 6190.169795887310407687302
5809 5808 6190.926665971511627195756
5810 5809 6192.097286028823218960567
5811 5810 6193.133431144429529257478
5812 5811 6193.902824192949343159026
5813 5812 6194.965274092488516895805
5814 5813 6195.672078990472128671059
5815 5814 6196.664752125840570041712
5816 5815 6197.387063257130763175228
5817 5816 6198.06538956070200104699
5818 5817 6198.652216561331644632868
5819 5818 6200.674034464229283029163
5820 5819 6201.593088508775883273702
5821 5820 6201.832569639449296180227
5822 5821 6203.190910737261660907958
5823 5822 6203.867876241975048665658
5824 5823 6204.585656186870193123194
5825 5824 6205.73134233121510594285
5826 5825 6206.51302568540831513398
5827 5826 6207.35367736698029675647
5828 5827 6208.562086127367787078461
5829 5828 6208.81397241079579605049
5830 5829 6210.470030162985671912161
5831 5830 6211.20781654721815414305
5832 5831 6212.54968605797382349276
5833 5832 6213.187976900496243026391
5834 5833 6213.799999957366914719562
5835 5834 6214.501304729581620591147
5836 5835 6215.400957016780243214201
5837 5836 6216.668292162449824013276
5838 5837 6217.188858908823191031335
5839 5838 6218.517119863552869216887
5840 5839 6219.844220203323984112859
5841 5840 6220.276866168359960848763
5842 5841 6221.350127562687157238888
5843 5842 6221.641300960960463553933
5844 5843 6223.447708927403445850399
5845 5844 6223.854786959724420050583
5846 5845 6224.732447312543606945776
5847 5846 6225.470678081441736860113
5848 5847 6226.232883566194536997464
5849 5848 6227.450045327269222797584
5850 5849 6228.832840927518282241601
5851 5850 6229.761584418354129123509
5852 5851 6230.323749796148486810308
5853 5852 6231.186984214131169446629
5854 5853 6232.234236964409524422327
5855 5854 6232.811490700785666483301
5856 5855 6233.436150635210628266442
5857 5856 6234.90535602790765947796
5858 5857 6235.691811528844528331421
5859 5858 6236.8717972137507064455
5860 5859 6237.401188051517586852149
5861 5860 6238.50779015008246500565
5862 5861 6239.720298749178834360436
5863 5862 6240.518432488211752983441
5864 5863 6240.987478337604995883279
5865 5864 6242.263742648332989620537
5866 5865 6242.916128110378443450997
5867 5866 6243.536571206048710188135
5868 5867 6244.467501007128694225551
5869 5868 6245.846353792800501805559
5870 5869 6247.220803894968887354953
5871 5870 6247.765900412639837931506
5872 5871 6248.617590056633857018212
5873 5872 6249.22356720248598392914
5874 5873 6250.125998032665393587599
5875 5874 6251.160830038508715030923
5876 5875 6252.337721681161117737456
5877 5876 6252.96064162391112326062
5878 5877 6253.372699433021519516075
5879 5878 6255.212382593087241652058
5880 5879 6255.709995714932515218483
5881 5880 6256.737988103586667303977
5882 5881 6257.821913767863791689356
5883 5882 6258.86314220186606380982
5884 5883 6259.511130503419091932
5885 5884 6259.969134480434751244249
5886 5885 6260.941865601983487287145
5887 5886 6261.776846422373568857056
5888 5887 6263.065904931718502883112
5889 5888 6264.199277451351076367974
5890 5889 6265.060898277042834850186
5891 5890 6265.972125306059741623072
5892 5891 6266.645735922494529375323
5893 5892 6267.560486576163312046586
5894 5893 6268.625266754623981466297
5895 5894 6269.26735556647597596435
5896 5895 6270.349148874556124765742
5897 5896 6271.148771757297805292573
5898 5897 6271.964363395980884268251
5899 5898 6272.586182980715547561981
5900 5899 6274.619334058124033153733
5901 5900 6275.133981984459411514596
5902 5901 6275.846693888326961539231
5903 5902 6276.916164708130861698124
5904 5903 6277.22919488268901994553
5905 5904 6278.607595708884193469313
5906 5905 6279.122462096040720938596
5907 5906 6279.993148665393151052624
5908 5907 6281.406047966539854644854
5909 5908 6282.275812909980582035604
5910 5909 6283.220407901683433141011
5911 5910 6284.054280278027934605943
5912 5911 6284.78841111904123732582
5913 5912 6285.899070662988608542987
5914 5913 6287.173743024350783256162
5915 5914 6287.425952940815398619818
5916 5915 6288.211245409330052612688
5917 5916 6289.114831893080016509347
5918 5917 6290.03700659912978356941
5919 5918 6291.549652024560088969914
5920 5919 6292.329914868597809319443
5921 5920 6293.297335719867382599572
5922 5921 6294.349329653984613469809
5923 5922 6295.006181305976214400052
5924 5923 6295.221568857195857418735
5925 5924 6296.546591927773958859292
5926 5925 6297.771255864573130869783
5927 5926 6298.458690160453380733914
5928 5927 6299.172745574499790349695
5929 5928 6300.374887380822561922403
5930 5929 6301.383220877710107792296
5931 5930 6302.23025973977973249083
5932 5931 6303.490771613428405252769
5933 5932 6303.9491793886173286565
5934 5933 6304.900391851708683599407
5935 5934 6305.747858386109966545114
5936 5935 6306.557291346391699737449
5937 5936 6307.144720875522995450198
5938 5937 6308.253824515857693686567
5939 5938 6309.939810025127974587926
5940 5939 6310.837756045101963675388
5941 5940 6311.201065750283753075139
5942 5941 6311.879397195401941703638
5943 5942 6313.321021466825313884265
5944 5943 6313.825911946270715652837
5945 5944 6315.03100872321233050777
5946 5945 6315.483979856275076351362
5947 5946 6316.769600866338171251211
5948 5947 6317.255760098615846449138
5949 5948 6318.603143126995766392424
5950 5949 6319.382478611861085728394
5951 5950 6320.918880337805217809348
5952 5951 6321.415499802147126023966
5953 5952 6322.118186694310526629375
5954 5953 6323.1825944448678935737
5955 5954 6323.689061223936470141594
5956 5955 6324.348503493780794988227
5957 5956 6325.991157331886648638111
5958 5957 6326.550698605975945347902
5959 5958 6327.70932959605754529836
5960 5959 6328.768971501923933172786
5961 5960 6329.665095498507683840963
5962 5961 6330.240406355495641936296
5963 5962 6331.108424755269534355861
5964 5963 6332.346151108676920410035
5965 5964 6333.196346147333266403354
5966 5965 6333.916050927501329654488
5967 5966 6334.410684881733392366936
5968 5967 6335.356899771550918682316
5969 5968 6337.044248810119409828111
5970 5969 6337.822038198450647636813
5971 5970 6339.04195746834752884028
5972 5971 6339.248808949114715564585
5973 5972 6340.441439655440368629958
5974 5973 6341.029239095866058762191
5975 5974 6341.954159169849297249536
5976 5975 6343.025918905335253948585
5977 5976 6343.639577676622732046666
5978 5977 6345.124572354928616136147
5979 5978 6345.812781595794479126532
5980 5979 6346.708588292483206788293
5981 5980 6347.512774839417058411584
5982 5981 6348.864774975658755015613
5983 5982 6349.694650324670861344929
5984 5983 6350.349366018132023589182
5985 5984 6350.797904043100050054104
5986 5985 6352.124095646808434087757
5987 5986 6352.824041916451004197273
5988 5987 6353.487236191205026928767
5989 5988 6355.408107878889067195859
5990 5989 6355.930130900404423272717
5991 5990 6356.9841069328843898645
5992 5991 6357.606857658452497579655
5993 5992 6358.315701847617436001125
5994 5993 6359.169623810261232247339
5995 5994 6360.503448520766636966998
5996 5995 6361.108114371222121025045
5997 5996 6362.082499057126084295275
5998 5997 6362.685361830654181585679
5999 5998 6363.900839548029471636
6000 5999 6365.283583744359191039687
6001 6000 6365.85232102101638182037

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