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