wavefunction 0.0.1__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.
- wavefunction-0.0.1/LICENSE +21 -0
- wavefunction-0.0.1/PKG-INFO +47 -0
- wavefunction-0.0.1/README.md +12 -0
- wavefunction-0.0.1/pyproject.toml +85 -0
- wavefunction-0.0.1/setup.cfg +4 -0
- wavefunction-0.0.1/wavefunction/__init__.py +6 -0
- wavefunction-0.0.1/wavefunction/py.typed +0 -0
- wavefunction-0.0.1/wavefunction/wavefunction.py +675 -0
- wavefunction-0.0.1/wavefunction.egg-info/PKG-INFO +47 -0
- wavefunction-0.0.1/wavefunction.egg-info/SOURCES.txt +11 -0
- wavefunction-0.0.1/wavefunction.egg-info/dependency_links.txt +1 -0
- wavefunction-0.0.1/wavefunction.egg-info/requires.txt +4 -0
- wavefunction-0.0.1/wavefunction.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2001 ... 2025 Juha Meskanen
|
|
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.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wavefunction
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Quantum Wavefunction with Spectral Complexity measure
|
|
5
|
+
Author-email: Juha Meskanen <juha@meskanen.com>
|
|
6
|
+
Maintainer-email: Juha Meskanen <juha@meskanen.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/juhakm/wavefunction
|
|
9
|
+
Project-URL: Bug Reports, https://github.com/juhakm/wavefunction
|
|
10
|
+
Project-URL: Say Thanks!, https://github.com/juhakm/wavefunction
|
|
11
|
+
Project-URL: Source, https://github.com/juhakm/wavefunction
|
|
12
|
+
Keywords: quantum,quantum-field-theory,information-theory,wavefunction,spinor,emergent-physics,minimal-spectral-length,computational-physics
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Intended Audience :: Education
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
20
|
+
Classifier: Programming Language :: Python
|
|
21
|
+
Classifier: Programming Language :: Python :: 3
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Classifier: Operating System :: OS Independent
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: numpy<1.27,>=1.25
|
|
31
|
+
Requires-Dist: scipy>=1.10
|
|
32
|
+
Requires-Dist: numba>=0.59
|
|
33
|
+
Requires-Dist: matplotlib
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# Wavefunction
|
|
37
|
+
|
|
38
|
+
Quantum Mechanical complex valued wavefunction with Spectral Complexity measure.
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
pip install wavefunction
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
[https://pypi.org/project/wavefunction/](https://pypi.org/project/wavefunction/)
|
|
47
|
+
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[tool.setuptools]
|
|
6
|
+
include-package-data = true
|
|
7
|
+
packages = ["wavefunction"]
|
|
8
|
+
|
|
9
|
+
[project]
|
|
10
|
+
name = "wavefunction"
|
|
11
|
+
version = "0.0.1"
|
|
12
|
+
description = "Quantum Wavefunction with Spectral Complexity measure"
|
|
13
|
+
readme = {file = "README.md", content-type = "text/markdown"}
|
|
14
|
+
requires-python = ">=3.9"
|
|
15
|
+
license = "MIT"
|
|
16
|
+
|
|
17
|
+
keywords = [
|
|
18
|
+
"quantum",
|
|
19
|
+
"quantum-field-theory",
|
|
20
|
+
"information-theory",
|
|
21
|
+
"wavefunction",
|
|
22
|
+
"spinor",
|
|
23
|
+
"emergent-physics",
|
|
24
|
+
"minimal-spectral-length",
|
|
25
|
+
"computational-physics"
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
authors = [
|
|
30
|
+
{name = "Juha Meskanen", email = "juha@meskanen.com" }
|
|
31
|
+
]
|
|
32
|
+
maintainers = [
|
|
33
|
+
{name = "Juha Meskanen", email = "juha@meskanen.com" }
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
classifiers = [
|
|
37
|
+
# Development maturity
|
|
38
|
+
"Development Status :: 4 - Beta",
|
|
39
|
+
|
|
40
|
+
# Intended audience
|
|
41
|
+
"Intended Audience :: Science/Research",
|
|
42
|
+
"Intended Audience :: Education",
|
|
43
|
+
|
|
44
|
+
# Topic classification
|
|
45
|
+
"Topic :: Scientific/Engineering",
|
|
46
|
+
"Topic :: Scientific/Engineering :: Physics",
|
|
47
|
+
"Topic :: Scientific/Engineering :: Mathematics",
|
|
48
|
+
"Topic :: Scientific/Engineering :: Information Analysis",
|
|
49
|
+
|
|
50
|
+
# Programming language
|
|
51
|
+
"Programming Language :: Python",
|
|
52
|
+
"Programming Language :: Python :: 3",
|
|
53
|
+
"Programming Language :: Python :: 3.9",
|
|
54
|
+
"Programming Language :: Python :: 3.10",
|
|
55
|
+
"Programming Language :: Python :: 3.11",
|
|
56
|
+
|
|
57
|
+
# Typing / implementation
|
|
58
|
+
"Typing :: Typed",
|
|
59
|
+
"Operating System :: OS Independent",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
dependencies = [
|
|
64
|
+
"numpy>=1.25,<1.27",
|
|
65
|
+
"scipy>=1.10",
|
|
66
|
+
"numba>=0.59",
|
|
67
|
+
"matplotlib",
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
[project.urls]
|
|
72
|
+
"Homepage" = "https://github.com/juhakm/wavefunction"
|
|
73
|
+
"Bug Reports" = "https://github.com/juhakm/wavefunction"
|
|
74
|
+
"Say Thanks!" = "https://github.com/juhakm/wavefunction"
|
|
75
|
+
"Source" = "https://github.com/juhakm/wavefunction"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
[tool.mypy]
|
|
79
|
+
files = ["wavefunction/*.py"]
|
|
80
|
+
ignore_missing_imports = false
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
[tool.setuptools.package-data]
|
|
84
|
+
"wavefunction" = ["py.typed"]
|
|
85
|
+
|
|
File without changes
|
|
@@ -0,0 +1,675 @@
|
|
|
1
|
+
"""Spectral Complexity measure for complex-valued wavefunctions.
|
|
2
|
+
|
|
3
|
+
Theory background (Meskanen 2026 — "The Wavefunction as Compression")
|
|
4
|
+
======================================================================
|
|
5
|
+
The central hypothesis is that the quantum wavefunction is the universe's
|
|
6
|
+
data-compression codec. Internal observers — themselves composed of
|
|
7
|
+
compressed structures — perceive their constituent degrees of freedom as
|
|
8
|
+
wave-like because they are observing *compressed information*. The codec
|
|
9
|
+
that produces this compression is the Fourier / spectral decomposition.
|
|
10
|
+
|
|
11
|
+
Spectral Complexity C_s
|
|
12
|
+
-----------------------
|
|
13
|
+
A wavefunction ψ(x) can always be written as a superposition of spectral
|
|
14
|
+
modes, each characterised by two attributes:
|
|
15
|
+
|
|
16
|
+
frequency ω — the rate of oscillation, unbounded above zero
|
|
17
|
+
phase φ — the offset of the oscillation, bounded in [0, 2π)
|
|
18
|
+
|
|
19
|
+
The *spectral complexity* C_s(ψ) is the total continuous information cost
|
|
20
|
+
needed to specify the set of modes that materially compose ψ:
|
|
21
|
+
|
|
22
|
+
C_s(ψ) = Σ_i [ ω_i / Δω + φ_cost(φ_i) ]
|
|
23
|
+
|
|
24
|
+
Frequency cost (dominant term)
|
|
25
|
+
ω_i / Δω is the number of resolution steps Δω needed to locate
|
|
26
|
+
frequency ω_i. It is unbounded, continuous, and grows linearly with
|
|
27
|
+
frequency. This term *dominates* C_s and is the reason the measure
|
|
28
|
+
exponentially suppresses high-frequency (rough, chaotic) states.
|
|
29
|
+
The identification Δω = ℏ ln 2 connects the minimum frequency
|
|
30
|
+
resolution to Planck's constant (Meskanen 2026, §3.1).
|
|
31
|
+
|
|
32
|
+
Phase cost (subdominant, bounded)
|
|
33
|
+
Each phase φ_i ∈ [0, 2π) requires a finite amount of information to
|
|
34
|
+
specify. The cost is *global* over all modes: it measures how much
|
|
35
|
+
information is needed to distinguish the phases from one another.
|
|
36
|
+
With only two modes at phases 0 and π, very little is needed; with
|
|
37
|
+
many modes at crowded, uneven phases, somewhat more is required.
|
|
38
|
+
In practice this term is bounded by log₂(N_modes) and is a
|
|
39
|
+
second-order correction. The current implementation uses a simple
|
|
40
|
+
uniform fixed cost per non-reference mode as a tractable proxy; the
|
|
41
|
+
reference mode (highest amplitude) is exempt because only *relative*
|
|
42
|
+
phases are observable — a global phase shift leaves |ψ(x)|² unchanged.
|
|
43
|
+
|
|
44
|
+
Amplitude and the fidelity engine
|
|
45
|
+
Amplitude does not appear as a separate encoding cost. Instead it
|
|
46
|
+
determines *which modes are included* in the description via a
|
|
47
|
+
power-ranked fidelity engine: modes are added in descending power
|
|
48
|
+
order until the accumulated power reaches a target fraction of the
|
|
49
|
+
total. Modes below this threshold are simply absent from the
|
|
50
|
+
description — they are not part of the codec output and contribute
|
|
51
|
+
zero complexity cost. This correctly handles the case where many
|
|
52
|
+
weak modes coexist with a few dominant ones: the dominant modes
|
|
53
|
+
determine C_s; the weak modes are free.
|
|
54
|
+
|
|
55
|
+
Solomonoff suppression and the probability profile
|
|
56
|
+
Under Solomonoff-like induction the prior probability of a
|
|
57
|
+
configuration is P(ψ) ∝ 2^{-C_s(ψ)}. Because C_s is a *sum* over
|
|
58
|
+
independent modes, the probability *factorises*:
|
|
59
|
+
|
|
60
|
+
P(ψ) ∝ Π_i 2^{-ω_i/Δω}
|
|
61
|
+
|
|
62
|
+
Each mode is suppressed independently and exponentially by its
|
|
63
|
+
frequency. The resulting probability profile is Boltzmann-like with
|
|
64
|
+
inverse temperature β = ln(2)/Δω:
|
|
65
|
+
|
|
66
|
+
P(mode i present) ∝ exp(−ln(2) · ω_i / Δω)
|
|
67
|
+
|
|
68
|
+
Smooth, low-frequency, compressible states dominate the measure.
|
|
69
|
+
Boltzmann brains, random fluctuations, and chaotic configurations
|
|
70
|
+
are exponentially suppressed — not by fine-tuning, but because they
|
|
71
|
+
require many high-frequency modes to describe.
|
|
72
|
+
|
|
73
|
+
The conjecture C_s ∝ S_Euclidean
|
|
74
|
+
The central open conjecture (Meskanen 2026, §4) is that the minimum
|
|
75
|
+
spectral complexity path through configuration space coincides with
|
|
76
|
+
the minimum Euclidean action path of standard quantum gravity. If
|
|
77
|
+
true, quantum gravity is Solomonoff induction over compressed
|
|
78
|
+
descriptions of geometry, and ℏ is the minimum spectral resolution
|
|
79
|
+
of a finite informational universe.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
from __future__ import annotations
|
|
83
|
+
|
|
84
|
+
import numpy as np
|
|
85
|
+
from dataclasses import dataclass
|
|
86
|
+
from typing import Optional
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
# ---------------------------------------------------------------------------
|
|
90
|
+
# Spectral mode
|
|
91
|
+
# ---------------------------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
@dataclass
|
|
94
|
+
class SpectralMode:
|
|
95
|
+
"""A single Fourier mode in the spectral decomposition of a wavefunction.
|
|
96
|
+
|
|
97
|
+
Attributes:
|
|
98
|
+
frequency: Angular frequency ω (rad / spatial-unit). Signed —
|
|
99
|
+
positive and negative frequencies are physically distinct for
|
|
100
|
+
complex ψ. The frequency cost uses |ω|.
|
|
101
|
+
amplitude: Real-valued mode amplitude A ≥ 0, equal to
|
|
102
|
+
|FFT_k| / N after normalisation. Used only by the fidelity
|
|
103
|
+
engine to rank modes by power; it does not appear in C_s.
|
|
104
|
+
phase: Mode phase φ ∈ [0, 2π), equal to arg(FFT_k) mod 2π.
|
|
105
|
+
Relative phases between modes determine interference structure
|
|
106
|
+
and enter C_s through the (subdominant) phase cost term.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
frequency: float
|
|
110
|
+
amplitude: float
|
|
111
|
+
phase: float
|
|
112
|
+
|
|
113
|
+
def __post_init__(self) -> None:
|
|
114
|
+
self.amplitude = float(abs(self.amplitude))
|
|
115
|
+
self.phase = float(self.phase % (2.0 * np.pi))
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
# ---------------------------------------------------------------------------
|
|
119
|
+
# Wavefunction
|
|
120
|
+
# ---------------------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
class Wavefunction:
|
|
123
|
+
"""A normalised complex wavefunction on a uniform 1-D spatial grid.
|
|
124
|
+
|
|
125
|
+
The wavefunction ψ(x) is stored as a complex NumPy array of length N.
|
|
126
|
+
Its primary analytical interface is the spectral complexity C_s(ψ),
|
|
127
|
+
a continuous, computable measure of how many spectral resources are
|
|
128
|
+
required to describe ψ to a given fidelity.
|
|
129
|
+
|
|
130
|
+
Spectral complexity formula
|
|
131
|
+
---------------------------
|
|
132
|
+
C_s(ψ) = Σ_{i ∈ retained} [ |ω_i| / Δω + φ_cost(i) ]
|
|
133
|
+
|
|
134
|
+
where the sum runs over modes retained by the fidelity engine
|
|
135
|
+
(see below), and:
|
|
136
|
+
|
|
137
|
+
|ω_i| / Δω — frequency cost: dominant, continuous, unbounded.
|
|
138
|
+
Mirrors E = ℏω; under Solomonoff suppression
|
|
139
|
+
2^{-C_s} this produces an exponential / Boltzmann
|
|
140
|
+
distribution over frequency.
|
|
141
|
+
|
|
142
|
+
φ_cost(i) — phase cost: subdominant, bounded. Zero for the
|
|
143
|
+
reference mode (highest amplitude — global phase
|
|
144
|
+
unobservable); a fixed resolution cost
|
|
145
|
+
`phase_resolution` for every other retained mode.
|
|
146
|
+
Represents the information needed to distinguish
|
|
147
|
+
this mode's phase from the reference.
|
|
148
|
+
|
|
149
|
+
Fidelity engine
|
|
150
|
+
---------------
|
|
151
|
+
Not all FFT bins materially contribute to ψ. The fidelity engine
|
|
152
|
+
ranks bins by power (|FFT_k|²) and greedily accumulates them until
|
|
153
|
+
the retained set accounts for at least `fidelity_target` of the
|
|
154
|
+
total power. Only retained modes enter C_s. This has two effects:
|
|
155
|
+
|
|
156
|
+
1. Correctness: two wavefunctions with the same |ψ(x)|² but
|
|
157
|
+
different numbers of negligible-power modes receive the same C_s.
|
|
158
|
+
The codec describes the *observable state*, not a particular
|
|
159
|
+
representation.
|
|
160
|
+
|
|
161
|
+
2. Stability: noise and numerical artefacts in low-power bins do
|
|
162
|
+
not inflate C_s.
|
|
163
|
+
|
|
164
|
+
Planck identification
|
|
165
|
+
---------------------
|
|
166
|
+
The minimum resolvable frequency Δω defaults to 2π / (N dx), the
|
|
167
|
+
natural FFT resolution of the grid. The identification
|
|
168
|
+
ℏ = Δω / ln(2) connects this resolution to Planck's constant
|
|
169
|
+
(Meskanen 2026, §3.1). This is a correspondence to be investigated,
|
|
170
|
+
not a derivation.
|
|
171
|
+
|
|
172
|
+
Args:
|
|
173
|
+
psi: Complex wavefunction amplitudes on a uniform spatial grid.
|
|
174
|
+
Normalised to unit L² norm on construction.
|
|
175
|
+
dx: Spatial grid spacing. Determines angular frequencies via
|
|
176
|
+
ω_k = 2π k / (N dx). Defaults to 1.0.
|
|
177
|
+
delta_omega: Minimum resolvable angular frequency Δω. Defaults
|
|
178
|
+
to the natural FFT resolution 2π / (N dx).
|
|
179
|
+
fidelity_target: Fraction of total spectral power that the
|
|
180
|
+
retained modes must collectively explain. Must be in (0, 1].
|
|
181
|
+
Higher values retain more modes and increase C_s.
|
|
182
|
+
Defaults to 0.999 (99.9 % of power).
|
|
183
|
+
phase_resolution: Continuous cost assigned to the phase of each
|
|
184
|
+
non-reference retained mode. Represents the information
|
|
185
|
+
needed to resolve that mode's phase from the reference to
|
|
186
|
+
the required precision. Bounded and subdominant relative to
|
|
187
|
+
the frequency cost. Defaults to 1.0 (one unit per mode,
|
|
188
|
+
interpretable as ~ 1 bit of phase separation information).
|
|
189
|
+
|
|
190
|
+
Attributes:
|
|
191
|
+
dx: Spatial grid spacing.
|
|
192
|
+
delta_omega: Minimum resolvable angular frequency Δω.
|
|
193
|
+
fidelity_target: Power-fidelity threshold for mode retention.
|
|
194
|
+
phase_resolution: Per-mode phase cost for non-reference modes.
|
|
195
|
+
hbar_identified: Δω / ln(2) — the value of ℏ implied by the
|
|
196
|
+
grid resolution under the Meskanen (2026) identification.
|
|
197
|
+
"""
|
|
198
|
+
|
|
199
|
+
def __init__(
|
|
200
|
+
self,
|
|
201
|
+
psi: np.ndarray,
|
|
202
|
+
dx: float = 1.0,
|
|
203
|
+
delta_omega: Optional[float] = None,
|
|
204
|
+
fidelity_target: float = 0.999,
|
|
205
|
+
phase_resolution: float = 1.0,
|
|
206
|
+
) -> None:
|
|
207
|
+
self._psi: np.ndarray = self._normalise(np.asarray(psi, dtype=complex))
|
|
208
|
+
self.dx: float = float(dx)
|
|
209
|
+
self.fidelity_target: float = float(fidelity_target)
|
|
210
|
+
self.phase_resolution: float = float(phase_resolution)
|
|
211
|
+
|
|
212
|
+
N = len(self._psi)
|
|
213
|
+
self.delta_omega: float = (
|
|
214
|
+
float(delta_omega) if delta_omega is not None
|
|
215
|
+
else 2.0 * np.pi / (N * self.dx)
|
|
216
|
+
)
|
|
217
|
+
self.hbar_identified: float = self.delta_omega / np.log(2.0)
|
|
218
|
+
|
|
219
|
+
# ------------------------------------------------------------------
|
|
220
|
+
# Core properties
|
|
221
|
+
# ------------------------------------------------------------------
|
|
222
|
+
|
|
223
|
+
@property
|
|
224
|
+
def psi(self) -> np.ndarray:
|
|
225
|
+
"""Normalised complex wavefunction array ψ(x), shape (N,)."""
|
|
226
|
+
return self._psi
|
|
227
|
+
|
|
228
|
+
@property
|
|
229
|
+
def N(self) -> int:
|
|
230
|
+
"""Number of spatial grid points."""
|
|
231
|
+
return len(self._psi)
|
|
232
|
+
|
|
233
|
+
@property
|
|
234
|
+
def x(self) -> np.ndarray:
|
|
235
|
+
"""Spatial grid positions x_n = n · dx, shape (N,)."""
|
|
236
|
+
return np.arange(self.N) * self.dx
|
|
237
|
+
|
|
238
|
+
@property
|
|
239
|
+
def probability_density(self) -> np.ndarray:
|
|
240
|
+
"""|ψ(x)|² — Born-rule probability density, shape (N,).
|
|
241
|
+
|
|
242
|
+
Normalised so that sum(|ψ|²) = 1 (discrete L² norm).
|
|
243
|
+
"""
|
|
244
|
+
return np.abs(self._psi) ** 2
|
|
245
|
+
|
|
246
|
+
# ------------------------------------------------------------------
|
|
247
|
+
# Fidelity engine — mode selection
|
|
248
|
+
# ------------------------------------------------------------------
|
|
249
|
+
|
|
250
|
+
def retained_modes(self) -> list[SpectralMode]:
|
|
251
|
+
"""Return the set of spectral modes retained by the fidelity engine.
|
|
252
|
+
|
|
253
|
+
Modes are ranked by power (|FFT_k|²) in descending order and
|
|
254
|
+
accumulated greedily until the retained set accounts for at least
|
|
255
|
+
`fidelity_target` of the total power. The result is the minimal
|
|
256
|
+
set of modes that reproduces ψ(x) to the required fidelity.
|
|
257
|
+
|
|
258
|
+
The reference mode (highest power, first in the ranked list) is
|
|
259
|
+
flagged implicitly: its phase is the global reference and costs
|
|
260
|
+
nothing. All other retained modes pay `phase_resolution`.
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
List of SpectralMode objects sorted by ascending |ω|, one per
|
|
264
|
+
retained FFT bin. The highest-power mode appears somewhere
|
|
265
|
+
in this list and is identifiable as the one with the largest
|
|
266
|
+
amplitude.
|
|
267
|
+
"""
|
|
268
|
+
N = self.N
|
|
269
|
+
fft_coeffs: np.ndarray = np.fft.fft(self._psi)
|
|
270
|
+
freqs: np.ndarray = 2.0 * np.pi * np.fft.fftfreq(N, d=self.dx)
|
|
271
|
+
power: np.ndarray = np.abs(fft_coeffs) ** 2
|
|
272
|
+
total_power: float = float(power.sum())
|
|
273
|
+
|
|
274
|
+
if total_power == 0.0:
|
|
275
|
+
return []
|
|
276
|
+
|
|
277
|
+
# Rank bins by descending power
|
|
278
|
+
sorted_idx: np.ndarray = np.argsort(power)[::-1]
|
|
279
|
+
|
|
280
|
+
accumulated: float = 0.0
|
|
281
|
+
kept: list[int] = []
|
|
282
|
+
for idx in sorted_idx:
|
|
283
|
+
accumulated += float(power[idx])
|
|
284
|
+
kept.append(int(idx))
|
|
285
|
+
if accumulated / total_power >= self.fidelity_target:
|
|
286
|
+
break
|
|
287
|
+
|
|
288
|
+
modes: list[SpectralMode] = [
|
|
289
|
+
SpectralMode(
|
|
290
|
+
frequency=float(freqs[k]),
|
|
291
|
+
amplitude=float(np.abs(fft_coeffs[k])) / N,
|
|
292
|
+
phase=float(np.angle(fft_coeffs[k]) % (2.0 * np.pi)),
|
|
293
|
+
)
|
|
294
|
+
for k in kept
|
|
295
|
+
]
|
|
296
|
+
modes.sort(key=lambda m: abs(m.frequency))
|
|
297
|
+
return modes
|
|
298
|
+
|
|
299
|
+
# ------------------------------------------------------------------
|
|
300
|
+
# Spectral complexity C_s(ψ)
|
|
301
|
+
# ------------------------------------------------------------------
|
|
302
|
+
|
|
303
|
+
def spectral_complexity(self, verbose: bool = False) -> float:
|
|
304
|
+
"""Compute the spectral complexity C_s(ψ).
|
|
305
|
+
|
|
306
|
+
C_s is the total continuous information cost of specifying the
|
|
307
|
+
retained spectral modes:
|
|
308
|
+
|
|
309
|
+
C_s(ψ) = Σ_{i ∈ retained} [ |ω_i| / Δω + φ_cost(i) ]
|
|
310
|
+
|
|
311
|
+
where φ_cost(i) = 0 for the reference mode (highest amplitude)
|
|
312
|
+
and `phase_resolution` for all other retained modes.
|
|
313
|
+
|
|
314
|
+
The frequency term |ω_i| / Δω is the dominant, unbounded
|
|
315
|
+
contribution. The phase term is a bounded correction that
|
|
316
|
+
accounts for the information needed to distinguish each mode's
|
|
317
|
+
phase from the reference.
|
|
318
|
+
|
|
319
|
+
Under Solomonoff suppression P(ψ) ∝ 2^{-C_s(ψ)}, and because
|
|
320
|
+
the sum factorises over modes:
|
|
321
|
+
|
|
322
|
+
P(ψ) ∝ Π_i 2^{-|ω_i|/Δω} · 2^{-φ_cost(i)}
|
|
323
|
+
|
|
324
|
+
The probability profile is exponential in frequency — each mode
|
|
325
|
+
independently suppressed by its oscillation rate.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
verbose: If True, print a per-mode breakdown to stdout.
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
C_s as a non-negative float. Zero only if no modes are
|
|
332
|
+
retained (degenerate zero wavefunction).
|
|
333
|
+
"""
|
|
334
|
+
modes: list[SpectralMode] = self.retained_modes()
|
|
335
|
+
if not modes:
|
|
336
|
+
return 0.0
|
|
337
|
+
|
|
338
|
+
# Reference mode: highest amplitude — pays zero phase cost.
|
|
339
|
+
# Only relative phases are observable; the highest-amplitude mode
|
|
340
|
+
# is the natural phase reference. Ties broken by lowest |ω| for
|
|
341
|
+
# numerical stability (avoids C_s jumping by 1 when two equal-power
|
|
342
|
+
# modes exchange amplitudes under tiny perturbations).
|
|
343
|
+
ref_amplitude: float = max(m.amplitude for m in modes)
|
|
344
|
+
ref_freq_abs: float = min(
|
|
345
|
+
abs(m.frequency) for m in modes if m.amplitude == ref_amplitude
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
total: float = 0.0
|
|
349
|
+
|
|
350
|
+
if verbose:
|
|
351
|
+
print(f"\n {'i':>4} {'ω':>10} {'A':>9} {'φ/2π':>7} "
|
|
352
|
+
f"{'|ω|/Δω':>10} {'φ_cost':>7} {'mode C_s':>9}")
|
|
353
|
+
print(" " + "-" * 62)
|
|
354
|
+
|
|
355
|
+
for i, mode in enumerate(modes):
|
|
356
|
+
freq_cost: float = abs(mode.frequency) / self.delta_omega
|
|
357
|
+
# Reference mode (global phase) is unobservable — zero phase cost
|
|
358
|
+
is_reference: bool = (
|
|
359
|
+
mode.amplitude == ref_amplitude
|
|
360
|
+
and abs(mode.frequency) == ref_freq_abs
|
|
361
|
+
)
|
|
362
|
+
phase_cost: float = 0.0 if is_reference else self.phase_resolution
|
|
363
|
+
mode_cs: float = freq_cost + phase_cost
|
|
364
|
+
total += mode_cs
|
|
365
|
+
|
|
366
|
+
if verbose:
|
|
367
|
+
print(f" {i:>4} {mode.frequency:>10.4f} {mode.amplitude:>9.5f}"
|
|
368
|
+
f" {mode.phase / (2*np.pi):>7.4f}"
|
|
369
|
+
f" {freq_cost:>10.3f} {phase_cost:>7.2f} {mode_cs:>9.3f}"
|
|
370
|
+
+ (" ← ref" if is_reference else ""))
|
|
371
|
+
|
|
372
|
+
if verbose:
|
|
373
|
+
print(" " + "-" * 62)
|
|
374
|
+
n_ret = len(modes)
|
|
375
|
+
print(f" C_s = {total:.4f} "
|
|
376
|
+
f"({n_ret} modes retained at fidelity ≥ {self.fidelity_target})\n")
|
|
377
|
+
|
|
378
|
+
return total
|
|
379
|
+
|
|
380
|
+
# ------------------------------------------------------------------
|
|
381
|
+
# Derived quantities
|
|
382
|
+
# ------------------------------------------------------------------
|
|
383
|
+
|
|
384
|
+
def solomonoff_weight(self) -> float:
|
|
385
|
+
"""Unnormalised Solomonoff prior weight 2^{-C_s(ψ)}.
|
|
386
|
+
|
|
387
|
+
Under Solomonoff-like induction, configurations are weighted by
|
|
388
|
+
their compressibility. The weight is exponential in C_s:
|
|
389
|
+
|
|
390
|
+
w(ψ) = 2^{-C_s(ψ)}
|
|
391
|
+
|
|
392
|
+
Because C_s factorises over modes, this equals the product of
|
|
393
|
+
per-mode suppression factors:
|
|
394
|
+
|
|
395
|
+
w(ψ) = Π_i 2^{-|ω_i|/Δω} · 2^{-φ_cost(i)}
|
|
396
|
+
|
|
397
|
+
Smooth, low-frequency wavefunctions receive exponentially higher
|
|
398
|
+
weight than chaotic, high-frequency ones.
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
Float in (0, 1]. Returns 1.0 for the zero wavefunction
|
|
402
|
+
(no retained modes, C_s = 0).
|
|
403
|
+
"""
|
|
404
|
+
return 2.0 ** (-self.spectral_complexity())
|
|
405
|
+
|
|
406
|
+
def mode_suppression_factors(self) -> dict[float, float]:
|
|
407
|
+
"""Per-mode Boltzmann suppression factors from the frequency cost.
|
|
408
|
+
|
|
409
|
+
For each retained mode i, the frequency term |ω_i| / Δω
|
|
410
|
+
contributes an independent suppression factor:
|
|
411
|
+
|
|
412
|
+
s_i = 2^{-|ω_i|/Δω} = exp(−ln2 · |ω_i| / Δω)
|
|
413
|
+
|
|
414
|
+
This is a Boltzmann factor with inverse temperature
|
|
415
|
+
β = ln(2) / Δω. The identification ℏ = Δω / ln(2) makes
|
|
416
|
+
β = 1 / ℏ in natural units, consistent with E = ℏω.
|
|
417
|
+
|
|
418
|
+
Returns:
|
|
419
|
+
Dict mapping ω_i (float) → unnormalised suppression factor s_i.
|
|
420
|
+
The factors are *not* normalised to a probability distribution
|
|
421
|
+
here; use solomonoff_weight() for the joint weight of the full
|
|
422
|
+
wavefunction.
|
|
423
|
+
"""
|
|
424
|
+
return {
|
|
425
|
+
m.frequency: 2.0 ** (-abs(m.frequency) / self.delta_omega)
|
|
426
|
+
for m in self.retained_modes()
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
# ------------------------------------------------------------------
|
|
430
|
+
# Convenience constructors
|
|
431
|
+
# ------------------------------------------------------------------
|
|
432
|
+
|
|
433
|
+
@classmethod
|
|
434
|
+
def gaussian_packet(
|
|
435
|
+
cls,
|
|
436
|
+
N: int = 256,
|
|
437
|
+
x0: float = 0.0,
|
|
438
|
+
sigma: float = 1.0,
|
|
439
|
+
k0: float = 1.0,
|
|
440
|
+
dx: float = 0.1,
|
|
441
|
+
**kwargs,
|
|
442
|
+
) -> "Wavefunction":
|
|
443
|
+
"""Construct a Gaussian wave packet.
|
|
444
|
+
|
|
445
|
+
ψ(x) = exp(−(x−x0)² / 4σ²) · exp(i k0 x), then normalised.
|
|
446
|
+
|
|
447
|
+
A Gaussian packet is narrow in both position and momentum space
|
|
448
|
+
and serves as a natural low-C_s reference state: it has a single
|
|
449
|
+
dominant frequency k0 and a smooth Gaussian envelope that
|
|
450
|
+
concentrates spectral power near k0.
|
|
451
|
+
|
|
452
|
+
Args:
|
|
453
|
+
N: Number of grid points.
|
|
454
|
+
x0: Packet centre in position space.
|
|
455
|
+
sigma: Position-space width (standard deviation).
|
|
456
|
+
k0: Carrier wavenumber (dominant angular frequency ω ≈ k0).
|
|
457
|
+
dx: Spatial grid spacing.
|
|
458
|
+
**kwargs: Passed to Wavefunction.__init__
|
|
459
|
+
(e.g. fidelity_target, phase_resolution).
|
|
460
|
+
|
|
461
|
+
Returns:
|
|
462
|
+
Normalised Wavefunction instance.
|
|
463
|
+
"""
|
|
464
|
+
x = np.arange(N) * dx
|
|
465
|
+
psi = np.exp(-((x - x0) ** 2) / (4.0 * sigma ** 2)) * np.exp(1j * k0 * x)
|
|
466
|
+
return cls(psi, dx=dx, **kwargs)
|
|
467
|
+
|
|
468
|
+
@classmethod
|
|
469
|
+
def plane_wave_superposition(
|
|
470
|
+
cls,
|
|
471
|
+
N: int = 256,
|
|
472
|
+
amplitudes: list[float] = (0.6, 0.8),
|
|
473
|
+
wavenumbers: list[float] = (1.0, 3.0),
|
|
474
|
+
phases: list[float] = (0.0, 0.0),
|
|
475
|
+
dx: float = 0.1,
|
|
476
|
+
**kwargs,
|
|
477
|
+
) -> "Wavefunction":
|
|
478
|
+
"""Construct an explicit superposition of plane waves.
|
|
479
|
+
|
|
480
|
+
ψ(x) = Σ_i α_i · exp(i (k_i x + φ_i)), then normalised.
|
|
481
|
+
|
|
482
|
+
Useful for constructing states with known spectral structure and
|
|
483
|
+
testing how C_s responds to adding modes or shifting phases.
|
|
484
|
+
|
|
485
|
+
Args:
|
|
486
|
+
N: Number of grid points.
|
|
487
|
+
amplitudes: Real amplitudes α_i for each plane wave.
|
|
488
|
+
wavenumbers: Wavenumbers k_i (angular frequencies ω_i = k_i).
|
|
489
|
+
phases: Initial phases φ_i for each plane wave.
|
|
490
|
+
dx: Spatial grid spacing.
|
|
491
|
+
**kwargs: Passed to Wavefunction.__init__.
|
|
492
|
+
|
|
493
|
+
Returns:
|
|
494
|
+
Normalised Wavefunction instance.
|
|
495
|
+
"""
|
|
496
|
+
x = np.arange(N) * dx
|
|
497
|
+
psi = np.zeros(N, dtype=complex)
|
|
498
|
+
for a, k, phi in zip(amplitudes, wavenumbers, phases):
|
|
499
|
+
psi += a * np.exp(1j * (k * x + phi))
|
|
500
|
+
return cls(psi, dx=dx, **kwargs)
|
|
501
|
+
|
|
502
|
+
@classmethod
|
|
503
|
+
def random_state(
|
|
504
|
+
cls,
|
|
505
|
+
N: int = 256,
|
|
506
|
+
seed: int = 42,
|
|
507
|
+
dx: float = 0.1,
|
|
508
|
+
**kwargs,
|
|
509
|
+
) -> "Wavefunction":
|
|
510
|
+
"""Construct a maximally chaotic (high-C_s) random wavefunction.
|
|
511
|
+
|
|
512
|
+
Draws real and imaginary parts independently from N(0,1). The
|
|
513
|
+
resulting state activates all FFT bins with roughly equal power,
|
|
514
|
+
giving the maximum number of retained modes and hence the highest
|
|
515
|
+
possible C_s for a given N. Useful as an upper-bound reference.
|
|
516
|
+
|
|
517
|
+
Args:
|
|
518
|
+
N: Number of grid points.
|
|
519
|
+
seed: Random seed for reproducibility.
|
|
520
|
+
dx: Spatial grid spacing.
|
|
521
|
+
**kwargs: Passed to Wavefunction.__init__.
|
|
522
|
+
|
|
523
|
+
Returns:
|
|
524
|
+
Normalised Wavefunction instance.
|
|
525
|
+
"""
|
|
526
|
+
rng = np.random.default_rng(seed)
|
|
527
|
+
psi = rng.standard_normal(N) + 1j * rng.standard_normal(N)
|
|
528
|
+
return cls(psi, dx=dx, **kwargs)
|
|
529
|
+
|
|
530
|
+
# ------------------------------------------------------------------
|
|
531
|
+
# Arithmetic
|
|
532
|
+
# ------------------------------------------------------------------
|
|
533
|
+
|
|
534
|
+
def __add__(self, other: "Wavefunction") -> "Wavefunction":
|
|
535
|
+
"""Superpose two wavefunctions: ψ_new = normalise(ψ_a + ψ_b).
|
|
536
|
+
|
|
537
|
+
The result is renormalised. Interference fringes in the
|
|
538
|
+
superposition share spectral modes, so C_s(ψ_a + ψ_b) is
|
|
539
|
+
typically less than C_s(ψ_a) + C_s(ψ_b) — the codec description
|
|
540
|
+
of the superposition is cheaper than two independent descriptions.
|
|
541
|
+
|
|
542
|
+
Args:
|
|
543
|
+
other: Wavefunction on the same grid (same N and dx).
|
|
544
|
+
|
|
545
|
+
Returns:
|
|
546
|
+
New normalised Wavefunction.
|
|
547
|
+
|
|
548
|
+
Raises:
|
|
549
|
+
ValueError: If grid sizes differ.
|
|
550
|
+
"""
|
|
551
|
+
if self.N != other.N:
|
|
552
|
+
raise ValueError(
|
|
553
|
+
f"Grid size mismatch: {self.N} vs {other.N}")
|
|
554
|
+
return Wavefunction(
|
|
555
|
+
self._psi + other._psi,
|
|
556
|
+
dx=self.dx,
|
|
557
|
+
delta_omega=self.delta_omega,
|
|
558
|
+
fidelity_target=self.fidelity_target,
|
|
559
|
+
phase_resolution=self.phase_resolution,
|
|
560
|
+
)
|
|
561
|
+
|
|
562
|
+
def __mul__(self, scalar: complex) -> "Wavefunction":
|
|
563
|
+
"""Scale ψ by a complex scalar (result is renormalised)."""
|
|
564
|
+
return Wavefunction(
|
|
565
|
+
self._psi * scalar,
|
|
566
|
+
dx=self.dx,
|
|
567
|
+
delta_omega=self.delta_omega,
|
|
568
|
+
fidelity_target=self.fidelity_target,
|
|
569
|
+
phase_resolution=self.phase_resolution,
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
def __rmul__(self, scalar: complex) -> "Wavefunction":
|
|
573
|
+
return self.__mul__(scalar)
|
|
574
|
+
|
|
575
|
+
def inner_product(self, other: "Wavefunction") -> complex:
|
|
576
|
+
"""Discrete inner product ⟨self|other⟩ = Σ_x ψ*(x) φ(x) dx.
|
|
577
|
+
|
|
578
|
+
Args:
|
|
579
|
+
other: Wavefunction on the same grid.
|
|
580
|
+
|
|
581
|
+
Returns:
|
|
582
|
+
Complex scalar.
|
|
583
|
+
"""
|
|
584
|
+
return complex(np.sum(self._psi.conj() * other._psi) * self.dx)
|
|
585
|
+
|
|
586
|
+
# ------------------------------------------------------------------
|
|
587
|
+
# Internal helpers
|
|
588
|
+
# ------------------------------------------------------------------
|
|
589
|
+
|
|
590
|
+
@staticmethod
|
|
591
|
+
def _normalise(psi: np.ndarray) -> np.ndarray:
|
|
592
|
+
"""Normalise ψ to unit L² norm.
|
|
593
|
+
|
|
594
|
+
Args:
|
|
595
|
+
psi: Complex array.
|
|
596
|
+
|
|
597
|
+
Returns:
|
|
598
|
+
ψ / ‖ψ‖.
|
|
599
|
+
|
|
600
|
+
Raises:
|
|
601
|
+
ValueError: If ψ is identically zero.
|
|
602
|
+
"""
|
|
603
|
+
norm: float = float(np.sqrt(np.sum(np.abs(psi) ** 2)))
|
|
604
|
+
if norm == 0.0:
|
|
605
|
+
raise ValueError("Cannot normalise a zero wavefunction.")
|
|
606
|
+
return psi / norm
|
|
607
|
+
|
|
608
|
+
def __repr__(self) -> str:
|
|
609
|
+
cs = self.spectral_complexity()
|
|
610
|
+
n_modes = len(self.retained_modes())
|
|
611
|
+
return (
|
|
612
|
+
f"Wavefunction(N={self.N}, dx={self.dx}, "
|
|
613
|
+
f"C_s={cs:.3f}, modes={n_modes}, "
|
|
614
|
+
f"ℏ_id={self.hbar_identified:.3e})"
|
|
615
|
+
)
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
# ---------------------------------------------------------------------------
|
|
619
|
+
# Demo
|
|
620
|
+
# ---------------------------------------------------------------------------
|
|
621
|
+
|
|
622
|
+
if __name__ == "__main__":
|
|
623
|
+
print(__doc__)
|
|
624
|
+
print("=" * 65)
|
|
625
|
+
print("Demo")
|
|
626
|
+
print("=" * 65)
|
|
627
|
+
|
|
628
|
+
# 1. Gaussian packet — few dominant modes, low C_s
|
|
629
|
+
gp = Wavefunction.gaussian_packet(N=256, x0=12.8, sigma=2.0, k0=2.0, dx=0.1)
|
|
630
|
+
print("\n[1] Gaussian wave packet")
|
|
631
|
+
gp.spectral_complexity(verbose=True)
|
|
632
|
+
print(gp)
|
|
633
|
+
|
|
634
|
+
# 2. Two-component superposition — moderate C_s
|
|
635
|
+
sp = Wavefunction.plane_wave_superposition(
|
|
636
|
+
N=256, amplitudes=[0.6, 0.8],
|
|
637
|
+
wavenumbers=[1.0, 5.0], phases=[0.0, np.pi / 4], dx=0.1)
|
|
638
|
+
print("\n[2] Two-component superposition")
|
|
639
|
+
sp.spectral_complexity(verbose=True)
|
|
640
|
+
print(sp)
|
|
641
|
+
|
|
642
|
+
# 3. Random state — all modes active, high C_s
|
|
643
|
+
rnd = Wavefunction.random_state(N=256, seed=0, dx=0.1)
|
|
644
|
+
print("\n[3] Random (high-entropy) state")
|
|
645
|
+
print(f" C_s = {rnd.spectral_complexity():.2f} (verbose suppressed)")
|
|
646
|
+
print(rnd)
|
|
647
|
+
|
|
648
|
+
# 4. Solomonoff weights — exponential ordering
|
|
649
|
+
print("\nSolomonoff weights 2^{{-C_s}}:")
|
|
650
|
+
for label, wf in [("Gaussian", gp), ("Superposition", sp), ("Random", rnd)]:
|
|
651
|
+
print(f" {label:>16s}: {wf.solomonoff_weight():.4e}")
|
|
652
|
+
|
|
653
|
+
# 5. Interference economy
|
|
654
|
+
gp2 = Wavefunction.gaussian_packet(N=256, x0=20.0, sigma=2.0, k0=2.0, dx=0.1)
|
|
655
|
+
combined = gp + gp2
|
|
656
|
+
print(f"\n[5] Interference economy:")
|
|
657
|
+
print(f" C_s(ψ₁) = {gp.spectral_complexity():.2f}")
|
|
658
|
+
print(f" C_s(ψ₂) = {gp2.spectral_complexity():.2f}")
|
|
659
|
+
print(f" C_s(ψ₁ + ψ₂) = {combined.spectral_complexity():.2f}")
|
|
660
|
+
print(" Superposition is cheaper than two independent descriptions.")
|
|
661
|
+
|
|
662
|
+
# 6. Fidelity engine: weak modes don't inflate C_s
|
|
663
|
+
x = np.arange(64)
|
|
664
|
+
psi_clean = sum(np.exp(1j * 2*np.pi*k*x/64) for k in [2, 7, 13])
|
|
665
|
+
rng = np.random.default_rng(0)
|
|
666
|
+
psi_noisy = psi_clean + 0.01 * sum(
|
|
667
|
+
np.exp(1j * (2*np.pi*k*x/64 + rng.uniform(0, 2*np.pi)))
|
|
668
|
+
for k in range(20, 50))
|
|
669
|
+
wf_clean = Wavefunction(psi_clean, dx=0.1)
|
|
670
|
+
wf_noisy = Wavefunction(psi_noisy, dx=0.1)
|
|
671
|
+
print(f"\n[6] Fidelity engine — weak modes ignored:")
|
|
672
|
+
print(f" C_s(clean, 3 modes) = {wf_clean.spectral_complexity():.3f}")
|
|
673
|
+
print(f" C_s(+ 30 weak noise modes) = {wf_noisy.spectral_complexity():.3f}")
|
|
674
|
+
print(f" Modes retained (clean/noisy) = "
|
|
675
|
+
f"{len(wf_clean.retained_modes())} / {len(wf_noisy.retained_modes())}")
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wavefunction
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Quantum Wavefunction with Spectral Complexity measure
|
|
5
|
+
Author-email: Juha Meskanen <juha@meskanen.com>
|
|
6
|
+
Maintainer-email: Juha Meskanen <juha@meskanen.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/juhakm/wavefunction
|
|
9
|
+
Project-URL: Bug Reports, https://github.com/juhakm/wavefunction
|
|
10
|
+
Project-URL: Say Thanks!, https://github.com/juhakm/wavefunction
|
|
11
|
+
Project-URL: Source, https://github.com/juhakm/wavefunction
|
|
12
|
+
Keywords: quantum,quantum-field-theory,information-theory,wavefunction,spinor,emergent-physics,minimal-spectral-length,computational-physics
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Intended Audience :: Education
|
|
16
|
+
Classifier: Topic :: Scientific/Engineering
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
20
|
+
Classifier: Programming Language :: Python
|
|
21
|
+
Classifier: Programming Language :: Python :: 3
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Classifier: Operating System :: OS Independent
|
|
27
|
+
Requires-Python: >=3.9
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Requires-Dist: numpy<1.27,>=1.25
|
|
31
|
+
Requires-Dist: scipy>=1.10
|
|
32
|
+
Requires-Dist: numba>=0.59
|
|
33
|
+
Requires-Dist: matplotlib
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# Wavefunction
|
|
37
|
+
|
|
38
|
+
Quantum Mechanical complex valued wavefunction with Spectral Complexity measure.
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
pip install wavefunction
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
[https://pypi.org/project/wavefunction/](https://pypi.org/project/wavefunction/)
|
|
47
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
wavefunction/__init__.py
|
|
5
|
+
wavefunction/py.typed
|
|
6
|
+
wavefunction/wavefunction.py
|
|
7
|
+
wavefunction.egg-info/PKG-INFO
|
|
8
|
+
wavefunction.egg-info/SOURCES.txt
|
|
9
|
+
wavefunction.egg-info/dependency_links.txt
|
|
10
|
+
wavefunction.egg-info/requires.txt
|
|
11
|
+
wavefunction.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
wavefunction
|