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 6 of 20 · 500/page · 10000 rows next →
# ngamma_n
2502 2501 3032.756029360224502941994
2503 2502 3033.218123972953621517453
2504 2503 3034.360907192326893515849
2505 2504 3035.074103947537975814395
2506 2505 3036.133113238208023315676
2507 2506 3037.980383590468515741819
2508 2507 3039.033651044210199536903
2509 2508 3039.521601571572104094388
2510 2509 3040.500427564659896173199
2511 2510 3041.256803549500078238284
2512 2511 3042.65304985413171795074
2513 2512 3043.670541621770201213688
2514 2513 3044.055127981914396199234
2515 2514 3046.050030224876108193262
2516 2515 3046.454504219288440377528
2517 2516 3047.708817640889868782237
2518 2517 3048.922632490404911869107
2519 2518 3050.01967675721217014526
2520 2519 3050.801233315720913693504
2521 2520 3051.342383341480500386289
2522 2521 3052.476848524261227364355
2523 2522 3053.348265936952123184665
2524 2523 3054.986520866536587891163
2525 2524 3056.242923309730601159817
2526 2525 3056.765138112965000587545
2527 2526 3058.013703009701794146336
2528 2527 3058.901494693164311768416
2529 2528 3059.437861758112786044891
2530 2529 3061.0627001175907560486
2531 2530 3061.837584445267609550764
2532 2531 3062.726873164640149674663
2533 2532 3063.435086485018649025414
2534 2533 3065.286555585297205549058
2535 2534 3066.32025040409628759396
2536 2535 3067.071320241176116647277
2537 2536 3068.013501341795335307245
2538 2537 3068.984266185526200890242
2539 2538 3069.782904779767485328251
2540 2539 3070.542621549808185443789
2541 2540 3072.000993377915675916944
2542 2541 3073.185237779942948672922
2543 2542 3074.523494285210268113199
2544 2543 3075.033872877410706842825
2545 2544 3075.833479242464054914139
2546 2545 3077.427473306812314210883
2547 2546 3078.286226917969259012236
2548 2547 3078.89737914713500822864
2549 2548 3079.871394642813721631306
2550 2549 3080.85638234197254749809
2551 2550 3082.163163759071705938955
2552 2551 3083.361357990431673945306
2553 2552 3084.838451504293315594439
2554 2553 3085.377268993634213100164
2555 2554 3085.96552225931062167729
2556 2555 3087.018815358645356167382
2557 2556 3088.083437042039377790693
2558 2557 3089.222308944517806296121
2559 2558 3090.282194902934828373465
2560 2559 3091.154469698493384814022
2561 2560 3092.687667040026927096669
2562 2561 3093.185445717523947539847
2563 2562 3094.833068430116325158114
2564 2563 3095.132031239453814405049
2565 2564 3096.515485512936433287197
2566 2565 3097.342606530991476389751
2567 2566 3098.038354972964634165924
2568 2567 3098.758089848813226278056
2569 2568 3101.079373086579266201903
2570 2569 3101.657370790144796557169
2571 2570 3102.436089122718192537554
2572 2571 3103.589916059588484008099
2573 2572 3104.362546341633841029486
2574 2573 3105.391402369857702780307
2575 2574 3106.396352646055475600068
2576 2575 3107.484255857023251197457
2577 2576 3108.303596266206330599604
2578 2577 3109.53309979035677203165
2579 2578 3110.557200380325680212218
2580 2579 3111.920727714090283124907
2581 2580 3112.84073785937315290221
2582 2581 3113.755213669486739332791
2583 2582 3114.473416203571962329658
2584 2583 3115.002672413544942605386
2585 2584 3116.720450815901517869103
2586 2585 3117.269723386899507206459
2587 2586 3118.955013666124334567057
2588 2587 3119.957556604338744135654
2589 2588 3120.986214975677487578649
2590 2589 3121.337219762925804002363
2591 2590 3122.610128875347619264062
2592 2591 3124.15022516432987171738
2593 2592 3124.525922645768604264818
2594 2593 3125.374441472110214656008
2595 2594 3126.450116434820057246934
2596 2595 3127.693012373442887604237
2597 2596 3129.468612609748064153091
2598 2597 3129.796205505420792431829
2599 2598 3130.877663729773828277277
2600 2599 3131.861090216301755055874
2601 2600 3132.698331366237529557118
2602 2601 3133.398883822980549090103
2603 2602 3134.635445901257679548083
2604 2603 3136.01556075204168210791
2605 2604 3137.175172666931396203768
2606 2605 3137.613495212022960485008
2607 2606 3139.049508498465517194745
2608 2607 3140.138494141052536644578
2609 2608 3141.001174828240382251755
2610 2609 3141.74803254288387940838
2611 2610 3142.979456728038722337401
2612 2611 3143.567499183578249704917
2613 2612 3144.490488145513050688511
2614 2613 3146.283528375944452145763
2615 2614 3147.344606625530372574765
2616 2615 3148.379041870468193505513
2617 2616 3148.861228783806526541779
2618 2617 3149.771738698990674432252
2619 2618 3150.824652722363499829892
2620 2619 3152.151059465736636027461
2621 2620 3152.994559995643581199062
2622 2621 3153.596976529534068961118
2623 2622 3155.312108217669944971217
2624 2623 3156.300357949570972091547
2625 2624 3156.905761454446546379407
2626 2625 3158.578287707936079910986
2627 2626 3159.265204659911244661193
2628 2627 3159.804097579086976713423
2629 2628 3161.061912577755098001948
2630 2629 3161.402435207892094347917
2631 2630 3163.311959557827161057799
2632 2631 3164.35053132092959483828
2633 2632 3165.54059789382948314752
2634 2633 3166.139586713599158182864
2635 2634 3167.121094757281260107132
2636 2635 3168.197515713895221076809
2637 2636 3169.179764607856546469709
2638 2637 3170.014131565626253552259
2639 2638 3171.343958069062042805582
2640 2639 3171.837774346067805220138
2641 2640 3173.011633917278397092887
2642 2641 3174.815385976386209966238
2643 2642 3175.528722743695324337451
2644 2643 3176.480343516462564475872
2645 2644 3176.915636009212935539448
2646 2645 3178.371705005000814341866
2647 2646 3178.902595536046510146304
2648 2647 3180.011213372893851882619
2649 2648 3181.328501713206250828388
2650 2649 3182.839446920271252891962
2651 2650 3183.205673345926898205755
2652 2651 3184.451499960332323149553
2653 2652 3185.214344580111471047419
2654 2653 3186.545869429537191384764
2655 2654 3187.646162708372385641981
2656 2655 3188.055482329445955800903
2657 2656 3188.877460714955629600238
2658 2657 3190.168661962152913633517
2659 2658 3191.706256362774499918137
2660 2659 3192.681791617886826657248
2661 2660 3193.557208472454684074536
2662 2661 3194.786707378558122382917
2663 2662 3195.326699929210305035032
2664 2663 3195.793895633893094622504
2665 2664 3197.547165656594029249623
2666 2665 3198.430125767817789743552
2667 2666 3199.248977114246401054548
2668 2667 3200.66327023074559227635
2669 2668 3201.424866361197312549627
2670 2669 3202.778286500735847541118
2671 2670 3203.630891152625213608279
2672 2671 3204.557410187842267700674
2673 2672 3205.497580563342251883904
2674 2673 3206.22889330382996201436
2675 2674 3207.270062357430561030771
2676 2675 3208.086133891918222198743
2677 2676 3210.352420539766727082765
2678 2677 3210.670388299201819085963
2679 2678 3211.618832522934956564643
2680 2679 3212.319227342931599790943
2681 2680 3213.606498798172233731539
2682 2681 3214.667562488094309240022
2683 2682 3215.325298903735371241088
2684 2683 3216.491524692370902474143
2685 2684 3217.430804778290282172144
2686 2685 3218.659983744025900190399
2687 2686 3219.639171305585305037367
2688 2687 3221.19834168296959514505
2689 2688 3221.609476301097409403826
2690 2689 3222.813840822902448192448
2691 2690 3223.372566375255521104614
2692 2691 3224.213706519638820464636
2693 2692 3225.366715964933818897246
2694 2693 3227.044102374515354443509
2695 2694 3227.525149515495061180533
2696 2695 3229.016311629953509730307
2697 2696 3229.981066960499388877113
2698 2697 3230.336636732169461220852
2699 2698 3231.741347918256233972565
2700 2699 3232.738713124808378130142
2701 2700 3233.913360603034175725564
2702 2701 3234.306591244919924810461
2703 2702 3235.154617182366475812645
2704 2703 3237.087579531708591928815
2705 2704 3237.998236326712589204578
2706 2705 3239.090434562689812449768
2707 2706 3239.76731407523959801581
2708 2707 3240.605747277956862198711
2709 2708 3241.595312938038556595314
2710 2709 3242.568307582365359198249
2711 2710 3243.501652711279887198695
2712 2711 3244.884157091134580115654
2713 2712 3246.040157816239797720052
2714 2713 3246.841676161959525694159
2715 2714 3247.570503533836460579108
2716 2715 3249.308085747434814590988
2717 2716 3249.906446318444415967392
2718 2717 3250.613324267405035189927
2719 2718 3251.510637744017582969145
2720 2719 3252.723990907270687158272
2721 2720 3253.369017244108257992217
2722 2721 3255.142076592548407877777
2723 2722 3256.346612817957653999222
2724 2723 3256.941943204737039133354
2725 2724 3257.831340012825337977778
2726 2725 3258.70671427545505340128
2727 2726 3259.539730686039659248328
2728 2727 3261.192124420504220716953
2729 2728 3261.535312602183417692445
2730 2729 3262.718968694528270682218
2731 2730 3263.78494048912647248176
2732 2731 3265.198771600650621898285
2733 2732 3266.15378641993579540004
2734 2733 3266.803954479647297578388
2735 2734 3268.188517855567123844392
2736 2735 3268.909408588716795153047
2737 2736 3269.51678536024809921278
2738 2737 3270.310803457827130573293
2739 2738 3272.019397610781094887448
2740 2739 3273.363032965270158222178
2741 2740 3274.059953011724818136298
2742 2741 3274.863567637972572131821
2743 2742 3276.124154984922090626336
2744 2743 3276.694554681215401362614
2745 2744 3278.059478289038270402537
2746 2745 3278.986193732023865913671
2747 2746 3279.489509639634966605547
2748 2747 3280.976418713721355348799
2749 2748 3281.70669082062175886775
2750 2749 3283.239124300114450886536
2751 2750 3284.499863132438584931466
2752 2751 3285.202828751691161488176
2753 2752 3285.682259710460894108015
2754 2753 3286.718540342294644164494
2755 2754 3287.773091992666597975722
2756 2755 3288.936972845327159588979
2757 2756 3289.724306536176169076498
2758 2757 3291.385725928433722910611
2759 2758 3292.222642049285009899049
2760 2759 3292.856716097554634971769
2761 2760 3293.975869245585136093182
2762 2761 3295.266663232727327626467
2763 2762 3296.021754764672060302692
2764 2763 3296.873142162695473488952
2765 2764 3297.836842310599282397956
2766 2765 3298.35787862156344129369
2767 2766 3300.450576192250525004255
2768 2767 3301.413776304367833885924
2769 2768 3302.01709766560449050995
2770 2769 3303.317261841697262716519
2771 2770 3303.813719205759852144816
2772 2771 3305.076177240834331712072
2773 2772 3305.472088698530180208821
2774 2773 3307.221711602476425917367
2775 2774 3308.045402223318982748747
2776 2775 3308.832877512969198407602
2777 2776 3310.235706773842968521381
2778 2777 3311.15530611827288501096
2779 2778 3312.349459450510319123683
2780 2779 3313.199876672725445138308
2781 2780 3313.842662273157149996819
2782 2781 3315.01501382797991005397
2783 2782 3315.619742540924528601965
2784 2783 3316.752453417716025589656
2785 2784 3318.387470170170478675355
2786 2785 3319.412648993159293997498
2787 2786 3320.476699682049447244704
2788 2787 3320.887941461201672133704
2789 2788 3321.663572698610211015802
2790 2789 3323.49092317979171947837
2791 2790 3323.875124914086264401145
2792 2791 3324.925684145982695330115
2793 2792 3325.691627038381709125749
2794 2793 3327.338441751472176750511
2795 2794 3327.98826920817017529723
2796 2795 3329.465583948409625625823
2797 2796 3330.290400360130219844494
2798 2797 3331.299404161488370421858
2799 2798 3331.892288243776279000784
2800 2799 3332.700898576001118556409
2801 2800 3333.781382961371509303428
2802 2801 3335.045996424475843016145
2803 2802 3336.575968429255216961522
2804 2803 3337.044211896701205873614
2805 2804 3338.150407356324767411543
2806 2805 3339.256673694617330510205
2807 2806 3340.117152697458989076575
2808 2807 3340.972263637847411333428
2809 2808 3342.211554859256917301118
2810 2809 3343.051722278339127690412
2811 2810 3343.6049085095928279984
2812 2811 3344.852255868193444556363
2813 2812 3346.848430816562101350416
2814 2813 3347.397830990955097521355
2815 2814 3347.936001610755013303903
2816 2815 3349.301027926845964516229
2817 2816 3349.856252114765060397869
2818 2817 3350.803704024568128833595
2819 2818 3352.153804096605706354558
2820 2819 3352.845364542639274646331
2821 2820 3354.278231280389732734155
2822 2821 3355.483680305992166158155
2823 2822 3355.880578183322015092159
2824 2823 3357.198154118336337409112
2825 2824 3358.402699623420513391359
2826 2825 3359.359283067236631377566
2827 2826 3359.852404381293300519676
2828 2827 3360.584153298317460106201
2829 2828 3361.887588621121048412545
2830 2829 3363.233878348850935833165
2831 2830 3364.35576355386237028717
2832 2831 3365.600957468561539405847
2833 2832 3366.120883810753051484352
2834 2833 3367.055542539618594379441
2835 2834 3367.769443868219103986577
2836 2835 3369.183728554805127239678
2837 2836 3370.061651746535245904354
2838 2837 3370.997536142718299903782
2839 2838 3371.922445600540289315795
2840 2839 3373.160140925225769804216
2841 2840 3374.42747199004650116919
2842 2841 3375.379955756309035727629
2843 2842 3376.298386044195575790359
2844 2843 3376.820970848442594658219
2845 2844 3378.258956962645052040874
2846 2845 3378.780608494869047029916
2847 2846 3379.460192668086182018733
2848 2847 3381.634647447098373954794
2849 2848 3382.296714921602043372692
2850 2849 3383.348489575834645347049
2851 2850 3383.871212415101493175623
2852 2851 3385.177310827910807710719
2853 2852 3386.166295750419583665821
2854 2853 3387.14956445934642983436
2855 2854 3387.808777785404583277855
2856 2855 3389.091880156599137301503
2857 2856 3389.648879040879658962026
2858 2857 3391.481233731884245223056
2859 2858 3392.147572630774221932891
2860 2859 3393.651785893134350471733
2861 2860 3394.13766635139364783238
2862 2861 3394.991106310709165727656
2863 2862 3395.614850938400898704643
2864 2863 3396.890066311007586694208
2865 2864 3398.271677189199063867006
2866 2865 3398.84119721990591006665
2867 2866 3400.322476548554032914663
2868 2867 3401.387450697162306480686
2869 2868 3402.000441414939204718612
2870 2869 3403.00886482018444292654
2871 2870 3404.362761572869179338124
2872 2871 3405.132918695120903243309
2873 2872 3405.809942804822240945244
2874 2873 3406.679482811959380378837
2875 2874 3407.728314289522088749114
2876 2875 3409.578736852470681075997
2877 2876 3410.424565211906291602865
2878 2877 3411.22363349727759897733
2879 2878 3411.855830275976530825615
2880 2879 3413.21903600534683702375
2881 2880 3413.710819476650165120964
2882 2881 3415.006415297804673981427
2883 2882 3415.806623572889535666055
2884 2883 3417.201725527572038894263
2885 2884 3418.194842708853560074495
2886 2885 3418.744246675150327036972
2887 2886 3420.540582987327352575289
2888 2887 3421.3075373182353124335
2889 2888 3421.882420407670481968623
2890 2889 3423.12859419232829395897
2891 2890 3423.611394671273642937988
2892 2891 3424.728989863384135984387
2893 2892 3425.830917735939438315602
2894 2893 3427.43181100569978399033
2895 2894 3428.345014648755457328078
2896 2895 3429.077161459129134002266
2897 2896 3430.158809529325825517425
2898 2897 3430.61161868017359007246
2899 2898 3432.026366531868686503828
2900 2899 3433.306331160306165797598
2901 2900 3433.769710163679019756695
2902 2901 3434.432930181269055513409
2903 2902 3436.183607569709236904282
2904 2903 3437.219161606905502377886
2905 2904 3438.212616154324993944634
2906 2905 3439.112430154170636995582
2907 2906 3440.229299588557141384727
2908 2907 3440.844025770543903456732
2909 2908 3441.467977670071328835466
2910 2909 3442.683392445439200520797
2911 2910 3444.036570701737662629919
2912 2911 3445.277432468729252246661
2913 2912 3446.015386158297972475766
2914 2913 3447.158925420623274971457
2915 2914 3447.700517605005566453896
2916 2915 3449.497002715466151504692
2917 2916 3449.68500106448041011419
2918 2917 3450.723487592525115796664
2919 2918 3451.940669427532542598583
2920 2919 3452.56981677166542460826
2921 2920 3453.677893918423440325633
2922 2921 3455.488799434788307255801
2923 2922 3456.258614559289426050508
2924 2923 3457.184172894584782544099
2925 2924 3457.573598857840152203968
2926 2925 3458.665410624784369257893
2927 2926 3460.046064018949500232569
2928 2927 3460.484230469053456704774
2929 2928 3461.91597119849383907924
2930 2929 3462.896732401836350478466
2931 2930 3464.08383216031446691628
2932 2931 3464.977695252427010404308
2933 2932 3465.827155727127310976651
2934 2933 3467.204403986263500585424
2935 2934 3467.909471078216765539772
2936 2935 3468.775551366812870431422
2937 2936 3469.551913132633304155837
2938 2937 3470.21410896144858466479
2939 2938 3472.249018221316013765705
2940 2939 3473.168763395135590199515
2941 2940 3473.814882020019058071445
2942 2941 3475.219106732750567370385
2943 2942 3475.71779281943085561728
2944 2943 3476.519931770807459761251
2945 2944 3477.700190284672462246426
2946 2945 3479.049830179214139446321
2947 2946 3479.465965312698372925499
2948 2947 3480.682915950611512287432
2949 2948 3481.776396694321817094612
2950 2949 3483.057856801383324829601
2951 2950 3484.15938804623392328704
2952 2951 3484.884585352891875690136
2953 2952 3485.691497728213846605443
2954 2953 3486.534339669457376093997
2955 2954 3487.539477842766211765717
2956 2955 3488.455776622254130102385
2957 2956 3489.665123316273469850097
2958 2957 3491.550561368235949774885
2959 2958 3491.811099965335454304974
2960 2959 3492.414435580418254574609
2961 2960 3493.720613082722983625876
2962 2961 3494.816408481537232133219
2963 2962 3495.988931967582387074883
2964 2963 3496.350361363768646776684
2965 2964 3497.372960542280375834219
2966 2965 3498.57613653901389306139
2967 2966 3499.686553821129431656351
2968 2967 3501.145919590462206622771
2969 2968 3501.897095232891164486617
2970 2969 3502.77586794857288073275
2971 2970 3503.63621579151093261458
2972 2971 3504.588927774941226318413
2973 2972 3504.992627195049954816113
2974 2973 3506.860778987002883813092
2975 2974 3507.545273797332293111855
2976 2975 3508.772500866958054949561
2977 2976 3509.636408038272356329351
2978 2977 3510.845083644571125639211
2979 2978 3511.731091112826518679587
2980 2979 3512.473586842893230449015
2981 2980 3513.877573873796726162339
2982 2981 3514.36675224394051215063
2983 2982 3515.416808849641115846399
2984 2983 3515.901814498895018015695
2985 2984 3518.026445239400234023475
2986 2985 3518.868409208556027115795
2987 2986 3519.870186740230064824073
2988 2987 3520.491665965545825865935
2989 2988 3521.365040902682598883688
2990 2989 3522.382212893841589858856
2991 2990 3523.635835723508375724121
2992 2991 3524.215220737581104589162
2993 2992 3525.386566637036723925035
2994 2993 3526.67025671132723479515
2995 2994 3527.615207050999354375843
2996 2995 3528.351824582806778596446
2997 2996 3529.955744345950771179874
2998 2997 3530.835046797711815440115
2999 2998 3531.201023963526098797839
3000 2999 3532.038508847499198516958
3001 3000 3533.328243395819939702367

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