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 16 of 20 · 500/page · 10000 rows next →
# ngamma_n
7502 7501 7709.242640641286697040673
7503 7502 7710.123839877936255232636
7504 7503 7711.223648931966409488849
7505 7504 7711.928933800227467300602
7506 7505 7712.779308288258003798683
7507 7506 7712.908648889921598174604
7508 7507 7714.904975654682960498715
7509 7508 7715.806809192833111791341
7510 7509 7716.493161846611898040574
7511 7510 7717.430625538000418881088
7512 7511 7718.209439895409993078952
7513 7512 7718.871828009921132073452
7514 7513 7719.753486074996462535511
7515 7514 7720.412175074541478008665
7516 7515 7721.553996963717986382997
7517 7516 7722.557228801705185151338
7518 7517 7723.61828222112613562999
7519 7518 7724.440916671356449555379
7520 7519 7725.242870633078969451133
7521 7520 7725.881074558964291255997
7522 7521 7727.365067834397736031365
7523 7522 7728.154537020827551332318
7524 7523 7728.345321205481334142449
7525 7524 7729.508444298457516566618
7526 7525 7730.156710684247130548094
7527 7526 7731.326343492595781144065
7528 7527 7731.904604016607426870026
7529 7528 7733.551152377834453643148
7530 7529 7734.637209896445598151586
7531 7530 7734.799051748370926483151
7532 7531 7735.920191802878703575295
7533 7532 7736.398982953628865109346
7534 7533 7737.281516673403699877111
7535 7534 7738.68340051495036037636
7536 7535 7739.076079126563653947122
7537 7536 7740.113547443324926015789
7538 7537 7740.932128954655378908962
7539 7538 7742.093826817392463537378
7540 7539 7742.861768148461114881205
7541 7540 7744.168742339143767238427
7542 7541 7744.539185766441797892209
7543 7542 7745.56417766555176129792
7544 7543 7746.617972149764558273796
7545 7544 7747.262729142251268794247
7546 7545 7747.603843256256533153963
7547 7546 7748.560899267973341833284
7548 7547 7749.950340468416227155032
7549 7548 7751.417942590560582958603
7550 7549 7751.732240722188094575151
7551 7550 7752.412059063885662990635
7552 7551 7753.812564124216337199876
7553 7552 7754.165808072856884783665
7554 7553 7755.042744738049505040672
7555 7554 7756.140545944699437312458
7556 7555 7756.961660293782967791658
7557 7556 7757.748648753477629801629
7558 7557 7758.441967610163541339315
7559 7558 7759.592954770951883867505
7560 7559 7760.470136603880948986854
7561 7560 7761.852016416726361594269
7562 7561 7762.516669838838029438655
7563 7562 7763.36553663748545884432
7564 7563 7763.887943627448154940823
7565 7564 7764.629540608917180512544
7566 7565 7765.580549321205474182373
7567 7566 7766.648068548923342018047
7568 7567 7767.347361427240878469546
7569 7568 7768.41709385647645967162
7570 7569 7769.913327770865059742386
7571 7570 7770.261243682984075318359
7572 7571 7770.983886849091107669868
7573 7572 7771.801935593383812456161
7574 7573 7773.152164235817351186694
7575 7574 7774.018899975771259936395
7576 7575 7774.296269528577907835923
7577 7576 7775.448785294472871319336
7578 7577 7775.977608167172568020767
7579 7578 7776.955377123453457053433
7580 7579 7778.619618817802508564541
7581 7580 7779.14773836891183233058
7582 7581 7780.294143760089890409977
7583 7582 7780.791631249869122201101
7584 7583 7781.703703737553585420109
7585 7584 7782.448108668124168756305
7586 7585 7783.333189556128682633957
7587 7586 7783.869822963324538796938
7588 7587 7785.543212016206338140029
7589 7588 7785.972158398128298984318
7590 7589 7786.910885163880594501875
7591 7590 7787.847577241957042956306
7592 7591 7788.942037729745572211233
7593 7592 7789.846487233922963475482
7594 7593 7790.584748288393133062631
7595 7594 7791.49812245836986893469
7596 7595 7792.057000206961825023364
7597 7596 7793.208438102891880381941
7598 7597 7793.73117934918877425282
7599 7598 7794.33064791502206670427
7600 7599 7796.167939908259864930758
7601 7600 7796.882750797398516421879
7602 7601 7797.939994785891134969014
7603 7602 7798.642876532039964212072
7604 7603 7799.027356176224375826372
7605 7604 7800.048866699561676676951
7606 7605 7801.085965692595485258764
7607 7606 7802.278136743012408000977
7608 7607 7802.563043838598344067765
7609 7608 7803.341640437309176651703
7610 7609 7804.662539155135742323494
7611 7610 7805.651244456075833297344
7612 7611 7806.365526757544997433011
7613 7612 7807.453947055253566163713
7614 7613 7808.521694540726764488176
7615 7614 7809.148095665498994221557
7616 7615 7809.949348552199654272604
7617 7616 7810.246422779107858450093
7618 7617 7811.425296754865822189759
7619 7618 7812.392880857759970509323
7620 7619 7813.480751249711268723517
7621 7620 7814.556090476849723611384
7622 7621 7815.586939345173126557388
7623 7622 7815.855841174666006841548
7624 7623 7817.152637267742354138433
7625 7624 7817.796685739582704506152
7626 7625 7818.660115006317333578856
7627 7626 7819.635648031588547838475
7628 7627 7820.586397432231386482112
7629 7628 7821.053880222406446644661
7630 7629 7822.094093501539303656648
7631 7630 7822.719034353719052117928
7632 7631 7824.645471276426298715306
7633 7632 7825.273177259965797550239
7634 7633 7825.827781341021992359116
7635 7634 7826.471180296940809470657
7636 7635 7827.806459758518663660837
7637 7636 7828.125195235319679025023
7638 7637 7828.993878289369157228108
7639 7638 7830.128538967395252916106
7640 7639 7830.877581937871584464896
7641 7640 7832.274462692866964308302
7642 7641 7832.824494593668014019615
7643 7642 7833.92075524859055910852
7644 7643 7834.383065914865345427786
7645 7644 7835.733258049544986127485
7646 7645 7836.463501636442424125193
7647 7646 7837.39694749032501496313
7648 7647 7838.064178062146856258135
7649 7648 7838.482550842813393207224
7650 7649 7839.568362838761170903947
7651 7650 7840.782349085685853421309
7652 7651 7841.828068608777058984477
7653 7652 7842.773773977402605945316
7654 7653 7843.741048100103646323574
7655 7654 7844.457429440748946437066
7656 7655 7845.080327763865381412749
7657 7656 7845.576147186456760340204
7658 7657 7847.000089158636192511676
7659 7658 7847.835966138221770958794
7660 7659 7848.647013323947102820805
7661 7660 7849.322974184131110759321
7662 7661 7850.381575865228688835663
7663 7662 7851.749375193902068484984
7664 7663 7852.055533000644163572526
7665 7664 7853.536887110030167454547
7666 7665 7854.099209290602833638555
7667 7666 7854.705243499414603995643
7668 7667 7855.730232864411345874615
7669 7668 7856.589741467901698421409
7670 7669 7857.007480210241983319877
7671 7670 7857.998247520007615201204
7672 7671 7859.863876592034631300151
7673 7672 7860.360848829582000532199
7674 7673 7861.074293126312700438826
7675 7674 7861.968307522175352955139
7676 7675 7862.576808489509429538537
7677 7676 7863.886469839469670605207
7678 7677 7864.688424186120414884322
7679 7678 7865.047548549886367146732
7680 7679 7866.327295716897213911313
7681 7680 7867.142338041973441554108
7682 7681 7867.701391247108394668558
7683 7682 7869.054058996961532802086
7684 7683 7870.100532362201615576986
7685 7684 7871.026268506168110536737
7686 7685 7871.891593703722377115853
7687 7686 7872.421051360308705767277
7688 7687 7873.25897473315492101251
7689 7688 7873.85741172542153340819
7690 7689 7874.894281010700568690616
7691 7690 7876.081256282227586569185
7692 7691 7876.811378416846240658608
7693 7692 7877.833953052452128988679
7694 7693 7878.910611220161473491382
7695 7694 7879.774371317584962201007
7696 7695 7880.247924997616576370234
7697 7696 7881.172597090475712192558
7698 7697 7882.440411048756300168435
7699 7698 7883.21913209124047210595
7700 7699 7883.739288678191780173497
7701 7700 7884.386136360235803273905
7702 7701 7885.310055570770696998982
7703 7702 7886.697844124513243934165
7704 7703 7887.902634545408345234976
7705 7704 7888.582508384610721213938
7706 7705 7889.247759852946294901286
7707 7706 7890.199885171151219287951
7708 7707 7890.829109253514844100568
7709 7708 7891.738485147038294194093
7710 7709 7892.471581268803168605734
7711 7710 7893.753775748136240402699
7712 7711 7894.14622424049558226154
7713 7712 7895.752701737036691891787
7714 7713 7896.284146796155547982733
7715 7714 7896.810706211280631983218
7716 7715 7898.443975525827186707886
7717 7716 7899.189387686444269430471
7718 7717 7899.737784133993088376827
7719 7718 7900.699743497209642625517
7720 7719 7901.203724772067005803867
7721 7720 7902.431940428291098475421
7722 7721 7902.84588234763987146113
7723 7722 7904.000011350513545594419
7724 7723 7905.495359792199461355666
7725 7724 7906.307057653093616261031
7726 7725 7907.033279619341611963157
7727 7726 7907.4620230267514222034
7728 7727 7908.754089324921159353816
7729 7728 7909.071081108475123852675
7730 7729 7910.496345642476800768377
7731 7730 7911.290474750288817284964
7732 7731 7911.974654015073718074302
7733 7732 7912.521894757600126174974
7734 7733 7913.958900163054718318253
7735 7734 7914.89822865528186686788
7736 7735 7916.139083618642743847046
7737 7736 7916.249620362815146867713
7738 7737 7917.846984218910823946106
7739 7738 7918.206299766420509603152
7740 7739 7919.009503413645378370458
7741 7740 7919.702077252900915643338
7742 7741 7920.394917845036454149681
7743 7742 7922.053034576523126393444
7744 7743 7922.7233124212708498725
7745 7744 7923.710141380545326056557
7746 7745 7924.582047217101688694188
7747 7746 7925.391338795337065414455
7748 7747 7926.04475027157519911617
7749 7748 7927.227859749140543147118
7750 7749 7928.007764629537458697817
7751 7750 7928.684234751108285159995
7752 7751 7929.540229147085190267111
7753 7752 7930.604941255269277009654
7754 7753 7930.94807682601847101836
7755 7754 7932.471666174170835472758
7756 7755 7933.645643224237610617145
7757 7756 7934.495415309209678609641
7758 7757 7935.214648402931288144582
7759 7758 7935.570718561864098031422
7760 7759 7936.442237033273580418209
7761 7760 7937.745180588848000266304
7762 7761 7938.31557407955654782991
7763 7762 7939.086639386133534157008
7764 7763 7940.354012879286253227416
7765 7764 7941.265683750245981310068
7766 7765 7942.317604788917489083508
7767 7766 7942.745097903532139213609
7768 7767 7943.785515988011247945124
7769 7768 7944.959519126582114810296
7770 7769 7945.740693786376979609259
7771 7770 7946.220788193227622596423
7772 7771 7947.289771165853284456996
7773 7772 7947.729600273440278889298
7774 7773 7948.634211573243663158302
7775 7774 7950.2654705397343258925
7776 7775 7951.314030649734244229843
7777 7776 7951.584851706328720173373
7778 7777 7952.794489272235759290286
7779 7778 7953.594656971265633749095
7780 7779 7954.308997263478397735668
7781 7780 7954.747608585548029160563
7782 7781 7956.152267105715985154831
7783 7782 7956.98957824903926636579
7784 7783 7957.947945783214972350934
7785 7784 7958.317455921222641340503
7786 7785 7959.688750437558963074459
7787 7786 7960.661379307818041510103
7788 7787 7961.649596876388566220021
7789 7788 7962.562547058959874145345
7790 7789 7962.956507789985675672782
7791 7790 7964.20360071038734246856
7792 7791 7964.684089862521197358537
7793 7792 7965.315678842991650231188
7794 7793 7966.568849824008191750501
7795 7794 7967.266107538539484995765
7796 7795 7968.909886518723575729018
7797 7796 7969.629440350558739369758
7798 7797 7970.220548110803347893145
7799 7798 7970.847928248576646650332
7800 7799 7971.821330830947431410253
7801 7800 7972.995331891869346341461
7802 7801 7973.804869056249173434504
7803 7802 7974.45812975706483343486
7804 7803 7975.017853871007803203366
7805 7804 7976.207792148187416362041
7806 7805 7977.291194443747992311751
7807 7806 7977.975322928936677752225
7808 7807 7979.419830145943101757004
7809 7808 7980.244153621042555421336
7810 7809 7980.592156635668950008416
7811 7810 7981.677158957607382228917
7812 7811 7982.329229078083915641266
7813 7812 7982.856726483099919423463
7814 7813 7984.194787625831126485351
7815 7814 7985.078461489260768106706
7816 7815 7986.116271568622282080206
7817 7816 7986.989921279801373111756
7818 7817 7987.776841671902316794163
7819 7818 7988.826884442917022877398
7820 7819 7989.527182533595759996661
7821 7820 7990.464730054409619720441
7822 7821 7991.154615188094188182781
7823 7822 7992.449601868436449372168
7824 7823 7992.775448790285504386277
7825 7824 7993.535520095777221949542
7826 7825 7994.268276831975995601955
7827 7826 7996.325873550479674119537
7828 7827 7996.702938035545649381411
7829 7828 7997.562596959064329774678
7830 7829 7998.503621700133202619652
7831 7830 7998.960515915091193449275
7832 7831 8000.086767551567702851368
7833 7832 8000.654289531123154565127
7834 7833 8001.82741414649336797876
7835 7834 8002.504226795772844960799
7836 7835 8003.54402073209488960662
7837 7836 8004.486900352285943621323
7838 7837 8005.558741555964987514027
7839 7838 8006.089452661674785613822
7840 7839 8007.166316113007589013273
7841 7840 8008.486686298687256588729
7842 7841 8009.024278312770174064935
7843 7842 8009.383936409158189519864
7844 7843 8010.212236319678885917038
7845 7844 8011.469380858899632747772
7846 7845 8011.92939113055367571824
7847 7846 8013.442022089037073320819
7848 7847 8014.276774716246914729102
7849 7848 8015.371885937362163720699
7850 7849 8016.201731490309621458595
7851 7850 8016.491199874104027826249
7852 7851 8017.361465467249648704251
7853 7852 8018.637826606620458282028
7854 7853 8019.356639065828380856826
7855 7854 8020.319689666986007497533
7856 7855 8020.837459741009345912918
7857 7856 8021.895481637498504234349
7858 7857 8022.717489709397734451672
7859 7858 8024.403582467122442404738
7860 7859 8024.670982458976817363093
7861 7860 8025.752452902289467715625
7862 7861 8026.391854103008163501292
7863 7862 8027.305874159539237493462
7864 7863 8028.124025978591543307383
7865 7864 8028.746401313329196402831
7866 7865 8029.407822326108269609429
7867 7866 8031.058009786897772147378
7868 7867 8031.951322173809005467954
7869 7868 8032.793383790672800697615
7870 7869 8033.269191957556393454358
7871 7870 8034.386240870654088612236
7872 7871 8035.393242316707517172023
7873 7872 8035.999510970187784500104
7874 7873 8037.03448989182163397671
7875 7874 8037.803468786898599192241
7876 7875 8038.428466931308487947827
7877 7876 8039.310951894776003402222
7878 7877 8040.363774173744879979582
7879 7878 8041.485092078732326045742
7880 7879 8042.752607553648801600638
7881 7880 8043.228211967930747454098
7882 7881 8044.222079323645538986967
7883 7882 8044.702036441095541902429
7884 7883 8045.412198483427385638167
7885 7884 8046.349100762353517914659
7886 7885 8047.858586760628135574776
7887 7886 8048.092532351143652260993
7888 7887 8048.939018671550035189588
7889 7888 8050.707855425853340518262
7890 7889 8050.928553718142458564157
7891 7890 8051.826700970998912324965
7892 7891 8052.854735733884378315776
7893 7892 8053.85068369192077933224
7894 7893 8054.632075493165131342516
7895 7894 8055.387536444195615896997
7896 7895 8056.043545401502731410817
7897 7896 8056.62856609033527987335
7898 7897 8057.84985409479208605666
7899 7898 8059.163910470731256631768
7900 7899 8060.410573957890341239912
7901 7900 8060.656750843521767938549
7902 7901 8061.432878644980935724125
7903 7902 8062.591530739172964813455
7904 7903 8063.105008848429323214024
7905 7904 8064.20551520802154603548
7906 7905 8064.758371516304114274896
7907 7906 8065.960611559453403165359
7908 7907 8066.852181448751743334591
7909 7908 8067.499979187696302931495
7910 7909 8068.480997184477666048647
7911 7910 8069.620473525597569735858
7912 7911 8070.895715103643613391016
7913 7912 8071.223812048207729738453
7914 7913 8072.006261155453019492326
7915 7914 8072.891660955189031313224
7916 7915 8073.661638198679893000803
7917 7916 8074.476781796316090572375
7918 7917 8075.21247953427177121702
7919 7918 8076.604646442832458785013
7920 7919 8077.693139054215131085407
7921 7920 8078.331290952394039325734
7922 7921 8079.345222788619861783739
7923 7922 8080.039511695499972681208
7924 7923 8080.371623669992276647255
7925 7924 8082.095848368999901692341
7926 7925 8082.727357334070038877724
7927 7926 8083.188121262285369971598
7928 7927 8084.353898815797597108728
7929 7928 8084.627810373944182403779
7930 7929 8086.389367184023677644301
7931 7930 8087.201332969661035532931
7932 7931 8087.989215922948171407924
7933 7932 8089.000277331536377836027
7934 7933 8090.011702435148623504163
7935 7934 8090.302075183276961722147
7936 7935 8091.013047475937122580565
7937 7936 8092.013186019190436365144
7938 7937 8093.056821600834072127895
7939 7938 8093.960796848973932362984
7940 7939 8095.226429752914992412328
7941 7940 8095.644649780624686746565
7942 7941 8096.881209450584837137155
7943 7942 8097.422804533747450727339
7944 7943 8098.601451658408618468085
7945 7944 8099.483713019982450112003
7946 7945 8100.033954898179982679622
7947 7946 8100.893317320693282346662
7948 7947 8101.847479883354213883924
7949 7948 8102.65289191743553823016
7950 7949 8103.081247385376049424078
7951 7950 8104.959580645941506927046
7952 7951 8106.001082599120794884226
7953 7952 8106.472478547109457759496
7954 7953 8106.981007272883090767062
7955 7954 8107.990030625679523500038
7956 7955 8108.858614987058085842499
7957 7956 8109.690218971911536724344
7958 7957 8110.637684029407507005112
7959 7958 8111.447479981097813545813
7960 7959 8112.264753495158791811725
7961 7960 8113.552643128010852877073
7962 7961 8114.16701984227215995518
7963 7962 8115.107358482817713029729
7964 7963 8116.251266964432260604541
7965 7964 8116.864424633298153198613
7966 7965 8118.004737871154121547012
7967 7966 8118.43737965319485833874
7968 7967 8119.287139450122608390584
7969 7968 8119.648862098551167680007
7970 7969 8121.226751668284966091962
7971 7970 8122.361423445455769205247
7972 7971 8123.010669984642826118741
7973 7972 8124.184278678352577776194
7974 7973 8124.843587425550850858001
7975 7974 8125.501626937460130360009
7976 7975 8126.529528436144386712205
7977 7976 8126.964551002275042778092
7978 7977 8128.592208780040464648507
7979 7978 8129.097632570099489250441
7980 7979 8129.501991536929023981852
7981 7980 8130.717735754437812812859
7982 7981 8131.714724491744096803991
7983 7982 8132.854767682930931738028
7984 7983 8133.952804659217480537415
7985 7984 8134.457140991120848305144
7986 7985 8135.253151706349794282827
7987 7986 8135.925988506041781701053
7988 7987 8136.958578382118043982147
7989 7988 8137.609942436052420398631
7990 7989 8138.43742927139136992684
7991 7990 8139.566538052355662706629
7992 7991 8140.950740591125937019127
7993 7992 8141.595750010060813512559
7994 7993 8142.276001937051921153607
7995 7994 8142.810496643743365341684
7996 7995 8144.358563539670256149425
7997 7996 8144.9262960783309285365
7998 7997 8145.927384407723426540296
7999 7998 8146.251283810104282264346
8000 7999 8147.375558663971466791501
8001 8000 8148.18840580462703496463

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