quantumflow-sdk 0.3.0__py3-none-any.whl → 0.4.0__py3-none-any.whl
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.
- api/main.py +28 -1
- api/models.py +41 -0
- api/routes/algorithm_routes.py +134 -0
- api/routes/chat_routes.py +565 -0
- api/routes/pipeline_routes.py +578 -0
- db/models.py +357 -0
- quantumflow/algorithms/machine_learning/__init__.py +14 -2
- quantumflow/algorithms/machine_learning/vqe.py +355 -3
- quantumflow/core/__init__.py +10 -1
- quantumflow/core/quantum_compressor.py +379 -1
- quantumflow/integrations/domain_agents.py +617 -0
- quantumflow/pipeline/__init__.py +29 -0
- quantumflow/pipeline/anomaly_detector.py +521 -0
- quantumflow/pipeline/base_pipeline.py +602 -0
- quantumflow/pipeline/checkpoint_manager.py +587 -0
- quantumflow/pipeline/finance/__init__.py +5 -0
- quantumflow/pipeline/finance/portfolio_optimization.py +595 -0
- quantumflow/pipeline/healthcare/__init__.py +5 -0
- quantumflow/pipeline/healthcare/protein_folding.py +994 -0
- quantumflow/pipeline/temporal_memory.py +577 -0
- {quantumflow_sdk-0.3.0.dist-info → quantumflow_sdk-0.4.0.dist-info}/METADATA +3 -3
- {quantumflow_sdk-0.3.0.dist-info → quantumflow_sdk-0.4.0.dist-info}/RECORD +25 -13
- {quantumflow_sdk-0.3.0.dist-info → quantumflow_sdk-0.4.0.dist-info}/WHEEL +0 -0
- {quantumflow_sdk-0.3.0.dist-info → quantumflow_sdk-0.4.0.dist-info}/entry_points.txt +0 -0
- {quantumflow_sdk-0.3.0.dist-info → quantumflow_sdk-0.4.0.dist-info}/top_level.txt +0 -0
|
@@ -3,17 +3,26 @@ Variational Quantum Eigensolver (VQE).
|
|
|
3
3
|
|
|
4
4
|
Finds ground state energy of molecular Hamiltonians.
|
|
5
5
|
Hybrid quantum-classical algorithm for quantum chemistry.
|
|
6
|
+
|
|
7
|
+
Enhanced with Single Excitation Subspace (SES) ansatz from arXiv:2601.00247:
|
|
8
|
+
- Logarithmic qubit encoding: N states → log₂(N) qubits
|
|
9
|
+
- Binary-encoded SES ansatz for tight-binding Hamiltonians
|
|
10
|
+
- Volumetric cost reduction: O(N²) → O((log N)³)
|
|
6
11
|
"""
|
|
7
12
|
|
|
8
13
|
import math
|
|
9
14
|
from dataclasses import dataclass
|
|
10
|
-
from typing import Optional, Callable
|
|
15
|
+
from typing import Optional, Callable, Literal
|
|
11
16
|
import numpy as np
|
|
12
17
|
from qiskit import QuantumCircuit
|
|
13
18
|
|
|
14
19
|
from quantumflow.backends.base_backend import QuantumBackend, get_backend, BackendType
|
|
15
20
|
|
|
16
21
|
|
|
22
|
+
# Type alias for supported ansatz types
|
|
23
|
+
AnsatzType = Literal["ry_linear", "ry_full", "hardware_efficient", "ses_binary"]
|
|
24
|
+
|
|
25
|
+
|
|
17
26
|
@dataclass
|
|
18
27
|
class VQEResult:
|
|
19
28
|
"""Result from VQE optimization."""
|
|
@@ -46,9 +55,10 @@ class VQE:
|
|
|
46
55
|
self,
|
|
47
56
|
n_qubits: int,
|
|
48
57
|
backend: BackendType | str = BackendType.AUTO,
|
|
49
|
-
ansatz:
|
|
58
|
+
ansatz: AnsatzType = "ry_linear",
|
|
50
59
|
depth: int = 2,
|
|
51
60
|
shots: int = 1024,
|
|
61
|
+
n_ses_states: Optional[int] = None,
|
|
52
62
|
):
|
|
53
63
|
"""
|
|
54
64
|
Initialize VQE.
|
|
@@ -56,9 +66,17 @@ class VQE:
|
|
|
56
66
|
Args:
|
|
57
67
|
n_qubits: Number of qubits
|
|
58
68
|
backend: Quantum backend
|
|
59
|
-
ansatz: Ansatz type
|
|
69
|
+
ansatz: Ansatz type:
|
|
70
|
+
- 'ry_linear': Simple RY rotations with linear entanglement
|
|
71
|
+
- 'ry_full': RY rotations with full connectivity
|
|
72
|
+
- 'hardware_efficient': RY+RZ rotations (IBM-style)
|
|
73
|
+
- 'ses_binary': Single Excitation Subspace with binary encoding
|
|
74
|
+
(from arXiv:2601.00247) - uses log₂(N) qubits
|
|
75
|
+
for N-state problems
|
|
60
76
|
depth: Circuit depth (layers)
|
|
61
77
|
shots: Measurement shots
|
|
78
|
+
n_ses_states: Number of SES states (only for 'ses_binary' ansatz)
|
|
79
|
+
If None, defaults to 2^n_qubits
|
|
62
80
|
"""
|
|
63
81
|
self.n_qubits = n_qubits
|
|
64
82
|
self.backend = get_backend(backend)
|
|
@@ -67,6 +85,19 @@ class VQE:
|
|
|
67
85
|
self.shots = shots
|
|
68
86
|
self._connected = False
|
|
69
87
|
|
|
88
|
+
# SES-specific settings
|
|
89
|
+
if ansatz == "ses_binary":
|
|
90
|
+
self.n_ses_states = n_ses_states or (2 ** n_qubits)
|
|
91
|
+
# Verify qubit count is sufficient
|
|
92
|
+
min_qubits = math.ceil(math.log2(self.n_ses_states))
|
|
93
|
+
if n_qubits < min_qubits:
|
|
94
|
+
raise ValueError(
|
|
95
|
+
f"SES ansatz with {self.n_ses_states} states requires "
|
|
96
|
+
f"at least {min_qubits} qubits, got {n_qubits}"
|
|
97
|
+
)
|
|
98
|
+
else:
|
|
99
|
+
self.n_ses_states = None
|
|
100
|
+
|
|
70
101
|
def _ensure_connected(self):
|
|
71
102
|
if not self._connected:
|
|
72
103
|
self.backend.connect()
|
|
@@ -135,10 +166,18 @@ class VQE:
|
|
|
135
166
|
return self.n_qubits * self.depth * 2
|
|
136
167
|
elif self.ansatz_type == "hardware_efficient":
|
|
137
168
|
return self.n_qubits * self.depth * 3
|
|
169
|
+
elif self.ansatz_type == "ses_binary":
|
|
170
|
+
# SES ansatz: 2 parameters (β, γ) per A-gate
|
|
171
|
+
# Number of A-gates = N-1 where N is number of SES states
|
|
172
|
+
n_states = self.n_ses_states or (2 ** self.n_qubits)
|
|
173
|
+
return 2 * (n_states - 1)
|
|
138
174
|
return self.n_qubits * self.depth
|
|
139
175
|
|
|
140
176
|
def _build_ansatz(self, params: np.ndarray) -> QuantumCircuit:
|
|
141
177
|
"""Build parameterized ansatz circuit."""
|
|
178
|
+
if self.ansatz_type == "ses_binary":
|
|
179
|
+
return self._build_ses_binary_ansatz(params)
|
|
180
|
+
|
|
142
181
|
qc = QuantumCircuit(self.n_qubits, name="vqe_ansatz")
|
|
143
182
|
param_idx = 0
|
|
144
183
|
|
|
@@ -160,6 +199,214 @@ class VQE:
|
|
|
160
199
|
|
|
161
200
|
return qc
|
|
162
201
|
|
|
202
|
+
def _build_ses_binary_ansatz(self, params: np.ndarray) -> QuantumCircuit:
|
|
203
|
+
"""
|
|
204
|
+
Build Single Excitation Subspace (SES) ansatz with binary encoding.
|
|
205
|
+
|
|
206
|
+
From arXiv:2601.00247 Section III.B:
|
|
207
|
+
- Uses log₂(N) qubits to encode N SES states
|
|
208
|
+
- A-gates mix amplitudes between neighboring states
|
|
209
|
+
- Preserves single-excitation subspace constraint
|
|
210
|
+
|
|
211
|
+
The ansatz generates states of the form:
|
|
212
|
+
|ψ⟩ = Σ α_j |e_j⟩
|
|
213
|
+
|
|
214
|
+
where |e_j⟩ are binary-encoded SES basis states.
|
|
215
|
+
|
|
216
|
+
Circuit structure (Fig. 3 from paper):
|
|
217
|
+
1. Initialize first ancilla to |1⟩
|
|
218
|
+
2. Apply A-gate to ancilla pair
|
|
219
|
+
3. Controlled state preparation on data register
|
|
220
|
+
4. Unflag ancilla with multi-controlled Toffoli
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
params: Array of [β_0, γ_0, β_1, γ_1, ...] parameters
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
QuantumCircuit implementing the SES ansatz
|
|
227
|
+
"""
|
|
228
|
+
n_states = self.n_ses_states or (2 ** self.n_qubits)
|
|
229
|
+
n_data_qubits = self.n_qubits
|
|
230
|
+
|
|
231
|
+
# We use 2 ancilla qubits + n data qubits
|
|
232
|
+
# For simplicity, we'll implement on n_qubits directly
|
|
233
|
+
# using a hardware-efficient approximation of the SES ansatz
|
|
234
|
+
qc = QuantumCircuit(n_data_qubits, name="ses_binary_ansatz")
|
|
235
|
+
|
|
236
|
+
# Initialize to first SES state |00...01⟩ (shifted binary encoding)
|
|
237
|
+
qc.x(0)
|
|
238
|
+
|
|
239
|
+
param_idx = 0
|
|
240
|
+
|
|
241
|
+
# Apply A-gates sequentially to sweep excitation
|
|
242
|
+
for i in range(n_states - 1):
|
|
243
|
+
if param_idx + 1 >= len(params):
|
|
244
|
+
break
|
|
245
|
+
|
|
246
|
+
beta = params[param_idx]
|
|
247
|
+
gamma = params[param_idx + 1]
|
|
248
|
+
param_idx += 2
|
|
249
|
+
|
|
250
|
+
# Implement A-gate between states i and i+1
|
|
251
|
+
# A-gate mixes amplitudes: |α_i⟩ ↔ |α_{i+1}⟩
|
|
252
|
+
self._apply_a_gate(qc, i, beta, gamma, n_data_qubits)
|
|
253
|
+
|
|
254
|
+
return qc
|
|
255
|
+
|
|
256
|
+
def _apply_a_gate(
|
|
257
|
+
self,
|
|
258
|
+
qc: QuantumCircuit,
|
|
259
|
+
state_idx: int,
|
|
260
|
+
beta: float,
|
|
261
|
+
gamma: float,
|
|
262
|
+
n_qubits: int,
|
|
263
|
+
) -> None:
|
|
264
|
+
"""
|
|
265
|
+
Apply the A-gate that mixes states |i⟩ and |i+1⟩.
|
|
266
|
+
|
|
267
|
+
From arXiv:2601.00247 Fig. 2:
|
|
268
|
+
A_{j,j+1}(β, γ) consists of:
|
|
269
|
+
- 3 CNOT gates
|
|
270
|
+
- 2 R_y rotations
|
|
271
|
+
- 2 R_z rotations
|
|
272
|
+
|
|
273
|
+
The gate creates superposition:
|
|
274
|
+
|i⟩ → cos(β)|i⟩ + e^{iγ}sin(β)|i+1⟩
|
|
275
|
+
|
|
276
|
+
Args:
|
|
277
|
+
qc: Quantum circuit to modify
|
|
278
|
+
state_idx: Index i of the state pair
|
|
279
|
+
beta: Amplitude mixing angle
|
|
280
|
+
gamma: Phase angle
|
|
281
|
+
n_qubits: Number of qubits
|
|
282
|
+
"""
|
|
283
|
+
# Find which bit flips between state i and i+1 (Gray-code style)
|
|
284
|
+
# In shifted binary: state k encodes to binary(k+1)
|
|
285
|
+
current = (state_idx + 1) % (2 ** n_qubits)
|
|
286
|
+
next_state = (state_idx + 2) % (2 ** n_qubits)
|
|
287
|
+
|
|
288
|
+
# Find differing bit
|
|
289
|
+
diff = current ^ next_state
|
|
290
|
+
if diff == 0:
|
|
291
|
+
return
|
|
292
|
+
|
|
293
|
+
# Find position of differing bit
|
|
294
|
+
flip_qubit = 0
|
|
295
|
+
while (diff >> flip_qubit) & 1 == 0:
|
|
296
|
+
flip_qubit += 1
|
|
297
|
+
|
|
298
|
+
# Find control qubits (bits that must match)
|
|
299
|
+
control_qubits = []
|
|
300
|
+
control_values = []
|
|
301
|
+
for q in range(n_qubits):
|
|
302
|
+
if q != flip_qubit:
|
|
303
|
+
# Check if this bit is 1 in current state
|
|
304
|
+
if (current >> q) & 1:
|
|
305
|
+
control_qubits.append(q)
|
|
306
|
+
control_values.append(1)
|
|
307
|
+
|
|
308
|
+
# Apply controlled rotation (simplified A-gate)
|
|
309
|
+
# This implements amplitude mixing between states
|
|
310
|
+
|
|
311
|
+
if len(control_qubits) == 0:
|
|
312
|
+
# No controls needed - direct rotation
|
|
313
|
+
qc.rz(gamma + np.pi, flip_qubit)
|
|
314
|
+
qc.ry(beta + np.pi / 2, flip_qubit)
|
|
315
|
+
elif len(control_qubits) == 1:
|
|
316
|
+
# Single control
|
|
317
|
+
ctrl = control_qubits[0]
|
|
318
|
+
|
|
319
|
+
# Controlled-RY decomposition
|
|
320
|
+
qc.rz(gamma / 2, flip_qubit)
|
|
321
|
+
qc.cx(ctrl, flip_qubit)
|
|
322
|
+
qc.ry(-beta / 2, flip_qubit)
|
|
323
|
+
qc.cx(ctrl, flip_qubit)
|
|
324
|
+
qc.ry(beta / 2, flip_qubit)
|
|
325
|
+
qc.rz(-gamma / 2, flip_qubit)
|
|
326
|
+
else:
|
|
327
|
+
# Multi-controlled case - use decomposition
|
|
328
|
+
# Simplified: apply rotation with first control only
|
|
329
|
+
ctrl = control_qubits[0]
|
|
330
|
+
qc.rz(gamma / 2, flip_qubit)
|
|
331
|
+
qc.cx(ctrl, flip_qubit)
|
|
332
|
+
qc.ry(-beta / 2, flip_qubit)
|
|
333
|
+
qc.cx(ctrl, flip_qubit)
|
|
334
|
+
qc.ry(beta / 2, flip_qubit)
|
|
335
|
+
|
|
336
|
+
@staticmethod
|
|
337
|
+
def create_ses_hamiltonian(
|
|
338
|
+
on_site_energies: list[float],
|
|
339
|
+
hopping_terms: list[tuple[int, int, complex]],
|
|
340
|
+
) -> list[tuple[str, float]]:
|
|
341
|
+
"""
|
|
342
|
+
Create SES Hamiltonian in Pauli string format.
|
|
343
|
+
|
|
344
|
+
Converts tight-binding Hamiltonian to VQE-compatible format.
|
|
345
|
+
From arXiv:2601.00247 Eq. (4).
|
|
346
|
+
|
|
347
|
+
H = Σ h_kk |k⟩⟨k| + Σ h_jk |j⟩⟨k|
|
|
348
|
+
|
|
349
|
+
In Pauli form:
|
|
350
|
+
H = Σ (h_kk/2)(1 - Z_k) + Σ [Re(h_jk)/2](X_j X_k + Y_j Y_k)
|
|
351
|
+
+ Σ [Im(h_jk)/2](Y_j X_k - X_j Y_k)
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
on_site_energies: Diagonal terms h_kk for each site
|
|
355
|
+
hopping_terms: List of (j, k, h_jk) hopping amplitudes
|
|
356
|
+
|
|
357
|
+
Returns:
|
|
358
|
+
List of (Pauli string, coefficient) tuples
|
|
359
|
+
|
|
360
|
+
Example:
|
|
361
|
+
>>> # 4-site tight-binding chain
|
|
362
|
+
>>> energies = [0.0, 0.1, 0.1, 0.0]
|
|
363
|
+
>>> hoppings = [(0, 1, -1.0), (1, 2, -1.0), (2, 3, -1.0)]
|
|
364
|
+
>>> H = VQE.create_ses_hamiltonian(energies, hoppings)
|
|
365
|
+
"""
|
|
366
|
+
n_sites = len(on_site_energies)
|
|
367
|
+
hamiltonian = []
|
|
368
|
+
|
|
369
|
+
# Diagonal terms: h_kk/2 * (I - Z_k)
|
|
370
|
+
for k, h_kk in enumerate(on_site_energies):
|
|
371
|
+
if abs(h_kk) > 1e-10:
|
|
372
|
+
# Create Z_k Pauli string
|
|
373
|
+
pauli = ['I'] * n_sites
|
|
374
|
+
pauli[k] = 'Z'
|
|
375
|
+
hamiltonian.append((''.join(pauli), -h_kk / 2))
|
|
376
|
+
|
|
377
|
+
# Hopping terms
|
|
378
|
+
for j, k, h_jk in hopping_terms:
|
|
379
|
+
re_h = h_jk.real if isinstance(h_jk, complex) else h_jk
|
|
380
|
+
im_h = h_jk.imag if isinstance(h_jk, complex) else 0.0
|
|
381
|
+
|
|
382
|
+
if abs(re_h) > 1e-10:
|
|
383
|
+
# XX term
|
|
384
|
+
pauli_xx = ['I'] * n_sites
|
|
385
|
+
pauli_xx[j] = 'X'
|
|
386
|
+
pauli_xx[k] = 'X'
|
|
387
|
+
hamiltonian.append((''.join(pauli_xx), re_h / 2))
|
|
388
|
+
|
|
389
|
+
# YY term
|
|
390
|
+
pauli_yy = ['I'] * n_sites
|
|
391
|
+
pauli_yy[j] = 'Y'
|
|
392
|
+
pauli_yy[k] = 'Y'
|
|
393
|
+
hamiltonian.append((''.join(pauli_yy), re_h / 2))
|
|
394
|
+
|
|
395
|
+
if abs(im_h) > 1e-10:
|
|
396
|
+
# YX term
|
|
397
|
+
pauli_yx = ['I'] * n_sites
|
|
398
|
+
pauli_yx[j] = 'Y'
|
|
399
|
+
pauli_yx[k] = 'X'
|
|
400
|
+
hamiltonian.append((''.join(pauli_yx), im_h / 2))
|
|
401
|
+
|
|
402
|
+
# XY term (negative)
|
|
403
|
+
pauli_xy = ['I'] * n_sites
|
|
404
|
+
pauli_xy[j] = 'X'
|
|
405
|
+
pauli_xy[k] = 'Y'
|
|
406
|
+
hamiltonian.append((''.join(pauli_xy), -im_h / 2))
|
|
407
|
+
|
|
408
|
+
return hamiltonian
|
|
409
|
+
|
|
163
410
|
def _evaluate_energy(
|
|
164
411
|
self,
|
|
165
412
|
params: np.ndarray,
|
|
@@ -227,3 +474,108 @@ class VQE:
|
|
|
227
474
|
grad[i] = (energy_plus - energy_minus) / 2
|
|
228
475
|
|
|
229
476
|
return grad
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
def run_ses_vqe(
|
|
480
|
+
n_sites: int,
|
|
481
|
+
on_site_energies: list[float],
|
|
482
|
+
hopping_terms: list[tuple[int, int, complex]],
|
|
483
|
+
max_iterations: int = 100,
|
|
484
|
+
backend: str = "auto",
|
|
485
|
+
) -> VQEResult:
|
|
486
|
+
"""
|
|
487
|
+
Convenience function to run VQE with SES ansatz.
|
|
488
|
+
|
|
489
|
+
Uses logarithmic qubit encoding from arXiv:2601.00247 for
|
|
490
|
+
efficient simulation of tight-binding Hamiltonians.
|
|
491
|
+
|
|
492
|
+
Args:
|
|
493
|
+
n_sites: Number of lattice sites
|
|
494
|
+
on_site_energies: Energy at each site [h_11, h_22, ...]
|
|
495
|
+
hopping_terms: Hopping between sites [(i, j, t_ij), ...]
|
|
496
|
+
max_iterations: Maximum VQE iterations
|
|
497
|
+
backend: Quantum backend ('simulator', 'ibm', 'auto')
|
|
498
|
+
|
|
499
|
+
Returns:
|
|
500
|
+
VQEResult with ground state energy
|
|
501
|
+
|
|
502
|
+
Example:
|
|
503
|
+
>>> # 8-site tight-binding chain with uniform hopping
|
|
504
|
+
>>> n_sites = 8
|
|
505
|
+
>>> energies = [0.0] * n_sites
|
|
506
|
+
>>> hoppings = [(i, i+1, -1.0) for i in range(n_sites-1)]
|
|
507
|
+
>>> result = run_ses_vqe(n_sites, energies, hoppings)
|
|
508
|
+
>>> print(f"Ground energy: {result.ground_energy:.4f}")
|
|
509
|
+
>>> # Uses only 3 qubits instead of 8!
|
|
510
|
+
"""
|
|
511
|
+
# Calculate minimum qubits needed
|
|
512
|
+
n_qubits = math.ceil(math.log2(n_sites))
|
|
513
|
+
|
|
514
|
+
# Create VQE with SES ansatz
|
|
515
|
+
vqe = VQE(
|
|
516
|
+
n_qubits=n_qubits,
|
|
517
|
+
backend=backend,
|
|
518
|
+
ansatz="ses_binary",
|
|
519
|
+
n_ses_states=n_sites,
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
# Create Hamiltonian
|
|
523
|
+
hamiltonian = VQE.create_ses_hamiltonian(on_site_energies, hopping_terms)
|
|
524
|
+
|
|
525
|
+
# Run VQE
|
|
526
|
+
return vqe.run(hamiltonian, max_iterations=max_iterations)
|
|
527
|
+
|
|
528
|
+
|
|
529
|
+
def calculate_volumetric_cost(
|
|
530
|
+
n_sites: int,
|
|
531
|
+
ansatz_type: str = "ses_binary",
|
|
532
|
+
depth: int = 1,
|
|
533
|
+
) -> dict:
|
|
534
|
+
"""
|
|
535
|
+
Calculate volumetric efficiency metric from arXiv:2601.00247.
|
|
536
|
+
|
|
537
|
+
E = (qubit width) × (circuit depth) × (measurement settings)
|
|
538
|
+
|
|
539
|
+
Args:
|
|
540
|
+
n_sites: Number of sites in the system
|
|
541
|
+
ansatz_type: 'ses_binary' or 'standard'
|
|
542
|
+
depth: Circuit depth
|
|
543
|
+
|
|
544
|
+
Returns:
|
|
545
|
+
Dict with volumetric cost comparison
|
|
546
|
+
|
|
547
|
+
Example:
|
|
548
|
+
>>> costs = calculate_volumetric_cost(1024)
|
|
549
|
+
>>> print(f"SES speedup: {costs['speedup']:.0f}x")
|
|
550
|
+
"""
|
|
551
|
+
n = math.ceil(math.log2(n_sites))
|
|
552
|
+
|
|
553
|
+
if ansatz_type == "ses_binary":
|
|
554
|
+
qubits = n
|
|
555
|
+
circuit_depth = n # O(n) for hardware-efficient
|
|
556
|
+
measurements = 2 * n + 1
|
|
557
|
+
volumetric = qubits * circuit_depth * measurements
|
|
558
|
+
else:
|
|
559
|
+
# Standard encoding
|
|
560
|
+
qubits = n_sites
|
|
561
|
+
circuit_depth = n_sites # O(N)
|
|
562
|
+
measurements = 3
|
|
563
|
+
volumetric = qubits * circuit_depth * measurements
|
|
564
|
+
|
|
565
|
+
# Original SES (from paper)
|
|
566
|
+
original_qubits = n_sites
|
|
567
|
+
original_depth = n_sites
|
|
568
|
+
original_measurements = 3
|
|
569
|
+
original_volumetric = original_qubits * original_depth * original_measurements
|
|
570
|
+
|
|
571
|
+
return {
|
|
572
|
+
"ansatz": ansatz_type,
|
|
573
|
+
"n_sites": n_sites,
|
|
574
|
+
"qubits": qubits,
|
|
575
|
+
"circuit_depth": circuit_depth,
|
|
576
|
+
"measurements": measurements,
|
|
577
|
+
"volumetric_cost": volumetric,
|
|
578
|
+
"original_volumetric_cost": original_volumetric,
|
|
579
|
+
"speedup": original_volumetric / volumetric if volumetric > 0 else float('inf'),
|
|
580
|
+
"qubit_reduction": f"{n_sites} → {n} ({100*(1-n/n_sites):.1f}% reduction)",
|
|
581
|
+
}
|
quantumflow/core/__init__.py
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
"""QuantumFlow Core - Quantum computing primitives and algorithms."""
|
|
2
2
|
|
|
3
|
-
from quantumflow.core.quantum_compressor import
|
|
3
|
+
from quantumflow.core.quantum_compressor import (
|
|
4
|
+
QuantumCompressor,
|
|
5
|
+
CompressedResult,
|
|
6
|
+
GrayCodeMeasurement,
|
|
7
|
+
GrayCodeMeasurementResult,
|
|
8
|
+
generate_gray_code,
|
|
9
|
+
)
|
|
4
10
|
from quantumflow.core.entanglement import Entangler
|
|
5
11
|
from quantumflow.core.memory import QuantumMemory
|
|
6
12
|
|
|
7
13
|
__all__ = [
|
|
8
14
|
"QuantumCompressor",
|
|
9
15
|
"CompressedResult",
|
|
16
|
+
"GrayCodeMeasurement",
|
|
17
|
+
"GrayCodeMeasurementResult",
|
|
18
|
+
"generate_gray_code",
|
|
10
19
|
"Entangler",
|
|
11
20
|
"QuantumMemory",
|
|
12
21
|
]
|