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.
- superquantx/__init__.py +321 -0
- superquantx/algorithms/__init__.py +55 -0
- superquantx/algorithms/base_algorithm.py +413 -0
- superquantx/algorithms/hybrid_classifier.py +628 -0
- superquantx/algorithms/qaoa.py +406 -0
- superquantx/algorithms/quantum_agents.py +1006 -0
- superquantx/algorithms/quantum_kmeans.py +575 -0
- superquantx/algorithms/quantum_nn.py +544 -0
- superquantx/algorithms/quantum_pca.py +499 -0
- superquantx/algorithms/quantum_svm.py +346 -0
- superquantx/algorithms/vqe.py +553 -0
- superquantx/algorithms.py +863 -0
- superquantx/backends/__init__.py +265 -0
- superquantx/backends/base_backend.py +321 -0
- superquantx/backends/braket_backend.py +420 -0
- superquantx/backends/cirq_backend.py +466 -0
- superquantx/backends/ocean_backend.py +491 -0
- superquantx/backends/pennylane_backend.py +419 -0
- superquantx/backends/qiskit_backend.py +451 -0
- superquantx/backends/simulator_backend.py +455 -0
- superquantx/backends/tket_backend.py +519 -0
- superquantx/circuits.py +447 -0
- superquantx/cli/__init__.py +28 -0
- superquantx/cli/commands.py +528 -0
- superquantx/cli/main.py +254 -0
- superquantx/client.py +298 -0
- superquantx/config.py +326 -0
- superquantx/exceptions.py +287 -0
- superquantx/gates.py +588 -0
- superquantx/logging_config.py +347 -0
- superquantx/measurements.py +702 -0
- superquantx/ml.py +936 -0
- superquantx/noise.py +760 -0
- superquantx/utils/__init__.py +83 -0
- superquantx/utils/benchmarking.py +523 -0
- superquantx/utils/classical_utils.py +575 -0
- superquantx/utils/feature_mapping.py +467 -0
- superquantx/utils/optimization.py +410 -0
- superquantx/utils/quantum_utils.py +456 -0
- superquantx/utils/visualization.py +654 -0
- superquantx/version.py +33 -0
- superquantx-0.1.0.dist-info/METADATA +365 -0
- superquantx-0.1.0.dist-info/RECORD +46 -0
- superquantx-0.1.0.dist-info/WHEEL +4 -0
- superquantx-0.1.0.dist-info/entry_points.txt +2 -0
- superquantx-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,451 @@
|
|
1
|
+
"""Qiskit backend implementation for SuperQuantX.
|
2
|
+
|
3
|
+
This module provides integration with IBM's Qiskit for quantum computing
|
4
|
+
operations and access to IBM Quantum hardware.
|
5
|
+
"""
|
6
|
+
|
7
|
+
import logging
|
8
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
9
|
+
|
10
|
+
import numpy as np
|
11
|
+
|
12
|
+
from .base_backend import BaseBackend
|
13
|
+
|
14
|
+
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from qiskit import QuantumCircuit
|
17
|
+
|
18
|
+
logger = logging.getLogger(__name__)
|
19
|
+
|
20
|
+
# Try to import Qiskit
|
21
|
+
try:
|
22
|
+
from qiskit import (
|
23
|
+
Aer,
|
24
|
+
ClassicalRegister,
|
25
|
+
QuantumCircuit,
|
26
|
+
QuantumRegister,
|
27
|
+
execute,
|
28
|
+
transpile,
|
29
|
+
)
|
30
|
+
from qiskit.algorithms.optimizers import COBYLA, L_BFGS_B
|
31
|
+
from qiskit.circuit.library import EfficientSU2, RealAmplitudes, ZZFeatureMap
|
32
|
+
from qiskit.providers.aer import AerSimulator
|
33
|
+
from qiskit.quantum_info import Statevector
|
34
|
+
QISKIT_AVAILABLE = True
|
35
|
+
|
36
|
+
# Try to import IBM Quantum provider
|
37
|
+
try:
|
38
|
+
from qiskit import IBMQ
|
39
|
+
from qiskit.providers.ibmq import IBMQBackend
|
40
|
+
IBMQ_AVAILABLE = True
|
41
|
+
except ImportError:
|
42
|
+
IBMQ_AVAILABLE = False
|
43
|
+
IBMQ = None
|
44
|
+
IBMQBackend = None
|
45
|
+
|
46
|
+
except ImportError:
|
47
|
+
QISKIT_AVAILABLE = False
|
48
|
+
QuantumCircuit = None
|
49
|
+
Aer = None
|
50
|
+
AerSimulator = None
|
51
|
+
Statevector = None
|
52
|
+
|
53
|
+
class QiskitBackend(BaseBackend):
|
54
|
+
"""Qiskit backend for quantum computing operations.
|
55
|
+
|
56
|
+
This backend provides access to Qiskit simulators and IBM Quantum
|
57
|
+
hardware for quantum algorithm execution.
|
58
|
+
|
59
|
+
Args:
|
60
|
+
device: Qiskit backend name ('aer_simulator', 'ibmq_qasm_simulator', etc.)
|
61
|
+
provider: IBM Quantum provider (if using IBMQ)
|
62
|
+
shots: Number of measurement shots
|
63
|
+
**kwargs: Additional backend parameters
|
64
|
+
|
65
|
+
"""
|
66
|
+
|
67
|
+
def __init__(self, device: str = 'aer_simulator', provider: Optional[str] = None,
|
68
|
+
shots: int = 1024, **kwargs):
|
69
|
+
if not QISKIT_AVAILABLE:
|
70
|
+
raise ImportError("Qiskit is required for QiskitBackend. Install with: pip install qiskit")
|
71
|
+
|
72
|
+
super().__init__(device=device, shots=shots, **kwargs)
|
73
|
+
|
74
|
+
self.provider = provider
|
75
|
+
self.backend = None
|
76
|
+
self.capabilities = {
|
77
|
+
'supports_gradient': False,
|
78
|
+
'supports_parameter_shift': True,
|
79
|
+
'supports_finite_diff': True,
|
80
|
+
'supports_hardware': IBMQ_AVAILABLE,
|
81
|
+
'supports_noise_models': True,
|
82
|
+
}
|
83
|
+
|
84
|
+
def _initialize_backend(self) -> None:
|
85
|
+
"""Initialize Qiskit backend."""
|
86
|
+
try:
|
87
|
+
if self.device == 'aer_simulator':
|
88
|
+
self.backend = AerSimulator()
|
89
|
+
logger.info("Initialized Qiskit AerSimulator")
|
90
|
+
|
91
|
+
elif self.device.startswith('ibmq_') or self.provider:
|
92
|
+
if not IBMQ_AVAILABLE:
|
93
|
+
raise ImportError("IBM Quantum provider not available")
|
94
|
+
|
95
|
+
# Load IBMQ account
|
96
|
+
if not IBMQ.active_account():
|
97
|
+
try:
|
98
|
+
IBMQ.load_account()
|
99
|
+
except Exception as e:
|
100
|
+
logger.error(f"Failed to load IBMQ account: {e}")
|
101
|
+
raise
|
102
|
+
|
103
|
+
# Get provider
|
104
|
+
if self.provider:
|
105
|
+
provider = IBMQ.get_provider(hub=self.provider.get('hub', 'ibm-q'),
|
106
|
+
group=self.provider.get('group', 'open'),
|
107
|
+
project=self.provider.get('project', 'main'))
|
108
|
+
else:
|
109
|
+
provider = IBMQ.get_provider()
|
110
|
+
|
111
|
+
# Get backend
|
112
|
+
self.backend = provider.get_backend(self.device)
|
113
|
+
logger.info(f"Initialized IBM Quantum backend: {self.device}")
|
114
|
+
|
115
|
+
else:
|
116
|
+
# Try to get backend from Aer
|
117
|
+
self.backend = Aer.get_backend(self.device)
|
118
|
+
logger.info(f"Initialized Aer backend: {self.device}")
|
119
|
+
|
120
|
+
except Exception as e:
|
121
|
+
logger.error(f"Failed to initialize Qiskit backend: {e}")
|
122
|
+
# Fallback to simulator
|
123
|
+
self.backend = AerSimulator()
|
124
|
+
logger.warning("Falling back to AerSimulator")
|
125
|
+
|
126
|
+
def create_circuit(self, n_qubits: int) -> Any:
|
127
|
+
"""Create a quantum circuit with n qubits."""
|
128
|
+
qreg = QuantumRegister(n_qubits, 'q')
|
129
|
+
creg = ClassicalRegister(n_qubits, 'c')
|
130
|
+
circuit = QuantumCircuit(qreg, creg)
|
131
|
+
return circuit
|
132
|
+
|
133
|
+
def add_gate(self, circuit: Any, gate: str, qubits: Union[int, List[int]],
|
134
|
+
params: Optional[List[float]] = None) -> Any:
|
135
|
+
"""Add a quantum gate to the circuit."""
|
136
|
+
if isinstance(qubits, int):
|
137
|
+
qubits = [qubits]
|
138
|
+
|
139
|
+
params = params or []
|
140
|
+
|
141
|
+
try:
|
142
|
+
if gate.upper() == 'H' or gate.upper() == 'HADAMARD':
|
143
|
+
circuit.h(qubits[0])
|
144
|
+
elif gate.upper() == 'X' or gate.upper() == 'PAULI_X':
|
145
|
+
circuit.x(qubits[0])
|
146
|
+
elif gate.upper() == 'Y' or gate.upper() == 'PAULI_Y':
|
147
|
+
circuit.y(qubits[0])
|
148
|
+
elif gate.upper() == 'Z' or gate.upper() == 'PAULI_Z':
|
149
|
+
circuit.z(qubits[0])
|
150
|
+
elif gate.upper() == 'RX':
|
151
|
+
circuit.rx(params[0] if params else 0, qubits[0])
|
152
|
+
elif gate.upper() == 'RY':
|
153
|
+
circuit.ry(params[0] if params else 0, qubits[0])
|
154
|
+
elif gate.upper() == 'RZ':
|
155
|
+
circuit.rz(params[0] if params else 0, qubits[0])
|
156
|
+
elif gate.upper() == 'CNOT' or gate.upper() == 'CX':
|
157
|
+
circuit.cx(qubits[0], qubits[1])
|
158
|
+
elif gate.upper() == 'CZ':
|
159
|
+
circuit.cz(qubits[0], qubits[1])
|
160
|
+
elif gate.upper() == 'SWAP':
|
161
|
+
circuit.swap(qubits[0], qubits[1])
|
162
|
+
elif gate.upper() == 'CCX' or gate.upper() == 'TOFFOLI':
|
163
|
+
circuit.ccx(qubits[0], qubits[1], qubits[2])
|
164
|
+
else:
|
165
|
+
logger.warning(f"Unknown gate: {gate}")
|
166
|
+
|
167
|
+
except Exception as e:
|
168
|
+
logger.error(f"Failed to add gate {gate}: {e}")
|
169
|
+
|
170
|
+
return circuit
|
171
|
+
|
172
|
+
def add_measurement(self, circuit: Any, qubits: Optional[List[int]] = None) -> Any:
|
173
|
+
"""Add measurement operations to the circuit."""
|
174
|
+
if qubits is None:
|
175
|
+
qubits = list(range(circuit.num_qubits))
|
176
|
+
|
177
|
+
for i, qubit in enumerate(qubits):
|
178
|
+
if i < circuit.num_clbits:
|
179
|
+
circuit.measure(qubit, i)
|
180
|
+
|
181
|
+
return circuit
|
182
|
+
|
183
|
+
def execute_circuit(self, circuit: Any, shots: Optional[int] = None) -> Dict[str, Any]:
|
184
|
+
"""Execute quantum circuit and return results."""
|
185
|
+
shots = shots or self.shots
|
186
|
+
|
187
|
+
try:
|
188
|
+
# Add measurements if not present
|
189
|
+
if circuit.num_clbits == 0 or not any(isinstance(instr.operation,
|
190
|
+
type(circuit.measure(0, 0).operation))
|
191
|
+
for instr in circuit):
|
192
|
+
circuit.add_register(ClassicalRegister(circuit.num_qubits, 'c'))
|
193
|
+
circuit.measure_all()
|
194
|
+
|
195
|
+
# Transpile circuit
|
196
|
+
transpiled = transpile(circuit, self.backend)
|
197
|
+
|
198
|
+
# Execute
|
199
|
+
job = execute(transpiled, self.backend, shots=shots)
|
200
|
+
result = job.result()
|
201
|
+
|
202
|
+
# Get counts
|
203
|
+
counts = result.get_counts()
|
204
|
+
|
205
|
+
return {
|
206
|
+
'counts': counts,
|
207
|
+
'shots': shots,
|
208
|
+
'backend': self.device,
|
209
|
+
'job_id': job.job_id(),
|
210
|
+
}
|
211
|
+
|
212
|
+
except Exception as e:
|
213
|
+
logger.error(f"Circuit execution failed: {e}")
|
214
|
+
raise
|
215
|
+
|
216
|
+
def get_statevector(self, circuit: Any) -> np.ndarray:
|
217
|
+
"""Get the statevector from a quantum circuit."""
|
218
|
+
try:
|
219
|
+
# Use statevector simulator
|
220
|
+
backend = AerSimulator(method='statevector')
|
221
|
+
|
222
|
+
# Create circuit copy without measurements
|
223
|
+
circuit_copy = circuit.copy()
|
224
|
+
circuit_copy.remove_final_measurements()
|
225
|
+
|
226
|
+
# Execute
|
227
|
+
job = execute(circuit_copy, backend, shots=1)
|
228
|
+
result = job.result()
|
229
|
+
|
230
|
+
# Get statevector
|
231
|
+
statevector = result.get_statevector()
|
232
|
+
return np.array(statevector.data)
|
233
|
+
|
234
|
+
except Exception as e:
|
235
|
+
logger.error(f"Statevector computation failed: {e}")
|
236
|
+
return np.array([1.0] + [0.0] * (2**circuit.num_qubits - 1))
|
237
|
+
|
238
|
+
def _get_n_qubits(self, circuit: Any) -> int:
|
239
|
+
"""Get number of qubits in circuit."""
|
240
|
+
return circuit.num_qubits
|
241
|
+
|
242
|
+
# ========================================================================
|
243
|
+
# Enhanced Qiskit-specific implementations
|
244
|
+
# ========================================================================
|
245
|
+
|
246
|
+
def create_feature_map(self, n_features: int, feature_map: str, reps: int = 1) -> Any:
|
247
|
+
"""Create quantum feature map for data encoding."""
|
248
|
+
if feature_map == 'ZZFeatureMap':
|
249
|
+
return ZZFeatureMap(n_features, reps=reps)
|
250
|
+
elif feature_map == 'PauliFeatureMap':
|
251
|
+
return self._create_pauli_feature_map(n_features, reps)
|
252
|
+
elif feature_map == 'AmplitudeMap':
|
253
|
+
return self._create_amplitude_map(n_features)
|
254
|
+
else:
|
255
|
+
logger.warning(f"Unknown feature map '{feature_map}', using angle encoding")
|
256
|
+
return self._create_angle_encoding_map(n_features)
|
257
|
+
|
258
|
+
def _create_pauli_feature_map(self, n_features: int, reps: int) -> Any:
|
259
|
+
"""Create Pauli feature map circuit."""
|
260
|
+
circuit = QuantumCircuit(n_features)
|
261
|
+
|
262
|
+
for r in range(reps):
|
263
|
+
# Pauli rotations
|
264
|
+
for i in range(n_features):
|
265
|
+
circuit.rx(circuit.parameters[0], i) # Placeholder parameter
|
266
|
+
circuit.ry(circuit.parameters[0], i)
|
267
|
+
circuit.rz(circuit.parameters[0], i)
|
268
|
+
|
269
|
+
# Entangling layer
|
270
|
+
for i in range(n_features - 1):
|
271
|
+
circuit.cx(i, i + 1)
|
272
|
+
|
273
|
+
return circuit
|
274
|
+
|
275
|
+
def _create_amplitude_map(self, n_features: int) -> Any:
|
276
|
+
"""Create amplitude encoding map."""
|
277
|
+
n_qubits = int(np.ceil(np.log2(n_features)))
|
278
|
+
circuit = QuantumCircuit(n_qubits)
|
279
|
+
|
280
|
+
# Amplitude encoding would require state initialization
|
281
|
+
# This is a simplified placeholder
|
282
|
+
logger.warning("Amplitude encoding not fully implemented")
|
283
|
+
|
284
|
+
return circuit
|
285
|
+
|
286
|
+
def _create_angle_encoding_map(self, n_features: int) -> Any:
|
287
|
+
"""Create angle encoding map."""
|
288
|
+
circuit = QuantumCircuit(n_features)
|
289
|
+
|
290
|
+
for i in range(n_features):
|
291
|
+
circuit.ry(circuit.parameters[0], i) # Placeholder parameter
|
292
|
+
|
293
|
+
return circuit
|
294
|
+
|
295
|
+
def compute_kernel_matrix(self, X1: np.ndarray, X2: np.ndarray,
|
296
|
+
feature_map: QuantumCircuit, shots: Optional[int] = None) -> np.ndarray:
|
297
|
+
"""Compute quantum kernel matrix using Qiskit."""
|
298
|
+
n1, n2 = len(X1), len(X2)
|
299
|
+
kernel_matrix = np.zeros((n1, n2))
|
300
|
+
|
301
|
+
for i in range(n1):
|
302
|
+
for j in range(n2):
|
303
|
+
try:
|
304
|
+
# Create kernel evaluation circuit
|
305
|
+
circuit = QuantumCircuit(feature_map.num_qubits, feature_map.num_qubits)
|
306
|
+
|
307
|
+
# Encode first data point
|
308
|
+
circuit.compose(feature_map.bind_parameters(X1[i]), inplace=True)
|
309
|
+
|
310
|
+
# Encode second data point with inverse
|
311
|
+
inverse_map = feature_map.bind_parameters(-X2[j]).inverse()
|
312
|
+
circuit.compose(inverse_map, inplace=True)
|
313
|
+
|
314
|
+
# Measure
|
315
|
+
circuit.measure_all()
|
316
|
+
|
317
|
+
# Execute
|
318
|
+
result = self.execute_circuit(circuit, shots)
|
319
|
+
counts = result['counts']
|
320
|
+
|
321
|
+
# Kernel value is probability of measuring |00...0⟩
|
322
|
+
zero_state = '0' * feature_map.num_qubits
|
323
|
+
kernel_matrix[i, j] = counts.get(zero_state, 0) / sum(counts.values())
|
324
|
+
|
325
|
+
except Exception as e:
|
326
|
+
logger.warning(f"Kernel computation failed for ({i},{j}): {e}")
|
327
|
+
kernel_matrix[i, j] = 0.0
|
328
|
+
|
329
|
+
return kernel_matrix
|
330
|
+
|
331
|
+
def create_ansatz(self, ansatz_type: str, n_qubits: int, params: np.ndarray,
|
332
|
+
include_custom_gates: bool = False) -> Any:
|
333
|
+
"""Create parameterized ansatz circuit."""
|
334
|
+
if ansatz_type == 'RealAmplitudes':
|
335
|
+
return RealAmplitudes(n_qubits, reps=len(params) // (n_qubits * 2))
|
336
|
+
elif ansatz_type == 'EfficientSU2':
|
337
|
+
return EfficientSU2(n_qubits, reps=len(params) // (n_qubits * 3))
|
338
|
+
elif ansatz_type == 'TwoLocal':
|
339
|
+
return self._create_two_local_ansatz(n_qubits, params)
|
340
|
+
elif ansatz_type == 'UCCSD':
|
341
|
+
return self._create_uccsd_ansatz(n_qubits, params)
|
342
|
+
else:
|
343
|
+
logger.warning(f"Unknown ansatz '{ansatz_type}', using RealAmplitudes")
|
344
|
+
return RealAmplitudes(n_qubits, reps=len(params) // (n_qubits * 2))
|
345
|
+
|
346
|
+
def _create_two_local_ansatz(self, n_qubits: int, params: np.ndarray) -> Any:
|
347
|
+
"""Create TwoLocal ansatz."""
|
348
|
+
from qiskit.circuit.library import TwoLocal
|
349
|
+
return TwoLocal(n_qubits, 'ry', 'cx', 'linear', reps=len(params) // (n_qubits * 2))
|
350
|
+
|
351
|
+
def _create_uccsd_ansatz(self, n_qubits: int, params: np.ndarray) -> Any:
|
352
|
+
"""Create UCCSD ansatz (simplified)."""
|
353
|
+
circuit = QuantumCircuit(n_qubits)
|
354
|
+
|
355
|
+
# Simplified UCCSD implementation
|
356
|
+
param_idx = 0
|
357
|
+
|
358
|
+
# Single excitations
|
359
|
+
for i in range(0, n_qubits, 2):
|
360
|
+
for j in range(1, n_qubits, 2):
|
361
|
+
if param_idx < len(params) and i != j:
|
362
|
+
circuit.cx(i, j)
|
363
|
+
circuit.ry(params[param_idx], j)
|
364
|
+
circuit.cx(i, j)
|
365
|
+
param_idx += 1
|
366
|
+
|
367
|
+
# Double excitations (simplified)
|
368
|
+
for i in range(0, n_qubits - 3, 2):
|
369
|
+
if param_idx < len(params):
|
370
|
+
circuit.cx(i, i + 1)
|
371
|
+
circuit.cx(i + 2, i + 3)
|
372
|
+
circuit.ry(params[param_idx], i + 1)
|
373
|
+
circuit.cx(i, i + 1)
|
374
|
+
circuit.cx(i + 2, i + 3)
|
375
|
+
param_idx += 1
|
376
|
+
|
377
|
+
return circuit
|
378
|
+
|
379
|
+
def compute_expectation(self, circuit: Any, hamiltonian: Any,
|
380
|
+
shots: Optional[int] = None) -> float:
|
381
|
+
"""Compute expectation value of Hamiltonian."""
|
382
|
+
try:
|
383
|
+
# For Qiskit, we need to decompose Hamiltonian into Pauli terms
|
384
|
+
if isinstance(hamiltonian, np.ndarray):
|
385
|
+
# Compute expectation using statevector
|
386
|
+
statevector = self.get_statevector(circuit)
|
387
|
+
expectation = np.real(np.conj(statevector) @ hamiltonian @ statevector)
|
388
|
+
return float(expectation)
|
389
|
+
else:
|
390
|
+
logger.warning("Hamiltonian expectation not fully implemented")
|
391
|
+
return 0.0
|
392
|
+
|
393
|
+
except Exception as e:
|
394
|
+
logger.error(f"Expectation computation failed: {e}")
|
395
|
+
return 0.0
|
396
|
+
|
397
|
+
def create_qaoa_circuit(self, n_qubits: int, gammas: np.ndarray, betas: np.ndarray,
|
398
|
+
problem_hamiltonian: Any, mixer_hamiltonian: Any,
|
399
|
+
initial_state: Any, problem_instance: Any) -> Any:
|
400
|
+
"""Create QAOA circuit with given parameters."""
|
401
|
+
circuit = QuantumCircuit(n_qubits)
|
402
|
+
|
403
|
+
# Initial state (uniform superposition)
|
404
|
+
for i in range(n_qubits):
|
405
|
+
circuit.h(i)
|
406
|
+
|
407
|
+
# QAOA layers
|
408
|
+
for gamma, beta in zip(gammas, betas):
|
409
|
+
# Problem Hamiltonian layer
|
410
|
+
self._apply_problem_hamiltonian(circuit, gamma, problem_instance)
|
411
|
+
|
412
|
+
# Mixer Hamiltonian layer
|
413
|
+
self._apply_mixer_hamiltonian(circuit, beta)
|
414
|
+
|
415
|
+
return circuit
|
416
|
+
|
417
|
+
def _apply_problem_hamiltonian(self, circuit: Any, gamma: float, problem_instance: Any) -> None:
|
418
|
+
"""Apply problem Hamiltonian to circuit."""
|
419
|
+
# Simplified implementation for Max-Cut type problems
|
420
|
+
n_qubits = circuit.num_qubits
|
421
|
+
|
422
|
+
if hasattr(problem_instance, 'shape') and len(problem_instance.shape) == 2:
|
423
|
+
# Assume adjacency matrix
|
424
|
+
for i in range(n_qubits):
|
425
|
+
for j in range(i + 1, n_qubits):
|
426
|
+
if problem_instance[i, j] != 0:
|
427
|
+
circuit.cx(i, j)
|
428
|
+
circuit.rz(gamma * problem_instance[i, j], j)
|
429
|
+
circuit.cx(i, j)
|
430
|
+
|
431
|
+
def _apply_mixer_hamiltonian(self, circuit: Any, beta: float) -> None:
|
432
|
+
"""Apply mixer Hamiltonian to circuit."""
|
433
|
+
# Standard X-mixer
|
434
|
+
for i in range(circuit.num_qubits):
|
435
|
+
circuit.rx(2 * beta, i)
|
436
|
+
|
437
|
+
def get_version_info(self) -> Dict[str, Any]:
|
438
|
+
"""Get Qiskit version information."""
|
439
|
+
info = super().get_version_info()
|
440
|
+
|
441
|
+
try:
|
442
|
+
import qiskit
|
443
|
+
info.update({
|
444
|
+
'qiskit_version': qiskit.__version__,
|
445
|
+
'backend_name': self.backend.name() if self.backend else 'Unknown',
|
446
|
+
'backend_version': getattr(self.backend, 'version', 'Unknown'),
|
447
|
+
})
|
448
|
+
except Exception as e:
|
449
|
+
info['version_error'] = str(e)
|
450
|
+
|
451
|
+
return info
|