qubasic 0.6.4__tar.gz → 0.6.5__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.
- {qubasic-0.6.4 → qubasic-0.6.5}/CHANGELOG.md +5 -0
- {qubasic-0.6.4/qubasic.egg-info → qubasic-0.6.5}/PKG-INFO +1 -1
- {qubasic-0.6.4 → qubasic-0.6.5}/pyproject.toml +1 -1
- {qubasic-0.6.4 → qubasic-0.6.5/qubasic.egg-info}/PKG-INFO +1 -1
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/__init__.py +1 -1
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/display.py +5 -3
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/memory.py +6 -4
- {qubasic-0.6.4 → qubasic-0.6.5}/tests/test_features.py +25 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/LICENSE +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/MANIFEST.in +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/README.md +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/examples/bell.qb +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/examples/grover3.qb +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/examples/locc_teleport.qb +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/examples/sweep_rx.qb +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic.egg-info/SOURCES.txt +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic.egg-info/dependency_links.txt +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic.egg-info/entry_points.txt +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic.egg-info/requires.txt +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic.egg-info/top_level.txt +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/__main__.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/analysis.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/backend.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/classic.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/cli.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/control_flow.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/debug.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/demos.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/engine.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/engine_state.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/errors.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/exec_context.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/executor.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/expression.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/file_io.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/gates.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/help_text.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/io_protocol.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/locc.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/locc_commands.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/locc_display.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/locc_engine.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/locc_execution.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/mock_backend.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/noise_mixin.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/parser.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/patterns.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/profiler.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/program_mgmt.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/protocol.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/qol.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/scope.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/screen.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/state_display.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/statements.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/strings.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/subs.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/sweep.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/qubasic_core/terminal.py +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/setup.cfg +0 -0
- {qubasic-0.6.4 → qubasic-0.6.5}/tests/test_qubasic.py +0 -0
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.6.5 (2026-06-19)
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- The Bloch sphere Y component had an inverted sign, so a qubit in |+i> was reported at -Y (and |-i> at +Y). `BLOCH`, `DRAW`, `PRINT QUBIT(n)`, and the memory-mapped Bloch-Y field (`$0100 + q*8 + 2`) were all affected, and `BLOCH` mislabeled |+i> as "|-i>". X and Z were already correct. Y now matches the standard convention (`<Y> = +2 Im(<1|rho|0>)`), verified against Qiskit expectation values.
|
|
7
|
+
|
|
3
8
|
## 0.6.4 (2026-06-19)
|
|
4
9
|
|
|
5
10
|
### Fixed
|
|
@@ -292,10 +292,12 @@ class DisplayMixin:
|
|
|
292
292
|
|
|
293
293
|
rho_00 = np.sum(np.abs(t0)**2)
|
|
294
294
|
rho_11 = np.sum(np.abs(t1)**2)
|
|
295
|
-
|
|
295
|
+
# conj(t0)*t1 sums to rho_10 = <1|rho|0>. <X> = 2 Re(rho_10) (Re is
|
|
296
|
+
# symmetric in rho_01/rho_10), and <Y> = -2 Im(rho_01) = +2 Im(rho_10).
|
|
297
|
+
rho_10 = np.sum(np.conj(t0) * t1)
|
|
296
298
|
|
|
297
|
-
x = float(2 *
|
|
298
|
-
y = float(
|
|
299
|
+
x = float(2 * rho_10.real)
|
|
300
|
+
y = float(2 * rho_10.imag)
|
|
299
301
|
z = float(rho_00 - rho_11)
|
|
300
302
|
|
|
301
303
|
return x, y, z
|
|
@@ -112,17 +112,19 @@ class MemoryMixin:
|
|
|
112
112
|
t0, t1 = t[0].flatten(), t[1].flatten()
|
|
113
113
|
rho_00 = float(np.sum(np.abs(t0) ** 2))
|
|
114
114
|
rho_11 = float(np.sum(np.abs(t1) ** 2))
|
|
115
|
-
|
|
115
|
+
# conj(t0)*t1 sums to rho_10 = <1|rho|0>. Bloch X = 2 Re(rho_10) and
|
|
116
|
+
# Bloch Y = -2 Im(rho_01) = +2 Im(rho_10).
|
|
117
|
+
rho_10 = complex(np.sum(np.conj(t0) * t1))
|
|
116
118
|
# Recover amplitudes with alpha as the real phase reference; beta then
|
|
117
119
|
# carries the relative phase (real and imaginary parts both exposed).
|
|
118
120
|
alpha = np.sqrt(max(0.0, rho_00))
|
|
119
121
|
if alpha > 1e-12:
|
|
120
|
-
beta =
|
|
122
|
+
beta = rho_10 / alpha
|
|
121
123
|
else:
|
|
122
124
|
beta = complex(np.sqrt(max(0.0, rho_11)))
|
|
123
125
|
return [rho_11,
|
|
124
|
-
float(2 *
|
|
125
|
-
float(
|
|
126
|
+
float(2 * rho_10.real),
|
|
127
|
+
float(2 * rho_10.imag),
|
|
126
128
|
float(rho_00 - rho_11),
|
|
127
129
|
float(alpha),
|
|
128
130
|
0.0,
|
|
@@ -2595,6 +2595,31 @@ class TestCommandSurfaceCoverage(unittest.TestCase):
|
|
|
2595
2595
|
self.assertIsInstance(t._status_prompt(), str)
|
|
2596
2596
|
capture(t._suggest_command, 'XYZ')
|
|
2597
2597
|
|
|
2598
|
+
def test_bloch_vector_axes(self):
|
|
2599
|
+
"""_bloch_vector and the $0100 By field carry the right sign on every
|
|
2600
|
+
axis. Regression: the Y component was inverted (|+i> read as -Y)."""
|
|
2601
|
+
import numpy as np
|
|
2602
|
+
from qubasic_core.terminal import QBasicTerminal
|
|
2603
|
+
t = QBasicTerminal()
|
|
2604
|
+
r2 = 1.0 / np.sqrt(2)
|
|
2605
|
+
cases = [
|
|
2606
|
+
(np.array([1, 0], dtype=complex), (0.0, 0.0, +1.0)), # |0> +Z
|
|
2607
|
+
(np.array([0, 1], dtype=complex), (0.0, 0.0, -1.0)), # |1> -Z
|
|
2608
|
+
(np.array([r2, r2], dtype=complex), (+1.0, 0.0, 0.0)), # |+> +X
|
|
2609
|
+
(np.array([r2, -r2], dtype=complex), (-1.0, 0.0, 0.0)), # |-> -X
|
|
2610
|
+
(np.array([r2, 1j * r2], dtype=complex), (0.0, +1.0, 0.0)), # |+i> +Y
|
|
2611
|
+
(np.array([r2, -1j * r2], dtype=complex), (0.0, -1.0, 0.0)), # |-i> -Y
|
|
2612
|
+
]
|
|
2613
|
+
for sv, (ex, ey, ez) in cases:
|
|
2614
|
+
x, y, z = t._bloch_vector(sv, 0, 1)
|
|
2615
|
+
self.assertAlmostEqual(x, ex, places=6)
|
|
2616
|
+
self.assertAlmostEqual(y, ey, places=6)
|
|
2617
|
+
self.assertAlmostEqual(z, ez, places=6)
|
|
2618
|
+
# Memory-mapped Bloch Y for q0 ($0102) must agree for |+i>.
|
|
2619
|
+
t.num_qubits = 1
|
|
2620
|
+
t.last_sv = np.array([r2, 1j * r2], dtype=complex)
|
|
2621
|
+
self.assertAlmostEqual(t._peek(0x0102), +1.0, places=6)
|
|
2622
|
+
|
|
2598
2623
|
def test_program_and_io_surface(self):
|
|
2599
2624
|
import builtins
|
|
2600
2625
|
t = self._ready()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|