quantumflow-sdk 0.1.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.
Files changed (60) hide show
  1. api/__init__.py +1 -0
  2. api/auth.py +208 -0
  3. api/main.py +403 -0
  4. api/models.py +137 -0
  5. api/routes/__init__.py +1 -0
  6. api/routes/auth_routes.py +234 -0
  7. api/routes/teleport_routes.py +415 -0
  8. db/__init__.py +15 -0
  9. db/crud.py +319 -0
  10. db/database.py +93 -0
  11. db/models.py +197 -0
  12. quantumflow/__init__.py +47 -0
  13. quantumflow/algorithms/__init__.py +48 -0
  14. quantumflow/algorithms/compression/__init__.py +7 -0
  15. quantumflow/algorithms/compression/amplitude_amplification.py +189 -0
  16. quantumflow/algorithms/compression/qft_compression.py +133 -0
  17. quantumflow/algorithms/compression/token_compression.py +261 -0
  18. quantumflow/algorithms/cryptography/__init__.py +6 -0
  19. quantumflow/algorithms/cryptography/qkd.py +205 -0
  20. quantumflow/algorithms/cryptography/qrng.py +231 -0
  21. quantumflow/algorithms/machine_learning/__init__.py +7 -0
  22. quantumflow/algorithms/machine_learning/qnn.py +276 -0
  23. quantumflow/algorithms/machine_learning/qsvm.py +249 -0
  24. quantumflow/algorithms/machine_learning/vqe.py +229 -0
  25. quantumflow/algorithms/optimization/__init__.py +7 -0
  26. quantumflow/algorithms/optimization/grover.py +223 -0
  27. quantumflow/algorithms/optimization/qaoa.py +251 -0
  28. quantumflow/algorithms/optimization/quantum_annealing.py +237 -0
  29. quantumflow/algorithms/utility/__init__.py +6 -0
  30. quantumflow/algorithms/utility/circuit_optimizer.py +194 -0
  31. quantumflow/algorithms/utility/error_correction.py +330 -0
  32. quantumflow/api/__init__.py +1 -0
  33. quantumflow/api/routes/__init__.py +4 -0
  34. quantumflow/api/routes/billing_routes.py +520 -0
  35. quantumflow/backends/__init__.py +33 -0
  36. quantumflow/backends/base_backend.py +184 -0
  37. quantumflow/backends/braket_backend.py +345 -0
  38. quantumflow/backends/ibm_backend.py +112 -0
  39. quantumflow/backends/simulator_backend.py +86 -0
  40. quantumflow/billing/__init__.py +25 -0
  41. quantumflow/billing/models.py +126 -0
  42. quantumflow/billing/stripe_service.py +619 -0
  43. quantumflow/core/__init__.py +12 -0
  44. quantumflow/core/entanglement.py +164 -0
  45. quantumflow/core/memory.py +147 -0
  46. quantumflow/core/quantum_backprop.py +394 -0
  47. quantumflow/core/quantum_compressor.py +309 -0
  48. quantumflow/core/teleportation.py +386 -0
  49. quantumflow/integrations/__init__.py +107 -0
  50. quantumflow/integrations/autogen_tools.py +501 -0
  51. quantumflow/integrations/crewai_agents.py +425 -0
  52. quantumflow/integrations/crewai_tools.py +407 -0
  53. quantumflow/integrations/langchain_memory.py +385 -0
  54. quantumflow/integrations/langchain_tools.py +366 -0
  55. quantumflow/integrations/mcp_server.py +575 -0
  56. quantumflow_sdk-0.1.0.dist-info/METADATA +190 -0
  57. quantumflow_sdk-0.1.0.dist-info/RECORD +60 -0
  58. quantumflow_sdk-0.1.0.dist-info/WHEEL +5 -0
  59. quantumflow_sdk-0.1.0.dist-info/entry_points.txt +2 -0
  60. quantumflow_sdk-0.1.0.dist-info/top_level.txt +3 -0
@@ -0,0 +1,189 @@
1
+ """
2
+ Amplitude Amplification Algorithm.
3
+
4
+ Generalization of Grover's algorithm for amplifying the probability
5
+ of marked states. Used in compression for selective retrieval.
6
+ """
7
+
8
+ import math
9
+ from dataclasses import dataclass
10
+ from typing import Callable, Optional
11
+ import numpy as np
12
+ from qiskit import QuantumCircuit
13
+
14
+ from quantumflow.backends.base_backend import QuantumBackend, get_backend, BackendType
15
+
16
+
17
+ @dataclass
18
+ class AmplificationResult:
19
+ """Result from amplitude amplification."""
20
+
21
+ circuit: QuantumCircuit
22
+ n_qubits: int
23
+ iterations: int
24
+ target_probability: float
25
+ amplified_probability: float
26
+
27
+
28
+ class AmplitudeAmplification:
29
+ """
30
+ Quantum Amplitude Amplification.
31
+
32
+ Amplifies the amplitude of marked states, increasing their
33
+ measurement probability from ~1/N to near certainty.
34
+
35
+ Applications:
36
+ - Selective token retrieval from compressed state
37
+ - Search optimization
38
+ - Probability boosting
39
+
40
+ Example:
41
+ >>> aa = AmplitudeAmplification()
42
+ >>> result = aa.amplify(initial_circuit, oracle, n_qubits=4)
43
+ >>> print(f"Amplified probability: {result.amplified_probability:.2%}")
44
+ """
45
+
46
+ def __init__(self, backend: BackendType | str = BackendType.AUTO):
47
+ self.backend = get_backend(backend)
48
+
49
+ def amplify(
50
+ self,
51
+ initial_state: QuantumCircuit,
52
+ oracle: QuantumCircuit,
53
+ n_qubits: int,
54
+ iterations: Optional[int] = None,
55
+ target_count: int = 1,
56
+ ) -> AmplificationResult:
57
+ """
58
+ Apply amplitude amplification.
59
+
60
+ Args:
61
+ initial_state: Circuit preparing initial superposition
62
+ oracle: Oracle marking target states (applies phase flip)
63
+ n_qubits: Number of qubits
64
+ iterations: Grover iterations (optimal if None)
65
+ target_count: Number of marked states
66
+
67
+ Returns:
68
+ AmplificationResult with amplified circuit
69
+ """
70
+ N = 2 ** n_qubits
71
+
72
+ # Calculate optimal iterations
73
+ if iterations is None:
74
+ if target_count > 0:
75
+ theta = math.asin(math.sqrt(target_count / N))
76
+ iterations = max(1, int(round(math.pi / (4 * theta) - 0.5)))
77
+ else:
78
+ iterations = 1
79
+
80
+ # Initial probability
81
+ initial_prob = target_count / N
82
+
83
+ # Build amplification circuit
84
+ circuit = self._build_circuit(
85
+ initial_state, oracle, n_qubits, iterations
86
+ )
87
+
88
+ # Calculate amplified probability
89
+ theta = math.asin(math.sqrt(target_count / N))
90
+ amplified_prob = math.sin((2 * iterations + 1) * theta) ** 2
91
+
92
+ return AmplificationResult(
93
+ circuit=circuit,
94
+ n_qubits=n_qubits,
95
+ iterations=iterations,
96
+ target_probability=initial_prob,
97
+ amplified_probability=amplified_prob,
98
+ )
99
+
100
+ def create_oracle(
101
+ self,
102
+ n_qubits: int,
103
+ marked_states: list[int],
104
+ ) -> QuantumCircuit:
105
+ """
106
+ Create an oracle that marks specified states.
107
+
108
+ Args:
109
+ n_qubits: Number of qubits
110
+ marked_states: List of state indices to mark
111
+
112
+ Returns:
113
+ Oracle circuit applying phase flip to marked states
114
+ """
115
+ oracle = QuantumCircuit(n_qubits, name="oracle")
116
+
117
+ for state in marked_states:
118
+ # Convert state to binary and apply X gates for 0s
119
+ binary = format(state, f'0{n_qubits}b')
120
+
121
+ # Apply X to qubits that should be |0⟩
122
+ for i, bit in enumerate(reversed(binary)):
123
+ if bit == '0':
124
+ oracle.x(i)
125
+
126
+ # Multi-controlled Z
127
+ if n_qubits == 1:
128
+ oracle.z(0)
129
+ elif n_qubits == 2:
130
+ oracle.cz(0, 1)
131
+ else:
132
+ oracle.h(n_qubits - 1)
133
+ oracle.mcx(list(range(n_qubits - 1)), n_qubits - 1)
134
+ oracle.h(n_qubits - 1)
135
+
136
+ # Undo X gates
137
+ for i, bit in enumerate(reversed(binary)):
138
+ if bit == '0':
139
+ oracle.x(i)
140
+
141
+ return oracle
142
+
143
+ def _build_circuit(
144
+ self,
145
+ initial_state: QuantumCircuit,
146
+ oracle: QuantumCircuit,
147
+ n_qubits: int,
148
+ iterations: int,
149
+ ) -> QuantumCircuit:
150
+ """Build the full amplitude amplification circuit."""
151
+ circuit = QuantumCircuit(n_qubits, name="amplitude_amp")
152
+
153
+ # Apply initial state preparation
154
+ circuit.compose(initial_state, inplace=True)
155
+
156
+ # Grover iterations
157
+ diffuser = self._create_diffuser(n_qubits)
158
+
159
+ for _ in range(iterations):
160
+ # Oracle
161
+ circuit.compose(oracle, inplace=True)
162
+ # Diffuser
163
+ circuit.compose(diffuser, inplace=True)
164
+
165
+ return circuit
166
+
167
+ def _create_diffuser(self, n_qubits: int) -> QuantumCircuit:
168
+ """Create the Grover diffusion operator."""
169
+ diffuser = QuantumCircuit(n_qubits, name="diffuser")
170
+
171
+ # H gates
172
+ diffuser.h(range(n_qubits))
173
+
174
+ # X gates
175
+ diffuser.x(range(n_qubits))
176
+
177
+ # Multi-controlled Z
178
+ diffuser.h(n_qubits - 1)
179
+ if n_qubits > 1:
180
+ diffuser.mcx(list(range(n_qubits - 1)), n_qubits - 1)
181
+ diffuser.h(n_qubits - 1)
182
+
183
+ # X gates
184
+ diffuser.x(range(n_qubits))
185
+
186
+ # H gates
187
+ diffuser.h(range(n_qubits))
188
+
189
+ return diffuser
@@ -0,0 +1,133 @@
1
+ """
2
+ Quantum Fourier Transform Compression.
3
+
4
+ Uses QFT for frequency-domain compression of token sequences,
5
+ similar to classical DCT/FFT compression but with quantum speedup.
6
+ """
7
+
8
+ import math
9
+ from dataclasses import dataclass
10
+ from typing import Optional
11
+ import numpy as np
12
+ from qiskit import QuantumCircuit
13
+ from qiskit.circuit.library import QFT
14
+
15
+ from quantumflow.backends.base_backend import QuantumBackend, get_backend, BackendType
16
+
17
+
18
+ @dataclass
19
+ class QFTResult:
20
+ """Result from QFT compression."""
21
+
22
+ circuit: QuantumCircuit
23
+ n_qubits: int
24
+ kept_coefficients: int
25
+ total_coefficients: int
26
+ compression_ratio: float
27
+
28
+
29
+ class QFTCompression:
30
+ """
31
+ Quantum Fourier Transform based compression.
32
+
33
+ Compresses data by:
34
+ 1. Encoding data as quantum amplitudes
35
+ 2. Applying QFT to transform to frequency domain
36
+ 3. Truncating high-frequency components
37
+ 4. Storing only significant coefficients
38
+
39
+ Best for: Periodic or smoothly varying data.
40
+
41
+ Example:
42
+ >>> qft = QFTCompression()
43
+ >>> result = qft.compress([100, 110, 105, 115, 100, 108])
44
+ >>> print(f"Kept {result.kept_coefficients}/{result.total_coefficients}")
45
+ """
46
+
47
+ def __init__(
48
+ self,
49
+ backend: BackendType | str = BackendType.AUTO,
50
+ keep_ratio: float = 0.5,
51
+ ):
52
+ """
53
+ Initialize QFT compression.
54
+
55
+ Args:
56
+ backend: Quantum backend to use
57
+ keep_ratio: Fraction of frequency components to keep (0.0-1.0)
58
+ """
59
+ self.backend = get_backend(backend)
60
+ self.keep_ratio = keep_ratio
61
+
62
+ def compress(
63
+ self,
64
+ data: list[float],
65
+ n_qubits: Optional[int] = None,
66
+ ) -> QFTResult:
67
+ """
68
+ Compress data using QFT.
69
+
70
+ Args:
71
+ data: Input data to compress
72
+ n_qubits: Number of qubits (auto if None)
73
+
74
+ Returns:
75
+ QFTResult with circuit and metadata
76
+ """
77
+ if not data:
78
+ raise ValueError("Cannot compress empty data")
79
+
80
+ # Calculate qubits needed
81
+ if n_qubits is None:
82
+ n_qubits = max(2, math.ceil(math.log2(len(data))))
83
+
84
+ target_size = 2 ** n_qubits
85
+
86
+ # Normalize data to amplitudes
87
+ data_arr = np.array(data, dtype=float)
88
+ data_arr = np.pad(data_arr, (0, max(0, target_size - len(data_arr))))
89
+ data_arr = data_arr[:target_size]
90
+
91
+ norm = np.linalg.norm(data_arr)
92
+ if norm > 0:
93
+ amplitudes = data_arr / norm
94
+ else:
95
+ amplitudes = np.ones(target_size) / np.sqrt(target_size)
96
+
97
+ # Build circuit
98
+ circuit = self._build_qft_circuit(amplitudes, n_qubits)
99
+
100
+ kept = int(target_size * self.keep_ratio)
101
+ ratio = target_size / max(kept, 1)
102
+
103
+ return QFTResult(
104
+ circuit=circuit,
105
+ n_qubits=n_qubits,
106
+ kept_coefficients=kept,
107
+ total_coefficients=target_size,
108
+ compression_ratio=ratio,
109
+ )
110
+
111
+ def _build_qft_circuit(
112
+ self,
113
+ amplitudes: np.ndarray,
114
+ n_qubits: int,
115
+ ) -> QuantumCircuit:
116
+ """Build QFT compression circuit."""
117
+ qc = QuantumCircuit(n_qubits, name="qft_compress")
118
+
119
+ # Initialize with data
120
+ qc.initialize(amplitudes, range(n_qubits))
121
+
122
+ # Apply QFT
123
+ qft = QFT(n_qubits, do_swaps=True)
124
+ qc.append(qft, range(n_qubits))
125
+
126
+ return qc
127
+
128
+ def inverse_qft_circuit(self, n_qubits: int) -> QuantumCircuit:
129
+ """Get inverse QFT circuit for decompression."""
130
+ qc = QuantumCircuit(n_qubits, name="iqft")
131
+ qft_inv = QFT(n_qubits, do_swaps=True, inverse=True)
132
+ qc.append(qft_inv, range(n_qubits))
133
+ return qc
@@ -0,0 +1,261 @@
1
+ """
2
+ Token Compression Algorithm.
3
+
4
+ Enhanced version of Paper 1 compression with additional features:
5
+ - Adaptive qubit allocation
6
+ - Batch compression
7
+ - Streaming support
8
+ """
9
+
10
+ import math
11
+ from dataclasses import dataclass
12
+ from typing import Optional, Iterator
13
+ import numpy as np
14
+ from qiskit import QuantumCircuit
15
+
16
+ from quantumflow.backends.base_backend import QuantumBackend, get_backend, BackendType
17
+
18
+
19
+ @dataclass
20
+ class CompressionConfig:
21
+ """Configuration for token compression."""
22
+
23
+ min_compression_ratio: float = 1.5
24
+ max_qubits: int = 20
25
+ adaptive: bool = True
26
+ error_mitigation: bool = False
27
+
28
+
29
+ @dataclass
30
+ class CompressedBatch:
31
+ """A batch of compressed tokens."""
32
+
33
+ circuit: QuantumCircuit
34
+ original_size: int
35
+ compressed_size: int
36
+ batch_index: int
37
+ amplitudes: np.ndarray
38
+
39
+
40
+ class TokenCompression:
41
+ """
42
+ Advanced token compression using quantum amplitude encoding.
43
+
44
+ Features:
45
+ - Adaptive qubit allocation based on token distribution
46
+ - Batch processing for large token sequences
47
+ - Streaming compression for real-time applications
48
+
49
+ Example:
50
+ >>> tc = TokenCompression()
51
+ >>> result = tc.compress([100, 200, 300, 400])
52
+ >>> print(f"Ratio: {result.compression_ratio}x")
53
+ """
54
+
55
+ def __init__(
56
+ self,
57
+ backend: BackendType | str = BackendType.AUTO,
58
+ config: Optional[CompressionConfig] = None,
59
+ ):
60
+ self.backend = get_backend(backend)
61
+ self.config = config or CompressionConfig()
62
+ self._connected = False
63
+
64
+ def _ensure_connected(self):
65
+ if not self._connected:
66
+ self.backend.connect()
67
+ self._connected = True
68
+
69
+ def compress(
70
+ self,
71
+ tokens: list[int],
72
+ n_qubits: Optional[int] = None,
73
+ ) -> CompressedBatch:
74
+ """
75
+ Compress a list of tokens.
76
+
77
+ Args:
78
+ tokens: Integer tokens to compress
79
+ n_qubits: Override automatic qubit calculation
80
+
81
+ Returns:
82
+ CompressedBatch with circuit and metadata
83
+ """
84
+ if not tokens:
85
+ raise ValueError("Cannot compress empty token list")
86
+
87
+ # Calculate optimal qubits
88
+ if n_qubits is None:
89
+ n_qubits = self._calculate_qubits(tokens)
90
+
91
+ n_qubits = min(n_qubits, self.config.max_qubits)
92
+
93
+ # Normalize to amplitudes
94
+ amplitudes = self._tokens_to_amplitudes(tokens, n_qubits)
95
+
96
+ # Build circuit
97
+ circuit = self._build_circuit(amplitudes, n_qubits)
98
+
99
+ return CompressedBatch(
100
+ circuit=circuit,
101
+ original_size=len(tokens),
102
+ compressed_size=n_qubits,
103
+ batch_index=0,
104
+ amplitudes=amplitudes,
105
+ )
106
+
107
+ def compress_batch(
108
+ self,
109
+ tokens: list[int],
110
+ batch_size: int = 256,
111
+ ) -> list[CompressedBatch]:
112
+ """
113
+ Compress tokens in batches.
114
+
115
+ Args:
116
+ tokens: All tokens to compress
117
+ batch_size: Max tokens per batch (must be power of 2)
118
+
119
+ Returns:
120
+ List of CompressedBatch objects
121
+ """
122
+ # Ensure batch_size is power of 2
123
+ batch_size = 2 ** int(math.log2(batch_size))
124
+
125
+ batches = []
126
+ for i in range(0, len(tokens), batch_size):
127
+ batch_tokens = tokens[i:i + batch_size]
128
+ batch = self.compress(batch_tokens)
129
+ batch.batch_index = i // batch_size
130
+ batches.append(batch)
131
+
132
+ return batches
133
+
134
+ def compress_stream(
135
+ self,
136
+ token_iterator: Iterator[int],
137
+ buffer_size: int = 64,
138
+ ) -> Iterator[CompressedBatch]:
139
+ """
140
+ Stream compress tokens as they arrive.
141
+
142
+ Args:
143
+ token_iterator: Iterator yielding tokens
144
+ buffer_size: Tokens to buffer before compression
145
+
146
+ Yields:
147
+ CompressedBatch objects
148
+ """
149
+ buffer = []
150
+ batch_idx = 0
151
+
152
+ for token in token_iterator:
153
+ buffer.append(token)
154
+
155
+ if len(buffer) >= buffer_size:
156
+ batch = self.compress(buffer)
157
+ batch.batch_index = batch_idx
158
+ yield batch
159
+ buffer = []
160
+ batch_idx += 1
161
+
162
+ # Final batch
163
+ if buffer:
164
+ batch = self.compress(buffer)
165
+ batch.batch_index = batch_idx
166
+ yield batch
167
+
168
+ def decompress(
169
+ self,
170
+ batch: CompressedBatch,
171
+ shots: int = 1024,
172
+ ) -> list[int]:
173
+ """
174
+ Decompress a batch back to tokens.
175
+
176
+ Args:
177
+ batch: CompressedBatch to decompress
178
+ shots: Measurement shots for reconstruction
179
+
180
+ Returns:
181
+ Reconstructed token list
182
+ """
183
+ self._ensure_connected()
184
+
185
+ result = self.backend.execute(batch.circuit, shots=shots)
186
+
187
+ # Reconstruct from statevector if available
188
+ if result.statevector is not None:
189
+ probs = np.abs(result.statevector) ** 2
190
+ else:
191
+ # Reconstruct from measurement counts
192
+ probs = np.zeros(2 ** batch.compressed_size)
193
+ for state, count in result.counts.items():
194
+ idx = int(state, 2)
195
+ probs[idx] = count / shots
196
+
197
+ # Scale back to token range
198
+ # This is approximate - exact reconstruction requires statevector
199
+ max_prob = np.max(probs)
200
+ if max_prob > 0:
201
+ tokens = (probs[:batch.original_size] / max_prob * 255).astype(int)
202
+ else:
203
+ tokens = np.zeros(batch.original_size, dtype=int)
204
+
205
+ return tokens.tolist()
206
+
207
+ def _calculate_qubits(self, tokens: list[int]) -> int:
208
+ """Calculate optimal qubit count based on token distribution."""
209
+ n = len(tokens)
210
+ base_qubits = max(1, math.ceil(math.log2(n)))
211
+
212
+ if self.config.adaptive:
213
+ # Analyze token distribution
214
+ tokens_arr = np.array(tokens)
215
+ variance = np.var(tokens_arr)
216
+
217
+ # High variance = need more precision = more qubits
218
+ if variance > 1000:
219
+ base_qubits += 1
220
+
221
+ return base_qubits
222
+
223
+ def _tokens_to_amplitudes(
224
+ self,
225
+ tokens: list[int],
226
+ n_qubits: int,
227
+ ) -> np.ndarray:
228
+ """Convert tokens to normalized quantum amplitudes."""
229
+ target_size = 2 ** n_qubits
230
+
231
+ tokens_arr = np.array(tokens, dtype=float)
232
+ tokens_arr = np.maximum(tokens_arr, 1e-10)
233
+
234
+ # Pad to target size
235
+ if len(tokens_arr) < target_size:
236
+ tokens_arr = np.pad(
237
+ tokens_arr,
238
+ (0, target_size - len(tokens_arr)),
239
+ constant_values=1e-10
240
+ )
241
+ else:
242
+ tokens_arr = tokens_arr[:target_size]
243
+
244
+ # Normalize
245
+ norm = np.linalg.norm(tokens_arr)
246
+ return tokens_arr / norm if norm > 0 else tokens_arr
247
+
248
+ def _build_circuit(
249
+ self,
250
+ amplitudes: np.ndarray,
251
+ n_qubits: int,
252
+ ) -> QuantumCircuit:
253
+ """Build quantum circuit for amplitude encoding."""
254
+ qc = QuantumCircuit(n_qubits, name="token_compress")
255
+ qc.initialize(amplitudes, range(n_qubits))
256
+ return qc
257
+
258
+ @property
259
+ def compression_ratio(self) -> float:
260
+ """Expected compression ratio based on config."""
261
+ return self.config.min_compression_ratio
@@ -0,0 +1,6 @@
1
+ """Cryptography Algorithms."""
2
+
3
+ from quantumflow.algorithms.cryptography.qkd import QKD
4
+ from quantumflow.algorithms.cryptography.qrng import QRNG
5
+
6
+ __all__ = ["QKD", "QRNG"]