| name | qiskit |
| description | Comprehensive guide for Qiskit - IBM's quantum computing framework. Use for quantum circuit design, quantum algorithms (VQE, QAOA, Grover, Shor), quantum simulation, noise modeling, quantum machine learning, and quantum chemistry calculations. Essential for quantum computing research and applications. |
| version | 1 |
| license | Apache-2.0 |
Qiskit - Quantum Computing Framework
Open-source quantum computing framework for building, simulating, and running quantum algorithms on quantum computers and simulators.
When to Use
- Building quantum circuits and gates
- Running quantum algorithms (VQE, QAOA, Grover, Shor)
- Quantum chemistry calculations (integration with PySCF)
- Quantum machine learning
- Quantum simulation and noise modeling
- Transpiling circuits for real quantum hardware
- Quantum optimization problems
- Quantum error correction
- Quantum cryptography
- Educational quantum computing demonstrations
Reference Documentation
Official docs: https://qiskit.org/documentation/
Search patterns: qiskit.circuit.QuantumCircuit, qiskit.algorithms.VQE, qiskit.quantum_info, qiskit_nature
Core Principles
Use Qiskit For
| Task | Module | Example |
|---|
| Circuit building | qiskit | QuantumCircuit(2, 2) |
| Quantum algorithms | qiskit.algorithms | VQE(ansatz, optimizer) |
| Quantum simulation | qiskit.providers.aer | AerSimulator() |
| Quantum chemistry | qiskit_nature | GroundStateEigensolver() |
| Noise modeling | qiskit.providers.aer.noise | NoiseModel() |
| Transpilation | qiskit.transpiler | transpile(circuit, backend) |
| Quantum ML | qiskit_machine_learning | VQC(feature_map, ansatz) |
| Visualization | qiskit.visualization | plot_histogram(counts) |
Do NOT Use For
- Classical machine learning (use scikit-learn, PyTorch)
- Classical optimization (use SciPy)
- General numerical computing (use NumPy)
- Classical cryptography (use cryptography package)
- Large-scale classical simulation (use classical simulators)
Quick Reference
Installation
pip install qiskit
pip install qiskit[visualization]
pip install qiskit-nature qiskit-nature-pyscf
pip install qiskit-machine-learning
pip install qiskit-optimization
pip install 'qiskit[all]' qiskit-nature qiskit-machine-learning qiskit-optimization
Standard Imports
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit import transpile, assemble
from qiskit.providers.aer import AerSimulator
from qiskit.visualization import plot_histogram, plot_bloch_multivector
from qiskit.algorithms import VQE, QAOA, Grover, Shor
from qiskit.algorithms.optimizers import SLSQP, COBYLA, SPSA
from qiskit.quantum_info import Statevector, DensityMatrix, Operator
from qiskit.quantum_info import entropy, entanglement_of_formation
from qiskit.circuit.library import QFT, RealAmplitudes, EfficientSU2
Basic Pattern - Circuit Building
from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
simulator = AerSimulator()
job = simulator.run(qc, shots=1000)
result = job.result()
counts = result.get_counts()
print(f"Results: {counts}")
Basic Pattern - Quantum Algorithm
from qiskit import QuantumCircuit
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SLSQP
from qiskit.circuit.library import RealAmplitudes
from qiskit.primitives import Estimator
from qiskit.quantum_info import SparsePauliOp
hamiltonian = SparsePauliOp(['ZZ', 'IZ', 'ZI'], coeffs=[1.0, -0.5, -0.5])
ansatz = RealAmplitudes(num_qubits=2, reps=1)
optimizer = SLSQP(maxiter=100)
estimator = Estimator()
vqe = VQE(estimator, ansatz, optimizer)
result = vqe.compute_minimum_eigenvalue(hamiltonian)
print(f"Ground state energy: {result.eigenvalue:.6f}")
Critical Rules
✅ DO
- Use simulators for development - Test on simulators before real hardware
- Transpile for target backend - Always transpile circuits for specific hardware
- Handle measurement statistics - Work with shot counts, not single results
- Use primitives for algorithms - Use Estimator/Sampler primitives
- Check circuit depth - Monitor gate count and depth for real hardware
- Implement error mitigation - Use error mitigation for noisy hardware
- Validate quantum states - Check state validity and normalization
- Use appropriate basis gates - Match hardware native gates
- Set random seed for reproducibility - Use seed for consistent results
- Monitor job status - Check if quantum jobs complete successfully
❌ DON'T
- Ignore hardware constraints - Real quantum computers have limitations
- Use too many qubits on simulators - Memory grows exponentially
- Forget to measure - Quantum states collapse on measurement
- Mix classical and quantum incorrectly - Understand measurement timing
- Ignore decoherence - Quantum states decay over time
- Over-transpile - Unnecessary transpilation adds gates
- Assume perfect gates - Real gates have errors
- Ignore topology - Not all qubits are connected
- Use deprecated APIs - Qiskit evolves rapidly
- Run without error handling - Quantum jobs can fail
Anti-Patterns (NEVER)
from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
from qiskit.primitives import Estimator
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
from qiskit import execute
result = execute(qc, backend, shots=1024).result()
simulator = AerSimulator()
job = simulator.run(qc, shots=1024)
result = job.result()
counts = result.get_counts()
assert counts['00'] == 512
counts = result.get_counts()
ratio = counts.get('00', 0) / sum(counts.values())
print(f"Measured |00⟩ with probability {ratio:.3f}")
qc = QuantumCircuit(20)
qc = QuantumCircuit()
()
()
()
job = backend.run(qc)
qiskit transpile
transpiled_qc = transpile(qc, backend=backend, optimization_level=)
job = backend.run(transpiled_qc)
Quantum Circuits (qiskit.QuantumCircuit)
Basic Circuit Construction
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
import numpy as np
qc = QuantumCircuit(3, 3)
qr = QuantumRegister(3, 'q')
cr = ClassicalRegister(3, 'c')
qc = QuantumCircuit(qr, cr)
qr1 = QuantumRegister(2, 'data')
qr2 = QuantumRegister(1, 'ancilla')
cr = ClassicalRegister(2, 'meas')
qc = QuantumCircuit(qr1, qr2, cr)
print(f"Number of qubits: {qc.num_qubits}")
print(f"Number of classical bits: {qc.num_clbits}")
print(f"Circuit depth: {qc.depth()}")
Single-Qubit Gates
from qiskit import QuantumCircuit
import numpy as np
qc = QuantumCircuit(1)
qc.x(0)
qc.y(0)
qc.z(0)
qc.h(0)
qc.s(0)
qc.t(0)
qc.sdg(0)
qc.tdg(0)
qc.rx(np.pi/4, 0)
qc.ry(np.pi/4, 0)
qc.rz(np.pi/4, 0)
qc.u(np.pi/4, np.pi/2, np.pi, 0)
qc.id(0)
print(f"Gate count: {len(qc.data)}")
Two-Qubit Gates
from qiskit import QuantumCircuit
import numpy as np
qc = QuantumCircuit(2)
qc.cx(0, 1)
qc.cy(0, 1)
qc.cz(0, 1)
qc.ch(0, 1)
qc.swap(0, 1)
qc.cp(np.pi/4, 0, 1)
qc.cu(np.pi/4, np.pi/2, np.pi, 0, 0, 1)
qc_3 = QuantumCircuit(3)
qc_3.ccx(0, 1, 2)
print(qc.draw())
Creating Entanglement
from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
from qiskit.quantum_info import Statevector
def create_bell_state():
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
return qc
bell = create_bell_state()
state = Statevector.from_instruction(bell)
print(f"Bell state: {state}")
def create_ghz_state(n):
qc = QuantumCircuit(n)
qc.h(0)
for i in range(n-1):
qc.cx(i, i+1)
return qc
ghz = create_ghz_state(3)
state_ghz = Statevector.from_instruction(ghz)
print(f"GHZ state: {state_ghz}")
def create_w_state():
qc = QuantumCircuit(3)
qc.ry(1.9106, 0)
qc.ch(0, 1)
qc.x(0)
qc.cy(0, 1)
qc.ccx(0, 1, 2)
qc.x(0)
return qc
w = create_w_state()
()
Parameterized Circuits
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter, ParameterVector
import numpy as np
theta = Parameter('θ')
qc = QuantumCircuit(1)
qc.ry(theta, 0)
bound_qc = qc.bind_parameters({theta: np.pi/4})
print(f"Unbound: {qc}")
print(f"Bound: {bound_qc}")
params = ParameterVector('θ', 4)
qc_param = QuantumCircuit(2)
qc_param.ry(params[0], 0)
qc_param.ry(params[1], 1)
qc_param.cx(0, 1)
qc_param.ry(params[2], 0)
qc_param.ry(params[3], 1)
values = [np.pi/4, np.pi/3, np.pi/2, np.pi/6]
bound = qc_param.bind_parameters(dict(zip(params, values)))
print(f"Number of parameters: {qc_param.num_parameters}")
Quantum Algorithms
Variational Quantum Eigensolver (VQE)
from qiskit import QuantumCircuit
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SLSQP, COBYLA
from qiskit.circuit.library import RealAmplitudes, EfficientSU2
from qiskit.primitives import Estimator
from qiskit.quantum_info import SparsePauliOp
import numpy as np
hamiltonian = SparsePauliOp(
['ZZ', 'XX', 'YY', 'ZI', 'IZ'],
coeffs=[-1.05, 0.39, -0.39, -0.01, -0.01]
)
ansatz = RealAmplitudes(num_qubits=2, reps=2)
optimizer = SLSQP(maxiter=100)
estimator = Estimator()
vqe = VQE(estimator, ansatz, optimizer)
result = vqe.compute_minimum_eigenvalue(hamiltonian)
print(f"Ground state energy: {result.eigenvalue:.6f}")
print(f"Optimal parameters: {result.optimal_parameters}")
print(f"Optimizer evaluations: {result.cost_function_evals}")
optimal_circuit = ansatz.bind_parameters(result.optimal_point)
()
QAOA (Quantum Approximate Optimization Algorithm)
from qiskit import QuantumCircuit
from qiskit.algorithms import QAOA
from qiskit.algorithms.optimizers import COBYLA
from qiskit.primitives import Sampler
from qiskit.quantum_info import SparsePauliOp
import numpy as np
cost_hamiltonian = SparsePauliOp(
['ZZ', 'ZI', 'IZ'],
coeffs=[0.5, -0.5, -0.5]
)
optimizer = COBYLA(maxiter=100)
sampler = Sampler()
qaoa = QAOA(sampler, optimizer, reps=2)
result = qaoa.compute_minimum_eigenvalue(cost_hamiltonian)
print(f"Optimal objective: {result.eigenvalue:.6f}")
print(f"Optimal parameters: {result.optimal_parameters}")
from qiskit.result import QuasiDistribution
prob_dist = result.eigenstate
if isinstance(prob_dist, QuasiDistribution):
most_likely = max(prob_dist, key=prob_dist.get)
print(f"Most likely solution: {bin(most_likely)[2:].zfill(2)}")
Grover's Algorithm (Quantum Search)
from qiskit import QuantumCircuit
from qiskit.algorithms import Grover, AmplificationProblem
from qiskit.circuit.library import GroverOperator
from qiskit.primitives import Sampler
import numpy as np
def grover_search(marked_states, n_qubits):
"""
Grover's algorithm to find marked states.
Args:
marked_states: List of marked states (e.g., ['101', '110'])
n_qubits: Number of qubits
"""
oracle = QuantumCircuit(n_qubits)
if '101' in marked_states:
oracle.x([0, 2])
oracle.h(2)
oracle.ccx(0, 1, 2)
oracle.h(2)
oracle.x([0, 2])
diffusion = QuantumCircuit(n_qubits)
diffusion.h(range(n_qubits))
diffusion.x(range(n_qubits))
diffusion.h(n_qubits - 1)
diffusion.mcx(list(range(n_qubits - 1)), n_qubits - 1)
diffusion.h(n_qubits - 1)
diffusion.x(range(n_qubits))
diffusion.h(range(n_qubits))
grover_op = oracle.compose(diffusion)
problem = AmplificationProblem(oracle, is_good_state=marked_states)
grover = Grover(sampler=Sampler())
result = grover.amplify(problem)
result
result = grover_search([], )
()
()
qc = QuantumCircuit(, )
qc.h([, ])
qc.cz(, )
qc.h([, ])
qc.x([, ])
qc.cz(, )
qc.x([, ])
qc.h([, ])
qc.measure([, ], [, ])
qiskit.providers.aer AerSimulator
simulator = AerSimulator()
job = simulator.run(qc, shots=)
counts = job.result().get_counts()
()
Quantum Phase Estimation (QPE)
from qiskit import QuantumCircuit
from qiskit.circuit.library import QFT
from qiskit.providers.aer import AerSimulator
import numpy as np
def quantum_phase_estimation(unitary, n_counting_qubits):
"""
Estimate the phase of an eigenstate of a unitary operator.
Args:
unitary: Unitary operator as a QuantumCircuit
n_counting_qubits: Precision qubits
"""
n_system_qubits = unitary.num_qubits
qc = QuantumCircuit(n_counting_qubits + n_system_qubits, n_counting_qubits)
qc.x(n_counting_qubits)
for i in range(n_counting_qubits):
qc.h(i)
repetitions = 1
for counting_qubit in range(n_counting_qubits):
for _ in range(repetitions):
qc.append(unitary.control(), [counting_qubit] +
list(range(n_counting_qubits, n_counting_qubits + n_system_qubits)))
repetitions *= 2
qc.append(QFT(n_counting_qubits, inverse=True), range(n_counting_qubits))
qc.measure(range(n_counting_qubits), range(n_counting_qubits))
return qc
t_gate = QuantumCircuit(1)
t_gate.t(0)
qpe_circuit = quantum_phase_estimation(t_gate, n_counting_qubits=)
simulator = AerSimulator()
job = simulator.run(qpe_circuit, shots=)
counts = job.result().get_counts()
()
most_common = (counts, key=counts.get)
phase_estimate = (most_common, ) / (**)
()
()
Quantum Chemistry with Qiskit Nature
Molecular Ground State Calculation
from qiskit_nature.units import DistanceUnit
from qiskit_nature.second_q.drivers import PySCFDriver
from qiskit_nature.second_q.mappers import JordanWignerMapper, ParityMapper
from qiskit_nature.second_q.circuit.library import HartreeFock, UCCSD
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SLSQP
from qiskit.primitives import Estimator
import numpy as np
driver = PySCFDriver(
atom='H 0 0 0; H 0 0 0.735',
basis='sto3g',
charge=0,
spin=0,
unit=DistanceUnit.ANGSTROM
)
problem = driver.run()
hamiltonian = problem.hamiltonian.second_q_op()
mapper = JordanWignerMapper()
qubit_op = mapper.map(hamiltonian)
print(f"Number of qubits required: {qubit_op.num_qubits}")
num_particles = problem.num_particles
num_spatial_orbitals = problem.num_spatial_orbitals
init_state = HartreeFock(
num_spatial_orbitals=num_spatial_orbitals,
num_particles=num_particles,
qubit_mapper=mapper
)
ansatz = UCCSD(
num_spatial_orbitals=num_spatial_orbitals,
num_particles=num_particles,
qubit_mapper=mapper,
initial_state=init_state
)
optimizer = SLSQP(maxiter=100)
estimator = Estimator()
vqe = VQE(estimator, ansatz, optimizer)
result = vqe.compute_minimum_eigenvalue(qubit_op)
print(f"\nVQE Ground State Energy: {result.eigenvalue:.6f} Ha")
()
Excited States Calculation
from qiskit_nature.second_q.algorithms import GroundStateEigensolver, ExcitedStatesEigensolver
from qiskit_nature.second_q.algorithms import QEOM
from qiskit_nature.second_q.mappers import JordanWignerMapper
from qiskit_nature.second_q.drivers import PySCFDriver
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SLSQP
from qiskit.primitives import Estimator
driver = PySCFDriver(atom='H 0 0 0; H 0 0 0.735', basis='sto3g')
problem = driver.run()
mapper = JordanWignerMapper()
optimizer = SLSQP(maxiter=100)
estimator = Estimator()
from qiskit.circuit.library import RealAmplitudes
ansatz = RealAmplitudes(num_qubits=4, reps=2)
vqe = VQE(estimator, ansatz, optimizer)
ground_solver = GroundStateEigensolver(mapper, vqe)
ground_result = ground_solver.solve(problem)
print(f"Ground state energy: {ground_result.total_energies[0]:.6f} Ha")
qeom = QEOM(ground_solver, 'sd')
excited_solver = ExcitedStatesEigensolver(mapper, qeom)
excited_result = excited_solver.solve(problem)
print(f"\nExcited state energies:")
for i, energy in enumerate(excited_result.total_energies):
()
Molecular Potential Energy Surface
from qiskit_nature.second_q.drivers import PySCFDriver
from qiskit_nature.second_q.mappers import JordanWignerMapper
from qiskit_nature.second_q.algorithms import GroundStateEigensolver
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SLSQP
from qiskit.primitives import Estimator
from qiskit.circuit.library import RealAmplitudes
import numpy as np
def calculate_pes(distances, molecule_template, basis='sto3g'):
"""
Calculate potential energy surface for a diatomic molecule.
Args:
distances: Array of interatomic distances
molecule_template: Molecule string with {} for distance
basis: Basis set
"""
energies = []
for distance in distances:
atom_string = molecule_template.format(distance)
driver = PySCFDriver(atom=atom_string, basis=basis)
problem = driver.run()
mapper = JordanWignerMapper()
ansatz = RealAmplitudes(num_qubits=4, reps=1)
optimizer = SLSQP(maxiter=50)
estimator = Estimator()
vqe = VQE(estimator, ansatz, optimizer)
solver = GroundStateEigensolver(mapper, vqe)
result = solver.solve(problem)
energies.append(result.total_energies[0])
print(f"Distance {distance:.2f} Å: Energy = Ha")
np.array(energies)
distances = np.linspace(, , )
molecule_template =
energies = calculate_pes(distances, molecule_template)
min_idx = np.argmin(energies)
()
()
Quantum Simulation
Hamiltonian Simulation with Trotter
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp, Statevector
from qiskit.synthesis import SuzukiTrotter
import numpy as np
def trotter_simulation(hamiltonian, time, n_steps):
"""
Simulate time evolution under Hamiltonian using Trotter decomposition.
Args:
hamiltonian: SparsePauliOp Hamiltonian
time: Total evolution time
n_steps: Number of Trotter steps
"""
dt = time / n_steps
n_qubits = hamiltonian.num_qubits
qc = QuantumCircuit(n_qubits)
for _ in range(n_steps):
for pauli, coeff in zip(hamiltonian.paulis, hamiltonian.coeffs):
angle = 2 * float(coeff.real) * dt
pauli_str = str(pauli)
if 'Z' in pauli_str and pauli_str.count('I') == n_qubits - 1:
idx = pauli_str.index('Z')
qc.rz(angle, n_qubits - 1 - idx)
elif 'X' in pauli_str and pauli_str.count() == n_qubits - :
idx = pauli_str.index()
qc.rx(angle, n_qubits - - idx)
qc
hamiltonian = SparsePauliOp([, , ], coeffs=[, -, -])
qc = trotter_simulation(hamiltonian, time=, n_steps=)
()
()
state = Statevector.from_instruction(qc)
()
Variational Quantum Simulation
from qiskit import QuantumCircuit
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SLSQP
from qiskit.circuit.library import RealAmplitudes
from qiskit.primitives import Estimator
from qiskit.quantum_info import SparsePauliOp
import numpy as np
def simulate_dynamics(hamiltonian, initial_state_circuit, times, ansatz_reps=2):
"""
Simulate quantum dynamics using VQE at different times.
Args:
hamiltonian: Time-evolution Hamiltonian
initial_state_circuit: Circuit preparing initial state
times: Array of times to simulate
ansatz_reps: Repetitions in ansatz
"""
n_qubits = hamiltonian.num_qubits
results = []
for t in times:
ansatz = RealAmplitudes(num_qubits=n_qubits, reps=ansatz_reps)
full_circuit = initial_state_circuit.copy()
full_circuit.compose(ansatz, inplace=True)
optimizer = SLSQP(maxiter=100)
estimator = Estimator()
vqe = VQE(estimator, full_circuit, optimizer)
result = vqe.compute_minimum_eigenvalue(hamiltonian)
results.append({
'time': t,
'energy': result.eigenvalue,
'parameters': result.optimal_parameters
})
print(f"Time {t:.2f}: Energy = {result.eigenvalue:.6f}")
results
hamiltonian = SparsePauliOp(
[, , ],
coeffs=[, , ]
)
initial_state = QuantumCircuit()
initial_state.x()
times = np.linspace(, , )
results = simulate_dynamics(hamiltonian, initial_state, times)
Quantum Machine Learning
Quantum Kernel Method
from qiskit_machine_learning.kernels import FidelityQuantumKernel
from qiskit.circuit.library import ZZFeatureMap
from qiskit.primitives import Sampler
from sklearn.svm import SVC
import numpy as np
np.random.seed(42)
X_train = np.random.rand(20, 2) * 2 * np.pi
y_train = (X_train[:, 0] + X_train[:, 1] > np.pi).astype(int)
X_test = np.random.rand(10, 2) * 2 * np.pi
y_test = (X_test[:, 0] + X_test[:, 1] > np.pi).astype(int)
feature_map = ZZFeatureMap(feature_dimension=2, reps=2)
sampler = Sampler()
quantum_kernel = FidelityQuantumKernel(feature_map=feature_map, fidelity=sampler)
kernel_matrix_train = quantum_kernel.evaluate(x_vec=X_train)
kernel_matrix_test = quantum_kernel.evaluate(x_vec=X_test, y_vec=X_train)
print(f"Training kernel matrix shape: {kernel_matrix_train.shape}")
print(f"Test kernel matrix shape: {kernel_matrix_test.shape}")
svc = SVC(kernel='precomputed')
svc.fit(kernel_matrix_train, y_train)
predictions = svc.predict(kernel_matrix_test)
accuracy = np.mean(predictions == y_test)
print(f"\nQuantum Kernel SVM Accuracy: ")
Variational Quantum Classifier (VQC)
from qiskit_machine_learning.algorithms import VQC
from qiskit.circuit.library import RealAmplitudes, ZZFeatureMap
from qiskit.algorithms.optimizers import COBYLA
from qiskit.primitives import Sampler
import numpy as np
np.random.seed(42)
X_train = np.random.rand(40, 2) * 2 - 1
y_train = (X_train[:, 0]**2 + X_train[:, 1]**2 < 0.5).astype(int)
X_test = np.random.rand(20, 2) * 2 - 1
y_test = (X_test[:, 0]**2 + X_test[:, 1]**2 < 0.5).astype(int)
feature_map = ZZFeatureMap(2)
ansatz = RealAmplitudes(2, reps=2)
optimizer = COBYLA(maxiter=100)
sampler = Sampler()
vqc = VQC(
sampler=sampler,
feature_map=feature_map,
ansatz=ansatz,
optimizer=optimizer,
)
vqc.fit(X_train, y_train)
train_score = vqc.score(X_train, y_train)
test_score = vqc.score(X_test, y_test)
print(f"Training accuracy: {train_score:.2%}")
print()
predictions = vqc.predict(X_test)
()
()
Quantum Neural Network (QNN)
from qiskit_machine_learning.neural_networks import SamplerQNN
from qiskit_machine_learning.algorithms import NeuralNetworkClassifier
from qiskit.circuit import QuantumCircuit, Parameter
from qiskit.circuit.library import RealAmplitudes
from qiskit.algorithms.optimizers import COBYLA
from qiskit.primitives import Sampler
import numpy as np
def create_qnn_circuit(num_qubits, num_features):
qc = QuantumCircuit(num_qubits)
feature_params = [Parameter(f'x{i}') for i in range(num_features)]
for i, param in enumerate(feature_params):
if i < num_qubits:
qc.ry(param, i)
ansatz = RealAmplitudes(num_qubits, reps=1)
qc.compose(ansatz, inplace=True)
return qc, feature_params, ansatz.parameters
num_qubits = 2
num_features = 2
qc, feature_params, weight_params = create_qnn_circuit(num_qubits, num_features)
sampler = Sampler()
qnn = SamplerQNN(
circuit=qc,
input_params=feature_params,
weight_params=weight_params,
sampler=sampler,
)
optimizer = COBYLA(maxiter=50)
classifier = NeuralNetworkClassifier(
neural_network=qnn,
optimizer=optimizer,
)
X_train = np.random.rand(, )
y_train = (X_train[:, ] > X_train[:, ]).astype()
classifier.fit(X_train, y_train)
X_test = np.random.rand(, )
y_test = (X_test[:, ] > X_test[:, ]).astype()
score = classifier.score(X_test, y_test)
()
Noise Modeling and Error Mitigation
Noise Models
from qiskit.providers.aer import AerSimulator
from qiskit.providers.aer.noise import NoiseModel
from qiskit.providers.aer.noise import depolarizing_error, thermal_relaxation_error
from qiskit import QuantumCircuit
import numpy as np
noise_model = NoiseModel()
error_1q = depolarizing_error(0.001, 1)
noise_model.add_all_qubit_quantum_error(error_1q, ['u1', 'u2', 'u3', 'rx', 'ry', 'rz'])
error_2q = depolarizing_error(0.01, 2)
noise_model.add_all_qubit_quantum_error(error_2q, ['cx', 'cz', 'swap'])
t1 = 50e3
t2 = 70e3
gate_time = 100
error_thermal = thermal_relaxation_error(t1, t2, gate_time)
noise_model.add_all_qubit_quantum_error(error_thermal, ['id'])
from qiskit.providers.aer.noise import ReadoutError
prob_meas0_prep1 = 0.05
prob_meas1_prep0 = 0.10
readout_error = ReadoutError([[ - prob_meas1_prep0, prob_meas1_prep0],
[prob_meas0_prep1, - prob_meas0_prep1]])
noise_model.add_all_qubit_readout_error(readout_error)
()
qc = QuantumCircuit(, )
qc.h()
qc.cx(, )
qc.measure([, ], [, ])
simulator_ideal = AerSimulator()
job_ideal = simulator_ideal.run(qc, shots=)
counts_ideal = job_ideal.result().get_counts()
simulator_noisy = AerSimulator(noise_model=noise_model)
job_noisy = simulator_noisy.run(qc, shots=)
counts_noisy = job_noisy.result().get_counts()
()
()
Zero-Noise Extrapolation (ZNE)
from qiskit import QuantumCircuit, transpile
from qiskit.providers.aer import AerSimulator
from qiskit.providers.aer.noise import NoiseModel, depolarizing_error
import numpy as np
from scipy.optimize import curve_fit
def run_circuit_with_noise(circuit, noise_level, shots=1000):
"""Run circuit with scaled noise."""
noise_model = NoiseModel()
error = depolarizing_error(noise_level, 1)
noise_model.add_all_qubit_quantum_error(error, ['u1', 'u2', 'u3'])
simulator = AerSimulator(noise_model=noise_model)
job = simulator.run(circuit, shots=shots)
result = job.result()
counts = result.get_counts()
expectation = sum(counts.get(bitstring, 0) * (-1)**bitstring.count('1')
for bitstring in counts) / shots
return expectation
def zero_noise_extrapolation(circuit, noise_levels, shots=1000):
"""
Perform zero-noise extrapolation.
Args:
circuit: Quantum circuit
noise_levels: List of noise scaling factors
shots: Number of shots per simulation
"""
expectations = []
for noise in noise_levels:
exp_val = run_circuit_with_noise(circuit, noise, shots)
expectations.append(exp_val)
print(f"Noise : Expectation = ")
():
a + b * np.exp(-c * x)
popt, _ = curve_fit(exp_model, noise_levels, expectations)
zero_noise_value = exp_model(, *popt)
()
zero_noise_value, expectations
qc = QuantumCircuit(, )
qc.h()
qc.cx(, )
qc.measure([, ], [, ])
noise_levels = np.array([, , , ])
zne_value, measured_values = zero_noise_extrapolation(qc, noise_levels)
Measurement Error Mitigation
from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
from qiskit.providers.aer.noise import NoiseModel, ReadoutError
from qiskit.result import marginal_counts
from qiskit.ignis.mitigation.measurement import (
complete_meas_cal,
CompleteMeasFitter
)
prob_meas0_prep1 = 0.1
prob_meas1_prep0 = 0.05
readout_error = ReadoutError([[1 - prob_meas1_prep0, prob_meas1_prep0],
[prob_meas0_prep1, 1 - prob_meas0_prep1]])
noise_model = NoiseModel()
noise_model.add_all_qubit_readout_error(readout_error)
n_qubits = 2
meas_calibs, state_labels = complete_meas_cal(qr=list(range(n_qubits)))
simulator = AerSimulator(noise_model=noise_model)
cal_results = []
for circuit in meas_calibs:
job = simulator.run(circuit, shots=1000)
cal_results.append(job.result())
meas_fitter = CompleteMeasFitter(cal_results, state_labels)
print("Calibration matrix:")
print(meas_fitter.cal_matrix)
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
job = simulator.run(qc, shots=1000)
result = job.result()
noisy_counts = result.get_counts()
mitigated_counts = meas_fitter..apply(noisy_counts)
()
()
Transpilation and Optimization
Basic Transpilation
from qiskit import QuantumCircuit, transpile
from qiskit.providers.fake_provider import FakeMontreal
from qiskit.visualization import plot_circuit_layout
import matplotlib.pyplot as plt
qc = QuantumCircuit(3)
qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)
qc.cx(0, 2)
backend = FakeMontreal()
for level in range(4):
transpiled = transpile(qc, backend=backend, optimization_level=level)
print(f"\nOptimization level {level}:")
print(f" Depth: {transpiled.depth()}")
print(f" Gate count: {len(transpiled.data)}")
print(f" CNOT count: {transpiled.count_ops().get('cx', 0)}")
best_transpiled = transpile(qc, backend=backend, optimization_level=3)
print(f"\nOriginal circuit:")
print(f" Depth: {qc.depth()}")
print(f" Gates: {len(qc.data)}")
()
()
()
Custom Transpilation Pass
from qiskit import QuantumCircuit
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import Optimize1qGates, CommutativeCancellation
from qiskit.transpiler.passes import UnitarySynthesis, Unroll3qOrMore
qc = QuantumCircuit(2)
qc.h(0)
qc.h(0)
qc.x(1)
qc.x(1)
qc.cx(0, 1)
print(f"Original circuit depth: {qc.depth()}")
print(f"Original gate count: {len(qc.data)}")
pm = PassManager()
pm.append(Optimize1qGates())
pm.append(CommutativeCancellation())
pm.append(Unroll3qOrMore())
pm.append(UnitarySynthesis())
optimized_qc = pm.run(qc)
print(f"\nOptimized circuit depth: {optimized_qc.depth()}")
print(f"Optimized gate count: {len(optimized_qc.data)}")
print("\nOriginal circuit:")
print(qc.draw())
print("\nOptimized circuit:")
(optimized_qc.draw())
Layout and Routing
from qiskit import QuantumCircuit, transpile
from qiskit.providers.fake_provider import FakeMontreal
from qiskit.transpiler import CouplingMap
qc = QuantumCircuit(5)
qc.h(0)
qc.cx(0, 4)
qc.cx(1, 3)
qc.cx(2, 4)
backend = FakeMontreal()
coupling_map = backend.configuration().coupling_map
print(f"Backend coupling map: {coupling_map[:10]}...")
transpiled = transpile(
qc,
backend=backend,
optimization_level=3,
seed_transpiler=42
)
final_layout = transpiled.layout.final_index_layout()
print(f"\nFinal qubit layout: {final_layout}")
print(f"\nOriginal circuit:")
print(f" Depth: {qc.depth()}")
print(f" CNOT count: {qc.count_ops().get('cx', 0)}")
print(f"\nTranspiled circuit (with routing):")
print(f" Depth: {transpiled.depth()}")
print(f" CNOT count: ")
()
Quantum Information Theory
Entanglement Measures
from qiskit.quantum_info import Statevector, DensityMatrix, partial_trace
from qiskit.quantum_info import entropy, entanglement_of_formation
from qiskit import QuantumCircuit
import numpy as np
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
state = Statevector.from_instruction(qc)
density_matrix = DensityMatrix(state)
print(f"Bell state: {state}")
entropy_full = entropy(density_matrix)
print(f"\nFull system entropy: {entropy_full:.6f}")
rho_0 = partial_trace(density_matrix, [1])
entropy_reduced = entropy(rho_0)
print(f"Reduced density matrix entropy: {entropy_reduced:.6f}")
eof = entanglement_of_formation(density_matrix)
print(f"Entanglement of formation: {eof:.6f}")
qc_sep = QuantumCircuit(2)
qc_sep.h(0)
qc_sep.h(1)
state_sep = Statevector.from_instruction(qc_sep)
dm_sep = DensityMatrix(state_sep)
rho_0_sep = partial_trace(dm_sep, [1])
entropy_sep = entropy(rho_0_sep)
print(f"\nSeparable state reduced entropy: {entropy_sep:.6f}")
Quantum Channels and Process Tomography
from qiskit.quantum_info import Choi, SuperOp, Kraus
from qiskit import QuantumCircuit
import numpy as np
def amplitude_damping_channel(gamma):
"""
Amplitude damping channel with damping parameter gamma.
Models energy dissipation.
"""
K0 = np.array([[1, 0], [0, np.sqrt(1 - gamma)]])
K1 = np.array([[0, np.sqrt(gamma)], [0, 0]])
return Kraus([K0, K1])
gamma = 0.3
channel = amplitude_damping_channel(gamma)
print(f"Amplitude damping channel (γ={gamma}):")
print(f"Number of Kraus operators: {len(channel)}")
superop = SuperOp(channel)
choi = Choi(channel)
print(f"\nSuperoperator shape: {superop.dim}")
print(f"Choi matrix shape: {choi.dim}")
from qiskit.quantum_info import Statevector, DensityMatrix
state = Statevector([0, 1])
dm = DensityMatrix(state)
dm_evolved = dm.evolve(channel)
print(f"\nInitial state: {state}")
()
qiskit.quantum_info state_fidelity
fidelity = state_fidelity(dm, dm_evolved)
()
Quantum State Tomography
from qiskit.quantum_info import Statevector, DensityMatrix
from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
from qiskit.quantum_info.states import state_fidelity
import numpy as np
def perform_state_tomography(qc, shots=1000):
"""
Simplified quantum state tomography.
Measures in X, Y, Z bases to reconstruct density matrix.
"""
simulator = AerSimulator()
measurements = {
'Z': QuantumCircuit(qc.num_qubits, qc.num_qubits),
'X': QuantumCircuit(qc.num_qubits, qc.num_qubits),
'Y': QuantumCircuit(qc.num_qubits, qc.num_qubits)
}
measurements['X'].h(range(qc.num_qubits))
measurements['Y'].sdg(range(qc.num_qubits))
measurements['Y'].h(range(qc.num_qubits))
for basis_circ in measurements.values():
basis_circ.measure(range(qc.num_qubits), range(qc.num_qubits))
results = {}
for basis, meas_circ in measurements.items():
full_circ = qc.copy()
full_circ.compose(meas_circ, inplace=True)
job = simulator.run(full_circ, shots=shots)
results[basis] = job.result().get_counts()
print(f"Z-basis measurements: ")
()
()
qc.num_qubits == :
z_exp = (results[].get(, ) - results[].get(, )) / shots
x_exp = (results[].get(, ) - results[].get(, )) / shots
y_exp = (results[].get(, ) - results[].get(, )) / shots
rho = np.array([
[ + *z_exp, *x_exp - *y_exp],
[*x_exp + *y_exp, - *z_exp]
])
DensityMatrix(rho)
qc = QuantumCircuit()
qc.ry(np.pi/, )
true_state = Statevector.from_instruction(qc)
true_dm = DensityMatrix(true_state)
reconstructed_dm = perform_state_tomography(qc, shots=)
reconstructed_dm :
fidelity = state_fidelity(true_dm, reconstructed_dm)
()
()
()
Visualization
Circuit Visualization
from qiskit import QuantumCircuit
from qiskit.visualization import circuit_drawer
import matplotlib.pyplot as plt
qc = QuantumCircuit(3, 3)
qc.h(0)
qc.cx(0, 1)
qc.cx(1, 2)
qc.barrier()
qc.measure([0, 1, 2], [0, 1, 2])
print("Text representation:")
print(qc.draw(output='text'))
print("\nMatplotlib style:")
qc.draw(output='mpl')
plt.show()
qc_labeled = QuantumCircuit(2, 2)
qc_labeled.h(0)
qc_labeled.cx(0, 1)
qc_labeled.measure_all()
qc_labeled.draw(output='mpl', style={'name': 'bw'})
plt.show()
Result Visualization
from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
from qiskit.visualization import plot_histogram, plot_bloch_multivector
from qiskit.quantum_info import Statevector
import matplotlib.pyplot as plt
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
simulator = AerSimulator()
job = simulator.run(qc, shots=1000)
counts = job.result().get_counts()
plot_histogram(counts, title='Bell State Measurement')
plt.show()
qc2 = QuantumCircuit(2, 2)
qc2.h(0)
qc2.h(1)
qc2.measure([0, 1], [0, 1])
job2 = simulator.run(qc2, shots=1000)
counts2 = job2.result().get_counts()
plot_histogram([counts, counts2],
legend=['Bell State', 'Product State'],
title='State Comparison')
plt.show()
qc_bloch = QuantumCircuit(1)
qc_bloch.ry(np.pi/4, 0)
state = Statevector.from_instruction(qc_bloch)
plot_bloch_multivector(state)
plt.show()
State Visualization
from qiskit.quantum_info import Statevector, DensityMatrix
from qiskit.visualization import plot_state_qsphere, plot_state_city
from qiskit.visualization import plot_state_hinton, plot_state_paulivec
import matplotlib.pyplot as plt
from qiskit import QuantumCircuit
qc = QuantumCircuit(2)
qc.h(0)
qc.ry(np.pi/4, 1)
qc.cx(0, 1)
state = Statevector.from_instruction(qc)
plot_state_qsphere(state, title='Q-sphere')
plt.show()
plot_state_city(state, title='State City')
plt.show()
dm = DensityMatrix(state)
plot_state_hinton(dm, title='Density Matrix')
plt.show()
plot_state_paulivec(state, title='Pauli Vector')
plt.show()
Practical Workflows
Complete VQE Workflow for Molecule
from qiskit_nature.second_q.drivers import PySCFDriver
from qiskit_nature.second_q.mappers import JordanWignerMapper
from qiskit_nature.second_q.circuit.library import UCCSD, HartreeFock
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SLSQP
from qiskit.primitives import Estimator
import numpy as np
def calculate_molecule_energy(atom_string, basis='sto3g', charge=0, spin=0):
"""
Complete workflow for molecular energy calculation.
Args:
atom_string: Atomic coordinates (e.g., 'H 0 0 0; H 0 0 0.735')
basis: Basis set
charge: Molecular charge
spin: Spin multiplicity
"""
print(f"Calculating energy for: {atom_string}")
print(f"Basis: {basis}, Charge: {charge}, Spin: {spin}\n")
driver = PySCFDriver(
atom=atom_string,
basis=basis,
charge=charge,
spin=spin
)
problem = driver.run()
mapper = JordanWignerMapper()
hamiltonian = problem.hamiltonian.second_q_op()
qubit_op = mapper.map(hamiltonian)
print(f"Number of qubits: {qubit_op.num_qubits}")
print(f"Number of Hamiltonian terms: {(qubit_op)}")
num_particles = problem.num_particles
num_spatial_orbitals = problem.num_spatial_orbitals
init_state = HartreeFock(
num_spatial_orbitals=num_spatial_orbitals,
num_particles=num_particles,
qubit_mapper=mapper
)
ansatz = UCCSD(
num_spatial_orbitals=num_spatial_orbitals,
num_particles=num_particles,
qubit_mapper=mapper,
initial_state=init_state
)
()
()
optimizer = SLSQP(maxiter=)
estimator = Estimator()
vqe = VQE(estimator, ansatz, optimizer)
result = vqe.compute_minimum_eigenvalue(qubit_op)
vqe_energy = result.eigenvalue
hf_energy = problem.reference_energy
()
()
()
()
{
: vqe_energy,
: hf_energy,
: vqe_energy - hf_energy,
: result.optimal_parameters,
: qubit_op.num_qubits
}
results = calculate_molecule_energy()
Quantum Circuit Optimization Pipeline
from qiskit import QuantumCircuit, transpile
from qiskit.providers.fake_provider import FakeMontreal
from qiskit.transpiler import PassManager, CouplingMap
from qiskit.transpiler.passes import *
import matplotlib.pyplot as plt
def optimize_circuit_for_hardware(qc, backend=None, optimization_level=3):
"""
Complete circuit optimization pipeline.
Args:
qc: Input quantum circuit
backend: Target backend (or None for generic optimization)
optimization_level: 0-3
"""
print(f"Original circuit:")
print(f" Qubits: {qc.num_qubits}")
print(f" Depth: {qc.depth()}")
print(f" Gate count: {len(qc.data)}")
print(f" Operations: {qc.count_ops()}\n")
if backend is None:
backend = FakeMontreal()
transpiled = transpile(
qc,
backend=backend,
optimization_level=optimization_level,
seed_transpiler=42
)
print(f"After transpilation (level {optimization_level}):")
print(f" Depth: {transpiled.depth()}")
print(f" Gate count: ")
()
()
pm = PassManager()
pm.append(Optimize1qGates())
pm.append(CommutativeCancellation())
pm.append(CXCancellation())
further_optimized = pm.run(transpiled)
()
()
()
()
depth_reduction = ( - further_optimized.depth() / qc.depth()) *
gate_reduction = ( - (further_optimized.data) / (qc.data)) *
()
()
()
further_optimized
qc = QuantumCircuit()
qc.h(())
i ():
qc.cx(i, i+)
qc.barrier()
i ():
qc.ry(np.pi/, i)
qc.barrier()
i ():
qc.cx(i, i+)
optimized = optimize_circuit_for_hardware(qc)
Quantum Algorithm Benchmarking
from qiskit import QuantumCircuit
from qiskit.algorithms import VQE, QAOA
from qiskit.algorithms.optimizers import SLSQP, COBYLA, SPSA
from qiskit.circuit.library import RealAmplitudes
from qiskit.primitives import Estimator
from qiskit.quantum_info import SparsePauliOp
import time
import numpy as np
def benchmark_vqe_optimizers(hamiltonian, ansatz, optimizers_dict, trials=3):
"""
Benchmark different optimizers for VQE.
Args:
hamiltonian: Problem Hamiltonian
ansatz: Variational ansatz
optimizers_dict: Dict of optimizer name -> optimizer instance
trials: Number of trials per optimizer
"""
results = {}
for opt_name, optimizer in optimizers_dict.items():
print(f"\nBenchmarking {opt_name}...")
trial_results = []
for trial in range(trials):
estimator = Estimator()
vqe = VQE(estimator, ansatz, optimizer)
start_time = time.time()
result = vqe.compute_minimum_eigenvalue(hamiltonian)
elapsed_time = time.time() - start_time
trial_results.append({
'energy': result.eigenvalue,
'time': elapsed_time,
'evals': result.cost_function_evals
})
print(f" Trial {trial + 1}: E = {result.eigenvalue:.6f}, "
)
energies = [r[] r trial_results]
times = [r[] r trial_results]
evals = [r[] r trial_results]
results[opt_name] = {
: np.mean(energies),
: np.std(energies),
: np.mean(times),
: np.mean(evals),
: (energies)
}
( + *)
()
(*)
()
(*)
opt_name, res results.items():
(
)
results
hamiltonian = SparsePauliOp([, , ], coeffs=[, -, -])
ansatz = RealAmplitudes(num_qubits=, reps=)
optimizers = {
: SLSQP(maxiter=),
: COBYLA(maxiter=),
: SPSA(maxiter=)
}
benchmark_results = benchmark_vqe_optimizers(hamiltonian, ansatz, optimizers, trials=)
Common Pitfalls and Solutions
Memory Management for Large Circuits
from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
import numpy as np
def bad_simulation():
qc = QuantumCircuit(25)
for i in range(25):
qc.h(i)
def good_simulation_sampling():
qc = QuantumCircuit(25, 25)
for i in range(25):
qc.h(i)
qc.measure_all()
simulator = AerSimulator(method='automatic')
result = simulator.run(qc, shots=1000).result()
counts = result.get_counts()
return counts
def good_simulation_mps():
qc = QuantumCircuit(50)
for i in range(49):
qc.h(i)
qc.cx(i, i+)
simulator = AerSimulator(method=)
qc.measure_all()
result = simulator.run(qc, shots=).result()
result.get_counts()
():
qc = QuantumCircuit()
i ():
qc.h(i)
simulator = AerSimulator()
qc.measure_all()
result = simulator.run(qc, shots=).result()
result.get_counts()
counts = good_simulation_sampling()
()
Handling Convergence Issues in VQE
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SLSQP, COBYLA
from qiskit.circuit.library import RealAmplitudes
from qiskit.primitives import Estimator
from qiskit.quantum_info import SparsePauliOp
import numpy as np
def robust_vqe(hamiltonian, n_qubits, max_attempts=5):
"""
VQE with multiple restart attempts and parameter initialization.
Args:
hamiltonian: Problem Hamiltonian
n_qubits: Number of qubits
max_attempts: Maximum restart attempts
"""
best_result = None
best_energy = float('inf')
for attempt in range(max_attempts):
print(f"\nAttempt {attempt + 1}/{max_attempts}")
ansatz = RealAmplitudes(num_qubits=n_qubits, reps=2)
initial_point = np.random.uniform(-np.pi, np.pi, ansatz.num_parameters)
if attempt < max_attempts // 2:
optimizer = COBYLA(maxiter=200)
else:
optimizer = SLSQP(maxiter=200)
estimator = Estimator()
vqe = VQE(estimator, ansatz, optimizer, initial_point=initial_point)
try:
result = vqe.compute_minimum_eigenvalue(hamiltonian)
()
()
result.eigenvalue < best_energy:
best_energy = result.eigenvalue
best_result = result
()
Exception e:
()
best_result :
RuntimeError()
()
best_result
hamiltonian = SparsePauliOp([, , ], coeffs=[, -, -])
result = robust_vqe(hamiltonian, n_qubits=, max_attempts=)