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 10 of 20 · 500/page · 10000 rows next →
# ngamma_n
4502 4501 4981.192703747710832641896
4503 4502 4982.512361526238627250862
4504 4503 4983.225027314619665334359
4505 4504 4983.979975829911587946726
4506 4505 4984.568543574519193796861
4507 4506 4986.252566835805268933186
4508 4507 4987.187900982755099012238
4509 4508 4988.19159730757435224204
4510 4509 4988.905166592147155553944
4511 4510 4990.345480286356102947603
4512 4511 4990.449701819016886674014
4513 4512 4991.214774408587082742057
4514 4513 4992.379462341421509393227
4515 4514 4993.495748983814606326373
4516 4515 4994.632742172267628213003
4517 4516 4995.879247704658085703275
4518 4517 4996.220820876864221072863
4519 4518 4997.396150707099834388129
4520 4519 4998.370030195671724560514
4521 4520 4999.329681372973090286407
4522 4521 5000.234316931327815845953
4523 4522 5000.834381432412614331076
4524 4523 5001.889773627192102742173
4525 4524 5002.854002891858256483593
4526 4525 5003.484944378312056018388
4527 4526 5005.495907487708251259021
4528 4527 5006.208381106211305894085
4529 4528 5006.788558806100997050523
4530 4529 5007.485982919851298144741
4531 4530 5008.626199656301915374882
4532 4531 5009.229044117222127631859
4533 4532 5010.811172544728761737386
4534 4533 5010.933198106039916088105
4535 4534 5012.396833739677234080991
4536 4535 5013.533605873148409157786
4537 4536 5014.238442056197719765854
4538 4537 5015.357927937939055490421
4539 4538 5016.192546914328135856651
4540 4539 5017.347756568168352434418
4541 4540 5018.084913547670188091081
4542 4541 5018.939831850465569235098
4543 4542 5019.395831473357619649812
4544 4543 5020.352759395483800806468
4545 4544 5022.203022983779874048569
4546 4545 5022.83452601918762202689
4547 4546 5023.904889141232344920039
4548 4547 5024.725752594867625769187
4549 4548 5025.730993593627878738209
4550 4549 5026.185476882352389189474
4551 4550 5027.221563711044324028307
4552 4551 5028.537886820898086272947
4553 4552 5029.216956939054499844591
4554 4553 5030.026936938536285427317
4555 4554 5030.967858186768958408658
4556 4555 5032.399063540915597539448
4557 4556 5033.16656608019975230645
4558 4557 5034.55036116301487664135
4559 4558 5035.013416408851633113892
4560 4559 5035.523058437430792138458
4561 4560 5036.841667107008453926243
4562 4561 5037.500692756887328126977
4563 4562 5038.324319636722802211465
4564 4563 5039.621887452849045080755
4565 4564 5041.041398993811192503494
4566 4565 5041.798034522457411666272
4567 4566 5042.492149716432382488506
4568 4567 5043.015445393966784867452
4569 4568 5044.656791091315078687114
4570 4569 5045.467130480166402850172
4571 4570 5045.941675502013132495971
4572 4571 5046.997617430009722499703
4573 4572 5047.863086184184779148111
4574 4573 5048.79022881972789416993
4575 4574 5050.308459699165668823025
4576 4575 5051.106699533685813490309
4577 4576 5052.279310472945103306488
4578 4577 5052.772155289672452262971
4579 4578 5053.712365319994519914145
4580 4579 5054.434547343369218920681
4581 4580 5055.19267247344323621871
4582 4581 5056.605813079880107721529
4583 4582 5057.589996235894704492089
4584 4583 5058.345409417078256418311
4585 4584 5059.439905818898518353158
4586 4585 5060.559080915019847258848
4587 4586 5061.326249329028331170356
4588 4587 5062.168472726690551121505
4589 4588 5063.182715937442192536333
4590 4589 5064.333813619172168378195
4591 4590 5064.628972968499205193106
4592 4591 5065.480124960543736393594
4593 4592 5066.57653918477886179879
4594 4593 5068.384815238836570255839
4595 4594 5069.09593594400752176707
4596 4595 5069.675544138524998279367
4597 4596 5070.86855126587538798996
4598 4597 5071.249797277137878964435
4599 4598 5072.410372660585291979816
4600 4599 5073.482256176993653119259
4601 4600 5074.356062041533516112903
4602 4601 5074.911470242946296834329
4603 4602 5076.598637947780646833056
4604 4603 5077.152989530737561257074
4605 4604 5078.001109183258438527889
4606 4605 5079.612726167140650950623
4607 4606 5080.123622144013806408359
4608 4607 5081.130097770619830517151
4609 4608 5081.694344429823108318472
4610 4609 5082.317781511685491549822
4611 4610 5083.769848918959806580224
4612 4611 5084.387439340744401276635
4613 4612 5085.944230786496559105842
4614 4613 5086.999761578075610576651
4615 4614 5087.53266893775924009762
4616 4615 5088.59890132201195368364
4617 4616 5089.178093913298069969006
4618 4617 5090.34587681155812047742
4619 4618 5091.262957883617969247909
4620 4619 5092.401941911388292989279
4621 4620 5092.837760452182251827646
4622 4621 5093.668880110625700741351
4623 4622 5095.086913061577273615363
4624 4623 5096.637933186210115848005
4625 4624 5096.959423856328942127213
4626 4625 5097.814429758905662099625
4627 4626 5098.956789006186162756041
4628 4627 5099.610743037994417965476
4629 4628 5100.491462416199868888955
4630 4629 5101.034063048501080097854
4631 4630 5102.645948615172030075384
4632 4631 5103.728341253025249208579
4633 4632 5104.418093046759452291534
4634 4633 5105.638635526429025863648
4635 4634 5106.052225949797688689157
4636 4635 5107.385740123910646358994
4637 4636 5108.447770149330523551056
4638 4637 5108.959096698433068087661
4639 4638 5109.838982090977290990274
4640 4639 5110.806041672267145060609
4641 4640 5111.503124654462063026616
4642 4641 5113.01015722172519923225
4643 4642 5113.946042880454384678775
4644 4643 5115.372842952989609526448
4645 4644 5115.726762097795616183894
4646 4645 5116.560557463714867068723
4647 4646 5117.025993413477693458934
4648 4647 5118.533838768627424994377
4649 4648 5119.365669161571294682257
4650 4649 5120.240023466489858091601
4651 4650 5121.083490155638517328988
4652 4651 5122.454781409748932337491
4653 4652 5123.302893477929983004887
4654 4653 5124.061784988072757051829
4655 4654 5125.253686756768291331899
4656 4655 5126.279118015171371214087
4657 4656 5126.7299932917837646295
4658 4657 5127.741716959095506530271
4659 4658 5128.681624974387486933324
4660 4659 5128.964483858673426250984
4661 4660 5131.043898973589796381438
4662 4661 5132.007167837768660047417
4663 4662 5132.683137054001938141456
4664 4663 5133.306575989659824481933
4665 4664 5134.663043878822156243088
4666 4665 5135.171964073656003916245
4667 4666 5136.129936082095095041325
4668 4667 5137.206291398494659305963
4669 4668 5138.042957957294814228472
4670 4669 5139.12153096212012792437
4671 4670 5139.679125649692981793229
4672 4671 5141.096623935637952248122
4673 4672 5142.447907864871204579547
4674 4673 5142.902032222719679590237
4675 4674 5143.933700533922096768827
4676 4675 5144.587752601527890411695
4677 4676 5145.480449174140746483558
4678 4677 5146.149645919570475006988
4679 4678 5147.562791840009665020003
4680 4679 5148.253527357285335924559
4681 4680 5149.768260280787071307714
4682 4681 5150.709614962306254269504
4683 4682 5151.141849586537944718563
4684 4683 5152.186214623064310686374
4685 4684 5152.95312729470274756821
4686 4685 5154.656845439167194142252
4687 4686 5154.899143797593817567906
4688 4687 5155.493362582533331295993
4689 4688 5156.509447328251626335596
4690 4689 5157.819065555745591696221
4691 4690 5158.954824000827013148292
4692 4691 5160.057736251625052802006
4693 4692 5160.852779927914940710523
4694 4693 5161.605392922148715681082
4695 4694 5162.587186685206547310626
4696 4695 5163.060164468373098306138
4697 4696 5164.102312022032839919196
4698 4697 5165.306771505407776619083
4699 4698 5166.191972908493194078952
4700 4699 5167.483594402169787732355
4701 4700 5167.990828057263121705349
4702 4701 5169.070194564031900180282
4703 4702 5170.291516087272926588443
4704 4703 5171.235927501473585934943
4705 4704 5171.585481171242232963364
4706 4705 5172.801688876791558194468
4707 4706 5173.675024556315321053306
4708 4707 5174.359901137178414315558
4709 4708 5175.093122777010638591376
4710 4709 5177.23713224938115439813
4711 4710 5177.609630022530782334817
4712 4711 5178.752194620450083267493
4713 4712 5179.202606391488615074237
4714 4713 5180.106626202653647771617
4715 4714 5181.189792408520290618047
4716 4715 5182.130914016585829116263
4717 4716 5182.998826329179209128522
4718 4717 5183.95030701323823533801
4719 4718 5184.685795032389032660979
4720 4719 5186.355746810168784938796
4721 4720 5186.709472600945588774217
4722 4721 5187.887847767473078600916
4723 4722 5189.076719613567148930016
4724 4723 5189.859588661657877412449
4725 4724 5190.355291128359821379847
4726 4725 5191.126801598029861976591
4727 4726 5192.046486955980150351052
4728 4727 5193.404415343728237540989
4729 4728 5194.707488901574489027614
4730 4729 5195.159163853735983902007
4731 4730 5196.707324197993591792984
4732 4731 5197.117498331677797398348
4733 4732 5197.718324176152350107921
4734 4733 5199.223858199089145806742
4735 4734 5199.776329229934362690368
4736 4735 5200.961311213041449357708
4737 4736 5201.555843874248731917879
4738 4737 5202.457989722174338484814
4739 4738 5203.521216949646943921184
4740 4739 5205.099606994962291136136
4741 4740 5205.900595704827940998234
4742 4741 5206.633161678679178450654
4743 4742 5207.215066682223930204957
4744 4743 5208.288522939907664344392
4745 4744 5209.13823930166559828317
4746 4745 5210.010911048566907380841
4747 4746 5210.808218699839701125772
4748 4747 5212.419404469541874645345
4749 4748 5213.316674242103039183577
4750 4749 5213.896943192008384233391
4751 4750 5214.775252559325230552122
4752 4751 5216.054491352254741806104
4753 4752 5216.932009341216547414415
4754 4753 5217.650795320354484685444
4755 4754 5218.691413008385234350575
4756 4755 5219.057877220099204326042
4757 4756 5220.220855174182011999665
4758 4757 5221.422951323059394562764
4759 4758 5222.858787673092249084269
4760 4759 5223.43442893776441651125
4761 4760 5224.457463495684488782811
4762 4761 5225.256065096585147125983
4763 4762 5226.148424105465283508371
4764 4763 5226.351540382446588332962
4765 4764 5228.183098672056617813016
4766 4765 5229.198557199220350758552
4767 4766 5229.241811258999048090136
4768 4767 5230.897209709423758636958
4769 4768 5231.815083588342978895645
4770 4769 5232.884620192417921202451
4771 4770 5233.658115095419190148738
4772 4771 5234.640289888718683602617
4773 4772 5235.57473516603345251441
4774 4773 5236.300461229102020424053
4775 4774 5236.957439364859299854674
4776 4775 5237.801695401995093000054
4777 4776 5239.192789208160858222262
4778 4777 5240.607636041085598135217
4779 4778 5241.502825459770520995767
4780 4779 5241.822720416351958467031
4781 4780 5242.792985388688308660445
4782 4781 5243.882548868623914348204
4783 4782 5244.845451001427876341324
4784 4783 5245.755732517577688582732
4785 4784 5246.279250856914455853221
4786 4785 5247.610320391933150497428
4787 4786 5248.44153901607535534375
4788 4787 5249.366336131659808682484
4789 4788 5250.675238104248727528674
4790 4789 5251.798558626512278738006
4791 4790 5252.522037866706190527712
4792 4791 5252.890575148449676202778
4793 4792 5253.944070491726712801254
4794 4793 5254.912630870913019883399
4795 4794 5255.613164303761636458112
4796 4795 5257.081180064535814839094
4797 4796 5257.924941007523623475134
4798 4797 5259.108320960425698728941
4799 4798 5259.771904521843154423047
4800 4799 5260.959190246010196544703
4801 4800 5261.180476047183218312517
4802 4801 5262.848835686331714595108
4803 4802 5263.39696510167781375444
4804 4803 5264.411378017649577121512
4805 4804 5265.088374535057779128517
4806 4805 5265.605936327469949975304
4807 4806 5267.885364151472454248547
4808 4807 5268.198270777970710374255
4809 4808 5269.201393021088832644674
4810 4809 5270.259454504893143448342
4811 4810 5270.886227525980259449627
4812 4811 5271.696969115179243939555
4813 4812 5272.51796036003330646543
4814 4813 5273.578737968436974991708
4815 4814 5274.691509015373242710004
4816 4815 5275.643878877955565252092
4817 4816 5276.683503025369402139914
4818 4817 5277.475759502642438202314
4819 4818 5278.379390382477423818759
4820 4819 5279.775667717842231453478
4821 4820 5280.315445981201706762885
4822 4821 5281.239950686326654408521
4823 4822 5281.633380065803255970206
4824 4823 5283.163868559922222479764
4825 4824 5283.478719186035010837354
4826 4825 5284.926926629153060666566
4827 4826 5286.437161557581821254061
4828 4827 5287.137482205340801281763
4829 4828 5287.711380226104619519508
4830 4829 5288.515549597786830232249
4831 4830 5289.353245221510542055885
4832 4831 5290.674974347994516346316
4833 4832 5291.399590509319293167125
4834 4833 5292.275016391077825548794
4835 4834 5293.024355514839242709732
4836 4835 5294.464760714006737214288
4837 4836 5295.126355475198738560168
4838 4837 5296.581056719181438210923
4839 4838 5297.125394919595072527415
4840 4839 5297.981183439350916043514
4841 4840 5299.274679237929758347216
4842 4841 5299.627300319932980495217
4843 4842 5300.144736871138323253496
4844 4843 5301.458131809212704797545
4845 4844 5302.981454220329492734765
4846 4845 5303.885255545878519478468
4847 4846 5304.508457854940300320774
4848 4847 5305.526333012086415830559
4849 4848 5306.498769767441890959535
4850 4849 5307.300388636241972362185
4851 4850 5308.072790499981746545377
4852 4851 5309.361753481891643254814
4853 4852 5310.03276472699836201928
4854 4853 5310.606801112027837806153
4855 4854 5311.859049891718092976299
4856 4855 5312.980209158523011855579
4857 4856 5314.439426791834597276318
4858 4857 5314.954794049511502950115
4859 4858 5315.726296859325166773651
4860 4859 5316.639253906217356670236
4861 4860 5317.139734905883567713067
4862 4861 5318.44524095923063129298
4863 4862 5319.364734297887860430016
4864 4863 5320.10975301028394956275
4865 4864 5321.536694997694722439123
4866 4865 5322.633280584938644929665
4867 4866 5323.137231112140493956401
4868 4867 5323.796327875688757786689
4869 4868 5325.466411142999958056247
4870 4869 5326.038512792133092053912
4871 4870 5326.867763789801584594914
4872 4871 5327.480222283036371053168
4873 4872 5328.463844665270486815936
4874 4873 5329.377158593330007126806
4875 4874 5331.015051848383100098796
4876 4875 5331.855033782666971768769
4877 4876 5332.582449338871892253253
4878 4877 5333.746349452669544201375
4879 4878 5334.061217957371564856829
4880 4879 5335.195388351516317344863
4881 4880 5335.947926227236176699916
4882 4881 5337.059672760578857575873
4883 4882 5338.214274771734007030337
4884 4883 5338.933125464858255529763
4885 4884 5339.674564986855845227651
4886 4885 5341.264957858608639366354
4887 4886 5341.907714556882095232136
4888 4887 5342.986689833522694072159
4889 4888 5343.623359433019280535648
4890 4889 5344.507532612439043407189
4891 4890 5345.528297341695390408928
4892 4891 5346.069965615356604020419
4893 4892 5346.890937421842787745259
4894 4893 5348.769669281725552938557
4895 4894 5349.489057840143921701433
4896 4895 5350.395904772442639034694
4897 4896 5351.225419925846713171101
4898 4897 5351.771637383498354802498
4899 4898 5352.900178207069687185059
4900 4899 5354.185202829311065197946
4901 4900 5354.773479714049486155848
4902 4901 5355.347063675623206182712
4903 4902 5356.538865828704991157855
4904 4903 5357.711619892324723795539
4905 4904 5358.669106441790825322224
4906 4905 5359.633917927375471732196
4907 4906 5360.877126531294127320275
4908 4907 5361.630997292119675022633
4909 4908 5361.916637016828460063173
4910 4909 5362.990405326631597644878
4911 4910 5363.717280477004778220011
4912 4911 5365.296267419233728875117
4913 4912 5365.742257680618417976666
4914 4913 5367.380123852191657579968
4915 4914 5367.905543114681266121855
4916 4915 5368.813641601140092121946
4917 4916 5369.80759645258569521009
4918 4917 5370.713539813717386183079
4919 4918 5371.538329750509979083698
4920 4919 5372.680867258249723821871
4921 4920 5373.219972947191730787293
4922 4921 5374.114835212555717758037
4923 4922 5374.86973824503644976846
4924 4923 5376.722663658617110389129
4925 4924 5377.719730868922778861453
4926 4925 5378.20703813004627003507
4927 4926 5378.768713720048698165175
4928 4927 5380.103731882796235512445
4929 4928 5380.877056510779138825141
4930 4929 5381.348150697046463256593
4931 4930 5382.80999337051447727806
4932 4931 5383.528600988369024420741
4933 4932 5384.819764523645932911282
4934 4933 5385.689781133582734908808
4935 4934 5386.311049248220996439321
4936 4935 5387.7055341288953818182
4937 4936 5388.449137494742566372566
4938 4937 5389.608146493819127374344
4939 4938 5389.909513561418771360618
4940 4939 5390.992260083001205962799
4941 4940 5391.505965627098090247525
4942 4941 5392.981959683038198565226
4943 4942 5394.083717252515683245785
4944 4943 5395.116663427587022498649
4945 4944 5396.115859471749497639701
4946 4945 5397.003429726802106528526
4947 4946 5397.26196015786015640104
4948 4947 5398.277621995208377808307
4949 4948 5399.712504640470590968509
4950 4949 5400.418887868290302097895
4951 4950 5401.194496185364366292665
4952 4951 5401.947143074564835031479
4953 4952 5403.38959011523765155739
4954 4953 5404.287687736618271033576
4955 4954 5405.354453322769112692248
4956 4955 5406.184132744065129585855
4957 4956 5407.075537996711088736112
4958 4957 5407.735014383861153000149
4959 4958 5408.588715767542952961095
4960 4959 5409.577739475961611771895
4961 4960 5410.101872017244926204184
4962 4961 5412.119660738806724868659
4963 4962 5412.756931861645764869174
4964 4963 5413.448942338434564108734
4965 4964 5414.39188465514572198891
4966 4965 5415.225062963723573461309
4967 4966 5416.511814309129688515556
4968 4967 5417.190777293038612768896
4969 4968 5417.73077596648454186167
4970 4969 5419.145769365587780365706
4971 4970 5419.647914017258612098617
4972 4971 5420.595118618174322385529
4973 4972 5422.10720154439465146786
4974 4973 5423.364285030068457508797
4975 4974 5423.582839997252837863374
4976 4975 5424.99013750159272679703
4977 4976 5425.205579331656943187066
4978 4977 5426.077473621457306594563
4979 4978 5427.327787267212627938845
4980 4979 5428.200793507517209823303
4981 4980 5429.307069477648462636769
4982 4981 5430.093232394629979912852
4983 4982 5431.518550461935834887462
4984 4983 5432.081300563690918500732
4985 4984 5432.867061873673654868702
4986 4985 5433.939314658022811572276
4987 4986 5435.224510669428081366189
4988 4987 5435.614214161095066505331
4989 4988 5436.658400672125095266533
4990 4989 5436.820644930087936748917
4991 4990 5438.486077902408754917697
4992 4991 5439.874947381833328753332
4993 4992 5440.645160132014937884514
4994 4993 5441.565050360556652074379
4995 4994 5442.197196540771423174145
4996 4995 5443.283539712419868619387
4997 4996 5443.795137320656387965599
4998 4997 5444.966959569919281410007
4999 4998 5445.925027099689905584586
5000 4999 5446.765247872766322860979
5001 5000 5447.861998301299856412159

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