Current task: —

E-022b-valley-analysis.py

Experiments: E-022b · script updated 08-19-2026

E-022b-valley.csv — 87.2 KB, updated 08-19-2026

← prev page 4 of 10 · 500/page · 4600 rows next →
# azlogK
1502 6 43.000 2.248734
1503 6 43.050 2.075576
1504 6 43.100 1.831342
1505 6 43.150 1.499108
1506 6 43.200 1.060644
1507 6 43.250 0.519091
1508 6 43.300 0.017936
1509 6 43.350 -0.008210
1510 6 43.400 0.472090
1511 6 43.450 1.017247
1512 6 43.500 1.463141
1513 6 43.550 1.802315
1514 6 43.600 2.052815
1515 6 43.650 2.231886
1516 6 43.700 2.353324
1517 6 43.750 2.428458
1518 6 43.800 2.467320
1519 6 43.850 2.479452
1520 6 43.900 2.474234
1521 6 43.950 2.460662
1522 6 44.000 2.446569
1523 6 44.050 2.437575
1524 6 44.100 2.436278
1525 6 44.150 2.442223
1526 6 44.200 2.452756
1527 6 44.250 2.464349
1528 6 44.300 2.473858
1529 6 44.350 2.479321
1530 6 44.400 2.480245
1531 6 44.450 2.477463
1532 6 44.500 2.472704
1533 6 44.550 2.467988
1534 6 44.600 2.465017
1535 6 44.650 2.464700
1536 6 44.700 2.466977
1537 6 44.750 2.470958
1538 6 44.800 2.475311
1539 6 44.850 2.478739
1540 6 44.900 2.480365
1541 6 44.950 2.479956
1542 6 45.000 2.477920
1543 6 45.050 2.475137
1544 6 45.100 2.472645
1545 6 45.150 2.471305
1546 6 45.200 2.471538
1547 6 45.250 2.473217
1548 6 45.300 2.475740
1549 6 45.350 2.478264
1550 6 45.400 2.479993
1551 6 45.450 2.480433
1552 6 45.500 2.479532
1553 6 45.550 2.477686
1554 6 45.600 2.475586
1555 6 45.650 2.473988
1556 6 45.700 2.473454
1557 6 45.750 2.474151
1558 6 45.800 2.475804
1559 6 45.850 2.477785
1560 6 45.900 2.479341
1561 6 45.950 2.479851
1562 6 46.000 2.479048
1563 6 46.050 2.477120
1564 6 46.100 2.474668
1565 6 46.150 2.472511
1566 6 46.200 2.471410
1567 6 46.250 2.471780
1568 6 46.300 2.473516
1569 6 46.350 2.475991
1570 6 46.400 2.478247
1571 6 46.450 2.479318
1572 6 46.500 2.478570
1573 6 46.550 2.475961
1574 6 46.600 2.472122
1575 6 46.650 2.468212
1576 6 46.700 2.465564
1577 6 46.750 2.465203
1578 6 46.800 2.467402
1579 6 46.850 2.471451
1580 6 46.900 2.475775
1581 6 46.950 2.478378
1582 6 47.000 2.477487
1583 6 47.050 2.472204
1584 6 47.100 2.462996
1585 6 47.150 2.451854
1586 6 47.200 2.441987
1587 6 47.250 2.436928
1588 6 47.300 2.439182
1589 6 47.350 2.448821
1590 6 47.400 2.462665
1591 6 47.450 2.474433
1592 6 47.500 2.475671
1593 6 47.550 2.456867
1594 6 47.600 2.408181
1595 6 47.650 2.319578
1596 6 47.700 2.180367
1597 6 47.750 1.978251
1598 6 47.800 1.698095
1599 6 47.850 1.321483
1600 6 47.900 0.833682
1601 6 47.950 0.274155
1602 6 48.000 -0.077242
1603 6 48.050 0.169622
1604 6 48.100 0.718871
1605 6 48.150 1.224285
1606 6 48.200 1.618956
1607 6 48.250 1.913917
1608 6 48.300 2.128163
1609 6 48.350 2.277810
1610 6 48.400 2.375934
1611 6 48.450 2.433708
1612 6 48.500 2.461284
1613 6 48.550 2.468152
1614 6 48.600 2.462957
1615 6 48.650 2.452895
1616 6 48.700 2.442995
1617 6 48.750 2.435774
1618 6 48.800 2.431569
1619 6 48.850 2.429504
1620 6 48.900 2.428650
1621 6 48.950 2.428860
1622 6 49.000 2.430947
1623 6 49.050 2.436124
1624 6 49.100 2.444920
1625 6 49.150 2.456031
1626 6 49.200 2.465642
1627 6 49.250 2.467488
1628 6 49.300 2.453489
1629 6 49.350 2.414507
1630 6 49.400 2.340786
1631 6 49.450 2.221888
1632 6 49.500 2.046071
1633 6 49.550 1.799236
1634 6 49.600 1.463980
1635 6 49.650 1.022122
1636 6 49.700 0.480131
1637 6 49.750 -0.003114
1638 6 49.800 0.010949
1639 6 49.850 0.506376
1640 6 49.900 1.048230
1641 6 49.950 1.488214
1642 6 50.000 1.822071
1643 6 50.050 2.067991
1644 6 50.100 2.243007
1645 6 50.150 2.360772
1646 6 50.200 2.432589
1647 6 50.250 2.468554
1648 6 50.300 2.478333
1649 6 50.350 2.471450
1650 6 50.400 2.456994
1651 6 50.450 2.442784
1652 6 50.500 2.434281
1653 6 50.550 2.433816
1654 6 50.600 2.440646
1655 6 50.650 2.451891
1656 6 50.700 2.463905
1657 6 50.750 2.473505
1658 6 50.800 2.478743
1659 6 50.850 2.479153
1660 6 50.900 2.475606
1661 6 50.950 2.469900
1662 6 51.000 2.464176
1663 6 51.050 2.460319
1664 6 51.100 2.459453
1665 6 51.150 2.461689
1666 6 51.200 2.466190
1667 6 51.250 2.471498
1668 6 51.300 2.476003
1669 6 51.350 2.478399
1670 6 51.400 2.478017
1671 6 51.450 2.474985
1672 6 51.500 2.470193
1673 6 51.550 2.465073
1674 6 51.600 2.461217
1675 6 51.650 2.459915
1676 6 51.700 2.461727
1677 6 51.750 2.466237
1678 6 51.800 2.472085
1679 6 51.850 2.477302
1680 6 51.900 2.479835
1681 6 51.950 2.478137
1682 6 52.000 2.471684
1683 6 52.050 2.461317
1684 6 52.100 2.449289
1685 6 52.150 2.438903
1686 6 52.200 2.433659
1687 6 52.250 2.435998
1688 6 52.300 2.446032
1689 6 52.350 2.460816
1690 6 52.400 2.474480
1691 6 52.450 2.479082
1692 6 52.500 2.465636
1693 6 52.550 2.424821
1694 6 52.600 2.347154
1695 6 52.650 2.222618
1696 6 52.700 2.039833
1697 6 52.750 1.784886
1698 6 52.800 1.440424
1699 6 52.850 0.988810
1700 6 52.900 0.441186
1701 6 52.950 -0.023407
1702 6 53.000 0.036341
1703 6 53.050 0.547239
1704 6 53.100 1.084125
1705 6 53.150 1.516643
1706 6 53.200 1.844121
1707 6 53.250 2.084841
1708 6 53.300 2.255482
1709 6 53.350 2.369421
1710 6 53.400 2.437836
1711 6 53.450 2.470862
1712 6 53.500 2.478348
1713 6 53.550 2.470081
1714 6 53.600 2.455368
1715 6 53.650 2.442036
1716 6 53.700 2.435218
1717 6 53.750 2.436622
1718 6 53.800 2.444800
1719 6 53.850 2.456357
1720 6 53.900 2.467504
1721 6 53.950 2.475333
1722 6 54.000 2.478481
1723 6 54.050 2.477217
1724 6 54.100 2.473071
1725 6 54.150 2.468183
1726 6 54.200 2.464557
1727 6 54.250 2.463424
1728 6 54.300 2.464931
1729 6 54.350 2.468241
1730 6 54.400 2.471976
1731 6 54.450 2.474786
1732 6 54.500 2.475832
1733 6 54.550 2.475025
1734 6 54.600 2.472981
1735 6 54.650 2.470735
1736 6 54.700 2.469307
1737 6 54.750 2.469296
1738 6 54.800 2.470645
1739 6 54.850 2.472682
1740 6 54.900 2.474402
1741 6 54.950 2.474898
1742 6 55.000 2.473739
1743 6 55.050 2.471185
1744 6 55.100 2.468142
1745 6 55.150 2.465843
1746 6 55.200 2.465355
1747 6 55.250 2.467086
1748 6 55.300 2.470484
1749 6 55.350 2.474111
1750 6 55.400 2.476064
1751 6 55.450 2.474639
1752 6 55.500 2.469015
1753 6 55.550 2.459754
1754 6 55.600 2.448951
1755 6 55.650 2.439856
1756 6 55.700 2.435915
1757 6 55.750 2.439350
1758 6 55.800 2.449781
1759 6 55.850 2.463527
1760 6 55.900 2.473894
1761 6 55.950 2.472182
1762 6 56.000 2.448777
1763 6 56.050 2.393806
1764 6 56.100 2.297165
1765 6 56.150 2.147973
1766 6 56.200 1.933546
1767 6 56.250 1.638161
1768 6 56.300 1.243093
1769 6 56.350 0.736926
1770 6 56.400 0.183146
1771 6 56.450 -0.078658
1772 6 56.500 0.260680
1773 6 56.550 0.818523
1774 6 56.600 1.307344
1775 6 56.650 1.685178
1776 6 56.700 1.966523
1777 6 56.750 2.169915
1778 6 56.800 2.310616
1779 6 56.850 2.400996
1780 6 56.900 2.451749
1781 6 56.950 2.472806
1782 6 57.000 2.473776
1783 6 57.050 2.463816
1784 6 57.100 2.450964
1785 6 57.150 2.441173
1786 6 57.200 2.437546
1787 6 57.250 2.440267
1788 6 57.300 2.447377
1789 6 57.350 2.456018
1790 6 57.400 2.463616
1791 6 57.450 2.468617
1792 6 57.500 2.470684
1793 6 57.550 2.470466
1794 6 57.600 2.469110
1795 6 57.650 2.467711
1796 6 57.700 2.466901
1797 6 57.750 2.466706
1798 6 57.800 2.466688
1799 6 57.850 2.466291
1800 6 57.900 2.465206
1801 6 57.950 2.463602
1802 6 58.000 2.462116
1803 6 58.050 2.461588
1804 6 58.100 2.462649
1805 6 58.150 2.465314
1806 6 58.200 2.468799
1807 6 58.250 2.471650
1808 6 58.300 2.472187
1809 6 58.350 2.469115
1810 6 58.400 2.462123
1811 6 58.450 2.452262
1812 6 58.500 2.441961
1813 6 58.550 2.434513
1814 6 58.600 2.433016
1815 6 58.650 2.439002
1816 6 58.700 2.451281
1817 6 58.750 2.465534
1818 6 58.800 2.474817
1819 6 58.850 2.470592
1820 6 58.900 2.443687
1821 6 58.950 2.384798
1822 6 59.000 2.284408
1823 6 59.050 2.132199
1824 6 59.100 1.916062
1825 6 59.150 1.620951
1826 6 59.200 1.229079
1827 6 59.250 0.730171
1828 6 59.300 0.186037
1829 6 59.350 -0.079883
1830 6 59.400 0.240965
1831 6 59.450 0.792226
1832 6 59.500 1.283561
1833 6 59.550 1.667318
1834 6 59.600 1.955659
1835 6 59.650 2.165876
1836 6 59.700 2.312168
1837 6 59.750 2.405804
1838 6 59.800 2.456373
1839 6 59.850 2.472976
1840 6 59.900 2.465127
1841 6 59.950 2.443204
1842 8 14.000 1.779814
1843 8 14.050 1.133179
1844 8 14.100 0.280431
1845 8 14.150 0.015608
1846 8 14.200 0.814567
1847 8 14.250 1.557401
1848 8 14.300 2.066136
1849 8 14.350 2.399753
1850 8 14.400 2.606653
1851 8 14.450 2.720066
1852 8 14.500 2.766126
1853 8 14.550 2.768752
1854 8 14.600 2.750986
1855 8 14.650 2.732740
1856 8 14.700 2.726350
1857 8 14.750 2.733829
1858 8 14.800 2.749040
1859 8 14.850 2.763387
1860 8 14.900 2.770895
1861 8 14.950 2.770342
1862 8 15.000 2.764647
1863 8 15.050 2.758589
1864 8 15.100 2.756070
1865 8 15.150 2.758246
1866 8 15.200 2.763432
1867 8 15.250 2.768579
1868 8 15.300 2.771194
1869 8 15.350 2.770570
1870 8 15.400 2.767841
1871 8 15.450 2.765085
1872 8 15.500 2.764050
1873 8 15.550 2.765227
1874 8 15.600 2.767764
1875 8 15.650 2.770147
1876 8 15.700 2.771157
1877 8 15.750 2.770512
1878 8 15.800 2.768898
1879 8 15.850 2.767457
1880 8 15.900 2.767088
1881 8 15.950 2.767953
1882 8 16.000 2.769477
1883 8 16.050 2.770766
1884 8 16.100 2.771166
1885 8 16.150 2.770604
1886 8 16.200 2.769568
1887 8 16.250 2.768755
1888 8 16.300 2.768653
1889 8 16.350 2.769274
1890 8 16.400 2.770202
1891 8 16.450 2.770893
1892 8 16.500 2.771001
1893 8 16.550 2.770566
1894 8 16.600 2.769936
1895 8 16.650 2.769533
1896 8 16.700 2.769586
1897 8 16.750 2.770023
1898 8 16.800 2.770543
1899 8 16.850 2.770836
1900 8 16.900 2.770767
1901 8 16.950 2.770445
1902 8 17.000 2.770122
1903 8 17.050 2.770019
1904 8 17.100 2.770190
1905 8 17.150 2.770504
1906 8 17.200 2.770748
1907 8 17.250 2.770778
1908 8 17.300 2.770608
1909 8 17.350 2.770380
1910 8 17.400 2.770260
1911 8 17.450 2.770314
1912 8 17.500 2.770476
1913 8 17.550 2.770597
1914 8 17.600 2.770572
1915 8 17.650 2.770414
1916 8 17.700 2.770253
1917 8 17.750 2.770238
1918 8 17.800 2.770418
1919 8 17.850 2.770691
1920 8 17.900 2.770861
1921 8 17.950 2.770772
1922 8 18.000 2.770429
1923 8 18.050 2.770019
1924 8 18.100 2.769800
1925 8 18.150 2.769934
1926 8 18.200 2.770357
1927 8 18.250 2.770800
1928 8 18.300 2.770945
1929 8 18.350 2.770639
1930 8 18.400 2.770011
1931 8 18.450 2.769425
1932 8 18.500 2.769259
1933 8 18.550 2.769653
1934 8 18.600 2.770392
1935 8 18.650 2.771001
1936 8 18.700 2.771035
1937 8 18.750 2.770369
1938 8 18.800 2.769320
1939 8 18.850 2.768488
1940 8 18.900 2.768393
1941 8 18.950 2.769132
1942 8 19.000 2.770257
1943 8 19.050 2.771016
1944 8 19.100 2.770803
1945 8 19.150 2.769573
1946 8 19.200 2.767936
1947 8 19.250 2.766847
1948 8 19.300 2.767023
1949 8 19.350 2.768439
1950 8 19.400 2.770242
1951 8 19.450 2.771200
1952 8 19.500 2.770444
1953 8 19.550 2.768081
1954 8 19.600 2.765266
1955 8 19.650 2.763619
1956 8 19.700 2.764236
1957 8 19.750 2.766874
1958 8 19.800 2.769892
1959 8 19.850 2.771095
1960 8 19.900 2.769052
1961 8 19.950 2.764147
1962 8 20.000 2.758690
1963 8 20.050 2.755834
1964 8 20.100 2.757641
1965 8 20.150 2.763414
1966 8 20.200 2.769513
1967 8 20.250 2.771050
1968 8 20.300 2.764633
1969 8 20.350 2.750826
1970 8 20.400 2.735079
1971 8 20.450 2.725980
1972 8 20.500 2.730444
1973 8 20.550 2.747791
1974 8 20.600 2.766906
1975 8 20.650 2.768505
1976 8 20.700 2.729687
1977 8 20.750 2.626637
1978 8 20.800 2.433765
1979 8 20.850 2.119285
1980 8 20.900 1.637440
1981 8 20.950 0.927906
1982 8 21.000 0.091338
1983 8 21.050 0.173537
1984 8 21.100 1.024516
1985 8 21.150 1.703869
1986 8 21.200 2.162337
1987 8 21.250 2.460255
1988 8 21.300 2.641275
1989 8 21.350 2.736044
1990 8 21.400 2.769607
1991 8 21.450 2.765411
1992 8 21.500 2.745822
1993 8 21.550 2.729259
1994 8 21.600 2.725843
1995 8 21.650 2.735569
1996 8 21.700 2.751392
1997 8 21.750 2.764952
1998 8 21.800 2.771064
1999 8 21.850 2.769273
2000 8 21.900 2.762930
2001 8 21.950 2.756863

E-022b-valley.json — 3.5 KB, updated 08-19-2026

JSON sidecar (click to expand)
{
  "experiment": "E-022b",
  "task": "2.10 analysis: K-diagonal valleys + mass concentration",
  "script": "research/numerics/scripts/E-022b-valley-analysis.py",
  "checks": {
    "V1_valleys_at_gamma": true,
    "V2_mass_concentrated": true,
    "V4_fit_quality": true
  },
  "key_values": {
    "4": {
      "valley_depth": 2.1593140478568413,
      "logK_at_gamma": -0.106956845297883,
      "logK_at_midpoints": 2.0523572025589583,
      "mass_frac_pm0.1": 0.6338714893637662,
      "uniform_expectation": 0.09000000000000001,
      "mass_ratio_vs_uniform": 7.043016548486291,
      "within_bin_meanlogw": {
        "z10-60_d0.0-0.1": 0.05321233524569066,
        "z10-60_d0.3-0.7": -1.7997896503200193,
        "z120-200_d0.0-0.1": 0.10247759965464488,
        "z120-200_d0.3-0.7": -1.7570525979064509
      },
      "elapsed_s": 2.9
    },
    "6": {
      "valley_depth": 2.5087271936533595,
      "logK_at_gamma": -0.04029578260580941,
      "logK_at_midpoints": 2.46843141104755,
      "mass_frac_pm0.1": 0.6986826134175042,
      "uniform_expectation": 0.09000000000000001,
      "mass_ratio_vs_uniform": 7.7631401490833785,
      "within_bin_meanlogw": {
        "z10-60_d0.0-0.1": -0.10145611105454076,
        "z10-60_d0.3-0.7": -2.4097253102207548,
        "z120-200_d0.0-0.1": 0.029192545882919238,
        "z120-200_d0.3-0.7": -2.314439077156247
      },
      "elapsed_s": 5.1
    },
    "8": {
      "valley_depth": 2.7352201581877043,
      "logK_at_gamma": 0.030554703235580436,
      "logK_at_midpoints": 2.7657748614232847,
      "mass_frac_pm0.1": 0.7251109123178877,
      "uniform_expectation": 0.09000000000000001,
      "mass_ratio_vs_uniform": 8.056787914643197,
      "within_bin_meanlogw": {
        "z10-60_d0.0-0.1": -0.1389960979715335,
        "z10-60_d0.3-0.7": -2.7392603482112916,
        "z120-200_d0.0-0.1": -0.20043183472111312,
        "z120-200_d0.3-0.7": -2.6451890375288283
      },
      "elapsed_s": 7.9
    },
    "10": {
      "valley_depth": 2.8706885758089333,
      "logK_at_gamma": 0.11948603922925684,
      "logK_at_midpoints": 2.9901746150381903,
      "mass_frac_pm0.1": 0.7251715332604941,
      "uniform_expectation": 0.09000000000000001,
      "mass_ratio_vs_uniform": 8.057461480672156,
      "within_bin_meanlogw": {
        "z10-60_d0.0-0.1": -0.07371951844373904,
        "z10-60_d0.3-0.7": -2.974563705268562,
        "z120-200_d0.0-0.1": -0.2233480705431757,
        "z120-200_d0.3-0.7": -2.8788847145178686
      },
      "elapsed_s": 11.4
    },
    "12": {
      "valley_depth": 2.9442229398281423,
      "logK_at_gamma": 0.22834844487190686,
      "logK_at_midpoints": 3.172571384700049,
      "mass_frac_pm0.1": 0.7241062961289328,
      "uniform_expectation": 0.09000000000000001,
      "mass_ratio_vs_uniform": 8.045625512543698,
      "within_bin_meanlogw": {
        "z10-60_d0.0-0.1": -0.1831905054381875,
        "z10-60_d0.3-0.7": -3.1605455546413452,
        "z120-200_d0.0-0.1": -0.35321115246295404,
        "z120-200_d0.3-0.7": -3.0663074224107776
      },
      "elapsed_s": 15.5
    },
    "V4_saturation_fit": {
      "Delta_inf": 3.3338697242432738,
      "c": 4.760242352939846,
      "max_resid": 0.03176880509994007
    },
    "valley_depths": {
      "4.0": 2.1593140478568413,
      "6.0": 2.5087271936533595,
      "8.0": 2.7352201581877043,
      "10.0": 2.8706885758089333,
      "12.0": 2.9442229398281423
    }
  },
  "elapsed_seconds": 59.7,
  "timestamp_utc": "2026-08-19T17:37:47.138364+00:00"
}

Source code

Python script (click to expand)
"""E-022b — task 2.10 analysis stage: reproducing-kernel valley structure
and gamma-mass concentration (post-hoc analysis of E-022).

E-022 found the coarse weak metric flat (O3) but a persistent mass
elevation near the true zeros. This script resolves the mechanism:

  K_a(z,z) := Re(b_z^H v), v the bordered (L^2_0) Galerkin solution of
  T_a v = e^{-izx} — the diagonal of the model-space reproducing kernel.

Measurements (a in {4,6,8,10,12}, theta=pi):
  V1. valley depth: Delta(a) = mean log K at gamma-gap midpoints minus
      mean log K at gammas, z-grid step 0.05 in [14,60).
  V2. mass concentration: fraction of the E-022 spectral mass within
      +/-0.1 of a true zero (vs uniform-lattice expectation).
  V3. artifact control: mean log w vs distance-to-nearest-gamma WITHIN
      z-bins (controls the gamma-density/weight-trend confound that
      naive O5 fails — shifted-gamma null test showed the raw O5
      elevation is mostly distributional).
  V4. saturation model: Delta(a) ~ Delta_inf - c/a fit.

Outputs: research/numerics/data/E-022b-valley.csv (+ .json)
"""
import importlib.util
import json
import sys
import time
from datetime import datetime, timezone
from pathlib import Path

import mpmath as mp
import numpy as np
import scipy.linalg

REPO = Path(__file__).resolve().parents[3]
DATA = REPO / "research" / "numerics" / "data"
CSV = DATA / "E-022b-valley.csv"
JSON = DATA / "E-022b-valley.json"

spec = importlib.util.spec_from_file_location(
    "E16", Path(__file__).with_name("E-016-herglotz-fine-structure.py"))
E16 = importlib.util.module_from_spec(spec)
spec.loader.exec_module(E16)                     # runs the e^20 sieve
sys.path.insert(0, str(Path(__file__).parent))
from prime_backend_v2 import PrimeBackendV2       # noqa: E402

H = E16.H_MAIN
LAM = E16.LAM_SHIFT
A_LIST = (4.0, 6.0, 8.0, 10.0, 12.0)
XN = E16.XN


def collect_t_points(a, h):
    n_elem = int(round(2 * a / h))
    pts = []

    def add_quad(lo, hi, peak):
        n_lo = int(np.ceil(np.exp(lo)))
        n_hi = int(np.floor(np.exp(hi)))
        if n_hi - n_lo > 64:
            for aa, bb in ((lo, peak), (peak, hi)):
                if bb - aa > 0:
                    mid, half = 0.5 * (aa + bb), 0.5 * (bb - aa)
                    pts.extend(mid + half * XN)
            return
        segs = sorted({lo, peak, hi} |
                      {float(np.log(n))
                       for n in range(max(n_lo, 2), n_hi + 1)
                       if lo < np.log(n) < hi})
        for p0, p1 in zip(segs, segs[1:]):
            if p1 - p0 > 0:
                mid, half = 0.5 * (p0 + p1), 0.5 * (p1 - p0)
                pts.extend(mid + half * XN)

    for k in range(n_elem):
        if k == 0:
            add_quad(0.0, h, 0.0)
        else:
            add_quad((k - 1) * h, (k + 1) * h, k * h)
    return np.array(pts)


def make_K1(a):
    x, h, Q, M, _b = E16.build(a, H)
    n = Q.shape[0]
    mc = np.zeros(n)
    mc[0] = 2 * h / 3
    mc[1] = h / 6
    tc = Q[:, 0] - LAM * mc
    u1 = scipy.linalg.solve_toeplitz((tc, tc), np.ones(n))
    s1 = u1.sum()

    def K1(z):
        bz = E16.hat_FT(np.array([z]), h)[0] * np.exp(-1j * z * x)
        u0 = scipy.linalg.solve_toeplitz((tc, tc), bz)
        v = u0 - (u0.sum() / s1) * u1
        return float(np.real(np.conj(bz) @ v))

    return K1


def main() -> int:
    if JSON.exists() and "--force" not in sys.argv:
        print(f"cached: {JSON} (use --force to recompute)")
        return 0
    t0 = time.time()

    tq = np.concatenate([collect_t_points(a, H) for a in A_LIST])
    be = PrimeBackendV2(tq)
    be.load_cache(DATA / "E-022-backend-cache.npz")
    E16._BUILD.clear()
    E16.prime_sum_vec = be.prime_sum

    mp.mp.dps = 30
    gam_all = np.array([float(mp.zetazero(k).imag)
                        for k in range(1, 201)])
    gam = gam_all[gam_all <= 280]

    # E-022 weights
    import csv as csvmod
    data = {}
    with open(DATA / "E-022-spectral-measure.csv") as f:
        for r in csvmod.DictReader(f):
            data.setdefault(float(r["a"]), []).append(
                (float(r["z_k"]), float(r["w_k"])))

    zgrid = np.arange(14.0, 60.0, 0.05)
    gsel = gam_all[(gam_all >= 14) & (gam_all < 60)]
    mids = (gsel[:-1] + gsel[1:]) / 2
    idxg = np.round((gsel - 14) / 0.05).astype(int)
    idxm = np.round((mids - 14) / 0.05).astype(int)

    per_a = {}
    grid_rows = []
    for a in A_LIST:
        ta = time.time()
        K1 = make_K1(a)
        lg = np.array([np.log(K1(z)) for z in zgrid])
        dip = float(lg[idxm].mean() - lg[idxg].mean())
        # mass fraction within +-0.1 of gamma (full window to 280)
        z = np.array([p[0] for p in data[a]])
        w = np.array([p[1] for p in data[a]])
        m = z <= 280
        zm, wm = z[m], w[m]
        idx = np.clip(np.searchsorted(gam, zm), 1, len(gam) - 1)
        d = np.minimum(np.abs(zm - gam[idx - 1]), np.abs(zm - gam[idx]))
        frac = float(wm[d <= 0.1].sum() / wm.sum())
        unif = float(0.2 * len(gam) / 280.0)
        # V3: within-z-bin mean log w by distance bin
        lw = np.log(wm)
        bins = {}
        for lo, hi in ((10, 60), (120, 200)):
            sel = (zm >= lo) & (zm < hi)
            for blo, bhi in ((0.0, 0.1), (0.3, 0.7)):
                s2 = sel & (d >= blo) & (d < bhi)
                if s2.sum() > 3:
                    bins[f"z{lo}-{hi}_d{blo}-{bhi}"] = float(lw[s2].mean())
        per_a[f"{a:g}"] = {
            "valley_depth": dip,
            "logK_at_gamma": float(lg[idxg].mean()),
            "logK_at_midpoints": float(lg[idxm].mean()),
            "mass_frac_pm0.1": frac,
            "uniform_expectation": unif,
            "mass_ratio_vs_uniform": frac / unif,
            "within_bin_meanlogw": bins,
            "elapsed_s": round(time.time() - ta, 1),
        }
        print(f"a={a:g}: dip={dip:.4f}, massfrac={frac:.4f} "
              f"({per_a[f'{a:g}']['elapsed_s']}s)", flush=True)
        for zz, ll in zip(zgrid, lg):
            grid_rows.append((a, zz, ll))

    # V4: saturation fit Delta(a) = Dinf - c/a
    av = np.array(A_LIST)
    dv = np.array([per_a[f"{a:g}"]["valley_depth"] for a in A_LIST])
    Afit = np.vstack([np.ones_like(av), -1.0 / av]).T
    Dinf, c = np.linalg.lstsq(Afit, dv, rcond=None)[0]
    resid = dv - (Dinf - c / av)
    print(f"V4: Delta_inf = {Dinf:.3f}, c = {c:.3f}, "
          f"max fit resid {np.abs(resid).max():.4f}", flush=True)

    checks = {
        "V1_valleys_at_gamma": bool(np.all(dv > 1.5)),
        "V2_mass_concentrated": bool(np.all(
            [per_a[f"{a:g}"]["mass_frac_pm0.1"] > 0.5 for a in A_LIST])),
        "V4_fit_quality": bool(np.abs(resid).max() < 0.1),
    }

    with open(CSV, "w", newline="") as f:
        wcsv = csvmod.writer(f)
        wcsv.writerow(["a", "z", "logK"])
        for a, zz, ll in grid_rows:
            wcsv.writerow([f"{a:g}", f"{zz:.3f}", f"{ll:.6f}"])

    meta = {
        "experiment": "E-022b",
        "task": "2.10 analysis: K-diagonal valleys + mass concentration",
        "script": "research/numerics/scripts/E-022b-valley-analysis.py",
        "checks": checks,
        "key_values": {**per_a,
                       "V4_saturation_fit": {"Delta_inf": float(Dinf),
                                             "c": float(c),
                                             "max_resid": float(
                                                 np.abs(resid).max())},
                       "valley_depths": dict(zip([str(a) for a in av],
                                                 dv.tolist()))},
        "elapsed_seconds": round(time.time() - t0, 1),
        "timestamp_utc": datetime.now(timezone.utc).isoformat(),
    }
    JSON.write_text(json.dumps(meta, indent=2))
    print(f"wrote {CSV.name}, {JSON.name}; elapsed "
          f"{meta['elapsed_seconds']}s", flush=True)
    return 0 if all(checks.values()) else 1


if __name__ == "__main__":
    sys.exit(main())