qubasic 0.18.0__tar.gz → 0.19.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.
Files changed (84) hide show
  1. {qubasic-0.18.0 → qubasic-0.19.0}/CHANGELOG.md +42 -0
  2. {qubasic-0.18.0/qubasic.egg-info → qubasic-0.19.0}/PKG-INFO +137 -39
  3. {qubasic-0.18.0 → qubasic-0.19.0}/README.md +136 -38
  4. {qubasic-0.18.0 → qubasic-0.19.0}/pyproject.toml +2 -2
  5. {qubasic-0.18.0 → qubasic-0.19.0/qubasic.egg-info}/PKG-INFO +137 -39
  6. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic.egg-info/SOURCES.txt +8 -1
  7. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/__init__.py +1 -1
  8. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/algos2.py +215 -124
  9. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/analysis.py +146 -92
  10. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/benchmarking.py +14 -23
  11. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/bosonic.py +1 -1
  12. qubasic-0.19.0/qubasic_core/capacity.py +144 -0
  13. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/classic.py +87 -108
  14. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/cli.py +5 -5
  15. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/control_flow.py +218 -51
  16. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/debug.py +20 -13
  17. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/display.py +53 -80
  18. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/dynamics.py +60 -32
  19. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/engine.py +7 -9
  20. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/engine_state.py +28 -2
  21. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/exec_context.py +3 -0
  22. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/executor.py +175 -106
  23. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/expression.py +53 -8
  24. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/file_io.py +37 -8
  25. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/gates.py +134 -43
  26. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/help_text.py +20 -9
  27. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/jupyter_kernel.py +19 -7
  28. qubasic-0.19.0/qubasic_core/live.py +671 -0
  29. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/locc_commands.py +1 -1
  30. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/locc_engine.py +71 -76
  31. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/locc_execution.py +103 -53
  32. qubasic-0.19.0/qubasic_core/logical.py +391 -0
  33. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/memory.py +41 -26
  34. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/mock_backend.py +4 -3
  35. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/parser.py +38 -1
  36. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/pauliprop.py +8 -1
  37. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/profiler.py +0 -10
  38. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/program_mgmt.py +2 -2
  39. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/qec.py +339 -138
  40. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/qec2.py +34 -6
  41. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/qol.py +82 -56
  42. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/qudits.py +13 -9
  43. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/resources.py +67 -11
  44. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/state_display.py +1 -1
  45. qubasic-0.19.0/qubasic_core/statetools.py +239 -0
  46. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/subs.py +38 -43
  47. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/sweep.py +1 -1
  48. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/terminal.py +651 -373
  49. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/web_repl.py +61 -16
  50. qubasic-0.19.0/tests/test_encoded_and_open.py +129 -0
  51. {qubasic-0.18.0 → qubasic-0.19.0}/tests/test_features.py +10 -19
  52. qubasic-0.19.0/tests/test_frontends_and_benchmarks.py +239 -0
  53. qubasic-0.19.0/tests/test_numpy_engine.py +120 -0
  54. {qubasic-0.18.0 → qubasic-0.19.0}/tests/test_qubasic.py +10 -7
  55. qubasic-0.19.0/tests/test_semantics.py +297 -0
  56. qubasic-0.18.0/qubasic_core/logical.py +0 -164
  57. {qubasic-0.18.0 → qubasic-0.19.0}/LICENSE +0 -0
  58. {qubasic-0.18.0 → qubasic-0.19.0}/MANIFEST.in +0 -0
  59. {qubasic-0.18.0 → qubasic-0.19.0}/examples/bell.qb +0 -0
  60. {qubasic-0.18.0 → qubasic-0.19.0}/examples/grover3.qb +0 -0
  61. {qubasic-0.18.0 → qubasic-0.19.0}/examples/locc_teleport.qb +0 -0
  62. {qubasic-0.18.0 → qubasic-0.19.0}/examples/sweep_rx.qb +0 -0
  63. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic.egg-info/dependency_links.txt +0 -0
  64. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic.egg-info/entry_points.txt +0 -0
  65. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic.egg-info/requires.txt +0 -0
  66. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic.egg-info/top_level.txt +0 -0
  67. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/__main__.py +0 -0
  68. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/algorithms.py +0 -0
  69. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/backend.py +0 -0
  70. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/demos.py +0 -0
  71. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/errors.py +0 -0
  72. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/io_protocol.py +0 -0
  73. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/locc.py +0 -0
  74. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/locc_display.py +0 -0
  75. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/noise_mixin.py +0 -0
  76. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/patterns.py +0 -0
  77. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/protocol.py +0 -0
  78. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/qchem.py +0 -0
  79. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/scope.py +0 -0
  80. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/screen.py +0 -0
  81. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/statements.py +0 -0
  82. {qubasic-0.18.0 → qubasic-0.19.0}/qubasic_core/strings.py +0 -0
  83. {qubasic-0.18.0 → qubasic-0.19.0}/setup.cfg +0 -0
  84. {qubasic-0.18.0 → qubasic-0.19.0}/tests/test_golden.py +0 -0
@@ -1,5 +1,47 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.0 (2026-10-10)
4
+
5
+ ### Added
6
+ - Live execution: a program that reads a mid-circuit measurement bit as a number (PRINT, LET, comparisons, GOTO, loops) runs shot by shot on a numpy statevector, with MEAS returning the collapsed outcome. Only the first shot prints, later shots replay its INPUT answers and write no files, and the summary reads `method=live`. Afterwards variables hold the first shot's values and SAVE_EXPECT/SAVE_PROBS the mean over shots. Noise models run as quantum trajectories with readout error. MEASURE_X/Y/Z and SYNDROME bits behave the same. IF <bit> THEN <gates> still compiles to a dynamic circuit.
7
+ - `LQUBITS <n> CODE STEANE [PHYS p]` simulates the program encoded: [[7,1,3]] blocks, transversal Clifford gates, depolarizing noise after every physical gate and on readout, a syndrome-extraction round with conditional corrections after every logical gate, and block-wise decoded readout on the stabilizer simulator. RUN reports the total variation distance from the ideal distribution (`_LOGICAL_TVD`). The other codes are labeled as modeled.
8
+ - `PRECISION SINGLE|DOUBLE` (also `$D00C`): complex64 amplitudes for Aer statevector-family methods, LOCC, STEP and live runs.
9
+ - Memory model (`qubasic_core/capacity.py`): runs are sized against the RAM available at the moment, and one that cannot fit is refused with its requirement and the alternatives. The banner, QUBITS, STATUS and RAM report the widest statevector run at each precision.
10
+ - Entanglement and state analysis without dense 2^n x 2^n matrices (`qubasic_core/statetools.py`): reduced density matrices accumulated block by block, used by ENTROPY, NEGATIVITY, CONCURRENCE, EXPECT, CONSISTENCY, BLOCH and HEATMAP.
11
+ - `PRINT STATE`, `PRINT QUBIT(q)` and `PRINT ENTANGLEMENT(a, b)` inside a program show the state at that line.
12
+ - HEATMAP shows pairwise quantum mutual information; `HEATMAP CONCURRENCE` shows concurrence.
13
+ - Exact minimum-weight perfect matching decoder (rustworkx blossom on the code's matching graph with boundary nodes; `MATCH`, alias `UF`). Lookup tables are built in order of error weight, and the default decoder is lookup while the syndrome space allows and matching beyond. THRESHOLD takes decoder flags and `TRIALS n`.
14
+ - DEVICE heavyhex builds Qiskit's heavy-hex coupling map. Device noise sits on coupled pairs only.
15
+
16
+ ### Changed
17
+ - Colon compounds run every statement whatever it is (`PRINT 1: PRINT 2`, `LET a = 1: LET b = 2`, `RESET 0: X 0`), and a colon inside a string is text. GOTO, GOSUB, RETURN and END inside a compound take effect. An IF owns the rest of its line, as do REM, `'` and DEF.
18
+ - Loops follow QBASIC. Single-line loops (`FOR I = 1 TO 3: H I: NEXT I`) and loops opened mid-line work. A FOR whose range the step cannot reach is zero-trip, and the counter ends one step past the limit. WHILE and DO keep one loop-stack entry per loop. NEXT, WEND and LOOP close loops a jump left open. EXIT FOR/WHILE/DO search statement by statement. GOSUB, ON GOSUB and CALL return to the next statement on the line, inside IF clauses as well.
19
+ - A single `=` inside an expression is equality (`IF x = 2 THEN`, `flag = a = b`). `^` is exponentiation and `MOD` the BASIC remainder (sign of the dividend). SGN, SQR, ATN, CINT, CLNG, CSNG and CDBL are available. A bare `PRINT` prints a blank line.
20
+ - In a running program an unassigned variable reads 0 (`""` for `name$`); qubit indices, gate parameters, matrix literals and prompt commands still reject unknown names.
21
+ - PRINT formats numbers as BASIC does: a leading space for non-negative values, a trailing space, whole numbers without a decimal point, exponents as `1E+20`.
22
+ - SELECT CASE takes value lists, `a TO b` ranges, `IS <op> v` comparisons, exact string cases and `CASE v: statement` on one line.
23
+ - STEP runs as one live shot, so MEAS collapses the displayed state and IF/PRINT see the outcome. STEP honors END.
24
+ - LOCC runs print on the first shot only, keep the first shot's variables, and re-execute the prefix per shot when noise is active.
25
+ - APPLYCHANNEL leaves METHOD unchanged. Shots sample the channel as trajectories, and a run without MEASURE keeps the mixed state for DENSITY.
26
+ - The exact LINDBLAD path keeps the Hamiltonian and jump operators sparse and reaches 10 qubits.
27
+ - A RUN with no gates skips the simulator.
28
+ - Measured runs keep their final state from inside the same simulation when memory allows. Otherwise it is computed on first use.
29
+ - The transpile cache is keyed on a digest of the built circuit, so DEF, UNITARY, SET_STATE and variable changes rebuild it.
30
+ - The numpy engine (LOCC, STEP, live runs) updates states in place, block by block.
31
+ - AMPEST is maximum-likelihood amplitude estimation over the program's state (`AMPEST [m] <qubit | |bits>> [SHOTS n]`), with a Fisher-information spread.
32
+ - HHL uses a signed clock register and a uniformly controlled RY, and reports fidelity and post-selection probability.
33
+ - CTRL takes gate parameters and UNITARY gates in both execution paths; UNITARY gates run in LOCC mode.
34
+ - OPTION ENDIAN applies to CSV, CLIP, COMPARE, ANIMATE, Lindblad populations and qudit output (qudit 0 rightmost).
35
+ - MEAS and RESET reject out-of-range qubits. A MEAS repeated in a loop compiles, with feedforward reading the latest outcome. SYNDROME and MEASURE_X/Y/Z bits drive IF feedforward.
36
+ - The web REPL serializes requests on its one terminal, compares the token in constant time, caps request size, and treats INPUT as end of input. The Jupyter kernel captures output per cell and asks INPUT through the notebook when allowed.
37
+ - Time-travel checkpoints hold up to 64 MiB each within a 256 MiB budget.
38
+ - LQUBITS OFF restores the noise model that was active before.
39
+ - SAMPLE samples the program's MEASURE subset (or every qubit) with the active noise model, precision and SEED.
40
+ - METHOD rejects unknown method names. POKE $D000 clamps to the method's qubit ceiling.
41
+ - PAULIPROP refuses programs that measure or reset.
42
+ - PROFILE reports the gates each line adds.
43
+ - CHAIN and MERGE read files that begin with a byte-order mark.
44
+
3
45
  ## 0.18.0 (2026-07-03)
4
46
 
5
47
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qubasic
3
- Version: 0.18.0
3
+ Version: 0.19.0
4
4
  Summary: Quantum BASIC Interactive Terminal
5
5
  Author-email: "Charles C. Norton" <machineelv@gmail.com>
6
6
  License-Expression: MIT
@@ -212,11 +212,16 @@ BARRIER Optimization barrier
212
212
  RESET 0 Reset qubit to |0>
213
213
  ```
214
214
 
215
- ### Multi-gate lines
215
+ ### Multi-statement lines
216
216
  ```
217
217
  10 H 0 : CX 0,1 : RZ PI/4, 0 Colon-separated
218
+ 10 FOR I = 0 TO 3: H I: NEXT I Any statements, loops included
218
219
  ```
219
220
 
221
+ A colon outside a string separates statements, whatever they are. An `IF`
222
+ owns the rest of its line (`IF c THEN A: B ELSE C: D`), and so do `REM`,
223
+ `'` comments and `DEF` bodies.
224
+
220
225
  ## Configuration
221
226
 
222
227
  ```
@@ -224,6 +229,7 @@ QUBITS 8 Set qubit count (ceiling is per METHOD)
224
229
  SHOTS 2048 Set measurement shots
225
230
  METHOD statevector Set simulation method
226
231
  METHOD GPU Set simulation device
232
+ PRECISION SINGLE complex64 amplitudes: half the memory, one more qubit (DOUBLE to restore)
227
233
  STATUS Show every active mode (qubits, method, LOCC, noise, ...)
228
234
  STATUS JSON Same, as machine-readable JSON
229
235
  ```
@@ -231,7 +237,9 @@ STATUS JSON Same, as machine-readable JSON
231
237
  ### Simulation methods
232
238
  `automatic`, `statevector`, `density_matrix`, `stabilizer`, `matrix_product_state`, `extended_stabilizer`, `unitary`, `superop`
233
239
 
234
- Automatic selection: stabilizer for Clifford-only circuits, MPS for >28 qubits, statevector otherwise.
240
+ Automatic selection: stabilizer for noiseless Clifford circuits at any width;
241
+ otherwise statevector while it fits in available memory (at double precision,
242
+ then single), and matrix_product_state beyond.
235
243
 
236
244
  Qubit ceilings are per method: the 32-qubit wall is a statevector memory
237
245
  limit only. `stabilizer` reaches 4096 qubits (polynomial tableau),
@@ -252,11 +260,20 @@ CLEAR x Remove a variable
252
260
 
253
261
  Functions and keywords are case-insensitive (`SQRT` and `sqrt` both work).
254
262
 
263
+ Inside a running program an unassigned variable reads as 0 (`""` for a
264
+ `name$` string), so `count = count + 1` needs no initialization. Qubit
265
+ indices, gate parameters and matrix literals still reject unknown names, as
266
+ do commands typed at the prompt.
267
+
268
+ `PRINT` shows numbers as BASIC does: a leading space in place of a plus sign,
269
+ a trailing space, and whole values without a decimal point (`PRINT 1; -2.5`
270
+ prints ` 1 -2.5 `).
271
+
255
272
  ### Constants
256
273
  `PI`, `TAU`, `E`, `SQRT2`, `True`, `False` (reserved; not usable as variable names)
257
274
 
258
275
  ### Math functions
259
- `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `sqrt`, `log`, `exp`, `abs`, `int` (floors), `fix` (truncates), `float`, `min`, `max`, `round`, `ceil`, `floor`, `len`
276
+ `sin`, `cos`, `tan`, `asin`, `acos`, `atan`, `atan2`, `sqrt`, `log`, `exp`, `abs`, `int` (floors), `fix` (truncates), `float`, `min`, `max`, `round`, `ceil`, `floor`, `len`, and the QBASIC spellings `SGN`, `SQR`, `ATN`, `CINT`, `CLNG`, `CSNG`, `CDBL`
260
277
 
261
278
  ### Runtime functions
262
279
  `RND(x)` random, `TIMER` elapsed seconds, `FRE(0)` free RAM bytes, `POS(0)` cursor column, `PEEK(addr)` memory read, `USR(addr)` call routine
@@ -265,8 +282,8 @@ Functions and keywords are case-insensitive (`SQRT` and `sqrt` both work).
265
282
  `LEFT$(s,n)`, `RIGHT$(s,n)`, `MID$(s,n,len)`, `CHR$(n)`, `STR$(n)`, `HEX$(n)`, `BIN$(n)`, `ASC(c)`, `VAL(s)`, `INSTR(haystack,needle)`, `LEN(s)`
266
283
 
267
284
  ### Operators
268
- Arithmetic: `+`, `-`, `*`, `/`, `//`, `%`, `**`
269
- Comparison: `==`, `!=`, `<>`, `<`, `>`, `<=`, `>=` (yield -1 for true, 0 for false; chain Python-style, so `0 <= x <= 10` works)
285
+ Arithmetic: `+`, `-`, `*`, `/`, `//`, `%`, `**` or `^` (power), `MOD` (operands rounded to integers, sign of the dividend: `-7 MOD 3` = -1)
286
+ Comparison: `=`, `==`, `<>`, `!=`, `<`, `>`, `<=`, `>=` (yield -1 for true, 0 for false; chain Python-style, so `0 <= x <= 10` works). Inside an expression a single `=` compares, so `IF x = 2 THEN` and `flag = a = b` read as in BASIC.
270
287
  Logical: `AND`, `OR`, `NOT`, `XOR`
271
288
  Bitwise: `AND`, `OR`, `XOR` on integers (`6 AND 3` = 2); `NOT` is logical
272
289
  Hex/binary literals: `&HFF`, `&B10110`
@@ -300,8 +317,8 @@ OPTION BASE 1 Set array index base
300
317
  10 WHILE n < 10 / WEND
301
318
  10 DO WHILE x > 0 / LOOP
302
319
  10 DO / LOOP UNTIL x == 0
303
- 10 IF flag == 1 THEN H 0 ELSE X 0
304
- 10 SELECT CASE x / CASE 1 / CASE 2 / CASE ELSE / END SELECT
320
+ 10 IF flag = 1 THEN H 0 ELSE X 0
321
+ 10 SELECT CASE x / CASE 1, 2 / CASE 3 TO 8 / CASE IS > 8 / CASE ELSE / END SELECT
305
322
  10 ON n GOTO 100, 200, 300
306
323
  10 ON n GOSUB 100, 200
307
324
  10 DATA 1, 2, 3, "hello"
@@ -311,6 +328,15 @@ EXIT FOR / EXIT WHILE / EXIT DO
311
328
  END
312
329
  ```
313
330
 
331
+ Loops behave as in QBASIC. A FOR whose range the step cannot reach skips its
332
+ body, and after the loop runs out the counter holds the first value past the
333
+ limit. A loop may sit on one line (`FOR I = 1 TO 3: H I: NEXT I`) or open
334
+ mid-line and close on a later one. GOSUB, ON GOSUB and CALL return to the
335
+ statement after the call, inside the same line or IF clause. A NEXT, WEND or
336
+ LOOP closes any loops a jump left open inside its own. SELECT CASE takes
337
+ value lists, `lo TO hi` ranges, `IS <op> v` comparisons and exact string
338
+ cases; `CASE v: statement` puts the case body on the same line.
339
+
314
340
  ## Subroutines
315
341
 
316
342
  ```
@@ -525,10 +551,33 @@ simulation time based on the actual outcome (no LOCC mode needed).
525
551
  ```
526
552
  10 H 0
527
553
  20 MEAS 0 -> c Mid-circuit measurement into classical bit c
528
- 30 IF c THEN X 0 Feedforward correction (also: IF c == 0, NOT c, with ELSE)
554
+ 30 IF c THEN X 0 Feedforward correction (also: IF c = 0, NOT c, c <> 1, with ELSE)
529
555
  40 MEASURE
530
556
  ```
531
557
 
558
+ A program that uses a measured bit any other way (PRINT c, LET y = c + 1,
559
+ IF a <> b, a GOTO chosen by it, a repeat-until-success loop) runs live: each
560
+ shot executes the program from the top on a numpy statevector, MEAS collapses
561
+ the state and returns its outcome, and every statement sees real bits. The
562
+ summary line reads `method=live`. Only the first shot prints; later shots
563
+ replay its INPUT answers and write no files, so the run reads as one
564
+ execution followed by the histogram over all shots. Afterwards the variables
565
+ hold the first shot's values and `SAVE_EXPECT`/`SAVE_PROBS` the mean over the
566
+ shots. An active noise model runs as quantum trajectories, readout error
567
+ included. `MEASURE_X/Y/Z` and `SYNDROME` bits work the same way.
568
+
569
+ ```
570
+ 10 H 0
571
+ 20 MEAS 0 -> m
572
+ 30 IF m = 1 THEN GOTO 50
573
+ 40 RESET 0: GOTO 10 Repeat until the qubit reads 1
574
+ 50 PRINT "tries done"
575
+ 60 MEASURE
576
+ ```
577
+
578
+ `STEP` runs the same way, as one live shot: MEAS collapses the state you are
579
+ watching.
580
+
532
581
  ## Mixed states
533
582
 
534
583
  ```
@@ -560,12 +609,17 @@ HAMILTONIAN H = ISING 1.0 0.5 Builders: ISING, HEISENBERG, HUBBARD, RY
560
609
  HAMILTONIAN H = MOLECULE H2 0.7414 H2/STO-3G (built-in integrals engine, no pyscf)
561
610
  10 EVOLVE H, 1.5, 20 Trotterized e^{-iHt} (time, steps) in a circuit
562
611
  10 SAVE_EXPECT H -> e <H> of a declared Hamiltonian (VQE cost)
563
- LINDBLAD NONE, 1.0, 200, 1.0 SM 0 Open-system master-equation evolution (dense, <=5 qubits)
612
+ LINDBLAD NONE, 1.0, 200, 1.0 SM 0 Open-system master-equation evolution (exact, <=10 qubits)
564
613
  LINDBLAD H, 1.0, 200, 1.0 SM 0 TRAJ 500 Monte Carlo wavefunction unraveling (<=15 qubits)
565
614
  CHANNEL AD = [[1,0],[0,0.95]] ; [[0,0.31],[0,0]] Define a Kraus channel
566
615
  10 APPLYCHANNEL AD 0 Apply a custom channel
567
616
  ```
568
617
 
618
+ The exact LINDBLAD path integrates the density matrix with RK4, the
619
+ Hamiltonian and the jump operators kept sparse. A channel applied with
620
+ APPLYCHANNEL is sampled as quantum trajectories across shots; a run without
621
+ MEASURE keeps the mixed state for DENSITY.
622
+
569
623
  `MOLECULE H2 [R]` computes the exact 4-qubit Jordan-Wigner Hamiltonian from a
570
624
  self-contained STO-3G integrals engine (Gaussian s-orbital closed forms, RHF
571
625
  by symmetry). Exact diagonalization at R = 0.7414 reproduces the FCI energy
@@ -576,9 +630,9 @@ by symmetry). Exact diagonalization at R = 0.7414 reproduces the FCI energy
576
630
  ```
577
631
  QEC STEANE Show a code (REP [d], STEANE, SHOR, SURFACE [d]) and its stabilizers
578
632
  QEC BB [l m] Bivariate-bicycle qLDPC (6 6 -> [[72,12,6]], 12 6 -> [[144,12,12]])
579
- LOGICAL_ERROR_RATE STEANE 0.02 Monte-Carlo logical error rate (optimal lookup decoder)
580
- LOGICAL_ERROR_RATE SURFACE 0.02 UF Union-find / matching decoder
581
- LOGICAL_ERROR_RATE SURFACE 11 0.05 MWPM Batched pymatching MWPM (large distances)
633
+ LOGICAL_ERROR_RATE STEANE 0.02 Monte-Carlo logical error rate (decoder chosen automatically)
634
+ LOGICAL_ERROR_RATE SURFACE 11 0.05 MATCH Exact minimum-weight matching (blossom; alias UF)
635
+ LOGICAL_ERROR_RATE SURFACE 11 0.05 MWPM Batched pymatching MWPM (needs the [qec] extra)
582
636
  LOGICAL_ERROR_RATE SURFACE 21 0.001 CIRCUIT 1000000 Circuit-level noise (stim + pymatching)
583
637
  LOGICAL_ERROR_RATE BB 0.01 BB codes decode with the internal BP+OSD
584
638
  THRESHOLD REP 0.0 0.5 11 Sweep p across distances 3/5/7 (crossing at 0.5)
@@ -588,10 +642,14 @@ LATTICE 0 1 Lattice-surgery joint Zbar-Zbar measurement of two patc
588
642
 
589
643
  Codes: repetition (any odd distance), Steane [[7,1,3]], Shor [[9,1,3]], rotated
590
644
  surface, and the bivariate-bicycle qLDPC family (parity checks built from the
591
- cyclic-shift polynomials, k verified by GF(2) ranks). Decoders: an optimal
592
- minimum-weight lookup table (all codes), a union-find / matching decoder (`UF`),
593
- batched pymatching MWPM (`MWPM`), and an internal belief-propagation +
594
- ordered-statistics decoder (BP+OSD-0) for the qLDPC codes.
645
+ cyclic-shift polynomials, k verified by GF(2) ranks). Decoders: a
646
+ minimum-weight lookup table, built in order of error weight, while the code's
647
+ syndrome space allows (`LOOKUP`); exact minimum-weight perfect matching on the
648
+ code's matching graph with boundary nodes (rustworkx blossom, `MATCH`) beyond
649
+ it; batched pymatching MWPM (`MWPM`); and an internal belief-propagation +
650
+ ordered-statistics decoder (BP+OSD-0, `BP`) for the qLDPC codes. The default
651
+ picks lookup while feasible and matching after that. The Monte Carlo is
652
+ vectorized over trials and decodes each distinct syndrome once.
595
653
 
596
654
  `CIRCUIT` switches from code capacity to full circuit-level noise: stim
597
655
  generates the noisy syndrome-extraction circuit (d rounds of gates,
@@ -602,19 +660,32 @@ patch (944 physical qubits, 9240 detectors) samples at ~13k shots/s.
602
660
  ### Logical-qubit mode
603
661
 
604
662
  ```
605
- LQUBITS 2 CODE SURFACE 5 PHYS 1e-3 Program on 2 LOGICAL qubits (surface, d=5)
663
+ LQUBITS 2 CODE STEANE PHYS 1e-3 Program on 2 LOGICAL qubits, simulated encoded
664
+ LQUBITS 2 CODE SURFACE 5 PHYS 1e-3 ...or on a modeled surface code, d=5
606
665
  10 H 0 Gates now act on logical qubits
607
- 20 CX 0,1 CX compiles to a lattice-surgery merge+split
666
+ 20 CX 0,1
608
667
  30 MEASURE
609
668
  RUN Histogram of LOGICAL outcomes
610
669
  LQUBITS OFF Back to physical qubits
611
670
  ```
612
671
 
613
- While active, every operation carries the code's per-op logical error channel
614
- (from the code-capacity rate for the chosen code, distance, and physical p),
615
- measurement carries a logical readout flip, and RUN appends the
616
- lattice-surgery report: surgery ops, syndrome rounds, physical-qubit total,
617
- wall time at 1 us/round, and the cumulative logical error budget.
672
+ `CODE STEANE` simulates the encoded program. Each logical qubit is a
673
+ [[7,1,3]] block of 7 physical qubits prepared in |0_L>, and logical Clifford
674
+ gates (H, S, SDG, SX, X, Y, Z, CX, CY, CZ, SWAP) are transversal. Depolarizing
675
+ noise at the physical rate follows every physical gate and the readout. A
676
+ round of syndrome extraction with conditional corrections follows every
677
+ logical gate, and the readout is decoded block by block. The circuit runs on
678
+ the stabilizer simulator (2 logical qubits are 15 physical), and RUN reports
679
+ the decoded histogram with its total variation distance from the ideal
680
+ distribution (`_LOGICAL_TVD`). T gates and rotations have no transversal
681
+ form on this code and are refused.
682
+
683
+ The other codes are modeled. Every operation carries the code's per-op
684
+ logical error channel (from the code-capacity rate for the chosen code,
685
+ distance, and physical p), measurement carries a logical readout flip, and
686
+ RUN appends the lattice-surgery report: surgery ops, syndrome rounds,
687
+ physical-qubit total, wall time at 1 us/round, and the cumulative logical
688
+ error budget.
618
689
 
619
690
  ## Benchmarking and verification
620
691
 
@@ -633,7 +704,8 @@ PAULIPROP ZZ 0 1 Pauli-propagation expectation (Heisenberg, truncated)
633
704
 
634
705
  ```
635
706
  IQPE 4 0 UGATE Iterative phase estimation of a UNITARY eigenphase
636
- AMPEST 5 0 Amplitude estimation of the marked amplitude
707
+ AMPEST 5 0 Amplitude estimation of the program's state (good = qubit 0 reads 1)
708
+ AMPEST 5 |101> ...good = a basis state, in the displayed bit order
637
709
  10 AMPLIFY 101 One amplitude-amplification (Grover) step
638
710
  QWALK 5 Discrete-time quantum walk on a cycle
639
711
  10 GRAPHSTATE 0-1, 1-2 Prepare a graph/cluster state (MBQC resource)
@@ -641,8 +713,18 @@ QWALK 5 Discrete-time quantum walk on a cycle
641
713
  QKERNEL 0.5 0.3 ; 0.4 0.2 Quantum kernel |<phi(x)|phi(y)>|^2
642
714
  SHOR 15 Order finding / factoring of small N
643
715
  HHL 1 0 0 2 1 1 Solve a 2x2 Hermitian system A x = v
716
+ HEATMAP Pairwise quantum mutual information grid (HEATMAP CONCURRENCE: concurrence)
644
717
  ```
645
718
 
719
+ AMPEST is maximum-likelihood amplitude estimation over the program (the
720
+ state preparation A, measure-free and unitary): it runs Q^k A|0> for k = 0, 1,
721
+ 2, 4, ..., counts good outcomes, maximizes the joint likelihood, and reports
722
+ the Fisher-information spread alongside the exact amplitude when the state
723
+ is small enough to compute. HHL runs phase estimation on a signed clock
724
+ register (negative eigenvalues read as two's complement) and a uniformly
725
+ controlled RY, then reports the post-selected solution's fidelity to the
726
+ classical A^-1 v and the post-selection success probability.
727
+
646
728
  ## Beyond qubits
647
729
 
648
730
  ```
@@ -755,10 +837,10 @@ $F000-$FFFF User SYS Routines
755
837
  | +6 | Re(beta) |
756
838
  | +7 | Im(beta) |
757
839
 
758
- ### QPU config ($D000-$D00B)
840
+ ### QPU config ($D000-$D00C)
759
841
  | Address | Name | Values |
760
842
  |---------|------|--------|
761
- | $D000 | num_qubits | 1-32 |
843
+ | $D000 | num_qubits | 1 to the METHOD's ceiling |
762
844
  | $D001 | shots | 1+ |
763
845
  | $D002 | sim_method | 0=auto, 1=statevector, 2=stabilizer, 3=MPS, 4=density |
764
846
  | $D003 | sim_device | 0=CPU, 1=GPU |
@@ -770,6 +852,7 @@ $F000-$FFFF User SYS Routines
770
852
  | $D009 | mps_truncation | float threshold |
771
853
  | $D00A | sv_parallel_threshold | int |
772
854
  | $D00B | es_approx_error | float |
855
+ | $D00C | precision | 0=double, 1=single |
773
856
 
774
857
  ### QPU status ($D010-$D014, read-only)
775
858
  | Address | Name |
@@ -862,7 +945,7 @@ FORWARD 1 Go forward 1 checkpoint
862
945
  HISTORY Show all checkpoints with current position
863
946
  ```
864
947
 
865
- Checkpoints are saved during STEP mode for circuits up to 16 qubits. Each checkpoint stores the full statevector after that gate application.
948
+ Checkpoints are saved during STEP mode. Each stores the full statevector after that line, at most 64 MiB per checkpoint (22 qubits at double precision) and 256 MiB in total, the oldest dropped first.
866
949
 
867
950
  ## Error handling
868
951
 
@@ -899,16 +982,27 @@ Quantum state names (`|+>`, `|0>`, `|1>`, `|->`, `|BELL>`, `|GHZ>`, `|GHZ3>`, `|
899
982
 
900
983
  ## Performance
901
984
 
902
- ### Auto-scaling
903
- QBASIC detects available RAM, estimates per-instance memory, and reports maximum qubit count and parallelism budget at startup and via the `RAM` command.
985
+ ### Memory
986
+ QUBASIC sizes every run against the RAM available at that moment. A
987
+ statevector run that returns counts peaks at about 1.04x the state (16 bytes
988
+ per amplitude at double precision, 8 at single), and a measure-free run that
989
+ keeps its final state costs the same, because Aer hands the buffer over. A
990
+ measured run keeps its final state from inside the same simulation when a
991
+ second copy fits; otherwise STATE, BLOCH and the other inspection commands
992
+ compute it on first use. The numpy engine (LOCC, live runs, STEP) updates
993
+ states in place, block by block, so its peak is the state plus one 64 MiB
994
+ block. A run that cannot fit is refused with the memory it needs and what to
995
+ change (`PRECISION SINGLE`, `METHOD matrix_product_state`). The banner,
996
+ `QUBITS`, `STATUS` and `RAM` report the widest statevector run at each
997
+ precision for the memory available now.
904
998
 
905
999
  ### Simulation method selection
906
- - **automatic**: stabilizer for Clifford-only circuits, MPS for >28 qubits, statevector otherwise
1000
+ - **automatic**: stabilizer for noiseless Clifford circuits; statevector while it fits (double, then single precision); MPS beyond
907
1001
  - **stabilizer**: polynomial-time for Clifford circuits (H, S, CX, SWAP, etc.)
908
- - **matrix_product_state**: memory-efficient for low-entanglement circuits; handles the full 32-qubit range that would exhaust statevector
1002
+ - **matrix_product_state**: memory-efficient for low-entanglement circuits; memory set by entanglement, not width
909
1003
  - **extended_stabilizer**: approximate simulation for near-Clifford circuits
910
- - **statevector**: exact, limited by RAM (~28 qubits on 16GB)
911
- - **density_matrix**: includes mixed states, ~14 qubits on 16GB
1004
+ - **statevector**: exact; width limited by available memory (see RAM)
1005
+ - **density_matrix**: includes mixed states; 4^n entries, about half the statevector width
912
1006
  - **unitary**: returns the full unitary matrix of the circuit
913
1007
  - **superop**: returns the superoperator (quantum channel)
914
1008
 
@@ -922,10 +1016,10 @@ POKE $D00B, 0.01 Extended stabilizer approximation error
922
1016
  ```
923
1017
 
924
1018
  ### Circuit caching
925
- Transpiled circuits are cached between RUN calls when the program and configuration have not changed. Cache invalidates on any program edit, qubit count change, method change, or tuning parameter change.
1019
+ Transpiled circuits are cached between RUN calls, keyed on a digest of the built circuit itself (every instruction, parameter, register and condition) together with the method, precision, device, noise and tuning settings, so any change that alters the circuit, including DEF, UNITARY, SET_STATE or variable values, rebuilds it.
926
1020
 
927
1021
  ### LOCC optimization
928
- Programs with SEND use prefix/suffix splitting: the deterministic prefix (before first SEND) executes once, the statevector is snapshotted, and only the suffix (from SEND onward) re-executes per shot. Falls back to full re-execution if the prefix contains GOTO/GOSUB.
1022
+ Programs with SEND use prefix/suffix splitting: the deterministic prefix (before first SEND) executes once, the statevector is snapshotted, and only the suffix (from SEND onward) re-executes per shot. It falls back to full re-execution when the prefix contains a jump or loop, or when noise is active (each shot draws its own noise). Only the first shot prints. Live runs reuse a deterministic prefix the same way.
929
1023
 
930
1024
  ## JSON output
931
1025
 
@@ -950,6 +1044,10 @@ qubasic_core/
950
1044
  engine_state.py Engine: standalone state container
951
1045
  terminal.py QBasicTerminal: REPL + command dispatch
952
1046
  engine.py Constants, gate tables, numpy simulation, LOCCEngine
1047
+ gates.py Gate matrices and the in-place, block-wise numpy engine
1048
+ capacity.py Memory model: peak bytes per method/precision, what fits
1049
+ statetools.py Reduced density matrices, entropies, entanglement measures
1050
+ live.py Shot-by-shot execution for programs that read measurements
953
1051
  parser.py 60+ typed Stmt objects from raw strings
954
1052
  statements.py Stmt type definitions
955
1053
  exec_context.py ExecContext: unified execution state
@@ -963,7 +1061,7 @@ qubasic_core/
963
1061
  locc.py LOCC commands, execution, display
964
1062
  analysis.py EXPECT, ENTROPY, DENSITY, BENCH, RAM
965
1063
  qec2.py Circuit-level QEC (stim/pymatching), BB qLDPC, BP+OSD
966
- logical.py LQUBITS logical-qubit mode + lattice-surgery report
1064
+ logical.py LQUBITS: encoded Steane simulation, modeled codes, surgery report
967
1065
  qchem.py STO-3G molecular Hamiltonians (MOLECULE H2)
968
1066
  jupyter_kernel.py Jupyter kernel (qubasic --install-kernel)
969
1067
  web_repl.py Browser REPL (qubasic --web)
@@ -980,11 +1078,11 @@ qubasic_core/
980
1078
  demos.py Built-in demo circuits
981
1079
  protocol.py TerminalProtocol (mixin contract)
982
1080
  mock_backend.py MockAerSimulator for fast testing
983
- tests/ Test suites (test_qubasic.py, test_features.py)
1081
+ tests/ Test suites (unit, feature, golden-script, numpy engine, BASIC semantics and live runs)
984
1082
  examples/ Sample .qb programs
985
1083
  ```
986
1084
 
987
- `Engine` holds all program state. `QBasicTerminal` inherits `Engine` + 20 mixins. Execution methods live on `QBasicTerminal`, so headless/agent use should instantiate `QBasicTerminal` (the `Engine` base is a state container only).
1085
+ `Engine` holds all program state. `QBasicTerminal` inherits `Engine` + 32 mixins. Execution methods live on `QBasicTerminal`, so headless/agent use should instantiate `QBasicTerminal` (the `Engine` base is a state container only).
988
1086
 
989
1087
  ## License
990
1088