qbitwave 0.1.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.
- qbitwave-0.1.0/LICENSE +21 -0
- qbitwave-0.1.0/PKG-INFO +55 -0
- qbitwave-0.1.0/README.md +27 -0
- qbitwave-0.1.0/pyproject.toml +58 -0
- qbitwave-0.1.0/qbitwave/__init__.py +0 -0
- qbitwave-0.1.0/qbitwave/py.typed +0 -0
- qbitwave-0.1.0/qbitwave/qbitwave.py +120 -0
- qbitwave-0.1.0/qbitwave/qbitwave_visualizer.py +45 -0
- qbitwave-0.1.0/qbitwave.egg-info/PKG-INFO +55 -0
- qbitwave-0.1.0/qbitwave.egg-info/SOURCES.txt +13 -0
- qbitwave-0.1.0/qbitwave.egg-info/dependency_links.txt +1 -0
- qbitwave-0.1.0/qbitwave.egg-info/requires.txt +7 -0
- qbitwave-0.1.0/qbitwave.egg-info/top_level.txt +1 -0
- qbitwave-0.1.0/setup.cfg +4 -0
- qbitwave-0.1.0/tests/test_qbitwave.py +50 -0
qbitwave-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 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.
|
qbitwave-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qbitwave
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Discrete emergent wavefunction
|
|
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/qbitwave
|
|
9
|
+
Project-URL: Bug Reports, https://github.com/juhakm/qbitwave
|
|
10
|
+
Project-URL: Funding, https://meskanen.com
|
|
11
|
+
Project-URL: Say Thanks!, http://meskanen.com
|
|
12
|
+
Project-URL: Source, https://github.com/juhakm/qbitwave
|
|
13
|
+
Keywords: physics,quantum
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Software Development
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: numpy>=1.24
|
|
22
|
+
Requires-Dist: matplotlib>=3.7
|
|
23
|
+
Requires-Dist: scipy>=1.10
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: check-manifest; extra == "dev"
|
|
26
|
+
Requires-Dist: types-pyz; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# Bitwave
|
|
30
|
+
|
|
31
|
+
**A minimal informational model of quantum emergence.**
|
|
32
|
+
|
|
33
|
+
`Bitwave` is a Python library for simulating quantum-like wavefunctions as emergent properties of binary strings. It unifies bitstrings, amplitudes, and entropy into a single foundational object.
|
|
34
|
+
|
|
35
|
+
## Key Concepts
|
|
36
|
+
|
|
37
|
+
- **Bit = Geometry**: Each bit encodes structure.
|
|
38
|
+
- **Bitstring = Universe State**: A single bitstring describes a possible quantum universe.
|
|
39
|
+
- **Bitwave = Wavefunction**: A discrete quantum object derived purely from bits.
|
|
40
|
+
|
|
41
|
+
## Features
|
|
42
|
+
|
|
43
|
+
- Convert any bitstring into a complex amplitude vector
|
|
44
|
+
- Extract |ψ|² and phase
|
|
45
|
+
- Measure entropy and emergent resolution
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## Example
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from bitwave import Bitwave
|
|
52
|
+
|
|
53
|
+
bw = Bitwave("1101010111001001")
|
|
54
|
+
amplitudes = bw.get_amplitudes()
|
|
55
|
+
entropy = bw.entropy()
|
qbitwave-0.1.0/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Bitwave
|
|
2
|
+
|
|
3
|
+
**A minimal informational model of quantum emergence.**
|
|
4
|
+
|
|
5
|
+
`Bitwave` is a Python library for simulating quantum-like wavefunctions as emergent properties of binary strings. It unifies bitstrings, amplitudes, and entropy into a single foundational object.
|
|
6
|
+
|
|
7
|
+
## Key Concepts
|
|
8
|
+
|
|
9
|
+
- **Bit = Geometry**: Each bit encodes structure.
|
|
10
|
+
- **Bitstring = Universe State**: A single bitstring describes a possible quantum universe.
|
|
11
|
+
- **Bitwave = Wavefunction**: A discrete quantum object derived purely from bits.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- Convert any bitstring into a complex amplitude vector
|
|
16
|
+
- Extract |ψ|² and phase
|
|
17
|
+
- Measure entropy and emergent resolution
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Example
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from bitwave import Bitwave
|
|
24
|
+
|
|
25
|
+
bw = Bitwave("1101010111001001")
|
|
26
|
+
amplitudes = bw.get_amplitudes()
|
|
27
|
+
entropy = bw.entropy()
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[tool.setuptools]
|
|
6
|
+
include-package-data = true
|
|
7
|
+
packages = ["qbitwave"]
|
|
8
|
+
|
|
9
|
+
[project]
|
|
10
|
+
name = "qbitwave"
|
|
11
|
+
version = "0.1.0"
|
|
12
|
+
description = "Discrete emergent wavefunction"
|
|
13
|
+
readme = {file = "README.md", content-type = "text/markdown"}
|
|
14
|
+
requires-python = ">=3.9"
|
|
15
|
+
license = "MIT"
|
|
16
|
+
keywords = ["physics", "quantum"]
|
|
17
|
+
authors = [
|
|
18
|
+
{name = "Juha Meskanen", email = "juha@meskanen.com" }
|
|
19
|
+
]
|
|
20
|
+
maintainers = [
|
|
21
|
+
{name = "Juha Meskanen", email = "juha@meskanen.com" }
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
classifiers = [
|
|
25
|
+
"Development Status :: 3 - Alpha",
|
|
26
|
+
"Intended Audience :: Developers",
|
|
27
|
+
"Topic :: Software Development",
|
|
28
|
+
"Programming Language :: Python :: 3.9",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
dependencies = [
|
|
32
|
+
"numpy >=1.24",
|
|
33
|
+
"matplotlib >=3.7",
|
|
34
|
+
"scipy >=1.10"]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
[project.optional-dependencies]
|
|
38
|
+
dev = [
|
|
39
|
+
"check-manifest",
|
|
40
|
+
"types-pyz"
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.urls]
|
|
44
|
+
"Homepage" = "https://github.com/juhakm/qbitwave"
|
|
45
|
+
"Bug Reports" = "https://github.com/juhakm/qbitwave"
|
|
46
|
+
"Funding" = "https://meskanen.com"
|
|
47
|
+
"Say Thanks!" = "http://meskanen.com"
|
|
48
|
+
"Source" = "https://github.com/juhakm/qbitwave"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
[tool.mypy]
|
|
52
|
+
files = ["bitwave/*.py", "examples/*.py"]
|
|
53
|
+
ignore_missing_imports = false
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
[tool.setuptools.package-data]
|
|
57
|
+
"qbitwave" = ["py.typed"]
|
|
58
|
+
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
class QBitwave:
|
|
4
|
+
def __init__(self, bitstring: str):
|
|
5
|
+
self.bitstring = bitstring
|
|
6
|
+
self.max_block_size = 32 # adjustable upper bound
|
|
7
|
+
self.min_block_size = 4 # minimum size to interpret anything
|
|
8
|
+
self.amplitudes = []
|
|
9
|
+
self.selected_block_size = None
|
|
10
|
+
|
|
11
|
+
self._analyze_bitstring()
|
|
12
|
+
|
|
13
|
+
def entropy(self):
|
|
14
|
+
"""Return Shannon entropy of the probability distribution |ψ|²."""
|
|
15
|
+
probs = np.abs(self.amplitudes) ** 2
|
|
16
|
+
probs = np.clip(probs, 1e-10, 1.0)
|
|
17
|
+
return -np.sum(probs * np.log2(probs))
|
|
18
|
+
|
|
19
|
+
def num_states(self):
|
|
20
|
+
"""Return the number of discrete quantum states (amplitudes)."""
|
|
21
|
+
return len(self.amplitudes)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def dimension(self):
|
|
25
|
+
"""Dimension of the Hilbert space."""
|
|
26
|
+
return len(self.amplitudes)
|
|
27
|
+
|
|
28
|
+
def norm(self):
|
|
29
|
+
"""Return the L2 norm of the wavefunction (should be ~1)."""
|
|
30
|
+
return np.linalg.norm(self.amplitudes)
|
|
31
|
+
|
|
32
|
+
def get_probability_distribution(self):
|
|
33
|
+
"""Return the |ψ|² values as a NumPy array."""
|
|
34
|
+
return np.abs(self.amplitudes) ** 2
|
|
35
|
+
|
|
36
|
+
def get_phase_distribution(self):
|
|
37
|
+
"""Return the phase angles in radians."""
|
|
38
|
+
return np.angle(self.amplitudes)
|
|
39
|
+
|
|
40
|
+
def __str__(self):
|
|
41
|
+
"""Pretty-print the wavefunction in Dirac-style notation."""
|
|
42
|
+
lines = []
|
|
43
|
+
for i, amp in enumerate(self.amplitudes):
|
|
44
|
+
prob = abs(amp) ** 2
|
|
45
|
+
if prob < 1e-6:
|
|
46
|
+
continue # skip negligible
|
|
47
|
+
lines.append(f"{amp:.3f} |{i:0{self._bitwidth()}b}⟩")
|
|
48
|
+
return " + ".join(lines) if lines else "∅"
|
|
49
|
+
|
|
50
|
+
def _bitwidth(self):
|
|
51
|
+
"""Helper: number of bits needed to label states."""
|
|
52
|
+
n = len(self.amplitudes)
|
|
53
|
+
return max(1, int(np.ceil(np.log2(n))))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _analyze_bitstring(self):
|
|
57
|
+
best_score = -np.inf
|
|
58
|
+
best_amplitudes = []
|
|
59
|
+
best_block_size = None
|
|
60
|
+
|
|
61
|
+
for block_size in range(self.min_block_size, self.max_block_size + 1, 2):
|
|
62
|
+
amps = self._interpret_as_wavefunction(block_size)
|
|
63
|
+
if not amps:
|
|
64
|
+
continue
|
|
65
|
+
|
|
66
|
+
score = self._score_amplitudes(amps)
|
|
67
|
+
|
|
68
|
+
if score > best_score:
|
|
69
|
+
best_score = score
|
|
70
|
+
best_amplitudes = amps
|
|
71
|
+
best_block_size = block_size
|
|
72
|
+
|
|
73
|
+
self.amplitudes = best_amplitudes
|
|
74
|
+
self.selected_block_size = best_block_size
|
|
75
|
+
|
|
76
|
+
def _interpret_as_wavefunction(self, block_size):
|
|
77
|
+
if len(self.bitstring) < block_size:
|
|
78
|
+
return []
|
|
79
|
+
|
|
80
|
+
step = block_size
|
|
81
|
+
half = step // 2
|
|
82
|
+
n_blocks = len(self.bitstring) // step
|
|
83
|
+
amplitudes = []
|
|
84
|
+
|
|
85
|
+
for i in range(n_blocks):
|
|
86
|
+
chunk = self.bitstring[i * step : (i + 1) * step]
|
|
87
|
+
real_bits = chunk[:half]
|
|
88
|
+
imag_bits = chunk[half:]
|
|
89
|
+
|
|
90
|
+
re = self._bits_to_signed_float(real_bits)
|
|
91
|
+
im = self._bits_to_signed_float(imag_bits)
|
|
92
|
+
amplitudes.append(complex(re, im))
|
|
93
|
+
|
|
94
|
+
norm = np.linalg.norm(amplitudes)
|
|
95
|
+
if norm == 0:
|
|
96
|
+
return []
|
|
97
|
+
|
|
98
|
+
return [amp / norm for amp in amplitudes]
|
|
99
|
+
|
|
100
|
+
def _bits_to_signed_float(self, bits: str):
|
|
101
|
+
if len(bits) == 0:
|
|
102
|
+
return 0.0
|
|
103
|
+
max_val = 2 ** (len(bits) - 1)
|
|
104
|
+
val = int(bits, 2)
|
|
105
|
+
if val >= max_val:
|
|
106
|
+
val -= 2 * max_val
|
|
107
|
+
return val / max_val # in range [-1, 1)
|
|
108
|
+
|
|
109
|
+
def _score_amplitudes(self, amps):
|
|
110
|
+
# Use entropy of |ψ|² as a proxy for structure
|
|
111
|
+
probs = np.abs(amps) ** 2
|
|
112
|
+
probs = np.clip(probs, 1e-10, 1.0)
|
|
113
|
+
entropy = -np.sum(probs * np.log2(probs))
|
|
114
|
+
return entropy / len(amps) # normalize per amplitude
|
|
115
|
+
|
|
116
|
+
def get_amplitudes(self):
|
|
117
|
+
return self.amplitudes
|
|
118
|
+
|
|
119
|
+
def get_selected_block_size(self):
|
|
120
|
+
return self.selected_block_size
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
from wavefunction import QBitwave
|
|
4
|
+
|
|
5
|
+
class QBitwaveVisualizer:
|
|
6
|
+
def __init__(self, wavefunction: QBitwave):
|
|
7
|
+
self.wf = wavefunction
|
|
8
|
+
self.amplitudes = self.wf.get_amplitudes()
|
|
9
|
+
self.indices = np.arange(len(self.amplitudes))
|
|
10
|
+
self.real = np.real(self.amplitudes)
|
|
11
|
+
self.imag = np.imag(self.amplitudes)
|
|
12
|
+
self.prob = np.abs(self.amplitudes) ** 2
|
|
13
|
+
self.phase = np.angle(self.amplitudes)
|
|
14
|
+
|
|
15
|
+
def plot_components(self, title: str = "QBitwave Components"):
|
|
16
|
+
fig, axs = plt.subplots(4, 1, figsize=(10, 10), sharex=True)
|
|
17
|
+
|
|
18
|
+
axs[0].bar(self.indices, self.real, color='blue')
|
|
19
|
+
axs[0].set_ylabel("Re(ψ)")
|
|
20
|
+
axs[0].set_title(title)
|
|
21
|
+
|
|
22
|
+
axs[1].bar(self.indices, self.imag, color='red')
|
|
23
|
+
axs[1].set_ylabel("Im(ψ)")
|
|
24
|
+
|
|
25
|
+
axs[2].bar(self.indices, self.prob, color='black')
|
|
26
|
+
axs[2].set_ylabel("|ψ|² (Prob)")
|
|
27
|
+
|
|
28
|
+
axs[3].bar(self.indices, self.phase, color='purple')
|
|
29
|
+
axs[3].set_ylabel("Arg(ψ)")
|
|
30
|
+
axs[3].set_xlabel("State Index")
|
|
31
|
+
|
|
32
|
+
plt.tight_layout()
|
|
33
|
+
plt.show()
|
|
34
|
+
|
|
35
|
+
def plot_heatmap(self, title: str = "QBitwave Heatmap"):
|
|
36
|
+
data = np.array([self.prob, self.phase])
|
|
37
|
+
fig, ax = plt.subplots(figsize=(10, 2))
|
|
38
|
+
im = ax.imshow(data, cmap='viridis', aspect='auto')
|
|
39
|
+
|
|
40
|
+
ax.set_yticks([0, 1])
|
|
41
|
+
ax.set_yticklabels(["|ψ|²", "Phase"])
|
|
42
|
+
ax.set_title(title)
|
|
43
|
+
|
|
44
|
+
plt.colorbar(im, ax=ax, orientation='vertical')
|
|
45
|
+
plt.show()
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qbitwave
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Discrete emergent wavefunction
|
|
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/qbitwave
|
|
9
|
+
Project-URL: Bug Reports, https://github.com/juhakm/qbitwave
|
|
10
|
+
Project-URL: Funding, https://meskanen.com
|
|
11
|
+
Project-URL: Say Thanks!, http://meskanen.com
|
|
12
|
+
Project-URL: Source, https://github.com/juhakm/qbitwave
|
|
13
|
+
Keywords: physics,quantum
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Software Development
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Requires-Python: >=3.9
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: numpy>=1.24
|
|
22
|
+
Requires-Dist: matplotlib>=3.7
|
|
23
|
+
Requires-Dist: scipy>=1.10
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: check-manifest; extra == "dev"
|
|
26
|
+
Requires-Dist: types-pyz; extra == "dev"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# Bitwave
|
|
30
|
+
|
|
31
|
+
**A minimal informational model of quantum emergence.**
|
|
32
|
+
|
|
33
|
+
`Bitwave` is a Python library for simulating quantum-like wavefunctions as emergent properties of binary strings. It unifies bitstrings, amplitudes, and entropy into a single foundational object.
|
|
34
|
+
|
|
35
|
+
## Key Concepts
|
|
36
|
+
|
|
37
|
+
- **Bit = Geometry**: Each bit encodes structure.
|
|
38
|
+
- **Bitstring = Universe State**: A single bitstring describes a possible quantum universe.
|
|
39
|
+
- **Bitwave = Wavefunction**: A discrete quantum object derived purely from bits.
|
|
40
|
+
|
|
41
|
+
## Features
|
|
42
|
+
|
|
43
|
+
- Convert any bitstring into a complex amplitude vector
|
|
44
|
+
- Extract |ψ|² and phase
|
|
45
|
+
- Measure entropy and emergent resolution
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## Example
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from bitwave import Bitwave
|
|
52
|
+
|
|
53
|
+
bw = Bitwave("1101010111001001")
|
|
54
|
+
amplitudes = bw.get_amplitudes()
|
|
55
|
+
entropy = bw.entropy()
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
qbitwave/__init__.py
|
|
5
|
+
qbitwave/py.typed
|
|
6
|
+
qbitwave/qbitwave.py
|
|
7
|
+
qbitwave/qbitwave_visualizer.py
|
|
8
|
+
qbitwave.egg-info/PKG-INFO
|
|
9
|
+
qbitwave.egg-info/SOURCES.txt
|
|
10
|
+
qbitwave.egg-info/dependency_links.txt
|
|
11
|
+
qbitwave.egg-info/requires.txt
|
|
12
|
+
qbitwave.egg-info/top_level.txt
|
|
13
|
+
tests/test_qbitwave.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
qbitwave
|
qbitwave-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
import numpy as np
|
|
3
|
+
from qbitwave import QBitwave
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestQBitwave(unittest.TestCase):
|
|
7
|
+
|
|
8
|
+
def test_initialization(self):
|
|
9
|
+
bw = QBitwave("010101")
|
|
10
|
+
self.assertIsInstance(bw.bitstring, str)
|
|
11
|
+
self.assertTrue(all(b in "01" for b in bw.bitstring))
|
|
12
|
+
|
|
13
|
+
def test_amplitudes_length(self):
|
|
14
|
+
bw = QBitwave("1100110011")
|
|
15
|
+
amplitudes = bw.get_amplitudes()
|
|
16
|
+
self.assertIsInstance(amplitudes, np.ndarray)
|
|
17
|
+
self.assertGreaterEqual(len(amplitudes), 1)
|
|
18
|
+
self.assertTrue(np.iscomplexobj(amplitudes))
|
|
19
|
+
|
|
20
|
+
def test_amplitudes_normalization(self):
|
|
21
|
+
bw = QBitwave("1100110011")
|
|
22
|
+
amplitudes = bw.get_amplitudes()
|
|
23
|
+
prob_sum = np.sum(np.abs(amplitudes) ** 2)
|
|
24
|
+
self.assertAlmostEqual(prob_sum, 1.0, places=6)
|
|
25
|
+
|
|
26
|
+
def test_entropy_increases_with_structure(self):
|
|
27
|
+
bw_low = QBitwave("0000000000")
|
|
28
|
+
bw_high = QBitwave("1011001010")
|
|
29
|
+
entropy_low = bw_low.entropy()
|
|
30
|
+
entropy_high = bw_high.entropy()
|
|
31
|
+
self.assertLess(entropy_low, entropy_high)
|
|
32
|
+
|
|
33
|
+
def test_resolution_consistency(self):
|
|
34
|
+
bw = QBitwave("1011010110110101")
|
|
35
|
+
self.assertEqual(bw.resolution(), len(bw.get_amplitudes()))
|
|
36
|
+
|
|
37
|
+
def test_entropy_bounds(self):
|
|
38
|
+
bw = QBitwave("00000000")
|
|
39
|
+
entropy = bw.entropy()
|
|
40
|
+
self.assertGreaterEqual(entropy, 0)
|
|
41
|
+
self.assertLessEqual(entropy, np.log2(bw.resolution() + 1e-10)) # entropy ≤ log2(n)
|
|
42
|
+
|
|
43
|
+
def test_num_states(self):
|
|
44
|
+
bw = QBitwave("1010011101")
|
|
45
|
+
n = bw.num_states()
|
|
46
|
+
self.assertEqual(n, len(bw.get_amplitudes()))
|
|
47
|
+
self.assertGreater(n, 0)
|
|
48
|
+
|
|
49
|
+
if __name__ == '__main__':
|
|
50
|
+
unittest.main()
|