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 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.
@@ -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,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,7 @@
1
+ numpy>=1.24
2
+ matplotlib>=3.7
3
+ scipy>=1.10
4
+
5
+ [dev]
6
+ check-manifest
7
+ types-pyz
@@ -0,0 +1 @@
1
+ qbitwave
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -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()