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 3 of 10 · 500/page · 4600 rows next →
# azlogK
1002 6 18.000 2.480359
1003 6 18.050 2.479324
1004 6 18.100 2.478883
1005 6 18.150 2.479185
1006 6 18.200 2.480131
1007 6 18.250 2.481405
1008 6 18.300 2.482573
1009 6 18.350 2.483220
1010 6 18.400 2.483092
1011 6 18.450 2.482180
1012 6 18.500 2.480738
1013 6 18.550 2.479206
1014 6 18.600 2.478077
1015 6 18.650 2.477734
1016 6 18.700 2.478310
1017 6 18.750 2.479630
1018 6 18.800 2.481252
1019 6 18.850 2.482599
1020 6 18.900 2.483149
1021 6 18.950 2.482606
1022 6 19.000 2.481021
1023 6 19.050 2.478801
1024 6 19.100 2.476604
1025 6 19.150 2.475140
1026 6 19.200 2.474928
1027 6 19.250 2.476098
1028 6 19.300 2.478301
1029 6 19.350 2.480785
1030 6 19.400 2.482614
1031 6 19.450 2.482966
1032 6 19.500 2.481422
1033 6 19.550 2.478153
1034 6 19.600 2.473944
1035 6 19.650 2.470013
1036 6 19.700 2.467653
1037 6 19.750 2.467774
1038 6 19.800 2.470512
1039 6 19.850 2.475046
1040 6 19.900 2.479745
1041 6 19.950 2.482609
1042 6 20.000 2.481873
1043 6 20.050 2.476626
1044 6 20.100 2.467268
1045 6 20.150 2.455693
1046 6 20.200 2.445027
1047 6 20.250 2.438849
1048 6 20.300 2.439921
1049 6 20.350 2.448816
1050 6 20.400 2.463008
1051 6 20.450 2.476871
1052 6 20.500 2.482487
1053 6 20.550 2.470737
1054 6 20.600 2.432108
1055 6 20.650 2.356942
1056 6 20.700 2.235102
1057 6 20.750 2.055160
1058 6 20.800 1.803204
1059 6 20.850 1.461846
1060 6 20.900 1.012958
1061 6 20.950 0.464834
1062 6 21.000 -0.012960
1063 6 21.050 0.025183
1064 6 21.100 0.532198
1065 6 21.150 1.073291
1066 6 21.200 1.509970
1067 6 21.250 1.840509
1068 6 21.300 2.083414
1069 6 21.350 2.255636
1070 6 21.400 2.370746
1071 6 21.450 2.440042
1072 6 21.500 2.473730
1073 6 21.550 2.481694
1074 6 21.600 2.473727
1075 6 21.650 2.459129
1076 6 21.700 2.445727
1077 6 21.750 2.438679
1078 6 21.800 2.439750
1079 6 21.850 2.447571
1080 6 21.900 2.458831
1081 6 21.950 2.469807
1082 6 22.000 2.477621
1083 6 22.050 2.480910
1084 6 22.100 2.479905
1085 6 22.150 2.476072
1086 6 22.200 2.471482
1087 6 22.250 2.468080
1088 6 22.300 2.467073
1089 6 22.350 2.468631
1090 6 22.400 2.471974
1091 6 22.450 2.475793
1092 6 22.500 2.478787
1093 6 22.550 2.480112
1094 6 22.600 2.479623
1095 6 22.650 2.477836
1096 6 22.700 2.475679
1097 6 22.750 2.474110
1098 6 22.800 2.473753
1099 6 22.850 2.474685
1100 6 22.900 2.476440
1101 6 22.950 2.478238
1102 6 23.000 2.479308
1103 6 23.050 2.479207
1104 6 23.100 2.477988
1105 6 23.150 2.476177
1106 6 23.200 2.474563
1107 6 23.250 2.473874
1108 6 23.300 2.474460
1109 6 23.350 2.476118
1110 6 23.400 2.478138
1111 6 23.450 2.479562
1112 6 23.500 2.479559
1113 6 23.550 2.477780
1114 6 23.600 2.474557
1115 6 23.650 2.470867
1116 6 23.700 2.468033
1117 6 23.750 2.467234
1118 6 23.800 2.468988
1119 6 23.850 2.472817
1120 6 23.900 2.477266
1121 6 23.950 2.480309
1122 6 24.000 2.480009
1123 6 24.050 2.475239
1124 6 24.100 2.466247
1125 6 24.150 2.454897
1126 6 24.200 2.444419
1127 6 24.250 2.438541
1128 6 24.300 2.440100
1129 6 24.350 2.449535
1130 6 24.400 2.463952
1131 6 24.450 2.477201
1132 6 24.500 2.480829
1133 6 24.550 2.465268
1134 6 24.600 2.420653
1135 6 24.650 2.337014
1136 6 24.700 2.203850
1137 6 24.750 2.009208
1138 6 24.800 1.738432
1139 6 24.850 1.373451
1140 6 24.900 0.897966
1141 6 24.950 0.338635
1142 6 25.000 -0.063740
1143 6 25.050 0.117024
1144 6 25.100 0.659012
1145 6 25.150 1.178837
1146 6 25.200 1.589036
1147 6 25.250 1.897362
1148 6 25.300 2.122695
1149 6 25.350 2.281229
1150 6 25.400 2.385905
1151 6 25.450 2.447601
1152 6 25.500 2.476214
1153 6 25.550 2.481305
1154 6 25.600 2.472238
1155 6 25.650 2.457736
1156 6 25.700 2.444963
1157 6 25.750 2.438498
1158 6 25.800 2.439790
1159 6 25.850 2.447484
1160 6 25.900 2.458513
1161 6 25.950 2.469448
1162 6 26.000 2.477582
1163 6 26.050 2.481517
1164 6 26.100 2.481257
1165 6 26.150 2.477937
1166 6 26.200 2.473335
1167 6 26.250 2.469283
1168 6 26.300 2.467146
1169 6 26.350 2.467485
1170 6 26.400 2.470009
1171 6 26.450 2.473795
1172 6 26.500 2.477661
1173 6 26.550 2.480559
1174 6 26.600 2.481856
1175 6 26.650 2.481457
1176 6 26.700 2.479762
1177 6 26.750 2.477493
1178 6 26.800 2.475454
1179 6 26.850 2.474288
1180 6 26.900 2.474312
1181 6 26.950 2.475453
1182 6 27.000 2.477317
1183 6 27.050 2.479331
1184 6 27.100 2.480930
1185 6 27.150 2.481714
1186 6 27.200 2.481542
1187 6 27.250 2.480555
1188 6 27.300 2.479113
1189 6 27.350 2.477683
1190 6 27.400 2.476703
1191 6 27.450 2.476460
1192 6 27.500 2.477012
1193 6 27.550 2.478182
1194 6 27.600 2.479615
1195 6 27.650 2.480881
1196 6 27.700 2.481600
1197 6 27.750 2.481552
1198 6 27.800 2.480738
1199 6 27.850 2.479386
1200 6 27.900 2.477891
1201 6 27.950 2.476708
1202 6 28.000 2.476212
1203 6 28.050 2.476583
1204 6 28.100 2.477736
1205 6 28.150 2.479328
1206 6 28.200 2.480854
1207 6 28.250 2.481788
1208 6 28.300 2.481748
1209 6 28.350 2.480625
1210 6 28.400 2.478645
1211 6 28.450 2.476329
1212 6 28.500 2.474356
1213 6 28.550 2.473362
1214 6 28.600 2.473721
1215 6 28.650 2.475388
1216 6 28.700 2.477873
1217 6 28.750 2.480349
1218 6 28.800 2.481895
1219 6 28.850 2.481782
1220 6 28.900 2.479733
1221 6 28.950 2.476070
1222 6 29.000 2.471693
1223 6 29.050 2.467870
1224 6 29.100 2.465856
1225 6 29.150 2.466453
1226 6 29.200 2.469645
1227 6 29.250 2.474471
1228 6 29.300 2.479218
1229 6 29.350 2.481880
1230 6 29.400 2.480760
1231 6 29.450 2.475064
1232 6 29.500 2.465323
1233 6 29.550 2.453535
1234 6 29.600 2.442876
1235 6 29.650 2.436894
1236 6 29.700 2.438258
1237 6 29.750 2.447420
1238 6 29.800 2.461776
1239 6 29.850 2.475701
1240 6 29.900 2.481370
1241 6 29.950 2.469819
1242 6 30.000 2.431718
1243 6 30.050 2.357607
1244 6 30.100 2.237566
1245 6 30.150 2.060417
1246 6 30.200 1.812569
1247 6 30.250 1.477009
1248 6 30.300 1.035644
1249 6 30.350 0.493720
1250 6 30.400 0.004284
1251 6 30.450 0.004500
1252 6 30.500 0.495768
1253 6 30.550 1.040397
1254 6 30.600 1.484157
1255 6 30.650 1.821405
1256 6 30.700 2.070044
1257 6 30.750 2.246956
1258 6 30.800 2.365664
1259 6 30.850 2.437384
1260 6 30.900 2.472250
1261 6 30.950 2.480171
1262 6 31.000 2.471171
1263 6 31.050 2.455044
1264 6 31.100 2.440302
1265 6 31.150 2.432764
1266 6 31.200 2.434513
1267 6 31.250 2.443978
1268 6 31.300 2.457186
1269 6 31.350 2.469564
1270 6 31.400 2.477502
1271 6 31.450 2.479275
1272 6 31.500 2.475285
1273 6 31.550 2.467732
1274 6 31.600 2.459845
1275 6 31.650 2.454792
1276 6 31.700 2.454573
1277 6 31.750 2.459283
1278 6 31.800 2.467076
1279 6 31.850 2.474847
1280 6 31.900 2.479327
1281 6 31.950 2.478176
1282 6 32.000 2.470783
1283 6 32.050 2.458641
1284 6 32.100 2.445172
1285 6 32.150 2.434894
1286 6 32.200 2.431943
1287 6 32.250 2.438289
1288 6 32.300 2.452390
1289 6 32.350 2.468957
1290 6 32.400 2.479859
1291 6 32.450 2.475525
1292 6 32.500 2.446054
1293 6 32.550 2.381659
1294 6 32.600 2.272428
1295 6 32.650 2.107545
1296 6 32.700 1.874129
1297 6 32.750 1.556062
1298 6 32.800 1.135051
1299 6 32.850 0.607306
1300 6 32.900 0.078644
1301 6 32.950 -0.048973
1302 6 33.000 0.380488
1303 6 33.050 0.933140
1304 6 33.100 1.397304
1305 6 33.150 1.753344
1306 6 33.200 2.017921
1307 6 33.250 2.208567
1308 6 33.300 2.339409
1309 6 33.350 2.421932
1310 6 33.400 2.466193
1311 6 33.450 2.481725
1312 6 33.500 2.477980
1313 6 33.550 2.464226
1314 6 33.600 2.448827
1315 6 33.650 2.438123
1316 6 33.700 2.435419
1317 6 33.750 2.440719
1318 6 33.800 2.451446
1319 6 33.850 2.463835
1320 6 33.900 2.474339
1321 6 33.950 2.480611
1322 6 34.000 2.481909
1323 6 34.050 2.479013
1324 6 34.100 2.473779
1325 6 34.150 2.468484
1326 6 34.200 2.465099
1327 6 34.250 2.464716
1328 6 34.300 2.467291
1329 6 34.350 2.471794
1330 6 34.400 2.476662
1331 6 34.450 2.480376
1332 6 34.500 2.481937
1333 6 34.550 2.481130
1334 6 34.600 2.478522
1335 6 34.650 2.475228
1336 6 34.700 2.472513
1337 6 34.750 2.471364
1338 6 34.800 2.472172
1339 6 34.850 2.474619
1340 6 34.900 2.477829
1341 6 34.950 2.480699
1342 6 35.000 2.482281
1343 6 35.050 2.482095
1344 6 35.100 2.480270
1345 6 35.150 2.477491
1346 6 35.200 2.474758
1347 6 35.250 2.473043
1348 6 35.300 2.472950
1349 6 35.350 2.474498
1350 6 35.400 2.477119
1351 6 35.450 2.479862
1352 6 35.500 2.481726
1353 6 35.550 2.482014
1354 6 35.600 2.480569
1355 6 35.650 2.477843
1356 6 35.700 2.474754
1357 6 35.750 2.472384
1358 6 35.800 2.471588
1359 6 35.850 2.472672
1360 6 35.900 2.475242
1361 6 35.950 2.478322
1362 6 36.000 2.480680
1363 6 36.050 2.481256
1364 6 36.100 2.479561
1365 6 36.150 2.475888
1366 6 36.200 2.471294
1367 6 36.250 2.467299
1368 6 36.300 2.465377
1369 6 36.350 2.466378
1370 6 36.400 2.470109
1371 6 36.450 2.475256
1372 6 36.500 2.479731
1373 6 36.550 2.481310
1374 6 36.600 2.478390
1375 6 36.650 2.470627
1376 6 36.700 2.459315
1377 6 36.750 2.447323
1378 6 36.800 2.438470
1379 6 36.850 2.436292
1380 6 36.900 2.442498
1381 6 36.950 2.455705
1382 6 37.000 2.471083
1383 6 37.050 2.481019
1384 6 37.100 2.476315
1385 6 37.150 2.447231
1386 6 37.200 2.383964
1387 6 37.250 2.276483
1388 6 37.300 2.113822
1389 6 37.350 1.882960
1390 6 37.400 1.567636
1391 6 37.450 1.149258
1392 6 37.500 0.622758
1393 6 37.550 0.088957
1394 6 37.600 -0.053295
1395 6 37.650 0.369923
1396 6 37.700 0.924268
1397 6 37.750 1.390676
1398 6 37.800 1.748127
1399 6 37.850 2.013422
1400 6 37.900 2.204395
1401 6 37.950 2.335444
1402 6 38.000 2.418280
1403 6 38.050 2.463120
1404 6 38.100 2.479560
1405 6 38.150 2.476980
1406 6 38.200 2.464416
1407 6 38.250 2.449881
1408 6 38.300 2.439375
1409 6 38.350 2.436046
1410 6 38.400 2.440035
1411 6 38.450 2.449179
1412 6 38.500 2.460238
1413 6 38.550 2.470119
1414 6 38.600 2.476708
1415 6 38.650 2.479192
1416 6 38.700 2.477974
1417 6 38.750 2.474322
1418 6 38.800 2.469878
1419 6 38.850 2.466166
1420 6 38.900 2.464213
1421 6 38.950 2.464373
1422 6 39.000 2.466364
1423 6 39.050 2.469478
1424 6 39.100 2.472845
1425 6 39.150 2.475675
1426 6 39.200 2.477406
1427 6 39.250 2.477763
1428 6 39.300 2.476752
1429 6 39.350 2.474613
1430 6 39.400 2.471778
1431 6 39.450 2.468816
1432 6 39.500 2.466370
1433 6 39.550 2.465053
1434 6 39.600 2.465303
1435 6 39.650 2.467217
1436 6 39.700 2.470423
1437 6 39.750 2.474050
1438 6 39.800 2.476851
1439 6 39.850 2.477481
1440 6 39.900 2.474886
1441 6 39.950 2.468714
1442 6 40.000 2.459644
1443 6 40.050 2.449490
1444 6 40.100 2.440970
1445 6 40.150 2.437008
1446 6 40.200 2.439669
1447 6 40.250 2.449009
1448 6 40.300 2.462330
1449 6 40.350 2.474178
1450 6 40.400 2.477011
1451 6 40.450 2.462096
1452 6 40.500 2.420193
1453 6 40.550 2.341747
1454 6 40.600 2.216568
1455 6 40.650 2.033029
1456 6 40.700 1.776913
1457 6 40.750 1.430513
1458 6 40.800 0.975995
1459 6 40.850 0.426010
1460 6 40.900 -0.031361
1461 6 40.950 0.048830
1462 6 41.000 0.568530
1463 6 41.050 1.104562
1464 6 41.100 1.533967
1465 6 41.150 1.857947
1466 6 41.200 2.095105
1467 6 41.250 2.262189
1468 6 41.300 2.372680
1469 6 41.350 2.437955
1470 6 41.400 2.468447
1471 6 41.450 2.474352
1472 6 41.500 2.465744
1473 6 41.550 2.451989
1474 6 41.600 2.440587
1475 6 41.650 2.435953
1476 6 41.700 2.438896
1477 6 41.750 2.447233
1478 6 41.800 2.457282
1479 6 41.850 2.465515
1480 6 41.900 2.469747
1481 6 41.950 2.469622
1482 6 42.000 2.466436
1483 6 42.050 2.462462
1484 6 42.100 2.459976
1485 6 42.150 2.460319
1486 6 42.200 2.463329
1487 6 42.250 2.467412
1488 6 42.300 2.470204
1489 6 42.350 2.469549
1490 6 42.400 2.464426
1491 6 42.450 2.455544
1492 6 42.500 2.445398
1493 6 42.550 2.437665
1494 6 42.600 2.435912
1495 6 42.650 2.441931
1496 6 42.700 2.454368
1497 6 42.750 2.468301
1498 6 42.800 2.475931
1499 6 42.850 2.467826
1500 6 42.900 2.434006
1501 6 42.950 2.364419

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