quantum-forge 2.7.0 → 3.0.0
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.
- package/QUANTUM_FORGE.md +213 -205
- package/README.md +74 -38
- package/dist/lib/quantum.d.ts +683 -64
- package/dist/lib/quantum.js +1073 -8
- package/dist/lib/quantum.js.map +1 -1
- package/dist/lib/vite-plugin.d.ts +1 -1
- package/dist/lib/vite-plugin.js.map +1 -1
- package/dist/quantum-forge-qubit/quantum-forge-web-esm.wasm +0 -0
- package/dist/quantum-forge-web-esm.wasm +0 -0
- package/package.json +6 -5
- package/quantum-forge-sw.js +3 -3
- package/scripts/prepare.mjs +16 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Real quantum mechanics for game developers. Superposition, entanglement, and interference powered by a compiled C++ quantum simulator running via WebAssembly.
|
|
4
4
|
|
|
5
|
-
This is the core package
|
|
5
|
+
This is the core package: WASM loader, quantum property handles, and Vite plugin. For the full game framework (engine, rendering, input, audio, and more), install [`quantum-forge-engine`](https://www.npmjs.com/package/quantum-forge-engine) instead. It depends on this package, so one install gets both.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -26,51 +26,60 @@ export default defineConfig({
|
|
|
26
26
|
|
|
27
27
|
> **ESM note:** If using `vite.config.js` (not `.ts` or `.mjs`), add `"type": "module"` to your `package.json`.
|
|
28
28
|
|
|
29
|
-
### 2.
|
|
29
|
+
### 2. Declare a quantum property
|
|
30
30
|
|
|
31
31
|
```typescript
|
|
32
|
-
import { ensureLoaded,
|
|
32
|
+
import { ensureLoaded, quantum } from "quantum-forge/quantum";
|
|
33
33
|
|
|
34
|
-
//
|
|
35
|
-
await ensureLoaded();
|
|
36
|
-
|
|
37
|
-
// Create a property manager
|
|
38
|
-
const qpm = new QuantumPropertyManager({ dimension: 2 });
|
|
34
|
+
await ensureLoaded(); // once, before the first quantum() call
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
qpm.hadamard(qubit);
|
|
36
|
+
const color = quantum(["red", "green", "blue"]); // a qutrit, starts "red"
|
|
37
|
+
color.superpose(); // equal superposition (alias for hadamard())
|
|
43
38
|
|
|
44
|
-
// Read
|
|
45
|
-
|
|
39
|
+
// Read without collapsing
|
|
40
|
+
color.probability("green"); // 1/3
|
|
41
|
+
color.probabilities();
|
|
42
|
+
// [{ value: "red", probability: 1/3 }, { value: "green", ... }, { value: "blue", ... }]
|
|
46
43
|
|
|
47
|
-
// Measure (collapses to
|
|
48
|
-
const
|
|
44
|
+
// Measure (collapses to one value)
|
|
45
|
+
const seen = color.measure(); // "red", "green" or "blue"
|
|
49
46
|
|
|
50
|
-
//
|
|
51
|
-
|
|
47
|
+
// End its life. dispose() measures, then frees the qudit for the next quantum() call.
|
|
48
|
+
color.dispose();
|
|
52
49
|
```
|
|
53
50
|
|
|
51
|
+
A property is declared by the values it can take, and the dimension is how many there are.
|
|
52
|
+
`quantum(3)` is the numeric form, with values `0`, `1`, `2`. A property needs at least two
|
|
53
|
+
values. A `using` declaration disposes the handle at the end of the scope; it needs TypeScript
|
|
54
|
+
5.2 or newer with `"ESNext.Disposable"` in the tsconfig `lib`. Code that never writes `using`
|
|
55
|
+
needs neither.
|
|
56
|
+
|
|
54
57
|
### 3. Entanglement
|
|
55
58
|
|
|
59
|
+
Entanglement is what an interaction leaves behind. A gate that touches two properties is an
|
|
60
|
+
interaction:
|
|
61
|
+
|
|
56
62
|
```typescript
|
|
57
|
-
|
|
58
|
-
const b = qpm.acquireProperty();
|
|
63
|
+
import { quantum, measure } from "quantum-forge/quantum";
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
|
|
65
|
+
const a = quantum([false, true]).flip(); // a = true
|
|
66
|
+
const b = quantum([false, true]); // b = false
|
|
67
|
+
a.iSwap(b, 0.5); // half iSwap: exactly one of the pair ends up true
|
|
62
68
|
|
|
63
|
-
const [va, vb] =
|
|
64
|
-
// va
|
|
69
|
+
const [va, vb] = measure(a, b); // one step, both collapse
|
|
70
|
+
// va !== vb, every time
|
|
65
71
|
```
|
|
66
72
|
|
|
73
|
+
So is a gate whose predicate reads another property. `b.flip({ when: [a.is(true)] })` is a
|
|
74
|
+
CNOT: `b` flips only where `a` is `true`. `a.is(1)` builds the same predicate by index.
|
|
75
|
+
|
|
67
76
|
## Editions
|
|
68
77
|
|
|
69
78
|
Two WASM builds are included:
|
|
70
79
|
|
|
71
80
|
| Edition | Dimensions | Max Qudits | Use Case |
|
|
72
81
|
|---------|-----------|------------|----------|
|
|
73
|
-
| **Qutrit** (default) | 2
|
|
82
|
+
| **Qutrit** (default) | 2 to 3 | 12 | Games using qutrits (3-state quantum digits) |
|
|
74
83
|
| **Qubit** | 2 | 20 | Games needing more qubits at dimension 2 |
|
|
75
84
|
|
|
76
85
|
To use the Qubit Edition:
|
|
@@ -78,31 +87,58 @@ To use the Qubit Edition:
|
|
|
78
87
|
```typescript
|
|
79
88
|
import { useQuantumForgeBuild, ensureLoaded } from "quantum-forge/quantum";
|
|
80
89
|
|
|
81
|
-
useQuantumForgeBuild("qubit"); //
|
|
90
|
+
useQuantumForgeBuild("qubit"); // before ensureLoaded()
|
|
91
|
+
await ensureLoaded();
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Node and headless use
|
|
95
|
+
|
|
96
|
+
The same code runs in Node (tests, servers, agents) with no Vite plugin. The loader finds the WASM inside the installed package, and `useQuantumForgeBuild("qubit")` picks the variant the same way. Point the loader elsewhere only when the WASM files live outside the package:
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { setWasmBasePath, ensureLoaded } from "quantum-forge/quantum";
|
|
100
|
+
import { pathToFileURL } from "node:url";
|
|
101
|
+
|
|
102
|
+
setWasmBasePath(pathToFileURL("/opt/wasm/quantum-forge-qubit").href);
|
|
82
103
|
await ensureLoaded();
|
|
83
104
|
```
|
|
84
105
|
|
|
106
|
+
Node 22 or newer.
|
|
107
|
+
|
|
85
108
|
## Package Exports
|
|
86
109
|
|
|
87
110
|
| Export | Contents |
|
|
88
111
|
|--------|----------|
|
|
89
|
-
| `quantum-forge/quantum` | `
|
|
112
|
+
| `quantum-forge/quantum` | `quantum`, `Quantum`, `measure`, `forcedMeasure`, `probabilities`, `densityMatrix`, `measureWhen`, `forcedMeasureWhen`, `probabilityWhen`, `phaseRotate`, `isQuantum`, `observeQuantum`, `clearQuantumCache`, `QuantumRecorder`, `ensureLoaded`, `startBackgroundLoad`, `isReady`, `useQuantumForgeBuild`, `setWasmBasePath`, `getVersion`, `getMaxDimension`, `getMaxQudits`, `getMaxStateSize`, `getAttribution`, `registerServiceWorker`, `OP` |
|
|
90
113
|
| `quantum-forge/logging` | `Logger` |
|
|
91
114
|
| `quantum-forge/vite-plugin` | `quantumForgeVitePlugin` |
|
|
92
115
|
|
|
93
116
|
## Gates
|
|
94
117
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
|
99
|
-
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
|
|
105
|
-
|
|
118
|
+
Gates are methods on the handle. Each alias runs exactly the same gate as the physics name
|
|
119
|
+
beside it.
|
|
120
|
+
|
|
121
|
+
| Gate | Alias | Qudits | Description |
|
|
122
|
+
|------|-------|--------|-------------|
|
|
123
|
+
| `hadamard` | `superpose` | 1 | Equal superposition |
|
|
124
|
+
| `inverseHadamard` | | 1 | Undoes `hadamard` |
|
|
125
|
+
| `cycle` | `next`, and `flip` on qubits | 1 | \|0⟩→\|1⟩→\|2⟩→\|0⟩ (a NOT at dimension 2) |
|
|
126
|
+
| `shift` | `previous` | 1 | Inverse of cycle; same as cycle at dimension 2 |
|
|
127
|
+
| `clock` | `phase` | 1 | Phase rotation |
|
|
128
|
+
| `x`, `z` | | 1 | Pauli X (same as `shift`) and Pauli Z (same as `clock`) |
|
|
129
|
+
| `y` | | 1 | Pauli Y, dimension 2 only |
|
|
130
|
+
| `iSwap(other, fraction)` | | 2 | Entangling swap; `fraction` is required |
|
|
131
|
+
| `swap(other)` | | 2 | Value swap |
|
|
132
|
+
| `phaseRotate(angle, { when })` | | any | Free function: phase on the part of the state where the predicates hold |
|
|
133
|
+
|
|
134
|
+
Every gate except `inverseHadamard`, `swap` and `iSwap` takes an optional fraction first. An
|
|
135
|
+
omitted fraction, or exactly 1, is the discrete gate; any other number is the continuous
|
|
136
|
+
version, and 0.5 is the square root of the gate. Predicates go last, in `{ when: [...] }`.
|
|
137
|
+
|
|
138
|
+
Measurement: `prop.measure()`, `measure(...props)`, `measureWhen(preds)`, and the forced
|
|
139
|
+
variants for replays and tests, which throw if the forced value has zero probability.
|
|
140
|
+
Read-only: `prop.probability(value)`, `prop.probabilities()`,
|
|
141
|
+
`probabilities(...props)`, `probabilityWhen(preds)`, `densityMatrix(...props)`.
|
|
106
142
|
|
|
107
143
|
## Documentation
|
|
108
144
|
|
|
@@ -112,4 +148,4 @@ All gates support fractional application and conditional predicates.
|
|
|
112
148
|
|
|
113
149
|
## License
|
|
114
150
|
|
|
115
|
-
TypeScript source: MIT (see [LICENSE.md](./LICENSE.md)). WASM binaries: proprietary
|
|
151
|
+
TypeScript source: MIT (see [LICENSE.md](./LICENSE.md)). WASM binaries: proprietary, free for apps under $100K annual revenue with attribution. See [dist/LICENSE-BINARY.md](./dist/LICENSE-BINARY.md) for binary terms.
|