superquantx 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 (46) hide show
  1. superquantx/__init__.py +321 -0
  2. superquantx/algorithms/__init__.py +55 -0
  3. superquantx/algorithms/base_algorithm.py +413 -0
  4. superquantx/algorithms/hybrid_classifier.py +628 -0
  5. superquantx/algorithms/qaoa.py +406 -0
  6. superquantx/algorithms/quantum_agents.py +1006 -0
  7. superquantx/algorithms/quantum_kmeans.py +575 -0
  8. superquantx/algorithms/quantum_nn.py +544 -0
  9. superquantx/algorithms/quantum_pca.py +499 -0
  10. superquantx/algorithms/quantum_svm.py +346 -0
  11. superquantx/algorithms/vqe.py +553 -0
  12. superquantx/algorithms.py +863 -0
  13. superquantx/backends/__init__.py +265 -0
  14. superquantx/backends/base_backend.py +321 -0
  15. superquantx/backends/braket_backend.py +420 -0
  16. superquantx/backends/cirq_backend.py +466 -0
  17. superquantx/backends/ocean_backend.py +491 -0
  18. superquantx/backends/pennylane_backend.py +419 -0
  19. superquantx/backends/qiskit_backend.py +451 -0
  20. superquantx/backends/simulator_backend.py +455 -0
  21. superquantx/backends/tket_backend.py +519 -0
  22. superquantx/circuits.py +447 -0
  23. superquantx/cli/__init__.py +28 -0
  24. superquantx/cli/commands.py +528 -0
  25. superquantx/cli/main.py +254 -0
  26. superquantx/client.py +298 -0
  27. superquantx/config.py +326 -0
  28. superquantx/exceptions.py +287 -0
  29. superquantx/gates.py +588 -0
  30. superquantx/logging_config.py +347 -0
  31. superquantx/measurements.py +702 -0
  32. superquantx/ml.py +936 -0
  33. superquantx/noise.py +760 -0
  34. superquantx/utils/__init__.py +83 -0
  35. superquantx/utils/benchmarking.py +523 -0
  36. superquantx/utils/classical_utils.py +575 -0
  37. superquantx/utils/feature_mapping.py +467 -0
  38. superquantx/utils/optimization.py +410 -0
  39. superquantx/utils/quantum_utils.py +456 -0
  40. superquantx/utils/visualization.py +654 -0
  41. superquantx/version.py +33 -0
  42. superquantx-0.1.0.dist-info/METADATA +365 -0
  43. superquantx-0.1.0.dist-info/RECORD +46 -0
  44. superquantx-0.1.0.dist-info/WHEEL +4 -0
  45. superquantx-0.1.0.dist-info/entry_points.txt +2 -0
  46. superquantx-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,528 @@
1
+ """CLI commands for SuperQuantX.
2
+
3
+ This module implements individual CLI commands for various SuperQuantX operations
4
+ including algorithm execution, benchmarking, configuration, and system information.
5
+ """
6
+
7
+ import json
8
+ import sys
9
+ import time
10
+ from typing import Optional
11
+
12
+ import click
13
+ import numpy as np
14
+
15
+ import superquantx as sqx
16
+
17
+
18
+ @click.command()
19
+ def info():
20
+ """Show system and backend information."""
21
+ click.echo("SuperQuantX System Information")
22
+ click.echo("=" * 40)
23
+
24
+ # Basic info
25
+ click.echo(f"Version: {sqx.__version__}")
26
+ click.echo(f"Installation path: {sqx.__file__}")
27
+
28
+ # Backend information
29
+ click.echo("\\nAvailable Backends:")
30
+ backend_info = sqx.get_backend_info()
31
+
32
+ for backend_name, version in backend_info.items():
33
+ status = "✓" if version else "✗"
34
+ version_str = version if version else "Not installed"
35
+ click.echo(f" {status} {backend_name}: {version_str}")
36
+
37
+ # Configuration
38
+ config = sqx.config
39
+ click.echo("\\nCurrent Configuration:")
40
+ click.echo(f" Default backend: {config.get('default_backend', 'auto')}")
41
+ click.echo(f" Random seed: {config.get('random_seed', 42)}")
42
+ click.echo(f" Shots: {config.get('shots', 1024)}")
43
+
44
+ # Hardware info
45
+ try:
46
+ import psutil
47
+ click.echo("\\nSystem Resources:")
48
+ click.echo(f" CPU cores: {psutil.cpu_count()}")
49
+ click.echo(f" RAM: {psutil.virtual_memory().total / (1024**3):.1f} GB")
50
+ except ImportError:
51
+ pass
52
+
53
+
54
+ @click.command('list-algorithms')
55
+ @click.option(
56
+ '--category', '-c',
57
+ type=click.Choice(['all', 'classification', 'regression', 'clustering', 'optimization']),
58
+ default='all',
59
+ help='Algorithm category to list'
60
+ )
61
+ @click.option(
62
+ '--verbose', '-v',
63
+ is_flag=True,
64
+ help='Show detailed algorithm information'
65
+ )
66
+ def list_algorithms(category: str, verbose: bool):
67
+ """List available quantum algorithms."""
68
+ algorithms = {
69
+ 'classification': [
70
+ ('QuantumSVM', 'Quantum Support Vector Machine'),
71
+ ('QuantumNN', 'Quantum Neural Network'),
72
+ ('HybridClassifier', 'Hybrid Classical-Quantum Classifier')
73
+ ],
74
+ 'regression': [
75
+ ('QuantumNN', 'Quantum Neural Network (regression mode)')
76
+ ],
77
+ 'clustering': [
78
+ ('QuantumKMeans', 'Quantum K-Means Clustering'),
79
+ ('QuantumPCA', 'Quantum Principal Component Analysis')
80
+ ],
81
+ 'optimization': [
82
+ ('QAOA', 'Quantum Approximate Optimization Algorithm'),
83
+ ('VQE', 'Variational Quantum Eigensolver')
84
+ ]
85
+ }
86
+
87
+ click.echo("Available Quantum Algorithms")
88
+ click.echo("=" * 40)
89
+
90
+ categories_to_show = [category] if category != 'all' else list(algorithms.keys())
91
+
92
+ for cat in categories_to_show:
93
+ if cat in algorithms:
94
+ click.echo(f"\\n{cat.title()}:")
95
+
96
+ for alg_name, description in algorithms[cat]:
97
+ if verbose:
98
+ click.echo(f" • {alg_name}")
99
+ click.echo(f" {description}")
100
+
101
+ # Try to get algorithm class and show parameters
102
+ try:
103
+ alg_class = getattr(sqx.algorithms, alg_name)
104
+ # This is a simplified approach - real implementation would
105
+ # need to inspect the class properly
106
+ click.echo(f" Module: superquantx.algorithms.{alg_name}")
107
+ except AttributeError:
108
+ pass
109
+ click.echo()
110
+ else:
111
+ click.echo(f" • {alg_name}: {description}")
112
+
113
+
114
+ @click.command('list-backends')
115
+ @click.option(
116
+ '--available-only', '-a',
117
+ is_flag=True,
118
+ help='Show only installed backends'
119
+ )
120
+ def list_backends(available_only: bool):
121
+ """List quantum computing backends."""
122
+ backends = {
123
+ 'Local Simulators': [
124
+ ('simulator', 'SuperQuantX built-in simulator'),
125
+ ('pennylane_local', 'PennyLane local simulators'),
126
+ ('qiskit_aer', 'Qiskit Aer simulator')
127
+ ],
128
+ 'Cloud Simulators': [
129
+ ('pennylane_cloud', 'PennyLane cloud devices'),
130
+ ('qiskit_ibm', 'IBM Quantum simulators'),
131
+ ('braket_sv1', 'AWS Braket SV1 simulator'),
132
+ ('cirq_cloud', 'Google Cirq cloud simulators')
133
+ ],
134
+ 'Quantum Hardware': [
135
+ ('ibm_quantum', 'IBM Quantum hardware'),
136
+ ('braket_hardware', 'AWS Braket hardware access'),
137
+ ('azure_quantum', 'Azure Quantum hardware'),
138
+ ('rigetti_qcs', 'Rigetti Quantum Cloud Services')
139
+ ]
140
+ }
141
+
142
+ backend_info = sqx.get_backend_info()
143
+
144
+ click.echo("Quantum Computing Backends")
145
+ click.echo("=" * 40)
146
+
147
+ for category, backend_list in backends.items():
148
+ click.echo(f"\\n{category}:")
149
+
150
+ for backend_name, description in backend_list:
151
+ # Check if backend is available (simplified logic)
152
+ is_available = any(info for info in backend_info.values())
153
+
154
+ if available_only and not is_available:
155
+ continue
156
+
157
+ status = "✓" if is_available else "✗"
158
+ click.echo(f" {status} {backend_name}: {description}")
159
+
160
+
161
+ @click.command('run')
162
+ @click.argument('algorithm')
163
+ @click.option(
164
+ '--data', '-d',
165
+ default='iris',
166
+ help='Dataset to use (iris, wine, digits, synthetic)'
167
+ )
168
+ @click.option(
169
+ '--backend', '-b',
170
+ default='auto',
171
+ help='Quantum backend to use'
172
+ )
173
+ @click.option(
174
+ '--output', '-o',
175
+ type=click.Path(),
176
+ help='Output file for results'
177
+ )
178
+ @click.option(
179
+ '--config-file', '-c',
180
+ type=click.Path(exists=True),
181
+ help='Algorithm configuration file'
182
+ )
183
+ @click.option(
184
+ '--verbose', '-v',
185
+ is_flag=True,
186
+ help='Enable verbose output'
187
+ )
188
+ def run_algorithm(
189
+ algorithm: str,
190
+ data: str,
191
+ backend: str,
192
+ output: Optional[str],
193
+ config_file: Optional[str],
194
+ verbose: bool
195
+ ):
196
+ """Run a quantum algorithm on specified dataset."""
197
+ if verbose:
198
+ click.echo(f"Running {algorithm} on {data} dataset using {backend} backend")
199
+
200
+ try:
201
+ # Load dataset
202
+ if data == 'iris':
203
+ X_train, X_test, y_train, y_test, metadata = sqx.datasets.load_iris_quantum()
204
+ elif data == 'wine':
205
+ X_train, X_test, y_train, y_test, metadata = sqx.datasets.load_wine_quantum()
206
+ elif data == 'synthetic':
207
+ X_train, X_test, y_train, y_test, metadata = sqx.datasets.generate_classification_data()
208
+ else:
209
+ click.echo(f"Unknown dataset: {data}", err=True)
210
+ sys.exit(1)
211
+
212
+ if verbose:
213
+ click.echo(f"Loaded {metadata['dataset_name']} dataset")
214
+ click.echo(f"Training samples: {len(X_train)}")
215
+ click.echo(f"Features: {metadata['n_features']}")
216
+
217
+ # Load configuration
218
+ config = {}
219
+ if config_file:
220
+ with open(config_file) as f:
221
+ config = json.load(f)
222
+
223
+ # Create algorithm
224
+ algorithm_map = {
225
+ 'qsvm': sqx.QuantumSVM,
226
+ 'qaoa': sqx.QAOA,
227
+ 'vqe': sqx.VQE,
228
+ 'qnn': sqx.QuantumNN,
229
+ 'qkmeans': sqx.QuantumKMeans,
230
+ 'qpca': sqx.QuantumPCA
231
+ }
232
+
233
+ if algorithm.lower() not in algorithm_map:
234
+ click.echo(f"Unknown algorithm: {algorithm}", err=True)
235
+ click.echo(f"Available: {list(algorithm_map.keys())}")
236
+ sys.exit(1)
237
+
238
+ AlgorithmClass = algorithm_map[algorithm.lower()]
239
+
240
+ # Set backend
241
+ config['backend'] = backend
242
+
243
+ alg = AlgorithmClass(**config)
244
+
245
+ if verbose:
246
+ click.echo(f"Created {AlgorithmClass.__name__} with config: {config}")
247
+
248
+ # Train
249
+ click.echo("Training...")
250
+ start_time = time.time()
251
+
252
+ alg.fit(X_train, y_train)
253
+
254
+ training_time = time.time() - start_time
255
+
256
+ # Predict
257
+ click.echo("Evaluating...")
258
+ y_pred = alg.predict(X_test)
259
+
260
+ # Calculate metrics
261
+ accuracy = np.mean(y_pred == y_test)
262
+
263
+ # Results
264
+ results = {
265
+ 'algorithm': AlgorithmClass.__name__,
266
+ 'dataset': metadata['dataset_name'],
267
+ 'backend': backend,
268
+ 'accuracy': float(accuracy),
269
+ 'training_time': training_time,
270
+ 'n_train_samples': len(X_train),
271
+ 'n_test_samples': len(X_test),
272
+ 'n_features': metadata['n_features']
273
+ }
274
+
275
+ # Output results
276
+ click.echo("\\nResults:")
277
+ click.echo(f"Accuracy: {accuracy:.4f}")
278
+ click.echo(f"Training time: {training_time:.2f}s")
279
+
280
+ if output:
281
+ with open(output, 'w') as f:
282
+ json.dump(results, f, indent=2)
283
+ click.echo(f"Results saved to {output}")
284
+
285
+ if verbose:
286
+ click.echo(f"Full results: {results}")
287
+
288
+ except Exception as e:
289
+ click.echo(f"Error running algorithm: {e}", err=True)
290
+ if verbose:
291
+ import traceback
292
+ traceback.print_exc()
293
+ sys.exit(1)
294
+
295
+
296
+ @click.command()
297
+ @click.option(
298
+ '--algorithms', '-a',
299
+ default='qsvm,qnn',
300
+ help='Comma-separated list of algorithms to benchmark'
301
+ )
302
+ @click.option(
303
+ '--datasets', '-d',
304
+ default='iris,wine',
305
+ help='Comma-separated list of datasets'
306
+ )
307
+ @click.option(
308
+ '--backends', '-b',
309
+ default='simulator',
310
+ help='Comma-separated list of backends'
311
+ )
312
+ @click.option(
313
+ '--output', '-o',
314
+ type=click.Path(),
315
+ default='benchmark_results.json',
316
+ help='Output file for benchmark results'
317
+ )
318
+ @click.option(
319
+ '--runs', '-r',
320
+ default=3,
321
+ help='Number of runs for averaging'
322
+ )
323
+ def benchmark(
324
+ algorithms: str,
325
+ datasets: str,
326
+ backends: str,
327
+ output: str,
328
+ runs: int
329
+ ):
330
+ """Benchmark algorithms across datasets and backends."""
331
+ alg_list = algorithms.split(',')
332
+ dataset_list = datasets.split(',')
333
+ backend_list = backends.split(',')
334
+
335
+ click.echo("SuperQuantX Benchmark")
336
+ click.echo("=" * 30)
337
+ click.echo(f"Algorithms: {alg_list}")
338
+ click.echo(f"Datasets: {dataset_list}")
339
+ click.echo(f"Backends: {backend_list}")
340
+ click.echo(f"Runs per combination: {runs}")
341
+ click.echo()
342
+
343
+ results = []
344
+ total_combinations = len(alg_list) * len(dataset_list) * len(backend_list)
345
+ current = 0
346
+
347
+ for algorithm in alg_list:
348
+ for dataset in dataset_list:
349
+ for backend in backend_list:
350
+ current += 1
351
+ click.echo(f"[{current}/{total_combinations}] {algorithm} on {dataset} with {backend}")
352
+
353
+ try:
354
+ # This would call the actual benchmark function
355
+ # For now, simulate results
356
+ result = {
357
+ 'algorithm': algorithm,
358
+ 'dataset': dataset,
359
+ 'backend': backend,
360
+ 'accuracy': np.random.uniform(0.7, 0.95),
361
+ 'execution_time': np.random.uniform(1.0, 10.0),
362
+ 'success': True
363
+ }
364
+ results.append(result)
365
+
366
+ click.echo(f" Accuracy: {result['accuracy']:.4f}")
367
+ click.echo(f" Time: {result['execution_time']:.2f}s")
368
+
369
+ except Exception as e:
370
+ click.echo(f" Failed: {e}")
371
+ results.append({
372
+ 'algorithm': algorithm,
373
+ 'dataset': dataset,
374
+ 'backend': backend,
375
+ 'success': False,
376
+ 'error': str(e)
377
+ })
378
+
379
+ # Save results
380
+ with open(output, 'w') as f:
381
+ json.dump(results, f, indent=2)
382
+
383
+ click.echo(f"\\nBenchmark complete. Results saved to {output}")
384
+
385
+
386
+ @click.command()
387
+ @click.option(
388
+ '--backend', '-b',
389
+ help='Set default backend'
390
+ )
391
+ @click.option(
392
+ '--shots', '-s',
393
+ type=int,
394
+ help='Set default number of shots'
395
+ )
396
+ @click.option(
397
+ '--seed',
398
+ type=int,
399
+ help='Set random seed'
400
+ )
401
+ @click.option(
402
+ '--show',
403
+ is_flag=True,
404
+ help='Show current configuration'
405
+ )
406
+ def configure(backend: Optional[str], shots: Optional[int], seed: Optional[int], show: bool):
407
+ """Configure SuperQuantX settings."""
408
+ if show:
409
+ click.echo("Current SuperQuantX Configuration:")
410
+ click.echo("=" * 40)
411
+ config = sqx.config
412
+ for key, value in config.items():
413
+ click.echo(f"{key}: {value}")
414
+ return
415
+
416
+ # Update configuration
417
+ config_updates = {}
418
+ if backend:
419
+ config_updates['default_backend'] = backend
420
+ click.echo(f"Set default backend to: {backend}")
421
+
422
+ if shots:
423
+ config_updates['shots'] = shots
424
+ click.echo(f"Set default shots to: {shots}")
425
+
426
+ if seed:
427
+ config_updates['random_seed'] = seed
428
+ click.echo(f"Set random seed to: {seed}")
429
+
430
+ if config_updates:
431
+ sqx.configure(**config_updates)
432
+ click.echo("Configuration updated successfully")
433
+ else:
434
+ click.echo("No configuration changes specified")
435
+
436
+
437
+ @click.command('create-dataset')
438
+ @click.argument('dataset_type', type=click.Choice(['classification', 'regression', 'clustering']))
439
+ @click.option(
440
+ '--samples', '-n',
441
+ default=200,
442
+ help='Number of samples to generate'
443
+ )
444
+ @click.option(
445
+ '--features', '-f',
446
+ default=4,
447
+ help='Number of features'
448
+ )
449
+ @click.option(
450
+ '--output', '-o',
451
+ type=click.Path(),
452
+ help='Output file (NPZ format)'
453
+ )
454
+ def create_dataset(dataset_type: str, samples: int, features: int, output: Optional[str]):
455
+ """Create synthetic datasets for testing."""
456
+ if dataset_type == 'classification':
457
+ X_train, X_test, y_train, y_test, metadata = sqx.datasets.generate_classification_data(
458
+ n_samples=samples,
459
+ n_features=features
460
+ )
461
+ elif dataset_type == 'regression':
462
+ X_train, X_test, y_train, y_test, metadata = sqx.datasets.generate_regression_data(
463
+ n_samples=samples,
464
+ n_features=features
465
+ )
466
+ elif dataset_type == 'clustering':
467
+ X, y_true, metadata = sqx.datasets.generate_clustering_data(
468
+ n_samples=samples,
469
+ n_features=features
470
+ )
471
+ # For clustering, no train/test split
472
+ X_train, X_test, y_train, y_test = X, X, y_true, y_true
473
+
474
+ click.echo(f"Created {dataset_type} dataset:")
475
+ click.echo(f" Samples: {samples}")
476
+ click.echo(f" Features: {features}")
477
+ click.echo(f" Training set: {len(X_train)}")
478
+ click.echo(f" Test set: {len(X_test)}")
479
+
480
+ if output:
481
+ np.savez(
482
+ output,
483
+ X_train=X_train,
484
+ X_test=X_test,
485
+ y_train=y_train,
486
+ y_test=y_test,
487
+ metadata=metadata
488
+ )
489
+ click.echo(f"Dataset saved to: {output}")
490
+
491
+
492
+ @click.command()
493
+ @click.argument('results_file', type=click.Path(exists=True))
494
+ @click.option(
495
+ '--plot-type', '-p',
496
+ type=click.Choice(['optimization', 'classification', 'regression']),
497
+ default='optimization',
498
+ help='Type of plot to generate'
499
+ )
500
+ @click.option(
501
+ '--output', '-o',
502
+ type=click.Path(),
503
+ help='Output file for plot'
504
+ )
505
+ def visualize(results_file: str, plot_type: str, output: Optional[str]):
506
+ """Visualize algorithm results."""
507
+ # Load results
508
+ with open(results_file) as f:
509
+ results = json.load(f)
510
+
511
+ click.echo(f"Visualizing results from {results_file}")
512
+ click.echo(f"Plot type: {plot_type}")
513
+
514
+ try:
515
+ sqx.visualize_results(
516
+ results,
517
+ plot_type=plot_type,
518
+ save_path=output
519
+ )
520
+
521
+ if output:
522
+ click.echo(f"Plot saved to: {output}")
523
+ else:
524
+ click.echo("Plot displayed")
525
+
526
+ except Exception as e:
527
+ click.echo(f"Error creating visualization: {e}", err=True)
528
+ sys.exit(1)