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 5 of 20 · 500/page · 10000 rows next →
# ngamma_n
2002 2001 2516.57104914288748599437
2003 2002 2517.146931880415356863337
2004 2003 2518.552852040690821002384
2005 2004 2519.634252640271893334172
2006 2005 2520.402323518036163973881
2007 2006 2521.88517564615100536324
2008 2007 2523.263480155872146142966
2009 2008 2523.967055819190529479675
2010 2009 2524.642045795694521479349
2011 2010 2525.687993324800683257013
2012 2011 2526.868810058592998243918
2013 2012 2527.418791160628952562372
2014 2013 2529.378043463275119619442
2015 2014 2530.273672274268411277603
2016 2015 2531.54396122006483741073
2017 2016 2531.969384081561968547217
2018 2017 2533.067317099047443932875
2019 2018 2534.408614098394202583134
2020 2019 2535.505886073966032071815
2021 2020 2536.091884920838980799483
2022 2021 2536.867485222561254438074
2023 2022 2538.559826936261153398774
2024 2023 2539.998407118591166468833
2025 2024 2540.53166193674222860222
2026 2025 2541.998729153671039536672
2027 2026 2542.687650514868867082422
2028 2027 2543.343955088606650134459
2029 2028 2544.290953656615606110892
2030 2029 2545.878017730333159662435
2031 2030 2546.761141283358773561276
2032 2031 2548.181615394108557459031
2033 2032 2548.895987575046567007906
2034 2033 2549.996484491522520390157
2035 2034 2551.41114199288503789677
2036 2035 2551.880445959599060879986
2037 2036 2553.275677995524692638673
2038 2037 2553.723069201209180248796
2039 2038 2555.050875291359249168982
2040 2039 2555.832350747303403083752
2041 2040 2558.009105942871789164342
2042 2041 2558.752211368471367338313
2043 2042 2559.234296597333972469714
2044 2043 2560.263289514388720620743
2045 2044 2561.405635747573315478714
2046 2045 2562.426113338143232051032
2047 2046 2563.501718903992988724494
2048 2047 2564.33210785433349039775
2049 2048 2565.975270478283844204012
2050 2049 2566.55755789708502248955
2051 2050 2567.958599725328829408293
2052 2051 2569.0430901733527799358
2053 2052 2569.94811159690457986047
2054 2053 2570.958525661919221860624
2055 2054 2571.540774147768717504372
2056 2055 2572.368208186207413775216
2057 2056 2574.207163950022860407176
2058 2057 2575.404511996903622548127
2059 2058 2576.141011184026154510829
2060 2059 2577.51983553260234469337
2061 2060 2578.070129925005555047026
2062 2061 2578.971298335895942474808
2063 2062 2580.346111565200706589691
2064 2063 2581.398140581892706632454
2065 2064 2582.138733931301889982644
2066 2065 2583.003294535099838204013
2067 2066 2584.758402441678541603673
2068 2067 2585.772739404011499256663
2069 2068 2586.925178957182227989286
2070 2069 2587.591000924191165002041
2071 2070 2588.368210423880449432982
2072 2071 2589.579264554434006855279
2073 2072 2590.371692925951522366762
2074 2073 2591.549378447984791502892
2075 2074 2593.275876806604425384422
2076 2075 2594.023618334686682569052
2077 2076 2594.905011552479901446776
2078 2077 2595.687530138859603929944
2079 2078 2597.546141488459564930271
2080 2079 2597.979353418423115901003
2081 2080 2598.598768319633465984132
2082 2081 2600.121355061881931092927
2083 2082 2600.641952319219978877613
2084 2083 2602.412300558055130095144
2085 2084 2603.628781118453252976396
2086 2085 2604.573564823718664179966
2087 2086 2605.368075915559231350757
2088 2087 2606.243664547518941377395
2089 2088 2607.003639114239009673557
2090 2089 2608.364899649035512772407
2091 2090 2609.552086740677385063283
2092 2091 2610.444520938915516022592
2093 2092 2611.54367038142293957944
2094 2093 2612.956807036694044383491
2095 2094 2613.731929438305032823639
2096 2095 2614.737136165400840807884
2097 2096 2615.847707268249514183878
2098 2097 2616.902118243953797343551
2099 2098 2617.335046934901114269679
2100 2099 2618.29291547802228594207
2101 2100 2620.279393694424618791568
2102 2101 2621.42905521322924086303
2103 2102 2622.048696798421354766341
2104 2103 2622.994507976302031269866
2105 2104 2624.050603854559431085874
2106 2105 2624.909501777169639509346
2107 2106 2626.46050222994433988183
2108 2107 2626.710471395806398951926
2109 2108 2628.098026523871191256657
2110 2109 2629.604139510848587789108
2111 2110 2629.994800764219984818912
2112 2111 2632.043116637112728952044
2113 2112 2632.443658949145354916575
2114 2113 2633.676399939781127792147
2115 2114 2633.966543434121262890081
2116 2115 2635.217331617179852718082
2117 2116 2636.432585995081861696981
2118 2117 2637.510683358462605418061
2119 2118 2639.062573045389558915227
2120 2119 2640.054245884027257587859
2121 2120 2640.462942828951323465832
2122 2121 2641.80174478410854879694
2123 2122 2642.755759063043897443806
2124 2123 2643.970900958345226199899
2125 2124 2644.887867143491581855777
2126 2125 2645.39556727857292922517
2127 2126 2646.689940172724319473542
2128 2127 2648.577429283763884870849
2129 2128 2649.325653551798772117115
2130 2129 2650.058544458382326108513
2131 2130 2651.227331332121326203932
2132 2131 2652.160775241539956053619
2133 2132 2652.770642826959688585187
2134 2133 2653.89706974564043827188
2135 2134 2655.61577232596184138416
2136 2135 2656.238998498017256462088
2137 2136 2657.537760758300554229157
2138 2137 2658.341557629756967527547
2139 2138 2659.65831602085961658676
2140 2139 2660.61024580295311457152
2141 2140 2661.582573758213880690856
2142 2141 2662.183573435627615494808
2143 2142 2663.39394562233962764409
2144 2143 2664.23548908324405939038
2145 2144 2666.030101479453968648605
2146 2145 2666.982849070546235931857
2147 2146 2668.291859037208910133532
2148 2147 2668.663651401292818537905
2149 2148 2669.25374488818001451035
2150 2149 2670.998998582165212287822
2151 2150 2671.918382668910966565955
2152 2151 2672.603779588146692066806
2153 2152 2673.874618711104655775557
2154 2153 2675.27175912963652574864
2155 2154 2676.066490230100449604583
2156 2155 2677.246193893199507580694
2157 2156 2678.538156521631728664964
2158 2157 2679.02528159628447337154
2159 2158 2680.039021548238460989996
2160 2159 2680.843117132923615719623
2161 2160 2681.841051456082719193231
2162 2161 2683.882275551469900195459
2163 2162 2684.529156904497649412205
2164 2163 2685.377113426632244066084
2165 2164 2686.496160151160446748579
2166 2165 2687.489939808026632666463
2167 2166 2688.385081595554101258963
2168 2167 2689.423275981138127722035
2169 2168 2690.633186856025274612834
2170 2169 2691.318382839997113768709
2171 2170 2692.36871895850991419485
2172 2171 2694.102820613441968378722
2173 2172 2695.208957968971278538637
2174 2173 2695.750049240104830877552
2175 2174 2696.695372581611462225268
2176 2175 2697.857558216759304730225
2177 2176 2698.290961321395782495101
2178 2177 2699.942027500086358854666
2179 2178 2700.731207011070332510604
2180 2179 2702.433544847737332716736
2181 2180 2703.143657511188948436549
2182 2181 2703.981714244772448908337
2183 2182 2704.955737551334258641148
2184 2183 2706.52824732675666912826
2185 2184 2707.09076464638887997076
2186 2185 2708.117069229272968488341
2187 2186 2708.476524960683297979038
2188 2187 2710.368359823606167293568
2189 2188 2711.458227864114997837425
2190 2189 2712.786687334756395277866
2191 2190 2713.525289303347907309146
2192 2191 2714.367906688518618850328
2193 2192 2715.339871631409058099314
2194 2193 2716.025049049534497997415
2195 2194 2717.665774871052640547113
2196 2195 2718.308652474352483038013
2197 2196 2719.770998978129882008571
2198 2197 2720.493474900152773743595
2199 2198 2721.798775616647991581767
2200 2199 2723.086082744475843491747
2201 2200 2723.768928849822694372151
2202 2201 2724.523924437069703432717
2203 2202 2725.882989203482000823935
2204 2203 2726.479701033963230793427
2205 2204 2727.274459431901557803273
2206 2205 2729.395041668594912117859
2207 2206 2730.492891807172182728788
2208 2207 2730.797702080186746567869
2209 2208 2732.004049913595246798743
2210 2209 2732.830123557482104623657
2211 2210 2734.200782967822427626622
2212 2211 2734.938856084208801315631
2213 2212 2736.000479107039897569416
2214 2213 2736.922048440000585821577
2215 2214 2738.266444163765032289615
2216 2215 2739.513547296201548952011
2217 2216 2740.311109421231381416013
2218 2217 2741.878852420557722856738
2219 2218 2742.254107878248024691441
2220 2219 2742.993068159927390245627
2221 2220 2743.953469810087824498557
2222 2221 2745.321831898192903945407
2223 2222 2746.714798952398406870847
2224 2223 2747.514097998184117739117
2225 2224 2748.916191066436435814843
2226 2225 2749.643649788653236287582
2227 2226 2750.314083410359824535791
2228 2227 2751.823671458527382104495
2229 2228 2752.715502493883261035838
2230 2229 2753.487796417396150788929
2231 2230 2754.458663082718398076079
2232 2231 2755.41687619148596685556
2233 2232 2757.301868214300791891696
2234 2233 2758.27810332833900224645
2235 2234 2758.858670968685004357921
2236 2235 2759.898613919658389157765
2237 2236 2760.65715154011170614868
2238 2237 2762.082880142575299998583
2239 2238 2762.444580467694463148621
2240 2239 2764.04184625208908305188
2241 2240 2765.407691146482925770701
2242 2241 2766.157035589919061983824
2243 2242 2766.887269747368007123943
2244 2243 2768.664523888139108086682
2245 2244 2769.144698796099990228123
2246 2245 2770.279093643343192131831
2247 2246 2771.017392142684773197474
2248 2247 2771.896293661727721094241
2249 2248 2773.02971342429484460132
2250 2249 2774.670010731832631333589
2251 2250 2775.725707342410327913288
2252 2251 2776.61916030792635618947
2253 2252 2777.512125202576134575008
2254 2253 2778.289695299772775651021
2255 2254 2779.127539134050768659383
2256 2255 2780.771118379071538600707
2257 2256 2781.656070227571440777525
2258 2257 2781.989239654647903962405
2259 2258 2783.943665286859110918462
2260 2259 2784.705283876121840163656
2261 2260 2786.043335738622757719653
2262 2261 2786.702566351368773988136
2263 2262 2787.932021258523774839056
2264 2263 2788.796278014511074338948
2265 2264 2789.197561121050912556081
2266 2265 2790.493080791035226040002
2267 2266 2792.113378557022842225899
2268 2267 2793.301469240871724336627
2269 2268 2794.238093335275467696773
2270 2269 2794.65382466532819842009
2271 2270 2796.034761603657805198703
2272 2271 2797.174539351897759421513
2273 2272 2797.972901229628421460709
2274 2273 2798.798140177045477205474
2275 2274 2800.067444818401492782559
2276 2275 2800.93760311623493101296
2277 2276 2802.224801536331663011348
2278 2277 2803.864955138344506909039
2279 2278 2804.418935676251152208985
2280 2279 2805.205300363064447173335
2281 2280 2806.002732416640888837714
2282 2281 2807.132318371189380278606
2283 2282 2808.153501197997633610067
2284 2283 2809.291652245192837469788
2285 2284 2810.724634082518464086602
2286 2285 2811.460992226052809724534
2287 2286 2812.861997588022148609889
2288 2287 2813.201488028300935978791
2289 2288 2814.656757980595164772594
2290 2289 2815.838653992747667445263
2291 2290 2816.337954815325156730237
2292 2291 2817.458907317419326169611
2293 2292 2817.94946216096694721522
2294 2293 2820.488842021916584974106
2295 2294 2820.660841053781159955141
2296 2295 2821.891930074870971273234
2297 2296 2822.923026217023214857504
2298 2297 2823.866992056607983967687
2299 2298 2824.281884122039627947519
2300 2299 2825.872656689750757996878
2301 2300 2826.712170374922746029583
2302 2301 2828.029973946250995071113
2303 2302 2828.851526590522587986638
2304 2303 2830.087545290016122224192
2305 2304 2831.128425437187258500389
2306 2305 2832.416550857943840752293
2307 2306 2833.138035851670906206916
2308 2307 2833.658717233308178244517
2309 2308 2834.980248462514047130411
2310 2309 2835.775847744530604761627
2311 2310 2837.014472081293122752571
2312 2311 2838.812881529271651030311
2313 2312 2839.485753395012631467188
2314 2313 2840.285754910691532813351
2315 2314 2840.920672973103976131407
2316 2315 2842.332641081100701383169
2317 2316 2843.469837884564750983044
2318 2317 2844.198986963261227135204
2319 2318 2845.025433610480155636918
2320 2319 2846.390776212726890003352
2321 2320 2847.535935529730751967492
2322 2321 2848.770308555407354207727
2323 2322 2849.797086647209651712201
2324 2323 2850.4718881974353470285
2325 2324 2851.678938036254349093725
2326 2325 2852.303726568369768934781
2327 2326 2852.926214764694869254346
2328 2327 2854.832394231931316229139
2329 2328 2855.853721192900111358019
2330 2329 2856.816133543913321204867
2331 2330 2857.73613980782205676683
2332 2331 2858.857860356251478371003
2333 2332 2859.838748954184361582006
2334 2333 2860.577436497612265941271
2335 2334 2862.12020823439640538305
2336 2335 2862.506966277762679317956
2337 2336 2863.363589552191153972211
2338 2337 2864.911426758851445613132
2339 2338 2866.493209755929753472366
2340 2339 2867.149356094087868215507
2341 2340 2868.224163663090438520984
2342 2341 2868.657629194218364434257
2343 2342 2869.843456574863653169161
2344 2343 2870.909506375380920701689
2345 2344 2872.02351111354819230379
2346 2345 2872.858555183438196862384
2347 2346 2874.569154072845864690232
2348 2347 2875.282119166366557731876
2349 2348 2875.889914340386435726439
2350 2349 2877.546649153796206289066
2351 2350 2878.52700262417992669394
2352 2351 2879.119907546978922105531
2353 2352 2879.868973936907339028877
2354 2353 2880.978994738386006888854
2355 2354 2882.153646390636910794871
2356 2355 2884.01365755283976667238
2357 2356 2884.346757790142943404964
2358 2357 2885.773055402722130329296
2359 2358 2886.308874639772579859463
2360 2359 2887.224885507060785203531
2361 2360 2888.394382456172131481713
2362 2361 2889.404168047578017266335
2363 2362 2890.642626361553295547118
2364 2363 2891.28007821545510649429
2365 2364 2892.462624016639248094348
2366 2365 2894.174448736821223258611
2367 2366 2894.746550356225012201364
2368 2367 2895.641103861971377405932
2369 2368 2896.825405168247547358461
2370 2369 2897.428300566969727455813
2371 2370 2898.541353179907942086946
2372 2371 2899.177779836548361095888
2373 2372 2901.263850361997178504857
2374 2373 2902.065102481250127796321
2375 2374 2902.855785528508264195501
2376 2375 2903.957879043037018592
2377 2376 2904.598196021987724123757
2378 2377 2906.176417596628539289812
2379 2378 2906.923339342985194483579
2380 2379 2907.605736911210832134911
2381 2380 2908.658045519742780668548
2382 2381 2910.028233435046379665789
2383 2382 2911.14290366458001567065
2384 2383 2912.345904726055916472618
2385 2384 2913.522785866686084032477
2386 2385 2914.044611072102739647947
2387 2386 2914.802702223863609720007
2388 2387 2915.685975327455177689079
2389 2388 2917.274173441487555351694
2390 2389 2917.982416701912520163859
2391 2390 2919.321772326527278134587
2392 2391 2920.615555992141325266987
2393 2392 2921.083198937259828575728
2394 2393 2922.396084557395077441944
2395 2394 2923.390932357376606244934
2396 2395 2924.333434993952654048656
2397 2396 2925.261509119313312551942
2398 2397 2926.295436226225759123124
2399 2398 2926.624014686465896988321
2400 2399 2928.761073846998261471974
2401 2400 2930.004366371979197589348
2402 2401 2930.711168697389571506234
2403 2402 2931.069101109814732085461
2404 2403 2932.806414415832769005011
2405 2404 2933.174857162008290084312
2406 2405 2934.290717835787845931994
2407 2406 2935.552463705747991325899
2408 2407 2936.550374848601820241496
2409 2408 2937.70895898156823787373
2410 2409 2938.581220350578455150906
2411 2410 2939.847529162593991235524
2412 2411 2941.261601534687117368538
2413 2412 2941.425217756342247031115
2414 2413 2942.724885865147488694871
2415 2414 2943.353684960178375485354
2416 2415 2944.321648794483433337463
2417 2416 2945.944499285887025994072
2418 2417 2946.9223948961883507509
2419 2418 2948.374261864690537504869
2420 2419 2948.867577209394886742292
2421 2420 2949.790143025785909072104
2422 2421 2950.52110835241838506342
2423 2422 2952.283829638947545679278
2424 2423 2952.82717658351190103087
2425 2424 2953.589030993758808120107
2426 2425 2954.71127529093356272781
2427 2426 2956.258730424157120002825
2428 2427 2957.236259246842562201737
2429 2428 2958.290776254197002720781
2430 2429 2959.221014234687151865428
2431 2430 2960.033617812008374302363
2432 2431 2960.81483926622022873063
2433 2432 2961.825970575348591466113
2434 2433 2962.819636335281423816159
2435 2434 2964.633921494808562758066
2436 2435 2965.39834158429091685325
2437 2436 2966.065269745648101403237
2438 2437 2967.270190426496198410397
2439 2438 2968.405348995407544712878
2440 2439 2969.401136655698809674132
2441 2440 2970.049930110913633646238
2442 2441 2971.122238124934487754082
2443 2442 2972.308884109068754752861
2444 2443 2972.811686391357692492661
2445 2444 2975.018020412780896122993
2446 2445 2975.619957166153440291091
2447 2446 2976.526232137094252540534
2448 2447 2977.55357491347025255604
2449 2448 2977.981978512600202759178
2450 2449 2979.319042212011449010752
2451 2450 2980.487381006559362305435
2452 2451 2981.343947481810291631948
2453 2452 2982.523719895924638061634
2454 2453 2983.82533326651940415623
2455 2454 2984.639177804446568973251
2456 2455 2985.547666235421072150718
2457 2456 2986.805393383297834851761
2458 2457 2987.856151502432137454886
2459 2458 2988.634699666938808340888
2460 2459 2988.855046367445202540788
2461 2460 2990.423270573698602405377
2462 2461 2992.163668675063220175137
2463 2462 2992.868866378301013829203
2464 2463 2993.974353092848010375763
2465 2464 2994.865507046753948241652
2466 2465 2995.540266915501954267219
2467 2466 2996.736506016221763597077
2468 2467 2997.647203114442794777893
2469 2468 2998.959301098028931730728
2470 2469 2999.494492994594582969443
2471 2470 3001.023331162879569093123
2472 2471 3001.707332456021018183755
2473 2472 3003.477042852710594846713
2474 2473 3004.290975917310578015247
2475 2474 3004.66230840824914309319
2476 2475 3005.772929284508010637544
2477 2476 3006.990738364633401842891
2478 2477 3007.468699216470850556117
2479 2478 3008.882120872393042159338
2480 2479 3010.514962129244277443409
2481 2480 3011.344380180512230899849
2482 2481 3012.074694785866823960861
2483 2482 3012.788450548678345343834
2484 2483 3014.45908220668191619151
2485 2484 3014.911666502729305189434
2486 2485 3016.348394169977961869569
2487 2486 3016.700060812629197002046
2488 2487 3017.783440191593068822172
2489 2488 3019.461775780365950075222
2490 2489 3020.487633896939095244552
2491 2490 3021.420400692511292958162
2492 2491 3022.447483793125912477866
2493 2492 3023.338509067940910824846
2494 2493 3023.930996073902266231672
2495 2494 3024.793963871217760710637
2496 2495 3026.510826907845434071327
2497 2496 3027.299522807341472230391
2498 2497 3028.401522528630682094523
2499 2498 3029.499388369681240645993
2500 2499 3030.594529650982070439919
2501 2500 3031.28921746806128491754

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