resona 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- resona-0.4.0/LICENSE +21 -0
- resona-0.4.0/PKG-INFO +168 -0
- resona-0.4.0/README.md +143 -0
- resona-0.4.0/pyproject.toml +37 -0
- resona-0.4.0/resona/__init__.py +29 -0
- resona-0.4.0/resona/beta.py +40 -0
- resona-0.4.0/resona/cost.py +84 -0
- resona-0.4.0/resona/defect.py +147 -0
- resona-0.4.0/resona/flow.py +42 -0
- resona-0.4.0/resona/free.py +105 -0
- resona-0.4.0/resona/lift.py +205 -0
- resona-0.4.0/resona/solve.py +122 -0
- resona-0.4.0/resona/spectral.py +441 -0
- resona-0.4.0/resona/subordination.py +66 -0
- resona-0.4.0/resona/wkernel.py +54 -0
- resona-0.4.0/resona.egg-info/PKG-INFO +168 -0
- resona-0.4.0/resona.egg-info/SOURCES.txt +23 -0
- resona-0.4.0/resona.egg-info/dependency_links.txt +1 -0
- resona-0.4.0/resona.egg-info/requires.txt +8 -0
- resona-0.4.0/resona.egg-info/top_level.txt +1 -0
- resona-0.4.0/setup.cfg +4 -0
- resona-0.4.0/tests/test_hardness_tools.py +129 -0
- resona-0.4.0/tests/test_solve.py +75 -0
- resona-0.4.0/tests/test_spectral.py +195 -0
- resona-0.4.0/tests/test_theory.py +172 -0
resona-0.4.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dmitry Sierikov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
resona-0.4.0/PKG-INFO
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: resona
|
|
3
|
+
Version: 0.4.0
|
|
4
|
+
Summary: The FFT of operators: probe, compose, read — matrix-free spectral computation with a built-in cost law.
|
|
5
|
+
Author: Dmitry Sierikov
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dimaq12/resona
|
|
8
|
+
Project-URL: Source, https://github.com/dimaq12/resona
|
|
9
|
+
Keywords: spectral,operator,matrix-free,stochastic-lanczos-quadrature,free-probability,density-of-states,log-determinant,trace-estimation,krylov,numerical-linear-algebra
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
15
|
+
Requires-Python: >=3.9
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: numpy>=1.20
|
|
19
|
+
Requires-Dist: scipy>=1.7
|
|
20
|
+
Provides-Extra: test
|
|
21
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
22
|
+
Provides-Extra: exact
|
|
23
|
+
Requires-Dist: mpmath>=1.2; extra == "exact"
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# resona — the FFT of operators
|
|
27
|
+
|
|
28
|
+
> `fft(x)` takes a **signal** to the basis where convolution becomes pointwise
|
|
29
|
+
> multiply. `Spectral.of(A)` takes an **operator** (black-box matvec) to the
|
|
30
|
+
> representation where composition becomes addition — **matrix-free** — and from
|
|
31
|
+
> which every spectral functional is read.
|
|
32
|
+
|
|
33
|
+
One object. Three verbs. No matrix is ever formed; `eig` is never called.
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
import numpy as np, resona
|
|
37
|
+
|
|
38
|
+
s = resona.of(matvec, N) # PROBE — harvest the operator's response
|
|
39
|
+
t = resona.of(matvec2, N)
|
|
40
|
+
(s + t).extreme() # COMPOSE — eig(A+B), A+B never formed
|
|
41
|
+
(s @ t) # A·B
|
|
42
|
+
s.trace(np.log) # READ — log|A| (any spectral functional)
|
|
43
|
+
s.density(x) ; s.moment(2) ; s.extreme()
|
|
44
|
+
s.effective_rank() # the honest cost dial (Φ₁)
|
|
45
|
+
|
|
46
|
+
resona.apply(matvec, f, v) # APPLY — f(A)·v (exp(tA)·v, A⁻¹·v, …): evolve PDEs
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**New here?** → the **[how-to cookbook](docs/README.md)**: find your task in the
|
|
50
|
+
"I want to…" table, copy the recipe, follow the guide. The [`examples/`](examples/)
|
|
51
|
+
are the full, verified reference implementations.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install -e . # from source
|
|
57
|
+
pip install -e ".[test]" # with pytest
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## What it solves (matrix-free, one primitive)
|
|
61
|
+
|
|
62
|
+
Verified against dense ground truth in [`examples/killer_tasks.py`](examples/killer_tasks.py):
|
|
63
|
+
|
|
64
|
+
| task | what | metric |
|
|
65
|
+
|------|------|--------|
|
|
66
|
+
| **GP log-determinant** | `log|K|` for hyperparameter learning at scale | 0.84% rel.err, no Cholesky |
|
|
67
|
+
| **Loss-Hessian spectrum** | sharpness & curvature from HVPs, no Hessian formed | λ_max 0.00%, Tr 0.30% |
|
|
68
|
+
| **Spectrum of A+B** | composed, matrix-free (Horn's problem in practice) | extreme eig to 1e-9 |
|
|
69
|
+
| **Deep-net trainability** | `cond(W_L…W_1)` predicted from init, no fwd/bwd | Gaussian explodes, orthogonal ≈1 |
|
|
70
|
+
| **Effective rank Φ₁** | the cost dial: structured/cheap vs full/frontier | 14 vs 466 |
|
|
71
|
+
| **Nonlinear PDE (Burgers)** | lift to linear (Cole–Hopf) → `exp(tK)·v` via `resona.apply` | residual 5e-9, matrix-free |
|
|
72
|
+
| **35 operators → spectra** | matrix-free Ritz seed → Rayleigh polish (the sft35 pipeline) | seed 1e-4 → **1e-16**, 99% machine-zero |
|
|
73
|
+
| **Signal in noise (BBP)** | the detection threshold — does a spike detach from the bulk? | `extreme()` tracks λ=θ+1/θ above θ_c=1 |
|
|
74
|
+
| **Anderson localization** | metal→insulator transition from disorder, matrix-free | Λ=∫typ/∫mean LDOS, 0.97→0.15 in 3.4s |
|
|
75
|
+
| **Tracy–Widom edge** | the universal fluctuation law of `extreme()` (λ_max) | std·N^⅔→1.27, exponent −0.65 (target −⅔) |
|
|
76
|
+
|
|
77
|
+
More broadly: density of states, `Tr f(A)` (log-det, `Tr A⁻¹`, partition
|
|
78
|
+
functions, Schatten norms), extreme eigenvalues & spectral gaps, disorder-averaged
|
|
79
|
+
spectra, phase-transition detection, spectral clustering — anything that is a
|
|
80
|
+
spectral functional of a (possibly composed) operator you can only matvec.
|
|
81
|
+
|
|
82
|
+
## The three verbs
|
|
83
|
+
|
|
84
|
+
- **PROBE** — `Spectral.of(matvec, N)`: stochastic Lanczos quadrature →
|
|
85
|
+
Ritz nodes (the "frequencies") + weights (the "amplitudes"). Cost `O(probes·k)`
|
|
86
|
+
matvecs. (`local_density(matvec, v)` probes from a *chosen* vector instead of
|
|
87
|
+
random ones — the LDOS / vector-resolved response. `from_measure(nodes, weights)`
|
|
88
|
+
and `from_eigenbasis(λ, V)` are the **inverses** — a spectral measure / full
|
|
89
|
+
eigenbasis → the operator (the inverse spectral problem, machine-precise from the
|
|
90
|
+
full eigenbasis).)
|
|
91
|
+
- **COMPOSE** — `s + t`, `s @ t`: `A+B`, `A·B` without forming or diagonalizing
|
|
92
|
+
them (the free-convolution theorem; exact closure `(A+B)x = Ax + Bx`).
|
|
93
|
+
- **READ** — `trace`, `moment`, `density`, `extreme`: any spectral functional.
|
|
94
|
+
|
|
95
|
+
Plus the **cost dials** `effective_rank()` (`Φ₁`) and `condition()` — low ⇒
|
|
96
|
+
structured/cheap; high ⇒ near the genuine frontier — and the *Extraction Law*
|
|
97
|
+
they come from.
|
|
98
|
+
|
|
99
|
+
Everything else reads off the same object (the `Spectral` **hub**):
|
|
100
|
+
`s.boxplus(t)` (⊞ at the measure level), `s.cauchy(z)`, `s.r(w)`, `s.s(w)`,
|
|
101
|
+
`s.cumulants()` (the lifted coordinates), `s.flow(t, xs)`, `s.shock_time()`
|
|
102
|
+
(free heat flow / disorder averaging), `s.levels(N)` (the Beta closure).
|
|
103
|
+
When the matvec also maps blocks (`A @ X`), probing switches to one BLAS-3
|
|
104
|
+
block-Lanczos automatically — ~2–4× faster, bit-compatible.
|
|
105
|
+
|
|
106
|
+
## The theory, as first-class modules
|
|
107
|
+
|
|
108
|
+
The spectral core above is one pillar. The rest of the program is promoted to
|
|
109
|
+
tested library modules (not re-derived in each script):
|
|
110
|
+
|
|
111
|
+
- **`resona.wkernel`** — the spectral Jacobian `W[i,j] = ∂λ_i/∂k_j` (Hellmann–
|
|
112
|
+
Feynman) + inverse spectral **design** (choose parameters to hit a target spectrum).
|
|
113
|
+
- **`resona.lift`** — the LIFT, *"a shock is a sum of linearities"*: `r_transform` /
|
|
114
|
+
`s_transform` (free `⊞`/`⊠` linearizers), `carleman_scalar` (nonlinear ODE → one
|
|
115
|
+
matrix exponential), `carleman_gf` (exact GF(p) logic → linear polynomial).
|
|
116
|
+
- **`resona.beta`** — Beta-law closure: spectral support + 2 moments → the whole spectrum.
|
|
117
|
+
- **`resona.defect`** — error-as-information: `defect`, `richardson`, `defect_jump`
|
|
118
|
+
(`D_{2n}=Jⁿ·D_n` exact), and the **pseudospectrum** (`pseudospectrum_radius`,
|
|
119
|
+
`sigma_min`): the ε^{1/q} bloom law of non-normal defects — where the spectrum
|
|
120
|
+
lies and GMRES actually lives.
|
|
121
|
+
- **`resona.solve`** — precision on the defect's minimal support:
|
|
122
|
+
`catastrophe_solve` (order-q cluster detected → exactly q×target digits spent),
|
|
123
|
+
`rayleigh_polish` (one eigenvalue, Ritz seed → machine precision, cubic).
|
|
124
|
+
- **`resona.free`** — `free_cumulants`, the `freeness` criterion (mixed cumulants
|
|
125
|
+
vanish ⇔ composition closes), `cross_moment` — the response algebra's coordinates.
|
|
126
|
+
- **`resona.subordination`** — disorder averaging / free addition with a semicircle
|
|
127
|
+
in CLOSED FORM (the Pastur fixed point `g = G_A(z − σ²g)`), no realizations, no eig.
|
|
128
|
+
- **`resona.lift.free_convolution`** — compose two spectra **without a joint matvec**
|
|
129
|
+
(`κ_n(A⊞B)=κ_n(A)+κ_n(B)`), the measure-level version of `s + t`.
|
|
130
|
+
- **`resona.cost`** — the **Extraction Law** `Cost ~ ε^{-a}·dist(z,Σ*)^{-b}`, `phi1`
|
|
131
|
+
(Φ₁), the removable-vs-genuine classifier (`is_extractable`, lift-rank saturation),
|
|
132
|
+
and `level_spacing_ratio` (⟨r⟩: 0.386 Poisson/integrable vs 0.531 GOE/chaotic —
|
|
133
|
+
the 3-line is-there-a-lift detector; resolve symmetry sectors first).
|
|
134
|
+
- **`resona.lift.conserved_charge`** — the constructive side of the lift: a blind
|
|
135
|
+
commutator-Gram search that FINDS the conserved charges of an integrable H
|
|
136
|
+
(and honestly reports none for a chaotic one).
|
|
137
|
+
- **`resona.flow`** — free convolution as the complex **Burgers** flow; `shock_time`
|
|
138
|
+
finds the band-merger (defect = shock = spectral edge).
|
|
139
|
+
|
|
140
|
+
Each is verified against dense ground truth in `tests/` (R-transform additivity to
|
|
141
|
+
0.5%, freeness defect 0.004 vs 2.0, Carleman/logic exact, W-kernel vs finite-diff 2e-7,
|
|
142
|
+
Pastur m₂ matches Monte-Carlo, extractable-vs-genuine classifier, shock t_c≈1).
|
|
143
|
+
|
|
144
|
+
## Honesty
|
|
145
|
+
|
|
146
|
+
The underlying algorithms (SLQ, Lanczos, free probability) are **classical** and
|
|
147
|
+
credited in [`NOVELTY.md`](NOVELTY.md). `resona`'s contribution is the **single
|
|
148
|
+
primitive + matrix-free composition algebra + the built-in cost law** as one
|
|
149
|
+
object — the way FFT organizes signal processing. The unifying claims (the
|
|
150
|
+
Extraction Law, `Φ₁`-as-boundary) are research hypotheses, labelled as such; the
|
|
151
|
+
computations are verified.
|
|
152
|
+
|
|
153
|
+
## Theory
|
|
154
|
+
|
|
155
|
+
The unified picture behind the library — the response measure as a conjugate
|
|
156
|
+
pair, free probability (closure, the freeness boundary, the semicircle attractor),
|
|
157
|
+
the defect = shock = edge identity, and the Extraction Law — is in
|
|
158
|
+
[`THEORY.md`](THEORY.md), with reproducible verification scripts in
|
|
159
|
+
[`theory/`](theory/). The intellectual claims are stated honestly in
|
|
160
|
+
[`NOVELTY.md`](NOVELTY.md); what building it revealed — the open conjectures and a
|
|
161
|
+
research log that records the **failures** too — is in [`FRONTIER.md`](FRONTIER.md).
|
|
162
|
+
The cost (big-O, matrix-free vs dense, measured slopes) of every method is in
|
|
163
|
+
[`COMPLEXITY.md`](COMPLEXITY.md).
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
MIT © 2026 Dmitry Sierikov. Attribution requested for the research contributions
|
|
168
|
+
in `NOVELTY.md`.
|
resona-0.4.0/README.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# resona — the FFT of operators
|
|
2
|
+
|
|
3
|
+
> `fft(x)` takes a **signal** to the basis where convolution becomes pointwise
|
|
4
|
+
> multiply. `Spectral.of(A)` takes an **operator** (black-box matvec) to the
|
|
5
|
+
> representation where composition becomes addition — **matrix-free** — and from
|
|
6
|
+
> which every spectral functional is read.
|
|
7
|
+
|
|
8
|
+
One object. Three verbs. No matrix is ever formed; `eig` is never called.
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
import numpy as np, resona
|
|
12
|
+
|
|
13
|
+
s = resona.of(matvec, N) # PROBE — harvest the operator's response
|
|
14
|
+
t = resona.of(matvec2, N)
|
|
15
|
+
(s + t).extreme() # COMPOSE — eig(A+B), A+B never formed
|
|
16
|
+
(s @ t) # A·B
|
|
17
|
+
s.trace(np.log) # READ — log|A| (any spectral functional)
|
|
18
|
+
s.density(x) ; s.moment(2) ; s.extreme()
|
|
19
|
+
s.effective_rank() # the honest cost dial (Φ₁)
|
|
20
|
+
|
|
21
|
+
resona.apply(matvec, f, v) # APPLY — f(A)·v (exp(tA)·v, A⁻¹·v, …): evolve PDEs
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**New here?** → the **[how-to cookbook](docs/README.md)**: find your task in the
|
|
25
|
+
"I want to…" table, copy the recipe, follow the guide. The [`examples/`](examples/)
|
|
26
|
+
are the full, verified reference implementations.
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install -e . # from source
|
|
32
|
+
pip install -e ".[test]" # with pytest
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## What it solves (matrix-free, one primitive)
|
|
36
|
+
|
|
37
|
+
Verified against dense ground truth in [`examples/killer_tasks.py`](examples/killer_tasks.py):
|
|
38
|
+
|
|
39
|
+
| task | what | metric |
|
|
40
|
+
|------|------|--------|
|
|
41
|
+
| **GP log-determinant** | `log|K|` for hyperparameter learning at scale | 0.84% rel.err, no Cholesky |
|
|
42
|
+
| **Loss-Hessian spectrum** | sharpness & curvature from HVPs, no Hessian formed | λ_max 0.00%, Tr 0.30% |
|
|
43
|
+
| **Spectrum of A+B** | composed, matrix-free (Horn's problem in practice) | extreme eig to 1e-9 |
|
|
44
|
+
| **Deep-net trainability** | `cond(W_L…W_1)` predicted from init, no fwd/bwd | Gaussian explodes, orthogonal ≈1 |
|
|
45
|
+
| **Effective rank Φ₁** | the cost dial: structured/cheap vs full/frontier | 14 vs 466 |
|
|
46
|
+
| **Nonlinear PDE (Burgers)** | lift to linear (Cole–Hopf) → `exp(tK)·v` via `resona.apply` | residual 5e-9, matrix-free |
|
|
47
|
+
| **35 operators → spectra** | matrix-free Ritz seed → Rayleigh polish (the sft35 pipeline) | seed 1e-4 → **1e-16**, 99% machine-zero |
|
|
48
|
+
| **Signal in noise (BBP)** | the detection threshold — does a spike detach from the bulk? | `extreme()` tracks λ=θ+1/θ above θ_c=1 |
|
|
49
|
+
| **Anderson localization** | metal→insulator transition from disorder, matrix-free | Λ=∫typ/∫mean LDOS, 0.97→0.15 in 3.4s |
|
|
50
|
+
| **Tracy–Widom edge** | the universal fluctuation law of `extreme()` (λ_max) | std·N^⅔→1.27, exponent −0.65 (target −⅔) |
|
|
51
|
+
|
|
52
|
+
More broadly: density of states, `Tr f(A)` (log-det, `Tr A⁻¹`, partition
|
|
53
|
+
functions, Schatten norms), extreme eigenvalues & spectral gaps, disorder-averaged
|
|
54
|
+
spectra, phase-transition detection, spectral clustering — anything that is a
|
|
55
|
+
spectral functional of a (possibly composed) operator you can only matvec.
|
|
56
|
+
|
|
57
|
+
## The three verbs
|
|
58
|
+
|
|
59
|
+
- **PROBE** — `Spectral.of(matvec, N)`: stochastic Lanczos quadrature →
|
|
60
|
+
Ritz nodes (the "frequencies") + weights (the "amplitudes"). Cost `O(probes·k)`
|
|
61
|
+
matvecs. (`local_density(matvec, v)` probes from a *chosen* vector instead of
|
|
62
|
+
random ones — the LDOS / vector-resolved response. `from_measure(nodes, weights)`
|
|
63
|
+
and `from_eigenbasis(λ, V)` are the **inverses** — a spectral measure / full
|
|
64
|
+
eigenbasis → the operator (the inverse spectral problem, machine-precise from the
|
|
65
|
+
full eigenbasis).)
|
|
66
|
+
- **COMPOSE** — `s + t`, `s @ t`: `A+B`, `A·B` without forming or diagonalizing
|
|
67
|
+
them (the free-convolution theorem; exact closure `(A+B)x = Ax + Bx`).
|
|
68
|
+
- **READ** — `trace`, `moment`, `density`, `extreme`: any spectral functional.
|
|
69
|
+
|
|
70
|
+
Plus the **cost dials** `effective_rank()` (`Φ₁`) and `condition()` — low ⇒
|
|
71
|
+
structured/cheap; high ⇒ near the genuine frontier — and the *Extraction Law*
|
|
72
|
+
they come from.
|
|
73
|
+
|
|
74
|
+
Everything else reads off the same object (the `Spectral` **hub**):
|
|
75
|
+
`s.boxplus(t)` (⊞ at the measure level), `s.cauchy(z)`, `s.r(w)`, `s.s(w)`,
|
|
76
|
+
`s.cumulants()` (the lifted coordinates), `s.flow(t, xs)`, `s.shock_time()`
|
|
77
|
+
(free heat flow / disorder averaging), `s.levels(N)` (the Beta closure).
|
|
78
|
+
When the matvec also maps blocks (`A @ X`), probing switches to one BLAS-3
|
|
79
|
+
block-Lanczos automatically — ~2–4× faster, bit-compatible.
|
|
80
|
+
|
|
81
|
+
## The theory, as first-class modules
|
|
82
|
+
|
|
83
|
+
The spectral core above is one pillar. The rest of the program is promoted to
|
|
84
|
+
tested library modules (not re-derived in each script):
|
|
85
|
+
|
|
86
|
+
- **`resona.wkernel`** — the spectral Jacobian `W[i,j] = ∂λ_i/∂k_j` (Hellmann–
|
|
87
|
+
Feynman) + inverse spectral **design** (choose parameters to hit a target spectrum).
|
|
88
|
+
- **`resona.lift`** — the LIFT, *"a shock is a sum of linearities"*: `r_transform` /
|
|
89
|
+
`s_transform` (free `⊞`/`⊠` linearizers), `carleman_scalar` (nonlinear ODE → one
|
|
90
|
+
matrix exponential), `carleman_gf` (exact GF(p) logic → linear polynomial).
|
|
91
|
+
- **`resona.beta`** — Beta-law closure: spectral support + 2 moments → the whole spectrum.
|
|
92
|
+
- **`resona.defect`** — error-as-information: `defect`, `richardson`, `defect_jump`
|
|
93
|
+
(`D_{2n}=Jⁿ·D_n` exact), and the **pseudospectrum** (`pseudospectrum_radius`,
|
|
94
|
+
`sigma_min`): the ε^{1/q} bloom law of non-normal defects — where the spectrum
|
|
95
|
+
lies and GMRES actually lives.
|
|
96
|
+
- **`resona.solve`** — precision on the defect's minimal support:
|
|
97
|
+
`catastrophe_solve` (order-q cluster detected → exactly q×target digits spent),
|
|
98
|
+
`rayleigh_polish` (one eigenvalue, Ritz seed → machine precision, cubic).
|
|
99
|
+
- **`resona.free`** — `free_cumulants`, the `freeness` criterion (mixed cumulants
|
|
100
|
+
vanish ⇔ composition closes), `cross_moment` — the response algebra's coordinates.
|
|
101
|
+
- **`resona.subordination`** — disorder averaging / free addition with a semicircle
|
|
102
|
+
in CLOSED FORM (the Pastur fixed point `g = G_A(z − σ²g)`), no realizations, no eig.
|
|
103
|
+
- **`resona.lift.free_convolution`** — compose two spectra **without a joint matvec**
|
|
104
|
+
(`κ_n(A⊞B)=κ_n(A)+κ_n(B)`), the measure-level version of `s + t`.
|
|
105
|
+
- **`resona.cost`** — the **Extraction Law** `Cost ~ ε^{-a}·dist(z,Σ*)^{-b}`, `phi1`
|
|
106
|
+
(Φ₁), the removable-vs-genuine classifier (`is_extractable`, lift-rank saturation),
|
|
107
|
+
and `level_spacing_ratio` (⟨r⟩: 0.386 Poisson/integrable vs 0.531 GOE/chaotic —
|
|
108
|
+
the 3-line is-there-a-lift detector; resolve symmetry sectors first).
|
|
109
|
+
- **`resona.lift.conserved_charge`** — the constructive side of the lift: a blind
|
|
110
|
+
commutator-Gram search that FINDS the conserved charges of an integrable H
|
|
111
|
+
(and honestly reports none for a chaotic one).
|
|
112
|
+
- **`resona.flow`** — free convolution as the complex **Burgers** flow; `shock_time`
|
|
113
|
+
finds the band-merger (defect = shock = spectral edge).
|
|
114
|
+
|
|
115
|
+
Each is verified against dense ground truth in `tests/` (R-transform additivity to
|
|
116
|
+
0.5%, freeness defect 0.004 vs 2.0, Carleman/logic exact, W-kernel vs finite-diff 2e-7,
|
|
117
|
+
Pastur m₂ matches Monte-Carlo, extractable-vs-genuine classifier, shock t_c≈1).
|
|
118
|
+
|
|
119
|
+
## Honesty
|
|
120
|
+
|
|
121
|
+
The underlying algorithms (SLQ, Lanczos, free probability) are **classical** and
|
|
122
|
+
credited in [`NOVELTY.md`](NOVELTY.md). `resona`'s contribution is the **single
|
|
123
|
+
primitive + matrix-free composition algebra + the built-in cost law** as one
|
|
124
|
+
object — the way FFT organizes signal processing. The unifying claims (the
|
|
125
|
+
Extraction Law, `Φ₁`-as-boundary) are research hypotheses, labelled as such; the
|
|
126
|
+
computations are verified.
|
|
127
|
+
|
|
128
|
+
## Theory
|
|
129
|
+
|
|
130
|
+
The unified picture behind the library — the response measure as a conjugate
|
|
131
|
+
pair, free probability (closure, the freeness boundary, the semicircle attractor),
|
|
132
|
+
the defect = shock = edge identity, and the Extraction Law — is in
|
|
133
|
+
[`THEORY.md`](THEORY.md), with reproducible verification scripts in
|
|
134
|
+
[`theory/`](theory/). The intellectual claims are stated honestly in
|
|
135
|
+
[`NOVELTY.md`](NOVELTY.md); what building it revealed — the open conjectures and a
|
|
136
|
+
research log that records the **failures** too — is in [`FRONTIER.md`](FRONTIER.md).
|
|
137
|
+
The cost (big-O, matrix-free vs dense, measured slopes) of every method is in
|
|
138
|
+
[`COMPLEXITY.md`](COMPLEXITY.md).
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
MIT © 2026 Dmitry Sierikov. Attribution requested for the research contributions
|
|
143
|
+
in `NOVELTY.md`.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "resona"
|
|
7
|
+
version = "0.4.0"
|
|
8
|
+
description = "The FFT of operators: probe, compose, read — matrix-free spectral computation with a built-in cost law."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "Dmitry Sierikov" }]
|
|
13
|
+
keywords = [
|
|
14
|
+
"spectral", "operator", "matrix-free", "stochastic-lanczos-quadrature",
|
|
15
|
+
"free-probability", "density-of-states", "log-determinant", "trace-estimation",
|
|
16
|
+
"krylov", "numerical-linear-algebra",
|
|
17
|
+
]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 3 - Alpha",
|
|
20
|
+
"Intended Audience :: Science/Research",
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
24
|
+
]
|
|
25
|
+
dependencies = ["numpy>=1.20", "scipy>=1.7"]
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
test = ["pytest>=7"]
|
|
29
|
+
exact = ["mpmath>=1.2"] # resona.solve.catastrophe_solve (extended-precision roots)
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/dimaq12/resona"
|
|
33
|
+
Source = "https://github.com/dimaq12/resona"
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.packages.find]
|
|
36
|
+
where = ["."]
|
|
37
|
+
include = ["resona*"]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""
|
|
2
|
+
resona — the resonance of an operator. Probe it, hear its spectrum.
|
|
3
|
+
|
|
4
|
+
The FFT of operators: `fft(x)` takes a signal to the basis where convolution
|
|
5
|
+
becomes pointwise multiply. `resona.of(A)` takes an operator (black-box matvec)
|
|
6
|
+
to the representation where composition becomes addition (free convolution) —
|
|
7
|
+
matrix-free — and from which every spectral functional is read.
|
|
8
|
+
|
|
9
|
+
import resona
|
|
10
|
+
s = resona.of(matvec, N) # PROBE — ring the operator, read its modes
|
|
11
|
+
s + t ; s @ t # COMPOSE — A+B, A·B (never formed, never eig'd)
|
|
12
|
+
s.trace(f) ; s.density(x) ; s.extreme() ; s.moment(p) # READ
|
|
13
|
+
s.boxplus(t) ; s.cauchy(z) ; s.r(w) ; s.s(w) # free convolution & lifted coords
|
|
14
|
+
s.flow(t, xs) ; s.levels(N) # heat flow / disorder; Beta spectrum closure
|
|
15
|
+
s.effective_rank() ; s.condition() # the honest cost dials (Φ₁, κ)
|
|
16
|
+
|
|
17
|
+
resona.apply(matvec, f, v) # APPLY — f(A)·v: solve, evolve, filter
|
|
18
|
+
resona.solve.rayleigh_polish # PRECISION — spend effort only on the defect
|
|
19
|
+
"""
|
|
20
|
+
from .spectral import Spectral, apply, local_spectrum, local_density, from_measure, from_eigenbasis
|
|
21
|
+
from . import wkernel, lift, beta, defect, free, subordination, cost, flow, solve
|
|
22
|
+
|
|
23
|
+
#: convenience: ``resona.of(matvec, N)`` == ``Spectral.of(matvec, N)``
|
|
24
|
+
of = Spectral.of
|
|
25
|
+
|
|
26
|
+
__version__ = "0.4.0"
|
|
27
|
+
__all__ = ["Spectral", "of", "apply", "local_spectrum", "local_density",
|
|
28
|
+
"from_measure", "from_eigenbasis", "wkernel", "lift", "beta", "defect", "free",
|
|
29
|
+
"subordination", "cost", "flow", "solve"]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
resona.beta — the Beta-law spectral closure: support + 2 moments → full spectrum.
|
|
3
|
+
|
|
4
|
+
A local / structured operator's eigenvalue density is SMOOTH (a central-limit
|
|
5
|
+
effect over its many local terms). On a bounded support [E0, Emax] the
|
|
6
|
+
MAXIMUM-ENTROPY density with a prescribed mean and variance is a BETA
|
|
7
|
+
distribution. So the entire spectrum is fixed by FOUR numbers — the support
|
|
8
|
+
endpoints E0, Emax and the first two moments μ1 = Tr(A)/N, μ2 = Tr(A²)/N — every
|
|
9
|
+
one of them read matrix-free by resona. The inverse-CDF unfolds all N levels in
|
|
10
|
+
O(N), one and two factors of N below dense eig (O(N²)) and diagonalization
|
|
11
|
+
(O(N³)).
|
|
12
|
+
"""
|
|
13
|
+
import numpy as np
|
|
14
|
+
from scipy.stats import beta as _beta
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def beta_spectrum(E0, Emax, mu1, mu2, N, return_params=False):
|
|
18
|
+
"""Support [E0,Emax] + per-dimension moments (μ1,μ2) → the N Beta levels.
|
|
19
|
+
|
|
20
|
+
μ1 = Tr(A)/N, μ2 = Tr(A²)/N. Maximum-entropy closure on a bounded support.
|
|
21
|
+
"""
|
|
22
|
+
span = Emax - E0
|
|
23
|
+
if span <= 0:
|
|
24
|
+
levels = np.full(N, float(E0))
|
|
25
|
+
return (levels, (1.0, 1.0)) if return_params else levels
|
|
26
|
+
m1 = (mu1 - E0) / span # mean on [0,1]
|
|
27
|
+
m2 = (mu2 - 2 * E0 * mu1 + E0 ** 2) / span ** 2 # 2nd moment on [0,1]
|
|
28
|
+
var = max(m2 - m1 ** 2, 1e-12)
|
|
29
|
+
c = m1 * (1 - m1) / var - 1 # Beta concentration
|
|
30
|
+
a, b = max(m1 * c, 1e-3), max((1 - m1) * c, 1e-3)
|
|
31
|
+
levels = E0 + span * _beta.ppf((np.arange(N) + 0.5) / N, a, b)
|
|
32
|
+
return (levels, (a, b)) if return_params else levels
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def beta_from(spectral, N=None, return_params=False):
|
|
36
|
+
"""Beta spectrum straight from a Spectral object: pulls extreme() + moment(1,2)."""
|
|
37
|
+
N = N or spectral.N
|
|
38
|
+
E0, Emax = spectral.extreme()
|
|
39
|
+
mu1, mu2 = spectral.moment(1) / spectral.N, spectral.moment(2) / spectral.N
|
|
40
|
+
return beta_spectrum(E0, Emax, mu1, mu2, N, return_params)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""
|
|
2
|
+
resona.cost — the Extraction Law: how hard is the answer to extract?
|
|
3
|
+
|
|
4
|
+
The answer pre-exists in the resolvent field G(z)=(z−A)⁻¹; a solver only EXTRACTS
|
|
5
|
+
from it. The cost of extracting to accuracy ε near a query z follows
|
|
6
|
+
|
|
7
|
+
Cost(ε, z) ~ ε^{-a} · dist(z, Σ*)^{-b},
|
|
8
|
+
|
|
9
|
+
where Σ* is the NON-removable singular set (edges / branch points / shocks /
|
|
10
|
+
continua — NOT isolated poles, which deflate away). Φ₁ = Tr(A)²/Tr(A²) is the
|
|
11
|
+
GLOBAL summary (low ⇒ structured/cheap, high ⇒ genuine frontier).
|
|
12
|
+
|
|
13
|
+
The operational test — REMOVABLE vs GENUINE — is lift-rank SATURATION: lift a
|
|
14
|
+
signal to its trajectory (Hankel) operator at growing window k. If the effective
|
|
15
|
+
rank SATURATES, the singularity is removable → a finite chart linearizes it →
|
|
16
|
+
EXTRACTABLE. If the rank keeps GROWING with k, there is no finite chart →
|
|
17
|
+
a genuine wall (structureless, e.g. aˣ mod N). This is the dial that says
|
|
18
|
+
dequantizable-vs-quantum, easy-vs-hard, from the signal itself.
|
|
19
|
+
"""
|
|
20
|
+
import numpy as np
|
|
21
|
+
from scipy.linalg import hankel, svdvals
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def phi1(spectral):
|
|
25
|
+
"""Φ₁ = Tr(A)²/Tr(A²) — the global cost summary (participation ratio)."""
|
|
26
|
+
return spectral.effective_rank()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def lift_rank(signal, k=60):
|
|
30
|
+
"""Effective rank of the trajectory (Hankel) operator of a signal at window k.
|
|
31
|
+
= (Σσ²)²/Σσ⁴ of the Hankel singular values — the size of the linearizing chart."""
|
|
32
|
+
s = np.asarray(signal, float)
|
|
33
|
+
s = (s - s.mean()) / (s.std() + 1e-12)
|
|
34
|
+
H = hankel(s[:k], s[k - 1:2 * k - 1])
|
|
35
|
+
s2 = svdvals(H) ** 2
|
|
36
|
+
return float(s2.sum() ** 2 / (s2 ** 2).sum())
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def is_extractable(signal, windows=(20, 40, 80, 120), grow=0.25):
|
|
40
|
+
"""Removable-vs-genuine test by lift-rank SATURATION.
|
|
41
|
+
|
|
42
|
+
Returns (extractable: bool, ranks: list). Saturates (rank flattens, stays a
|
|
43
|
+
small fraction of the window) ⇒ removable ⇒ extractable. Keeps growing ~k ⇒
|
|
44
|
+
no finite chart ⇒ genuine wall.
|
|
45
|
+
"""
|
|
46
|
+
ranks = [lift_rank(signal, k) for k in windows]
|
|
47
|
+
# genuine if the rank is still climbing with the window (chart never closes)
|
|
48
|
+
growth = (ranks[-1] - ranks[-2]) / (windows[-1] - windows[-2])
|
|
49
|
+
extractable = growth < grow and ranks[-1] < 0.4 * windows[-1]
|
|
50
|
+
return bool(extractable), ranks
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def level_spacing_ratio(eigenvalues, eps=1e-9):
|
|
54
|
+
"""The integrability detector: mean consecutive level-spacing ratio
|
|
55
|
+
⟨r⟩ = ⟨min(s_i, s_{i+1}) / max(s_i, s_{i+1})⟩ of a spectrum.
|
|
56
|
+
|
|
57
|
+
⟨r⟩ ≈ 0.386 → Poisson statistics → integrable (a lift EXISTS)
|
|
58
|
+
⟨r⟩ ≈ 0.531 → GOE level repulsion → chaotic (no lift)
|
|
59
|
+
(GUE 0.600, GSE 0.676; rigid picket-fence → 1.)
|
|
60
|
+
|
|
61
|
+
Unfolding-free (ratios cancel the local density), 3 lines, O(N log N).
|
|
62
|
+
|
|
63
|
+
LOUD CAVEAT (a real numerics trap): RESOLVE ALL SYMMETRY SECTORS FIRST.
|
|
64
|
+
Levels from different sectors do not repel; mixing sectors overlays
|
|
65
|
+
independent series and FAKES Poisson — an un-projected chaotic Hamiltonian
|
|
66
|
+
will read "integrable". Project H into one sector (one reflection /
|
|
67
|
+
momentum / magnetization sector) before calling this.
|
|
68
|
+
"""
|
|
69
|
+
s = np.diff(np.sort(np.asarray(eigenvalues, float)))
|
|
70
|
+
s = s[s > eps]
|
|
71
|
+
return float(np.mean(np.minimum(s[:-1], s[1:]) / np.maximum(s[:-1], s[1:])))
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def extraction_cost(eps, dist, a=1.0, b=1.0, c=1.0):
|
|
75
|
+
"""The law value Cost = c · ε^{-a} · dist^{-b}."""
|
|
76
|
+
return c * np.asarray(eps, float) ** (-a) * np.asarray(dist, float) ** (-b)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def fit_law(costs, eps, dist):
|
|
80
|
+
"""Fit (a, b, c) of Cost ~ c·ε^{-a}·dist^{-b} by log-log least squares."""
|
|
81
|
+
L = np.log(np.asarray(costs, float))
|
|
82
|
+
A = np.column_stack([-np.log(eps), -np.log(dist), np.ones_like(L)])
|
|
83
|
+
a, b, logc = np.linalg.lstsq(A, L, rcond=None)[0]
|
|
84
|
+
return float(a), float(b), float(np.exp(logc))
|