@quantumplayed/quantum-game-engine 1.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.
Files changed (55) hide show
  1. package/README.md +314 -0
  2. package/dist/CircuitLog.d.ts +54 -0
  3. package/dist/CircuitLog.js +80 -0
  4. package/dist/CircuitLog.js.map +1 -0
  5. package/dist/Complex.d.ts +13 -0
  6. package/dist/Complex.js +49 -0
  7. package/dist/Complex.js.map +1 -0
  8. package/dist/EntanglementEngine.d.ts +48 -0
  9. package/dist/EntanglementEngine.js +456 -0
  10. package/dist/EntanglementEngine.js.map +1 -0
  11. package/dist/Operations.d.ts +18 -0
  12. package/dist/Operations.js +107 -0
  13. package/dist/Operations.js.map +1 -0
  14. package/dist/QuantumEntity.d.ts +26 -0
  15. package/dist/QuantumEntity.js +142 -0
  16. package/dist/QuantumEntity.js.map +1 -0
  17. package/dist/index.d.ts +5 -0
  18. package/dist/index.js +6 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/src/CircuitLog.d.ts +54 -0
  21. package/dist/src/CircuitLog.js +80 -0
  22. package/dist/src/CircuitLog.js.map +1 -0
  23. package/dist/src/Complex.d.ts +13 -0
  24. package/dist/src/Complex.d.ts.map +1 -0
  25. package/dist/src/Complex.js +49 -0
  26. package/dist/src/Complex.js.map +1 -0
  27. package/dist/src/EntanglementEngine.d.ts +48 -0
  28. package/dist/src/EntanglementEngine.d.ts.map +1 -0
  29. package/dist/src/EntanglementEngine.js +456 -0
  30. package/dist/src/EntanglementEngine.js.map +1 -0
  31. package/dist/src/Operations.d.ts +18 -0
  32. package/dist/src/Operations.d.ts.map +1 -0
  33. package/dist/src/Operations.js +107 -0
  34. package/dist/src/Operations.js.map +1 -0
  35. package/dist/src/QuantumEntity.d.ts +26 -0
  36. package/dist/src/QuantumEntity.d.ts.map +1 -0
  37. package/dist/src/QuantumEntity.js +142 -0
  38. package/dist/src/QuantumEntity.js.map +1 -0
  39. package/dist/src/index.d.ts +5 -0
  40. package/dist/src/index.d.ts.map +1 -0
  41. package/dist/src/index.js +6 -0
  42. package/dist/src/index.js.map +1 -0
  43. package/dist/tests/DensityMatrix.test.d.ts +1 -0
  44. package/dist/tests/DensityMatrix.test.d.ts.map +1 -0
  45. package/dist/tests/DensityMatrix.test.js +41 -0
  46. package/dist/tests/DensityMatrix.test.js.map +1 -0
  47. package/dist/tests/EntanglementEngine.test.d.ts +1 -0
  48. package/dist/tests/EntanglementEngine.test.d.ts.map +1 -0
  49. package/dist/tests/EntanglementEngine.test.js +72 -0
  50. package/dist/tests/EntanglementEngine.test.js.map +1 -0
  51. package/dist/tests/QuantumEntity.test.d.ts +1 -0
  52. package/dist/tests/QuantumEntity.test.d.ts.map +1 -0
  53. package/dist/tests/QuantumEntity.test.js +60 -0
  54. package/dist/tests/QuantumEntity.test.js.map +1 -0
  55. package/package.json +19 -0
package/README.md ADDED
@@ -0,0 +1,314 @@
1
+ # Quantum Game Engine
2
+
3
+ A generalized, sparse-matrix quantum simulation library designed specifically for game developers.
4
+
5
+ Unlike traditional quantum SDKs (like Qiskit or Cirq) that focus on low-level circuit design and dense matrices, this engine abstracts Away the complex math. It uses "Second Quantization" and sparse amplitude dictionaries to allow you to easily attach quantum mechanics (superposition, entanglement, interference) directly to high-dimensional objects in your game (like an $(x,y)$ coordinate grid, a character's inventory, or a branching dialogue tree).
6
+
7
+ ## Core Concepts
8
+
9
+ * **`QuantumEntity`**: Represents any quantum object in your game (a player, a coin, a chess piece). It manages its own state, but if it becomes entangled, it defers mathematically to a joint system behind the scenes.
10
+ * **`Operations`**: A suite of generalized quantum gates (Shift, Phase, Hadamard) that work on *qudits* of any dimension, not just qubits.
11
+ * **`EntanglementEngine`**: A powerful manager that tracks interactions between different `QuantumEntity` objects. When entities interact conditionally (e.g., "IF player is on square 5, open the door"), their states become mathematically linked.
12
+
13
+ ---
14
+
15
+ ## 1. Creating and Modifying Entities
16
+
17
+ A `QuantumEntity` requires a `dimension` (how many possible classical states it can have) and an initial state index.
18
+
19
+ ```typescript
20
+ import { QuantumEntity, Operations } from 'quantum-game-engine';
21
+
22
+ // A coin has dimension 2 (Heads=0, Tails=1)
23
+ const coin = new QuantumEntity({ dimension: 2, initialState: 0 });
24
+
25
+ // A character moving on a 10x10 grid has dimension 100
26
+ const player = new QuantumEntity({ dimension: 100, initialState: 45 });
27
+ ```
28
+
29
+ ### Applying Operations
30
+
31
+ You can mutate the state of an entity using `apply()`.
32
+
33
+ **1. Shift (Generalized Pauli-X / Clock)**
34
+ Shifts the classical state by a certain amount modulo the dimension.
35
+ ```typescript
36
+ player.apply(Operations.Shift(1)); // Moves player from 45 to 46
37
+ ```
38
+
39
+ **2. Phase (Generalized Pauli-Z)**
40
+ Applies a phase rotation to the state. Crucial for interference effects.
41
+ ```typescript
42
+ coin.apply(Operations.Phase(Math.PI));
43
+ ```
44
+
45
+ **3. Hadamard (Quantum Fourier Transform)**
46
+ Puts the entity into a uniform superposition of all its possible states.
47
+ ```typescript
48
+ coin.apply(Operations.Hadamard());
49
+ // Coin is now 50% Heads, 50% Tails
50
+ ```
51
+
52
+ **4. SparseTransition**
53
+ For complex game logic (like a "Quantum Split" move in Checkers), you can define a custom transition matrix. You only need to provide the non-zero mappings.
54
+ ```typescript
55
+ const splitMove = Operations.SparseTransition(dimension, {
56
+ 45: [
57
+ { state: 54, amplitude: { re: 0.707, im: 0 } }, // 50% chance to move left
58
+ { state: 56, amplitude: { re: 0.707, im: 0 } } // 50% chance to move right
59
+ ]
60
+ });
61
+ player.apply(splitMove);
62
+ ```
63
+
64
+ ---
65
+
66
+ ## 2. Entanglement and Interactions
67
+
68
+ The true power of the engine is the `EntanglementEngine`. In games, things interact. If a quantum player steps on a quantum button, they become entangled. Measuring one affects the other.
69
+
70
+ Use `conditionalInteract` to apply operations to a `target` *only if* the `control` entity is in a specific state.
71
+
72
+ ```typescript
73
+ import { EntanglementEngine } from 'quantum-game-engine';
74
+
75
+ const player = new QuantumEntity({ dimension: 10, initialState: 5 });
76
+ const door = new QuantumEntity({ dimension: 2, initialState: 0 }); // 0=Closed, 1=Open
77
+
78
+ // Player steps left and right at the same time
79
+ player.apply(Operations.Hadamard());
80
+
81
+ // If the player is on square 6, they open the door.
82
+ EntanglementEngine.conditionalInteract({
83
+ controlEntities: [{ entity: player, state: 6 }],
84
+ targets: [{ entity: door, operation: Operations.Shift(1) }]
85
+ });
86
+
87
+ // The Player and the Door are now ENTANGLED.
88
+ // - In a universe where player is at 6, the door is Open (1).
89
+ // - In a universe where player is at 5, the door is Closed (0).
90
+ ```
91
+
92
+ ---
93
+
94
+ ## 3. Observation and Rendering
95
+
96
+ ### Extracting Probabilities (For UI)
97
+
98
+ To render the game to the screen, you need to know the likelihood of an entity being in a certain state. Use `getProbabilities()` to get a classical probability distribution (0.0 to 1.0).
99
+
100
+ ```typescript
101
+ const probs = player.getProbabilities();
102
+ // Returns: { '5': 0.5, '6': 0.5 }
103
+
104
+ // If entangled, getProbabilities() automatically calculates the
105
+ // marginal probabilities of just this entity from the joint system!
106
+ ```
107
+
108
+ **Advanced Physics: Reduced Density Matrices**
109
+ If your game logic requires knowing whether an entity has "decohered" due to entanglement (losing its quantum interference capability), you can calculate its One-Body Reduced Density Matrix:
110
+ ```typescript
111
+ const rho = player.getReducedDensityMatrix();
112
+ // Returns a 2D map of Complex numbers.
113
+ // rho[x][x] = Probability of state x
114
+ // rho[x][y] = Coherence between state x and y
115
+ ```
116
+
117
+ ### Measuring (Collapsing the Wavefunction)
118
+
119
+ When gameplay requires an entity to commit to a single reality (e.g., an enemy attacks the player, forcing them to be in one specific location), use `measure()`.
120
+
121
+ ```typescript
122
+ const finalPosition = player.measure();
123
+ // Returns exactly 5 or exactly 6.
124
+ ```
125
+
126
+ **The Magic of Entanglement:**
127
+ If `player` and `door` are entangled (as in the example above), measuring the `player` will **instantly collapse the `door` as well**.
128
+ If `player.measure()` returns `6`, any subsequent call to `door.measure()` is mathematically guaranteed to return `1` (Open).
129
+
130
+ ### Forced Measurements (Deterministic Replay)
131
+
132
+ Pass an optional `forcedOutcome` to `measure()` to force a specific collapse state. This bypasses `Math.random()` entirely.
133
+
134
+ ```typescript
135
+ const outcome = player.measure(0); // Always collapses to state 0
136
+ ```
137
+
138
+ This works with entangled systems too — the forced outcome propagates through the joint system, collapsing entangled partners accordingly. Use this for:
139
+ - **Game history replay** — reproduce recorded measurement outcomes exactly
140
+ - **Undo/redo** — re-apply the same measurement results
141
+ - **Testing** — verify specific branches without randomness
142
+
143
+ ---
144
+
145
+ ## 4. Circuit Logging
146
+
147
+ The engine includes a toggleable `CircuitLogger` that records every state-mutating operation as an append-only log. Recording is **off by default** — zero overhead during normal gameplay.
148
+
149
+ ```typescript
150
+ import { CircuitLogger } from 'quantum-game-engine';
151
+
152
+ CircuitLogger.startRecording();
153
+
154
+ // ... game operations (apply, interactMany, conditionalInteract, measure) ...
155
+
156
+ const log = CircuitLogger.stopRecording(); // CircuitEntry[]
157
+ ```
158
+
159
+ Each entry is either a `GateEntry` (for `apply`, `interactMany`, `conditionalInteract`) or a `MeasurementEntry` (for `measure`), tagged with entity IDs, dimensions, and an auto-incrementing timestamp.
160
+
161
+ | Method | Description |
162
+ |---|---|
163
+ | `startRecording()` | Begin recording (resets log) |
164
+ | `stopRecording()` | Stop and return `CircuitEntry[]` |
165
+ | `isRecording()` | Fast guard for hot path |
166
+ | `getLog()` | Get log copy while recording |
167
+ | `getLogForEntities(ids)` | Filter by entity IDs |
168
+ | `reset()` | Clear log and counter |
169
+
170
+ Every `QuantumEntity` has a unique readonly `id: number` (auto-incrementing), used to identify entities in log entries.
171
+
172
+ ## Engine Boundaries and Limitations
173
+
174
+ * **Joint Dimension Limit:** When entities entangle, their state spaces multiply (a dimension-10 player interacting with a dimension-10 enemy creates a dimension-100 joint system). The `EntanglementEngine` currently enforces a hard limit of `4096` total joint dimensions to prevent out-of-memory crashes on the browser's main thread. Design your game's entanglement mechanics to collapse frequently!
175
+
176
+
177
+ ---
178
+
179
+ ## 5. Full API Usage Examples
180
+
181
+ ### Example 1: A Quantum Platformer (Schrödinger's Jump)
182
+
183
+ **The Scenario:** You have a platformer game. The player (`playerX`) reaches a gap. They can press a "Quantum Jump" button to simultaneously jump *and* not jump, putting their position in a superposition. Later, they encounter a "Quantum Door" that only opens if the player is standing on a specific button.
184
+
185
+ ```javascript
186
+ import { QuantumEntity, Operations, EntanglementEngine } from 'quantum-game-engine';
187
+
188
+ // 1. Initialize the player's X position as a qudit (e.g., 100 possible tiles)
189
+ // We start purely classical: 100% chance of being at tile 5.
190
+ const playerX = new QuantumEntity({ dimension: 100, initialState: 5 });
191
+
192
+ // --- THE QUANTUM JUMP ---
193
+ // The player hits the "Quantum Jump" button!
194
+ // We want an equal 50/50 superposition of staying at 5 or jumping to 10.
195
+ // We apply a custom sparse unitary operation (a basic split/Hadamard variant).
196
+ const jumpOp = Operations.SparseTransition(100, {
197
+ 5: [
198
+ { state: 5, amplitude: { re: 0.707, im: 0 } }, // Branch A: didn't jump
199
+ { state: 10, amplitude: { re: 0.707, im: 0 } } // Branch B: did jump
200
+ ]
201
+ });
202
+
203
+ playerX.apply(jumpOp);
204
+
205
+ // playerX.amplitudes is now roughly:
206
+ // { 5: {re: 0.707, im: 0}, 10: {re: 0.707, im: 0} }
207
+
208
+
209
+ // --- ENTANGLEMENT ---
210
+ // A Quantum Door (qudit: 0=Closed, 1=Open)
211
+ const door = new QuantumEntity({ dimension: 2, initialState: 0 });
212
+
213
+ // If the player landed on the button at tile 10, the door opens.
214
+ EntanglementEngine.conditionalInteract({
215
+ controlEntities: [{ entity: playerX, state: 10 }],
216
+ targets: [{ entity: door, operation: Operations.Shift(1) }]
217
+ });
218
+
219
+ // Since playerX was in superposition, the Door is now entangled!
220
+ // The joint amplitudes (PlayerX ⊗ Door):
221
+ // {
222
+ // "5,0": {re: 0.707, im: 0}, // Player at 5, Door is Closed
223
+ // "10,1": {re: 0.707, im: 0} // Player at 10, Door is Open
224
+ // }
225
+
226
+
227
+ // --- MEASUREMENT / COLLAPSE ---
228
+ // The player walks into a "Camera / Observation Zone"
229
+ // We force a collapse of the player's position.
230
+ const result = playerX.measure();
231
+
232
+ // Let's say the engine rolled the 50% chance and returned '10'.
233
+ // Because of the Entanglement Engine, the Door's state automatically
234
+ // collapses to '1' (Open)! The universe branch where the player didn't
235
+ // jump is pruned (amplitudes deleted).
236
+ ```
237
+
238
+ ---
239
+
240
+ ### Example 2: Quantum Checkers (Squares as Qubits)
241
+
242
+ **The Scenario:** A player wants to move a piece from square 12. Instead of a normal move, they do a `SplitMove` to squares 16 and 17. Later, an opponent tries to take the piece on square 16.
243
+
244
+ *Note: In Cheqqers, instead of tracking a "Piece" as a 32-dimension entity (First Quantization), it is much more natural to track each "Square" as a 2-dimension Qubit (Second Quantization), where `0 = Empty` and `1 = Occupied`.*
245
+
246
+ ```javascript
247
+ import { QuantumEntity, Operations, EntanglementEngine } from 'quantum-game-engine';
248
+
249
+ // We represent squares as individual Qubits.
250
+ // Initial state: Square 12 is Occupied (1), Squares 16 and 17 are Empty (0).
251
+ const sq12 = new QuantumEntity({ dimension: 2, initialState: 1 });
252
+ const sq16 = new QuantumEntity({ dimension: 2, initialState: 0 });
253
+ const sq17 = new QuantumEntity({ dimension: 2, initialState: 0 });
254
+
255
+ // --- THE SPLIT MOVE ---
256
+ // The "Quantum Chess Split" matrix is an 8x8 matrix that acts on 3 qubits
257
+ // (From, To1, To2). Our engine provides a helper to apply this sparse sub-matrix.
258
+ // Because it involves 3 entities, the EntanglementEngine automatically merges them
259
+ // into an 8-dimension joint Hilbert space (2x2x2).
260
+ EntanglementEngine.interactMany([sq12, sq16, sq17], Operations.SparseTransition(8, {
261
+ // Binary 100 (state 4) -> 010 (state 2) + 001 (state 1)
262
+ 4: [
263
+ { state: 2, amplitude: { re: 0.707, im: 0 } },
264
+ { state: 1, amplitude: { re: 0.707, im: 0 } }
265
+ ]
266
+ }));
267
+
268
+ // After the split:
269
+ // sq12 is now definitely Empty (|0>).
270
+ // The system of (sq16 ⊗ sq17) is in a superposition:
271
+ // 50% chance of |1, 0> (Piece is on 16)
272
+ // 50% chance of |0, 1> (Piece is on 17)
273
+
274
+
275
+ // --- THE PASSAGE OF TIME (PHASE) ---
276
+ // In Cheqqers, time/turns applies a phase shift to superpositions.
277
+ EntanglementEngine.conditionalInteract({
278
+ controlEntities: [{ entity: sq16, state: 1 }],
279
+ targets: [{ entity: sq16, operation: Operations.Phase(Math.PI / 4) }]
280
+ });
281
+ EntanglementEngine.conditionalInteract({
282
+ controlEntities: [{ entity: sq17, state: 1 }],
283
+ targets: [{ entity: sq17, operation: Operations.Phase(Math.PI / 4) }]
284
+ });
285
+
286
+
287
+ // --- CONDITIONAL CAPTURE (ENTANGLEMENT) ---
288
+ // Opponent moves a black piece from square 20 to square 12, capturing 16.
289
+ const sq20 = new QuantumEntity({ dimension: 2, initialState: 1 }); // Black piece
290
+
291
+ // The capture logic:
292
+ // IF Black is on 20 (it is) AND White is on 16 (it's in superposition):
293
+ // 1. Black moves to 12 (sq20 -> 0, sq12 -> 1)
294
+ // 2. White is captured (sq16 -> 0)
295
+ // This translates to a Toffoli (CCX) and CNOT (CX) sequence in quantum circuits.
296
+
297
+ EntanglementEngine.conditionalInteract({
298
+ controlEntities: [{ entity: sq20, state: 1 }, { entity: sq16, state: 1 }],
299
+ targets: [
300
+ { entity: sq20, operation: Operations.Shift(1) }, // 1 -> 0 (wrapping)
301
+ { entity: sq12, operation: Operations.Shift(1) }, // 0 -> 1
302
+ { entity: sq16, operation: Operations.Shift(1) } // 1 -> 0 (captured)
303
+ ]
304
+ });
305
+
306
+ // The Joint Hilbert space now tracks the entangled state of shapes.
307
+ // Branch A: (White was on 17).
308
+ // sq16 resolves to 0. The capture condition fails! Black stays on 20.
309
+ // Branch B: (White was on 16).
310
+ // sq16 resolves to 1. Capture fires! Black moves to 12, sq16 flips to 0.
311
+
312
+ // Because everything is sparse, branches where mathematically invalid things happen
313
+ // (like trying to capture an empty square) don't consume memory.
314
+ ```
@@ -0,0 +1,54 @@
1
+ /**
2
+ * CircuitLog — toggleable, append-only log of quantum operations.
3
+ *
4
+ * When recording is active, every state-mutating call (gate or measurement)
5
+ * appends an entry. The log is designed for future incremental OpenQASM export:
6
+ * each new entry maps to one circuit instruction, so the export never rebuilds.
7
+ */
8
+ export interface GateEntry {
9
+ type: 'gate';
10
+ name: string;
11
+ entityIds: number[];
12
+ dimensions: number[];
13
+ controls?: {
14
+ entityId: number;
15
+ state: number;
16
+ }[];
17
+ params?: Record<string, any>;
18
+ timestamp: number;
19
+ }
20
+ export interface MeasurementEntry {
21
+ type: 'measurement';
22
+ entityId: number;
23
+ dimension: number;
24
+ outcome: number;
25
+ timestamp: number;
26
+ }
27
+ export type CircuitEntry = GateEntry | MeasurementEntry;
28
+ declare class CircuitLoggerImpl {
29
+ private _recording;
30
+ private _log;
31
+ private _counter;
32
+ /** Begin recording. Resets the existing log. */
33
+ startRecording(): void;
34
+ /** Stop recording and return the captured log. */
35
+ stopRecording(): CircuitEntry[];
36
+ /** Fast guard — check before constructing entry objects on the hot path. */
37
+ isRecording(): boolean;
38
+ /** Append an entry (auto-assigns timestamp). */
39
+ addGate(name: string, entityIds: number[], dimensions: number[], params?: Record<string, any>, controls?: {
40
+ entityId: number;
41
+ state: number;
42
+ }[]): void;
43
+ /** Append a measurement entry. */
44
+ addMeasurement(entityId: number, dimension: number, outcome: number): void;
45
+ /** Get a copy of the current log. */
46
+ getLog(): CircuitEntry[];
47
+ /** Filter log to entries involving any of the given entity IDs. */
48
+ getLogForEntities(entityIds: number[]): CircuitEntry[];
49
+ /** Clear the log and reset the counter. */
50
+ reset(): void;
51
+ }
52
+ /** Global singleton circuit logger. */
53
+ export declare const CircuitLogger: CircuitLoggerImpl;
54
+ export {};
@@ -0,0 +1,80 @@
1
+ /**
2
+ * CircuitLog — toggleable, append-only log of quantum operations.
3
+ *
4
+ * When recording is active, every state-mutating call (gate or measurement)
5
+ * appends an entry. The log is designed for future incremental OpenQASM export:
6
+ * each new entry maps to one circuit instruction, so the export never rebuilds.
7
+ */
8
+ // ── Logger ───────────────────────────────────────────────────────────
9
+ class CircuitLoggerImpl {
10
+ _recording = false;
11
+ _log = [];
12
+ _counter = 0;
13
+ /** Begin recording. Resets the existing log. */
14
+ startRecording() {
15
+ this._recording = true;
16
+ this._log = [];
17
+ this._counter = 0;
18
+ }
19
+ /** Stop recording and return the captured log. */
20
+ stopRecording() {
21
+ this._recording = false;
22
+ return [...this._log];
23
+ }
24
+ /** Fast guard — check before constructing entry objects on the hot path. */
25
+ isRecording() {
26
+ return this._recording;
27
+ }
28
+ /** Append an entry (auto-assigns timestamp). */
29
+ addGate(name, entityIds, dimensions, params, controls) {
30
+ const entry = {
31
+ type: 'gate',
32
+ name,
33
+ entityIds,
34
+ dimensions,
35
+ timestamp: this._counter++,
36
+ };
37
+ if (params)
38
+ entry.params = params;
39
+ if (controls)
40
+ entry.controls = controls;
41
+ this._log.push(entry);
42
+ }
43
+ /** Append a measurement entry. */
44
+ addMeasurement(entityId, dimension, outcome) {
45
+ this._log.push({
46
+ type: 'measurement',
47
+ entityId,
48
+ dimension,
49
+ outcome,
50
+ timestamp: this._counter++,
51
+ });
52
+ }
53
+ /** Get a copy of the current log. */
54
+ getLog() {
55
+ return [...this._log];
56
+ }
57
+ /** Filter log to entries involving any of the given entity IDs. */
58
+ getLogForEntities(entityIds) {
59
+ const idSet = new Set(entityIds);
60
+ return this._log.filter(entry => {
61
+ if (entry.type === 'measurement') {
62
+ return idSet.has(entry.entityId);
63
+ }
64
+ // Gate — check targets and controls
65
+ if (entry.entityIds.some(id => idSet.has(id)))
66
+ return true;
67
+ if (entry.controls?.some(c => idSet.has(c.entityId)))
68
+ return true;
69
+ return false;
70
+ });
71
+ }
72
+ /** Clear the log and reset the counter. */
73
+ reset() {
74
+ this._log = [];
75
+ this._counter = 0;
76
+ }
77
+ }
78
+ /** Global singleton circuit logger. */
79
+ export const CircuitLogger = new CircuitLoggerImpl();
80
+ //# sourceMappingURL=CircuitLog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CircuitLog.js","sourceRoot":"","sources":["../src/CircuitLog.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAwBH,wEAAwE;AAExE,MAAM,iBAAiB;IACX,UAAU,GAAG,KAAK,CAAC;IACnB,IAAI,GAAmB,EAAE,CAAC;IAC1B,QAAQ,GAAG,CAAC,CAAC;IAErB,gDAAgD;IAChD,cAAc;QACV,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IACtB,CAAC;IAED,kDAAkD;IAClD,aAAa;QACT,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,4EAA4E;IAC5E,WAAW;QACP,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED,gDAAgD;IAChD,OAAO,CACH,IAAY,EACZ,SAAmB,EACnB,UAAoB,EACpB,MAA4B,EAC5B,QAAgD;QAEhD,MAAM,KAAK,GAAc;YACrB,IAAI,EAAE,MAAM;YACZ,IAAI;YACJ,SAAS;YACT,UAAU;YACV,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE;SAC7B,CAAC;QACF,IAAI,MAAM;YAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QAClC,IAAI,QAAQ;YAAE,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAED,kCAAkC;IAClC,cAAc,CAAC,QAAgB,EAAE,SAAiB,EAAE,OAAe;QAC/D,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,aAAa;YACnB,QAAQ;YACR,SAAS;YACT,OAAO;YACP,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE;SAC7B,CAAC,CAAC;IACP,CAAC;IAED,qCAAqC;IACrC,MAAM;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,mEAAmE;IACnE,iBAAiB,CAAC,SAAmB;QACjC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBAC/B,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACrC,CAAC;YACD,oCAAoC;YACpC,IAAI,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC3D,IAAI,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YAClE,OAAO,KAAK,CAAC;QACjB,CAAC,CAAC,CAAC;IACP,CAAC;IAED,2CAA2C;IAC3C,KAAK;QACD,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;IACtB,CAAC;CACJ;AAED,uCAAuC;AACvC,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ export interface Complex {
2
+ re: number;
3
+ im: number;
4
+ }
5
+ export declare const ComplexMath: {
6
+ add(a: Complex, b: Complex): Complex;
7
+ subtract(a: Complex, b: Complex): Complex;
8
+ multiply(a: Complex, b: Complex): Complex;
9
+ conjugate(a: Complex): Complex;
10
+ scale(a: Complex, scalar: number): Complex;
11
+ magnitudeSquared(a: Complex): number;
12
+ phase(angle: number): Complex;
13
+ };
@@ -0,0 +1,49 @@
1
+ export const ComplexMath = {
2
+ // Add two complex numbers
3
+ add(a, b) {
4
+ return {
5
+ re: a.re + b.re,
6
+ im: a.im + b.im
7
+ };
8
+ },
9
+ // Subtract b from a
10
+ subtract(a, b) {
11
+ return {
12
+ re: a.re - b.re,
13
+ im: a.im - b.im
14
+ };
15
+ },
16
+ // Multiply two complex numbers
17
+ multiply(a, b) {
18
+ return {
19
+ re: a.re * b.re - a.im * b.im,
20
+ im: a.im * b.re + a.re * b.im
21
+ };
22
+ },
23
+ // Complex conjugate
24
+ conjugate(a) {
25
+ return {
26
+ re: a.re,
27
+ im: -a.im
28
+ };
29
+ },
30
+ // Multiply a complex number by a scalar
31
+ scale(a, scalar) {
32
+ return {
33
+ re: a.re * scalar,
34
+ im: a.im * scalar
35
+ };
36
+ },
37
+ // Calculate magnitude squared (probability)
38
+ magnitudeSquared(a) {
39
+ return a.re * a.re + a.im * a.im;
40
+ },
41
+ // Calculate the complex phase e^(i * angle)
42
+ phase(angle) {
43
+ return {
44
+ re: Math.cos(angle),
45
+ im: Math.sin(angle)
46
+ };
47
+ }
48
+ };
49
+ //# sourceMappingURL=Complex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Complex.js","sourceRoot":"","sources":["../src/Complex.ts"],"names":[],"mappings":"AAKA,MAAM,CAAC,MAAM,WAAW,GAAG;IACvB,0BAA0B;IAC1B,GAAG,CAAC,CAAU,EAAE,CAAU;QACtB,OAAO;YACH,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE;YACf,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE;SAClB,CAAC;IACN,CAAC;IAED,oBAAoB;IACpB,QAAQ,CAAC,CAAU,EAAE,CAAU;QAC3B,OAAO;YACH,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE;YACf,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE;SAClB,CAAC;IACN,CAAC;IAED,+BAA+B;IAC/B,QAAQ,CAAC,CAAU,EAAE,CAAU;QAC3B,OAAO;YACH,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE;YAC7B,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE;SAChC,CAAC;IACN,CAAC;IAED,oBAAoB;IACpB,SAAS,CAAC,CAAU;QAChB,OAAO;YACH,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE;SACZ,CAAC;IACN,CAAC;IAED,wCAAwC;IACxC,KAAK,CAAC,CAAU,EAAE,MAAc;QAC5B,OAAO;YACH,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM;YACjB,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM;SACpB,CAAC;IACN,CAAC;IAED,4CAA4C;IAC5C,gBAAgB,CAAC,CAAU;QACvB,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;IACrC,CAAC;IAED,4CAA4C;IAC5C,KAAK,CAAC,KAAa;QACf,OAAO;YACH,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;YACnB,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;SACtB,CAAC;IACN,CAAC;CACJ,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { QuantumEntity, type Predicate } from './QuantumEntity';
2
+ import { type QuantumOperation, type SparseAmplitudes } from './Operations';
3
+ import { type Complex } from './Complex';
4
+ export declare class JointQuantumSystem {
5
+ entities: QuantumEntity[];
6
+ dimensions: number[];
7
+ totalDimension: number;
8
+ jointAmplitudes: SparseAmplitudes;
9
+ private constructor();
10
+ static create(entities: QuantumEntity[]): JointQuantumSystem;
11
+ static merge(involvedEntities: QuantumEntity[]): JointQuantumSystem;
12
+ private _calculateTensorProduct;
13
+ decomposeState(jointState: number): number[];
14
+ composeState(states: number[]): number;
15
+ applyLocal(entityIndex: number, operation: QuantumOperation): void;
16
+ applyToSubspace(targetEntities: QuantumEntity[], operation: QuantumOperation): void;
17
+ getTargetProbabilities(targetEntity: QuantumEntity): Record<number, number>;
18
+ getTargetAmplitudes(targetEntity: QuantumEntity): Record<number, Complex>;
19
+ measureTarget(targetEntity: QuantumEntity, forcedOutcome?: number): number;
20
+ getProjectedAmplitudes(conditions: {
21
+ entity: QuantumEntity;
22
+ state: number;
23
+ }[]): SparseAmplitudes;
24
+ getJointProbability(conditions: {
25
+ entity: QuantumEntity;
26
+ state: number;
27
+ }[]): number;
28
+ areMutuallyExclusive(conditions: {
29
+ entity: QuantumEntity;
30
+ state: number;
31
+ }[]): boolean;
32
+ getReducedDensityMatrix(targetEntity: QuantumEntity): Record<number, Record<number, Complex>>;
33
+ /**
34
+ * Create a joint system from existing amplitudes and entities (Bit-Perfect Restoration/Cloning).
35
+ */
36
+ static inject(entities: QuantumEntity[], jointAmplitudes: SparseAmplitudes): JointQuantumSystem;
37
+ }
38
+ export interface TargetOperation {
39
+ entity: QuantumEntity;
40
+ operation: QuantumOperation;
41
+ }
42
+ export declare const EntanglementEngine: {
43
+ interactMany(entities: QuantumEntity[], operation: QuantumOperation): void;
44
+ conditionalInteract(args: {
45
+ controls: Predicate[];
46
+ targets: TargetOperation[];
47
+ }): void;
48
+ };