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 9 of 20 · 500/page · 10000 rows next →
# ngamma_n
4002 4001 4507.745182883217585712854
4003 4002 4508.211436902683191483435
4004 4003 4509.371444648123771834791
4005 4004 4509.943668937142796631323
4006 4005 4511.040014028519826947399
4007 4006 4511.462718596944825304867
4008 4007 4512.80999110719933329153
4009 4008 4514.077139589541616475394
4010 4009 4515.19130676458930337706
4011 4010 4516.089845213538949617175
4012 4011 4516.365671040829024137865
4013 4012 4518.275389222432388863171
4014 4013 4518.584679215418522579925
4015 4014 4519.57480002045911783584
4016 4015 4520.538555008726931684184
4017 4016 4521.475485153272691698191
4018 4017 4522.144077728261478388296
4019 4018 4523.237464378725200620258
4020 4019 4524.973397160755773243619
4021 4020 4525.790882296900267871033
4022 4021 4526.348586358787751873393
4023 4022 4527.353633124018429918452
4024 4023 4527.943893544785588109726
4025 4024 4529.069234592007498259577
4026 4025 4530.02523317441132352647
4027 4026 4531.318968337886596724274
4028 4027 4531.643575987181310538825
4029 4028 4533.297976471441726615658
4030 4029 4534.135598244321343192505
4031 4030 4534.935556004702284227945
4032 4031 4535.90756251672937651438
4033 4032 4537.252568547485587415566
4034 4033 4537.806098343882329936863
4035 4034 4538.508935088108176774141
4036 4035 4539.188862923705849811772
4037 4036 4540.3477266234541881285
4038 4037 4542.129666250978635069533
4039 4038 4542.620486098007612372084
4040 4039 4543.746922273790999177631
4041 4040 4544.720271320875110382421
4042 4041 4545.263343636485154453098
4043 4042 4546.141207421271979845561
4044 4043 4547.593415368720114184839
4045 4044 4547.938636006363253018545
4046 4045 4549.281071828127811086351
4047 4046 4550.068688879314210336149
4048 4047 4550.979693585295962613644
4049 4048 4552.321926160970289519545
4050 4049 4553.536850280879258971759
4051 4050 4554.197951050969598706635
4052 4051 4554.959391486876160667915
4053 4052 4555.595473599203158946601
4054 4053 4556.891310536484503768653
4055 4054 4557.533974070577998530496
4056 4055 4558.396623828290441557162
4057 4056 4560.215941097671281958777
4058 4057 4560.999833506231566524695
4059 4058 4561.62934660156966973205
4060 4059 4562.596817089267709950989
4061 4060 4563.416046267604426459661
4062 4061 4564.815955844672177597416
4063 4062 4565.416958272248864141663
4064 4063 4566.253326081946528362716
4065 4064 4567.121450990624194848385
4066 4065 4567.941686478497419875685
4067 4066 4569.615770295187562955575
4068 4067 4570.433329174898880336581
4069 4068 4571.457898785560828460419
4070 4069 4572.249860418587060394057
4071 4070 4573.246173187393333751288
4072 4071 4573.924130511974939764592
4073 4072 4574.297621384388679280113
4074 4073 4576.189954391835435575374
4075 4074 4576.793917799958071535659
4076 4075 4577.859111429864775476559
4077 4076 4578.927025832071771057651
4078 4077 4579.956917853998653677793
4079 4078 4580.717084505585650949386
4080 4079 4581.894187213451395060445
4081 4080 4582.568249086154888198908
4082 4081 4583.673687920993870673012
4083 4082 4584.380768499226686844002
4084 4083 4584.97725816543207735453
4085 4084 4586.207762605340608766408
4086 4085 4587.674877076508276421401
4087 4086 4588.977914220216893288138
4088 4087 4589.643449489509525831931
4089 4088 4589.748811533984073109027
4090 4089 4591.204146513097044716159
4091 4090 4592.049309087907912230368
4092 4091 4593.159791572761266279214
4093 4092 4593.83689198613064638386
4094 4093 4594.78719056032522336317
4095 4094 4596.263664401222352072995
4096 4095 4596.829908459071355620543
4097 4096 4597.820812342329887692851
4098 4097 4599.373672439866231106167
4099 4098 4599.907579437689900470336
4100 4099 4600.630054113463249328712
4101 4100 4601.602961817195210773848
4102 4101 4602.25612351384042502599
4103 4102 4603.209690545088494409881
4104 4103 4604.641681401318434572542
4105 4104 4605.883451695221001197263
4106 4105 4606.462472402408225286829
4107 4106 4607.753032587037468252489
4108 4107 4608.216380944203910570339
4109 4108 4609.224160777059836468833
4110 4109 4610.084231645927489915195
4111 4110 4611.484674457680128683711
4112 4111 4612.028597458638017180779
4113 4112 4612.788854013540499857263
4114 4113 4613.684307641332135748303
4115 4114 4615.536616091181920312009
4116 4115 4616.222300661647902674011
4117 4116 4616.958582780833962031387
4118 4117 4618.107678910147295189399
4119 4118 4618.767170618818314446484
4120 4119 4619.465593896856682251639
4121 4120 4620.544365612922411190542
4122 4121 4621.348279218696864140987
4123 4122 4622.819323121313133157468
4124 4123 4623.805611944196388813968
4125 4124 4624.726278755093853198317
4126 4125 4625.409262501686005167224
4127 4126 4626.342985703833363788291
4128 4127 4627.790229823108015390214
4129 4128 4628.463443401889382424945
4130 4129 4628.974234757263189026276
4131 4130 4629.888782939314473980451
4132 4131 4631.226406988970946891586
4133 4132 4631.762401043949186965878
4134 4133 4633.564438992180702633255
4135 4134 4634.30710541877199691066
4136 4135 4635.357160887010119287898
4137 4136 4636.028343960683841351498
4138 4137 4636.392280747452989367267
4139 4138 4637.792071980071969804127
4140 4139 4638.748153747896912504339
4141 4140 4639.715380822985125026757
4142 4141 4640.561739730958772813064
4143 4142 4641.758272380068695377118
4144 4143 4642.685758176652565692986
4145 4144 4643.75173586357258653419
4146 4145 4644.753105527211353893253
4147 4146 4645.362987352404960483362
4148 4147 4646.73948607407427810545
4149 4148 4647.117263732463690315344
4150 4149 4648.112608174797495897068
4151 4150 4648.564886816581811127258
4152 4151 4650.614330328304693315362
4153 4152 4651.664121145863517166712
4154 4153 4652.088399128892722097292
4155 4154 4653.119156055231474657853
4156 4155 4654.06894959962289296667
4157 4156 4654.947323957917146301856
4158 4157 4655.721560896440402116739
4159 4158 4656.922418573236229933754
4160 4159 4657.820890194845071378742
4161 4160 4658.394949957775201671083
4162 4161 4659.918687610412533546233
4163 4162 4660.563963934253226678015
4164 4163 4662.080004603230196498508
4165 4164 4662.945890919434681990323
4166 4165 4663.505025593543350008971
4167 4166 4664.322897246287663093205
4168 4167 4665.14137595313364015036
4169 4168 4666.090798752812430792978
4170 4169 4667.424428268022505182111
4171 4170 4668.055177752045005692737
4172 4171 4669.829513522149519349128
4173 4172 4670.350631746016705786864
4174 4173 4671.032106498723756281764
4175 4174 4671.877847964575568367393
4176 4175 4673.282690521288863774214
4177 4176 4674.126716048520155790806
4178 4177 4674.741639863472338033388
4179 4178 4675.727566686424795434077
4180 4179 4676.334095816126001878315
4181 4180 4677.930219147139760025767
4182 4181 4679.087491041081722265194
4183 4182 4680.088468859476682777
4184 4183 4680.606397111239046429496
4185 4184 4681.604890746662137231702
4186 4185 4682.648662425130068993295
4187 4186 4683.021291066600425704543
4188 4187 4684.186914789593926043381
4189 4188 4685.407789642226698401413
4190 4189 4686.708155145731282196585
4191 4190 4687.072177975256371598018
4192 4191 4688.252603006428156323794
4193 4192 4689.505062437305947085002
4194 4193 4690.178840007101156267685
4195 4194 4691.296768788712998698198
4196 4195 4691.862100090804364183891
4197 4196 4692.866432862005417494041
4198 4197 4693.939417293336188869628
4199 4198 4694.173942793324879121993
4200 4199 4696.095849872810785399512
4201 4200 4697.3541474715424375705
4202 4201 4697.774403761154303022259
4203 4202 4698.924504209172432605617
4204 4203 4699.497252230962505996396
4205 4204 4700.158603280910107107738
4206 4205 4701.842587035350229945044
4207 4206 4702.437645696001115081076
4208 4207 4703.015173840539884166212
4209 4208 4704.338118407428742202136
4210 4209 4705.482138782043212792744
4211 4210 4706.468570903250873605011
4212 4211 4707.187171952140145536904
4213 4212 4708.595427452169518532707
4214 4213 4709.332678157477530917877
4215 4214 4709.944940346285218461244
4216 4215 4710.552242005027289891058
4217 4216 4711.69198018483324449499
4218 4217 4712.777797477036918820697
4219 4218 4714.247723107137320849008
4220 4219 4714.997962824891633344728
4221 4220 4715.952621727107204636449
4222 4221 4716.660239219091658148254
4223 4222 4717.733401081525539588073
4224 4223 4718.529894766793406868459
4225 4224 4719.595704166862952002485
4226 4225 4720.386694373550362816859
4227 4226 4721.537540939960935212968
4228 4227 4721.954561819576412351491
4229 4228 4723.234934939146447074775
4230 4229 4724.99642187765109584682
4231 4230 4725.487196574650090782727
4232 4231 4726.271143852757387688054
4233 4232 4726.949295824610082952916
4234 4233 4728.211604352939923336085
4235 4234 4728.750507230119510960458
4236 4235 4729.661501548357264038112
4237 4236 4730.962714323503681029058
4238 4237 4732.021907044924884252694
4239 4238 4733.193764940088243857278
4240 4239 4733.844098699536374975904
4241 4240 4734.52781783289085148125
4242 4241 4736.044923936178173026095
4243 4242 4736.596840064478015168581
4244 4243 4737.784035547895767769999
4245 4244 4738.432582516829772804613
4246 4245 4738.793733317309791083735
4247 4246 4740.332565971351204974505
4248 4247 4741.721885804414925812942
4249 4248 4742.414037310372691953468
4250 4249 4743.717920629169778018592
4251 4250 4744.421811483696119835874
4252 4251 4744.996853269858667603642
4253 4252 4745.842419030443606409873
4254 4253 4746.839593742937682383372
4255 4254 4748.335806689634292785924
4256 4255 4748.700881129172875367838
4257 4256 4749.728100218336966139126
4258 4257 4751.215949059367057359546
4259 4258 4751.682732579110661369393
4260 4259 4753.084026101484586173342
4261 4260 4753.918835840181715726414
4262 4261 4754.589564975895352337695
4263 4262 4755.588948859221431649418
4264 4263 4756.356140489576219140275
4265 4264 4757.222671632898185402105
4266 4265 4757.970669573234211562328
4267 4266 4760.158590209302521649448
4268 4267 4760.441048058613566808246
4269 4268 4761.516430763499396543037
4270 4269 4761.983993808134506527862
4271 4270 4763.158188506213454892116
4272 4271 4764.275424407306483903778
4273 4272 4764.998476803593949182183
4274 4273 4765.803255384904621513469
4275 4274 4766.884818058115801703852
4276 4275 4767.868858831061510284738
4277 4276 4768.726470928571001757843
4278 4277 4770.256497157692319214927
4279 4278 4770.891284039308624229261
4280 4279 4772.057494829203420450518
4281 4280 4772.64493893611802345439
4282 4281 4773.439797772911971770462
4283 4282 4774.056619725543373055946
4284 4283 4775.395711249463670441966
4285 4284 4776.429201254369041933815
4286 4285 4777.635676983270711038053
4287 4286 4778.374124696471104169488
4288 4287 4779.596151378346832676449
4289 4288 4780.479123089006794458873
4290 4289 4780.708587502443035162939
4291 4290 4782.356874431613484150627
4292 4291 4783.343224125135875255251
4293 4292 4783.71451679538551670216
4294 4293 4784.640967678605631037359
4295 4294 4785.52541533809257636832
4296 4295 4787.252675346162013261863
4297 4296 4788.152570124255076385049
4298 4297 4788.999015740484347407785
4299 4298 4789.698347933761889233326
4300 4299 4790.733815868860531442154
4301 4300 4791.29117082101305287146
4302 4301 4792.408824018617677789229
4303 4302 4793.347319652198516780897
4304 4303 4794.286764715211680011303
4305 4304 4795.780117831537509010589
4306 4305 4796.352903431830801701959
4307 4306 4797.097933597945818840405
4308 4307 4798.420841862598135580285
4309 4308 4799.673211404293510211164
4310 4309 4800.097767615228696690197
4311 4310 4800.671002186036599460696
4312 4311 4802.188369508504326580809
4313 4312 4802.377850869757571068285
4314 4313 4803.704592676757202938736
4315 4314 4805.072216480051437183549
4316 4315 4806.37197358108813966351
4317 4316 4806.921270594435886644884
4318 4317 4807.541012033673238740761
4319 4318 4808.604499169223328929315
4320 4319 4809.346880319834907563187
4321 4320 4810.531881343335159221517
4322 4321 4811.632288844522749137389
4323 4322 4812.160772203606658080659
4324 4323 4813.045552124358051616453
4325 4324 4814.681559817523627224342
4326 4325 4815.324276549574915830465
4327 4326 4816.451758256975597922535
4328 4327 4817.232875407548554445944
4329 4328 4818.240133484467474530366
4330 4329 4819.028426196165153417289
4331 4330 4819.75462816856633826373
4332 4331 4820.2100300172031178572
4333 4332 4822.221164872703591670091
4334 4333 4822.905726969312732121209
4335 4334 4824.137537479789858745507
4336 4335 4824.678397755425805238372
4337 4336 4825.736295502362444363782
4338 4337 4826.494341214861117587587
4339 4338 4827.767321263362221931769
4340 4339 4828.337946620890113125042
4341 4340 4829.386309918933856651597
4342 4341 4830.136823559166987016243
4343 4342 4831.185693208819182863432
4344 4343 4832.224866730873780217304
4345 4344 4833.66326395936535609566
4346 4345 4834.665341189936119173765
4347 4346 4835.144026609661878036649
4348 4347 4835.951966776301744556276
4349 4348 4836.608965378976492897012
4350 4349 4838.026709907399510521103
4351 4350 4838.660483732967704551706
4352 4351 4839.647158112444012563326
4353 4352 4841.064723645309148014025
4354 4353 4842.043504687772379354121
4355 4354 4842.585412400115900515055
4356 4355 4843.621336000792441629591
4357 4356 4844.699612969358783736527
4358 4357 4845.696734419167149591622
4359 4358 4846.657760143518313429934
4360 4359 4846.916049334814343838389
4361 4360 4848.107405391168071671787
4362 4361 4848.88504190417096809729
4363 4362 4850.871518792202411429685
4364 4363 4851.468722998431765339792
4365 4364 4852.001065083394633811213
4366 4365 4853.425815431974229557236
4367 4366 4854.027006706021599251851
4368 4367 4854.574296102760764608794
4369 4368 4855.718462363850047365044
4370 4369 4856.921830081505002677005
4371 4370 4857.81538026017059084197
4372 4371 4858.604172218367619708396
4373 4372 4859.680531624429214001495
4374 4373 4860.809330725515107732068
4375 4374 4862.076654387724518460716
4376 4375 4862.359349645750220956624
4377 4376 4863.7601539197609325801
4378 4377 4864.191948667561191156469
4379 4378 4865.05535127265128279255
4380 4379 4866.071578271192035601271
4381 4380 4866.954021268905626335711
4382 4381 4868.588327038712939403402
4383 4382 4869.466636285996003582395
4384 4383 4870.517253831919863044501
4385 4384 4870.696564723359276882393
4386 4385 4871.705539530006271272227
4387 4386 4873.193181375946684880414
4388 4387 4873.818446227467478700958
4389 4388 4874.789996783109194462417
4390 4389 4875.237660837145282363842
4391 4390 4876.743142327452012738804
4392 4391 4877.725299567701846365741
4393 4392 4878.629005583154521603338
4394 4393 4880.058127358884297524322
4395 4394 4880.609661001629555419401
4396 4395 4881.311012339880100852682
4397 4396 4882.304462235103172031361
4398 4397 4882.890785935961674704651
4399 4398 4883.927414234290994553647
4400 4399 4885.362074723990061207893
4401 4400 4886.27047887999581296162
4402 4401 4887.198480646699728129695
4403 4402 4888.175610835218177967055
4404 4403 4888.908079346009931336947
4405 4404 4890.214451316183896227398
4406 4405 4890.627756888265251446725
4407 4406 4891.783056074756029841113
4408 4407 4892.93497904248662369324
4409 4408 4893.388337635763625767179
4410 4409 4893.96316952956690727676
4411 4410 4895.963739545985896382775
4412 4411 4896.957746690963674625451
4413 4412 4897.650781297577310623342
4414 4413 4898.457291766483546550555
4415 4414 4899.161200688896832048036
4416 4415 4900.429563379257629682572
4417 4416 4900.742881746494619588807
4418 4417 4902.307209902897363830742
4419 4418 4902.821632068548983028577
4420 4419 4904.228632937447432405918
4421 4420 4905.142489080673256296047
4422 4421 4906.098238142345993544038
4423 4422 4906.699541973659493237824
4424 4423 4908.330089351212601066641
4425 4424 4908.913521444295983650699
4426 4425 4909.624111714983894970842
4427 4426 4910.245081667458748148725
4428 4427 4911.291910102137935316907
4429 4428 4912.451308936105390130493
4430 4429 4913.66063761806629938368
4431 4430 4914.79264583157387007128
4432 4431 4915.700240689561518998173
4433 4432 4916.332164477558814301762
4434 4433 4917.23078050424447090092
4435 4434 4917.807535042850110860792
4436 4435 4919.487036337098303362462
4437 4436 4919.889325052079112123279
4438 4437 4920.840430543640467432904
4439 4438 4921.970590627642932376412
4440 4439 4922.718991373756672788759
4441 4440 4924.317098249989049526913
4442 4441 4925.077606689328753595156
4443 4442 4925.795026681425305622372
4444 4443 4926.72764220965099525154
4445 4444 4927.597951290635375503298
4446 4445 4928.526064803158376111679
4447 4446 4928.957136245708192328274
4448 4447 4930.240318442930018207394
4449 4448 4932.036812774137725341645
4450 4449 4932.600670527040718592686
4451 4450 4933.068125843811334931032
4452 4451 4934.352289122012126565361
4453 4452 4935.200994249787987339727
4454 4453 4936.133949523505740770364
4455 4454 4937.207162985993665628324
4456 4455 4937.770365700218142783289
4457 4456 4938.753815526292919965107
4458 4457 4939.641724784706801753506
4459 4458 4940.85229486265244160091
4460 4459 4942.135528578192400255083
4461 4460 4942.976896462189562261278
4462 4461 4943.977866731886657614486
4463 4462 4944.641603020049773269807
4464 4463 4945.186898517928171801013
4465 4464 4946.119253478643517898789
4466 4465 4947.500490321847553505484
4467 4466 4948.38980879744180519484
4468 4467 4949.085915385102584865755
4469 4468 4950.615812591258803037072
4470 4469 4951.502384929286173794437
4471 4470 4951.878797918170585580618
4472 4471 4953.200555668674743231228
4473 4472 4954.255067679664776881071
4474 4473 4954.976576379403295752937
4475 4474 4955.82225981611680572123
4476 4475 4956.466055278855659403708
4477 4476 4957.331889630291060201566
4478 4477 4959.028989320631797117685
4479 4478 4960.163928407693280929544
4480 4479 4960.758090264619476083664
4481 4480 4961.688462943186695758513
4482 4481 4962.261952448162617438946
4483 4482 4963.526118617487075963248
4484 4483 4964.307031405169229067657
4485 4484 4964.925235089607736324715
4486 4485 4966.633216269864611710006
4487 4486 4966.868645587163261187417
4488 4487 4968.394640927225772984156
4489 4488 4968.836094655103315129854
4490 4489 4970.479982679447772778006
4491 4490 4971.339245556210117404294
4492 4491 4971.824996149396399211104
4493 4492 4972.713491617352756412881
4494 4493 4973.711578032458529370783
4495 4494 4974.430478147270949109691
4496 4495 4975.310997142413226588642
4497 4496 4976.964034077549152808543
4498 4497 4977.755154086707724181144
4499 4498 4978.847855753176376949618
4500 4499 4979.580892326637990083368
4501 4500 4980.118762529119041125209

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