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 18 of 20 · 500/page · 10000 rows next →
# ngamma_n
8502 8501 8586.174833980533668991515
8503 8502 8587.197320926821737333409
8504 8503 8587.711288194941381826795
8505 8504 8588.094852601426590542691
8506 8505 8589.642476710266856486679
8507 8506 8590.127188416552788113236
8508 8507 8591.095567302459157727942
8509 8508 8591.803792343194415477841
8510 8509 8592.920901773499226052067
8511 8510 8594.055748658848465207026
8512 8511 8594.502062461294598229088
8513 8512 8595.550909469975511926956
8514 8513 8596.787241215077648903078
8515 8514 8597.384498850856617999587
8516 8515 8598.230072427937032366424
8517 8516 8599.006813111067075222104
8518 8517 8599.43178075870283606843
8519 8518 8600.495518301921980741334
8520 8519 8601.336163043638633788771
8521 8520 8602.800930632691458477774
8522 8521 8603.667158055496895345609
8523 8522 8604.204875745890528331936
8524 8523 8605.372037845811725810056
8525 8524 8606.065011944545916051325
8526 8525 8606.596847047910688729535
8527 8526 8607.469584159035841879654
8528 8527 8608.874054411912248821326
8529 8528 8609.476576483578544932939
8530 8529 8609.969946522661496558924
8531 8530 8610.900549174502022830779
8532 8531 8612.007241031537611021218
8533 8532 8613.349092570395605634283
8534 8533 8614.153530621093824816321
8535 8534 8614.57029761756004650414
8536 8535 8615.778990895758609920293
8537 8536 8616.334145127392525376319
8538 8537 8617.170423146717128200191
8539 8538 8617.682388007682137464667
8540 8539 8619.004610240153774105226
8541 8540 8619.610075256379934139299
8542 8541 8621.154330974113819210603
8543 8542 8621.952650157469247368311
8544 8543 8622.390314620142683427461
8545 8544 8623.284603669737179107102
8546 8545 8624.220096516319813496936
8547 8546 8625.481069982619450450768
8548 8547 8626.016582944009118746301
8549 8548 8626.570046898995809738059
8550 8549 8627.469440409708977566912
8551 8550 8628.431748372703441159775
8552 8551 8629.276843947526357938334
8553 8552 8630.330799696212246180088
8554 8553 8631.669465392838525246359
8555 8554 8632.398793410632181384147
8556 8555 8633.071914191365516477178
8557 8556 8633.591393342439908059439
8558 8557 8634.592755997274215962281
8559 8558 8635.206921731365036581573
8560 8559 8636.439865707612872104055
8561 8560 8637.1875639779814713208
8562 8561 8638.150805591881143470845
8563 8562 8638.929026205097093222354
8564 8563 8640.056739782064793261943
8565 8564 8640.930858833448140761311
8566 8565 8641.656960761905713825388
8567 8566 8642.643422719740661532975
8568 8567 8643.454487335060944690911
8569 8568 8644.166494252547647034591
8570 8569 8645.314890920888252582431
8571 8570 8645.629539138185800981983
8572 8571 8646.021671929313987896734
8573 8572 8648.18081766283947655849
8574 8573 8648.77461921736461691769
8575 8574 8649.780880842649050133477
8576 8575 8650.239461088615569009728
8577 8576 8651.375577780704800869608
8578 8577 8651.868483746335696647119
8579 8578 8652.861534419747976013473
8580 8579 8653.778576965077016382984
8581 8580 8654.501099440599020156164
8582 8581 8655.647399977164854231117
8583 8582 8656.072710341726166942228
8584 8583 8657.338800754277679807782
8585 8584 8658.222107503617528895739
8586 8585 8659.065463815270048610724
8587 8586 8660.46474977156631387138
8588 8587 8660.894985317800270606138
8589 8588 8661.469178733336303502783
8590 8589 8662.186065276713702129767
8591 8590 8663.160874844049215796925
8592 8591 8664.068204986472034843714
8593 8592 8664.933277766944935086721
8594 8593 8666.008296742532465974287
8595 8594 8667.232034709075928372203
8596 8595 8668.106266273988023547774
8597 8596 8668.375532887167894349459
8598 8597 8669.317504225814583122011
8599 8598 8670.23344619597444850019
8600 8599 8671.639127701579314712109
8601 8600 8671.820091555089658015681
8602 8601 8672.776806951548569348485
8603 8602 8673.52400609966831588003
8604 8603 8674.349201864056716653976
8605 8604 8675.596120099391587800815
8606 8605 8676.924281050593611824652
8607 8606 8677.519367827768467892934
8608 8607 8677.987746530281043470666
8609 8608 8679.2912781675860518566
8610 8609 8679.748657452122818431851
8611 8610 8680.584051407366986146981
8612 8611 8681.1618527791278706281
8613 8612 8682.385865916402384409108
8614 8613 8683.501223958029974366714
8615 8614 8684.345138141240288802778
8616 8615 8685.162576754764636532922
8617 8616 8685.79125988764525002053
8618 8617 8687.189699001746549521208
8619 8618 8687.777364110731457960296
8620 8619 8688.479057296975966864935
8621 8620 8689.551335129889538657011
8622 8621 8690.364817869790048317816
8623 8622 8690.6627976218338323751
8624 8623 8691.926226852759385957746
8625 8624 8692.523178293996199693502
8626 8625 8694.22841329489668388922
8627 8626 8694.902289443240436726808
8628 8627 8695.905093298259063625925
8629 8628 8696.258314852631880784444
8630 8629 8697.336511435268324186633
8631 8630 8697.610485681203415513471
8632 8631 8699.091219709500372577405
8633 8632 8699.936426457792994510552
8634 8633 8700.597521996259530546198
8635 8634 8701.161157565172230719786
8636 8635 8702.804254878287637675742
8637 8636 8703.417101021721669858631
8638 8637 8704.079332236731519026756
8639 8638 8705.318810428644875356006
8640 8639 8706.154650750803758987324
8641 8640 8707.005236581809291449171
8642 8641 8707.5975377009926657663
8643 8642 8708.113872195475842782983
8644 8643 8709.159693738630769342999
8645 8644 8709.949365152497698100619
8646 8645 8711.450294477422287317974
8647 8646 8712.275399475056358357528
8648 8647 8712.986720708001713061842
8649 8648 8714.030953900324142611547
8650 8649 8714.366502800913369918925
8651 8650 8715.585779950790129471261
8652 8651 8716.356426967991882737448
8653 8652 8717.003515227570737949618
8654 8653 8718.139853934953068558341
8655 8654 8719.090250677110978803681
8656 8655 8719.382554052767388451247
8657 8656 8720.447893299267370577825
8658 8657 8721.974942171497696243775
8659 8658 8722.755721398910324617992
8660 8659 8723.599098642280823025094
8661 8660 8724.108198074102960785455
8662 8661 8724.859676038092909913362
8663 8662 8725.956761584510106530825
8664 8663 8726.536842209521757729354
8665 8664 8727.253773684011104150697
8666 8665 8728.498800855315496974763
8667 8666 8729.628006989616057122308
8668 8667 8730.322892932990791072258
8669 8668 8731.474828184224395040947
8670 8669 8731.879802245324145242802
8671 8670 8732.623377538742182321915
8672 8671 8734.081398172941293166019
8673 8672 8734.67597383762252041204
8674 8673 8735.414586540170012956236
8675 8674 8736.080091411661290482801
8676 8675 8736.767658872634673507253
8677 8676 8737.886599701183484184929
8678 8677 8739.389508169814924013408
8679 8678 8739.714814518672152567579
8680 8679 8741.112495669393206326316
8681 8680 8741.683325895485824972797
8682 8681 8742.525510714970622129806
8683 8682 8742.997118093943360514002
8684 8683 8743.749048929480875055079
8685 8684 8745.053827139448503981783
8686 8685 8745.977161412504961572587
8687 8686 8746.443532495898885210093
8688 8687 8747.807308511779387860014
8689 8688 8748.384570855762560983081
8690 8689 8749.516423498661864181289
8691 8690 8750.330086645507356482086
8692 8691 8751.346430863811246003483
8693 8692 8751.999141009404108491891
8694 8693 8752.672763590087639620431
8695 8694 8753.775489788955153691308
8696 8695 8754.258907091737137855826
8697 8696 8755.009176121686840563627
8698 8697 8756.043831127347752253011
8699 8698 8757.903052120734428920843
8700 8699 8758.330109659318105603977
8701 8700 8758.806686423187321115125
8702 8701 8759.591981369532712845894
8703 8702 8760.797760691636335434518
8704 8703 8761.335651596278293465143
8705 8704 8762.328890282305019514654
8706 8705 8763.396469367102853855121
8707 8706 8763.65568619653868607999
8708 8707 8765.005865643435078383136
8709 8708 8765.741131577497227680435
8710 8709 8766.709274467539369267449
8711 8710 8767.797892850313404881195
8712 8711 8768.800400513366447696153
8713 8712 8769.371308012005626333728
8714 8713 8770.321068743479807449673
8715 8714 8771.029690955945140575811
8716 8715 8771.396367344524878341164
8717 8716 8772.413788998578383216526
8718 8717 8773.892563781475701994497
8719 8718 8774.336921665971815945041
8720 8719 8775.643665408925794870778
8721 8720 8776.412826980881843223693
8722 8721 8777.325477640991659500777
8723 8722 8778.016754195504789354917
8724 8723 8778.547501528247385489687
8725 8724 8779.8741523887632573444
8726 8725 8780.751048629249397384914
8727 8726 8781.399843069603514993677
8728 8727 8781.9994052502774193506
8729 8728 8782.763532846501363551399
8730 8729 8784.098180392591149244787
8731 8730 8785.349005620332959618673
8732 8731 8786.00141691975628395221
8733 8732 8786.925723642419197367222
8734 8733 8787.516533268482195797206
8735 8734 8788.234123962098932096866
8736 8735 8789.166704652085687213216
8737 8736 8790.055912968536284167278
8738 8737 8790.605373030883330934294
8739 8738 8791.865750060681725324933
8740 8739 8792.938115377125229082059
8741 8740 8793.748087605066687591991
8742 8741 8794.528210802315138089214
8743 8742 8795.102194578155570632212
8744 8743 8796.605348615251661649195
8745 8744 8797.281339330112661354796
8746 8745 8797.933469184164447529452
8747 8746 8798.459711536960882729079
8748 8747 8799.627566551526610320826
8749 8748 8800.402790797840229564941
8750 8749 8800.875335740939230151319
8751 8750 8802.633957952015665958889
8752 8751 8803.428243939236988303408
8753 8752 8804.22047221177318240861
8754 8753 8805.171186874198767399454
8755 8754 8805.59943536121063387809
8756 8755 8806.272540598552031899825
8757 8756 8807.488748833904883608815
8758 8757 8808.223313837878909651036
8759 8758 8809.413500175125344460322
8760 8759 8809.849477655007640265396
8761 8760 8810.602647387452933518651
8762 8761 8812.167774579549333789786
8763 8762 8812.725714811277436889509
8764 8763 8813.832162750636111742443
8765 8764 8814.311277665617166023673
8766 8765 8815.594893298596956367044
8767 8766 8816.333686040035957701066
8768 8767 8816.597902424007409803857
8769 8768 8817.604528338501310707802
8770 8769 8818.267042195531471785722
8771 8770 8819.823257463868956357835
8772 8771 8820.831983668506778243475
8773 8772 8821.428062324346722865429
8774 8773 8822.438231460547211904234
8775 8774 8822.982439195979790986712
8776 8775 8823.926324358185329465569
8777 8776 8824.821596600019523162479
8778 8777 8825.747064035054366113909
8779 8778 8826.471286823933534627177
8780 8779 8827.196344367449082294493
8781 8780 8828.126900136692825921441
8782 8781 8829.200853015417252819216
8783 8782 8829.757344107926561903989
8784 8783 8831.476274008274766487839
8785 8784 8832.095903441104232179842
8786 8785 8832.667733534361647811138
8787 8786 8833.35327270149431812005
8788 8787 8834.227333953716411790717
8789 8788 8834.898748526264062242069
8790 8789 8836.17494085791120591842
8791 8790 8836.623445374283525932672
8792 8791 8837.776447826209379000424
8793 8792 8839.103878636088430892113
8794 8793 8839.786452488945126456462
8795 8794 8840.183848849725310313899
8796 8795 8841.401930089409609111401
8797 8796 8842.186429293527121826327
8798 8797 8843.085298044888016940182
8799 8798 8844.209896066892286538348
8800 8799 8844.421280321555637580112
8801 8800 8845.399046170998185773115
8802 8801 8845.929067541601412536698
8803 8802 8847.529970809929198768397
8804 8803 8848.664758577926727477571
8805 8804 8849.293012163449703602591
8806 8805 8849.940859439543466812407
8807 8806 8850.968666279146486974321
8808 8807 8851.906343481166847184375
8809 8808 8852.149291308352437852651
8810 8809 8853.023070043142120371006
8811 8810 8854.558251386009148591367
8812 8811 8854.955551217050240362989
8813 8812 8856.079945291803025917419
8814 8813 8856.734523784161357420081
8815 8814 8857.963064805150935566996
8816 8815 8858.68099970813457513663
8817 8816 8859.693494672751923983222
8818 8817 8860.675496388900654729728
8819 8818 8861.046695268195078373933
8820 8819 8861.974859877250256321705
8821 8820 8862.808651073864113249399
8822 8821 8863.498357024211909492973
8823 8822 8864.378003968137747452768
8824 8823 8865.753819372408404115329
8825 8824 8866.791201368247230796931
8826 8825 8867.753787139255720786907
8827 8826 8868.092270036928155565948
8828 8827 8868.75096701518982243561
8829 8828 8869.691904788887035554266
8830 8829 8871.078180954406691569057
8831 8830 8871.689920885597672879323
8832 8831 8872.005432888385909902525
8833 8832 8873.297980868782522842984
8834 8833 8874.05005955138329855374
8835 8834 8875.172814314834318134868
8836 8835 8876.122838582175634684355
8837 8836 8876.890060628395981326359
8838 8837 8878.289574606814470285212
8839 8838 8878.480878109605737402361
8840 8839 8879.175609722502917093851
8841 8840 8880.343782096937282167862
8842 8841 8880.621668525396801359532
8843 8842 8881.726078190097949235646
8844 8843 8883.028741255179268274437
8845 8844 8884.165749604954081783332
8846 8845 8884.44668481487635157982
8847 8846 8885.602305364961861086122
8848 8847 8886.584181468503876512206
8849 8848 8887.058666340970962168797
8850 8849 8888.146956750708001597798
8851 8850 8888.831196779794475279072
8852 8851 8889.952996222665022359977
8853 8852 8890.537948368927836879596
8854 8853 8891.306737048091651396542
8855 8854 8891.874379356850020437504
8856 8855 8893.684840402352219777146
8857 8856 8894.604473093549139784006
8858 8857 8895.038202753997834853759
8859 8858 8896.10333681467074907682
8860 8859 8896.531323011318855433233
8861 8860 8897.673494065038797394147
8862 8861 8898.051507139095594674401
8863 8862 8899.30272446675868684711
8864 8863 8900.126946770479597563591
8865 8864 8900.854875977542358347717
8866 8865 8902.243765061542524089743
8867 8866 8903.054487161955441680698
8868 8867 8903.453422784505289911557
8869 8868 8904.497639306033068279848
8870 8869 8905.780057620077928567706
8871 8870 8906.334722625173358908636
8872 8871 8907.296439179869511846614
8873 8872 8907.620487927697502619123
8874 8873 8908.36586537200584680613
8875 8874 8909.714669787566048964019
8876 8875 8910.428989513738110859914
8877 8876 8911.756517260450521109869
8878 8877 8912.717343387955125039
8879 8878 8913.324972960765926911973
8880 8879 8914.111116780208331610461
8881 8880 8914.74118891225678722775
8882 8881 8915.623803671877804757046
8883 8882 8916.514178386545970279611
8884 8883 8917.678078159365577377732
8885 8884 8918.302168643903079036914
8886 8885 8918.917303083197480829294
8887 8886 8920.276287088843634400806
8888 8887 8920.80742492218118942049
8889 8888 8922.348329236662804980094
8890 8889 8922.962986121956534194663
8891 8890 8923.430369163904403644862
8892 8891 8924.452124840513384338708
8893 8892 8925.469534407589616037092
8894 8893 8925.913861820413822708693
8895 8894 8926.590671425493037841121
8896 8895 8927.543910280876006079102
8897 8896 8929.299323788705503870221
8898 8897 8929.808678924302886385539
8899 8898 8930.622184355024661498746
8900 8899 8931.360853742507463579383
8901 8900 8932.151532174342940739009
8902 8901 8933.161556855912995048766
8903 8902 8934.023589735781740222222
8904 8903 8934.74992530420177662938
8905 8904 8935.684604088346890842616
8906 8905 8936.253765070299399268383
8907 8906 8937.198156762437285575552
8908 8907 8938.346035492338352974861
8909 8908 8939.308181977247095673938
8910 8909 8940.290249827749770673001
8911 8910 8941.181572192283041262726
8912 8911 8942.047712429560052425963
8913 8912 8942.474071166487198040078
8914 8913 8942.901797183500399094834
8915 8914 8944.315501548008499892746
8916 8915 8945.056384872775316462192
8917 8916 8946.156952171697228499032
8918 8917 8946.789546432198553218602
8919 8918 8948.094866137137389506747
8920 8919 8948.87120307062221031162
8921 8920 8949.659174962521571370305
8922 8921 8950.0854384002341388444
8923 8922 8951.679585354738922941364
8924 8923 8952.132146366208646099193
8925 8924 8952.910570342162962489463
8926 8925 8953.663140523775190024782
8927 8926 8954.570266105707671412223
8928 8927 8955.021105983401590252845
8929 8928 8956.904086111224953458619
8930 8929 8957.719764459237791405785
8931 8930 8958.329612995061536035997
8932 8931 8959.083915903632603206066
8933 8932 8959.872529807257329457352
8934 8933 8960.757465936536756232333
8935 8934 8961.514277567270474738063
8936 8935 8962.376098409866840853754
8937 8936 8963.122595274161987619792
8938 8937 8964.501768867298787109665
8939 8938 8965.042322647060672121376
8940 8939 8965.909132690284015514901
8941 8940 8966.831852556912604958364
8942 8941 8968.083142598414282227276
8943 8942 8968.730830804888504979079
8944 8943 8969.57681339618263230197
8945 8944 8970.156460463083816442472
8946 8945 8971.008144511877467694452
8947 8946 8971.900341569523499027097
8948 8947 8972.398475358717187488871
8949 8948 8973.827888982770443115767
8950 8949 8974.779544770535592942072
8951 8950 8976.046813314545330288591
8952 8951 8976.339748017881237820865
8953 8952 8977.2677544702004656844
8954 8953 8978.139157900688046782831
8955 8954 8978.484856067782113705753
8956 8955 8980.105035039646564611862
8957 8956 8980.789975094998406875294
8958 8957 8981.364598450198000810307
8959 8958 8981.89380943289831191117
8960 8959 8983.298016881797080137759
8961 8960 8984.458470334755464355738
8962 8961 8984.976927663606188003039
8963 8962 8986.278143617257282958907
8964 8963 8986.765638638711482360954
8965 8964 8987.708763258454636653057
8966 8965 8988.513243868865349972449
8967 8966 8988.936179401069330609857
8968 8967 8989.737246620055605535527
8969 8968 8991.143647230733466598451
8970 8969 8991.84722246737151257061
8971 8970 8993.206522747888852386381
8972 8971 8993.843872416932860988176
8973 8972 8994.285296828882229077912
8974 8973 8995.438088516588276240106
8975 8974 8996.520060324059560272131
8976 8975 8997.025737752289599703966
8977 8976 8997.967571698080122847819
8978 8977 8998.648899442072681964737
8979 8978 8999.718728031784151473714
8980 8979 9000.243406943077335897715
8981 8980 9001.129405308298347687313
8982 8981 9002.623776992958244489569
8983 8982 9003.873677515279593387456
8984 8983 9004.052178244030414599696
8985 8984 9004.805111170249659680137
8986 8985 9005.606797077049685791851
8987 8986 9006.565630589181730613129
8988 8987 9007.260756057401045868843
8989 8988 9008.30470303777084874239
8990 8989 9009.070075285330438544866
8991 8990 9010.088962863381942404828
8992 8991 9011.033504193105030899378
8993 8992 9012.042284016974949088599
8994 8993 9012.644453437732441117009
8995 8994 9013.551021066800608085122
8996 8995 9014.565229679207605635239
8997 8996 9015.596687046418618706738
8998 8997 9015.977933055108684471629
8999 8998 9016.814019972604859566238
9000 8999 9017.3451601937728672926
9001 9000 9018.424475610377882564574

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