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 20 of 20 · 500/page · 10000 rows
# ngamma_n
9502 9501 9450.152313575517838853422
9503 9502 9451.044025469181487953328
9504 9503 9452.148976996906294188176
9505 9504 9452.581214093017369088895
9506 9505 9453.384466732684817187149
9507 9506 9454.941836695376157436448
9508 9507 9455.879794581773075445131
9509 9508 9456.638848993114638194301
9510 9509 9457.289938948843797185126
9511 9510 9457.972397294629056885096
9512 9511 9458.826684385939582786266
9513 9512 9459.769410651763696902907
9514 9513 9460.903772501188025463154
9515 9514 9461.404922056238932011015
9516 9515 9462.137989879679322227544
9517 9516 9462.93651616790396524126
9518 9517 9464.217904346365138169241
9519 9518 9465.26189553452927505624
9520 9519 9465.991177189080199889079
9521 9520 9466.722587065204372480842
9522 9521 9467.860632792306992398676
9523 9522 9468.494804378226595150426
9524 9523 9469.132039337016044265513
9525 9524 9469.45600650505510240641
9526 9525 9470.882771001473596779214
9527 9526 9471.819269688123019319734
9528 9527 9472.907942701792330986481
9529 9528 9473.723079554979143787997
9530 9529 9474.392245663754277719109
9531 9530 9475.565521140302117251068
9532 9531 9475.919635500875018165464
9533 9532 9477.13788571879726355574
9534 9533 9477.827320467828518351439
9535 9534 9478.855699954578301817779
9536 9535 9479.229478691426517104641
9537 9536 9480.23527134465883904671
9538 9537 9481.143882258962663884147
9539 9538 9481.839788621123747411063
9540 9539 9483.688815646472935607933
9541 9540 9484.207298377048456077515
9542 9541 9484.640388958238090163278
9543 9542 9485.753856656422082142459
9544 9543 9486.030868859609172042385
9545 9544 9487.215810246310383562584
9546 9545 9488.107214893484419642482
9547 9546 9488.903784852235907837658
9548 9547 9489.546258565251699314706
9549 9548 9491.036789278031653627922
9550 9549 9491.622337134984262011559
9551 9550 9492.559851589392107387463
9552 9551 9493.134847953395464653342
9553 9552 9494.478852244826342916791
9554 9553 9495.156477923671120969656
9555 9554 9495.860072044986932970106
9556 9555 9496.823908854260260684373
9557 9556 9497.255442783197418642268
9558 9557 9497.951007264428538772506
9559 9558 9499.137222929027451110605
9560 9559 9500.595321344587537617036
9561 9560 9501.217267713874678233346
9562 9561 9501.92252002564580211738
9563 9562 9503.042498302919704041347
9564 9563 9503.601117763335325358603
9565 9564 9504.264017632144006325898
9566 9565 9505.086080346834820866717
9567 9566 9506.113854057057659791889
9568 9567 9507.223790580799225671283
9569 9568 9507.961501776307635734617
9570 9569 9508.1296374492262955831
9571 9570 9509.769913842899123096092
9572 9571 9510.615551924727858427685
9573 9572 9511.550977665867548203467
9574 9573 9512.380208554100619668528
9575 9574 9513.335229212824097601439
9576 9575 9513.533893338416950940502
9577 9576 9514.814322806685032699687
9578 9577 9515.333335579303564547055
9579 9578 9516.047851769818793177156
9580 9579 9517.248001838854248860051
9581 9580 9518.401462280204561424916
9582 9581 9519.480657353684034455581
9583 9582 9520.014543684853781891917
9584 9583 9520.830643941693371417572
9585 9584 9521.162437132308680895621
9586 9585 9522.916082653631268696523
9587 9586 9523.293287273884070907291
9588 9587 9524.172145197426360200489
9589 9588 9524.673999746041780341968
9590 9589 9525.837508223161307844538
9591 9590 9526.527981212930727896834
9592 9591 9527.680937490483967348056
9593 9592 9528.632397360561266409724
9594 9593 9529.771681927852885083186
9595 9594 9530.405942179322025098064
9596 9595 9531.147923592071813588069
9597 9596 9531.625571622489072925861
9598 9597 9532.674849336538627209368
9599 9598 9533.23798585525460483088
9600 9599 9534.471660705845286516872
9601 9600 9535.377269524699473445624
9602 9601 9536.209876871133916893344
9603 9602 9537.253631706384040521991
9604 9603 9537.834915534641572577516
9605 9604 9539.182796449742345715331
9606 9605 9539.514744272631902917852
9607 9606 9540.396197262095422102949
9608 9607 9541.66710204619347792943
9609 9608 9542.028340453083947959228
9610 9609 9543.161504406562554812277
9611 9610 9543.327342114099745389014
9612 9611 9544.333386339599174865801
9613 9612 9546.14806213891717712709
9614 9613 9546.850958230858727687232
9615 9614 9547.451494516013113971958
9616 9615 9548.202699749706151398814
9617 9616 9549.109408072244078037563
9618 9617 9550.023825186957553336415
9619 9618 9550.297435818614259417706
9620 9619 9551.802310112949625281704
9621 9620 9552.369737287713665962517
9622 9621 9553.055529832435298762579
9623 9622 9554.43873102491442684741
9624 9623 9555.132351125928070576394
9625 9624 9555.765517186338260110851
9626 9625 9557.0334502426587701713
9627 9626 9557.864073545580146024178
9628 9627 9558.778597586110962337985
9629 9628 9559.497877391873840268284
9630 9629 9559.651002786866863544471
9631 9630 9560.804275858352439779986
9632 9631 9561.826855174030332528675
9633 9632 9562.595160265601077816217
9634 9633 9563.767484768306059513594
9635 9634 9564.941586598359537159951
9636 9635 9565.719270210826519406081
9637 9636 9565.99847375408613539536
9638 9637 9567.084762807113636559807
9639 9638 9567.68066864288012431463
9640 9639 9568.920136749612357888378
9641 9640 9569.757583804237239564808
9642 9641 9570.282928700381061771244
9643 9642 9571.225835960819895178308
9644 9643 9571.872993121369498659182
9645 9644 9573.170828778938441791541
9646 9645 9574.260212103264488528779
9647 9646 9575.159596766068858124397
9648 9647 9575.627693113068459526385
9649 9648 9576.504120426484488340939
9650 9649 9577.462720728044731422846
9651 9650 9578.082268990219020394036
9652 9651 9578.752937349978082671215
9653 9652 9579.449577446087551278419
9654 9653 9581.125284055394327441872
9655 9654 9581.813931393478143212544
9656 9655 9582.531012948870311420597
9657 9656 9583.488437066879631629775
9658 9657 9584.163335287170119282412
9659 9658 9585.143063862838947513739
9660 9659 9586.255233920493945725502
9661 9660 9586.572222390227484244979
9662 9661 9587.581534661284105961774
9663 9662 9588.562422367796474078569
9664 9663 9588.897946175894874810935
9665 9664 9589.946539842006510179601
9666 9665 9591.313819408709410407962
9667 9666 9592.130272135010300346085
9668 9667 9593.205180493658846173045
9669 9668 9593.91016540604438591074
9670 9669 9594.431429784413274197865
9671 9670 9594.98828587268733544466
9672 9671 9595.993695246837813871949
9673 9672 9597.340246229806388656963
9674 9673 9597.618342094728995633224
9675 9674 9598.766169772418767944448
9676 9675 9599.449375097213448843993
9677 9676 9601.023594442615011526536
9678 9677 9601.374051672791911108302
9679 9678 9601.972952765042330220821
9680 9679 9603.387320427234751615987
9681 9680 9604.113455998881627535452
9682 9681 9604.831331501784262477105
9683 9682 9605.509080556900758815046
9684 9683 9606.208589671675521674102
9685 9684 9606.948842119686854533481
9686 9685 9608.036444605873060809369
9687 9686 9609.580310488176489674099
9688 9687 9610.210766394500173007379
9689 9688 9610.802823321588173002489
9690 9689 9611.665887777861962098842
9691 9690 9612.606349754941479289813
9692 9691 9613.167963417455287934312
9693 9692 9614.252323364500127574018
9694 9693 9614.79092744738982269297
9695 9694 9616.080125100233765887598
9696 9695 9616.576304356222216020322
9697 9696 9617.711563455022569563091
9698 9697 9618.147803718693615352353
9699 9698 9619.662657556979815721799
9700 9699 9620.711570046190571682813
9701 9700 9621.165759368628061386666
9702 9701 9621.757407603287746049337
9703 9702 9622.96040119460652033128
9704 9703 9623.378434431066617362145
9705 9704 9624.134944535440568628645
9706 9705 9625.222075594958859263069
9707 9706 9626.015526809151806182521
9708 9707 9627.410922590326371213283
9709 9708 9628.224711924473750680942
9710 9709 9628.814176045421963016198
9711 9710 9629.724366465654195244951
9712 9711 9630.301966897596646411506
9713 9712 9631.280209290208506562289
9714 9713 9632.562265478025442789538
9715 9714 9633.111145441421180494537
9716 9715 9633.5899195810441311846
9717 9716 9634.275150158077611828595
9718 9717 9635.65173953014364158513
9719 9718 9636.586190719115106378417
9720 9719 9637.636829868488473224772
9721 9720 9638.333970206398725217631
9722 9721 9639.400372272585184616936
9723 9722 9639.941632652453206538676
9724 9723 9640.667624445024666011508
9725 9724 9641.271927640639914587069
9726 9725 9642.172583672366622915597
9727 9726 9643.651510536878041424675
9728 9727 9643.850300727237012503587
9729 9728 9645.268004100864105331332
9730 9729 9646.033601387987542209237
9731 9730 9646.682120242309280748225
9732 9731 9647.776874287209417000727
9733 9732 9648.593127494612782407017
9734 9733 9649.697627600659101603769
9735 9734 9649.853790958864717645259
9736 9735 9650.999123888005800829891
9737 9736 9651.871456186812567976979
9738 9737 9652.53846402765615185841
9739 9738 9653.014874566615366895358
9740 9739 9654.963345358770871395694
9741 9740 9655.670242556963393784617
9742 9741 9656.50915642900402016846
9743 9742 9657.006073676157458894914
9744 9743 9657.625816863722349657388
9745 9744 9658.780678230384615506653
9746 9745 9659.637116337265663062138
9747 9746 9660.202999377106689856385
9748 9747 9661.371533562066128138843
9749 9748 9661.957836041305761858973
9750 9749 9663.085768151967829900167
9751 9750 9663.881076548493356670219
9752 9751 9665.039454448804061064147
9753 9752 9665.485661646632161451316
9754 9753 9666.80721248964326922438
9755 9754 9667.56422730029703389518
9756 9755 9668.135428970973489653503
9757 9756 9668.700128123907917811827
9758 9757 9669.745616207286552019026
9759 9758 9670.162113845697508998164
9760 9759 9671.949512726717557566149
9761 9760 9672.494340342316708279714
9762 9761 9673.396190895942619331785
9763 9762 9674.547299394770301445635
9764 9763 9675.122226685422862664856
9765 9764 9675.734272080005008190535
9766 9765 9676.482970442664743373656
9767 9766 9677.762490773549705700014
9768 9767 9678.44144479738020595537
9769 9768 9679.309646020153214853846
9770 9769 9679.806168479680127851341
9771 9770 9680.762833610206135378782
9772 9771 9681.933181545262099109156
9773 9772 9683.097742918037775445068
9774 9773 9683.867021673075729416993
9775 9774 9684.589585901776689271207
9776 9775 9685.308004229365586362152
9777 9776 9685.960000518493414291316
9778 9777 9686.93890170550327968039
9779 9778 9687.635650374518576486192
9780 9779 9688.452504117910426432643
9781 9780 9689.424900299011553833205
9782 9781 9691.007692604953553641168
9783 9782 9691.345099412726314259069
9784 9783 9692.129608962687733291201
9785 9784 9692.775465087985222801479
9786 9785 9694.160018792738817178729
9787 9786 9694.810249048602317296675
9788 9787 9695.58726512324034528754
9789 9788 9696.340584322436407891031
9790 9789 9696.969092912941657394611
9791 9790 9697.964078699752353771869
9792 9791 9698.735918071114720512611
9793 9792 9699.909751127411665624352
9794 9793 9701.268636037585310124304
9795 9794 9701.750955885448483775343
9796 9795 9702.343670704510927804234
9797 9796 9703.640136866696275940471
9798 9797 9703.837388247138271345004
9799 9798 9704.480325775091432015939
9800 9799 9705.876215987490425377973
9801 9800 9706.802865517506481576504
9802 9801 9707.414647044850381710794
9803 9802 9708.186078193498034478428
9804 9803 9709.502438605258619000417
9805 9804 9710.185679567853324494634
9806 9805 9711.156381036051293554442
9807 9806 9711.887312336946229667108
9808 9807 9712.668956896418527246982
9809 9808 9713.803909573425151327376
9810 9809 9714.476372679759363245803
9811 9810 9714.689105558265422584887
9812 9811 9715.654426519519315074821
9813 9812 9716.864893947745227984756
9814 9813 9718.217323919808595985133
9815 9814 9719.003948229437313298665
9816 9815 9719.5846054092779898147
9817 9816 9720.464454076306097050533
9818 9817 9721.104473046968958726017
9819 9818 9721.996753309981627222327
9820 9819 9723.058455125069058343605
9821 9820 9723.737313265188253888775
9822 9821 9724.373873216511838896461
9823 9822 9725.549128994301248421754
9824 9823 9726.187902553736458850757
9825 9824 9727.403728478151436256048
9826 9825 9727.880335351850132346983
9827 9826 9729.496025752606641840109
9828 9827 9730.119586178587549418595
9829 9828 9730.576904308747722897736
9830 9829 9731.372827729493872967929
9831 9830 9732.00689364466710108742
9832 9831 9733.303859799544156065692
9833 9832 9733.610464090441313664782
9834 9833 9734.855515621142256328017
9835 9834 9736.090792315416289346833
9836 9835 9736.730369148979561580208
9837 9836 9737.855582949503274696132
9838 9837 9738.240421320171366020715
9839 9838 9739.021072198769395215714
9840 9839 9740.135575736943403259359
9841 9840 9741.076087748449238818003
9842 9841 9741.657972106349059143753
9843 9842 9742.623564743644967480055
9844 9843 9743.232096252093448559672
9845 9844 9743.733762360302486742903
9846 9845 9745.639066617375271209239
9847 9846 9746.440268750824353601183
9848 9847 9746.82572827977716777801
9849 9848 9748.002697060168310826108
9850 9849 9748.63928222325379683321
9851 9850 9749.482254346997222741452
9852 9851 9750.074742139966830949255
9853 9852 9750.773005612475693157547
9854 9853 9751.983307432256710439151
9855 9854 9753.034700475616718301189
9856 9855 9753.717213061297670186029
9857 9856 9754.680499290171124337323
9858 9857 9755.495112248225725556691
9859 9858 9756.380104702497565897888
9860 9859 9757.260899468928572943023
9861 9860 9758.3074540973946021577
9862 9861 9758.814665166590592302414
9863 9862 9759.592246659126328066496
9864 9863 9760.270891381358647294886
9865 9864 9761.363189250917882273864
9866 9865 9761.887569295263791077371
9867 9866 9763.294099801654022998447
9868 9867 9764.416349965648795897838
9869 9868 9765.29807729248359687411
9870 9869 9765.798045051534396931666
9871 9870 9766.238754743440926764072
9872 9871 9767.289858684207138669864
9873 9872 9768.168596164699024400775
9874 9873 9769.341847581768861546019
9875 9874 9769.963460333965136832728
9876 9875 9770.298585892207330804624
9877 9876 9771.872279801797226599507
9878 9877 9772.654168675884222661403
9879 9878 9773.284337854803651038974
9880 9879 9774.703617455913579668182
9881 9880 9775.088283540137052247897
9882 9881 9776.251533919415678348639
9883 9882 9776.73038188556109928285
9884 9883 9777.69267937558890063141
9885 9884 9778.148806606652925989853
9886 9885 9778.880763275066163891848
9887 9886 9780.313329425088943061112
9888 9887 9781.383732402793174066125
9889 9888 9782.385525671766152375466
9890 9889 9782.610816339745412337861
9891 9890 9783.722534561653153722973
9892 9891 9784.680677563404740073133
9893 9892 9785.381062853272199414532
9894 9893 9785.900034116508711828266
9895 9894 9787.27692018662259330453
9896 9895 9787.953486118466289417462
9897 9896 9788.477759390459476629128
9898 9897 9789.402370599819197870737
9899 9898 9790.364384932035709893186
9900 9899 9791.983400038892183438236
9901 9900 9792.246728932375253919126
9902 9901 9793.549999292038026153439
9903 9902 9793.647618792513487854562
9904 9903 9794.761051811067582348219
9905 9904 9795.420031375642897851855
9906 9905 9796.201811061875635237166
9907 9906 9797.293024611317090224322
9908 9907 9798.034191396092690483718
9909 9908 9799.096192514175697893781
9910 9909 9800.348712492729982616528
9911 9910 9800.831815354950878718418
9912 9911 9801.527598488981030473839
9913 9912 9802.247218201909121879282
9914 9913 9803.782724367467708280345
9915 9914 9804.339386746744349823631
9916 9915 9804.771010774445754230205
9917 9916 9805.672191920601336214595
9918 9917 9806.373069561859734648894
9919 9918 9807.41526867301207378577
9920 9919 9808.579426841199401817334
9921 9920 9809.662905147581751007131
9922 9921 9810.291826875659641939985
9923 9922 9811.323107614278453797966
9924 9923 9812.02619072749897582449
9925 9924 9812.268979445580014434621
9926 9925 9813.48897453111352222222
9927 9926 9814.292509387761066222807
9928 9927 9815.145409875074507551256
9929 9928 9816.280725472365878388204
9930 9929 9816.937616013131181092829
9931 9930 9817.665816070328513047741
9932 9931 9818.915101401563215094585
9933 9932 9819.703209234133167213375
9934 9933 9820.652109742502591663027
9935 9934 9821.399312628915174906572
9936 9935 9821.90282973924540581145
9937 9936 9823.078061393203362866652
9938 9937 9823.702895700077305930914
9939 9938 9824.295346709679424113234
9940 9939 9825.034070225098676686639
9941 9940 9826.946695210842271420678
9942 9941 9827.547832227359483373327
9943 9942 9828.155753564819510348531
9944 9943 9828.973287305271331255021
9945 9944 9829.933473335918002958959
9946 9945 9830.307902371356212629768
9947 9946 9831.760429334101807867294
9948 9947 9832.237602064833492365759
9949 9948 9833.139694319812938886736
9950 9949 9833.89835038003644398208
9951 9950 9834.670764972764236545525
9952 9951 9836.112660501271127842087
9953 9952 9836.485906520354733298145
9954 9953 9837.756654900430846673939
9955 9954 9838.631071530686382877134
9956 9955 9839.435359540697745611261
9957 9956 9840.038249688898638027866
9958 9957 9840.729469971663306224819
9959 9958 9841.165565424500599525265
9960 9959 9842.661664685199217223642
9961 9960 9843.426278643086802532532
9962 9961 9844.269014987098560059659
9963 9962 9845.514484924075167784956
9964 9963 9846.234022220622102669278
9965 9964 9846.883790560700947462059
9966 9965 9847.700262244546619510445
9967 9966 9848.563597129891541668464
9968 9967 9849.559686381093235343931
9969 9968 9850.340915387202658525994
9970 9969 9851.168115715308804975911
9971 9970 9851.623956975879965784412
9972 9971 9852.552236726619345482072
9973 9972 9853.637530407182175705905
9974 9973 9855.04580374647033773864
9975 9974 9856.031386999542062118635
9976 9975 9856.177060904510873079901
9977 9976 9856.9101756671628780548
9978 9977 9858.164581111085492643635
9979 9978 9858.732414135966943819689
9980 9979 9859.381159522503570437132
9981 9980 9860.360205325457811609874
9982 9981 9861.363515492228045888513
9983 9982 9862.379013196930130683428
9984 9983 9863.480482964539614171683
9985 9984 9863.698339983143821656195
9986 9985 9864.789829098051564406679
9987 9986 9866.12199398396833968642
9988 9987 9866.515268109411447344204
9989 9988 9867.444225598539548313843
9990 9989 9868.274452687335267911244
9991 9990 9868.714659330643201731353
9992 9991 9869.812878325986458201907
9993 9992 9870.332258556616445749494
9994 9993 9872.00062337813295573172
9995 9994 9872.558666059604231912379
9996 9995 9873.802220903648406406782
9997 9996 9874.323957629064029672233
9998 9997 9875.21899409884676714558
9999 9998 9875.600956248756888587221
10000 9999 9876.479017063783790065514
10001 10000 9877.782654005501142774099

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