- 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
```bash
# Core Qiskit
pip install qiskit
# With visualization tools
pip install qiskit[visualization]
# Quantum chemistry extension
pip install qiskit-nature qiskit-nature-pyscf
# Machine learning extension
pip install qiskit-machine-learning
# Optimization extension
pip install qiskit-optimization
# Full installation
pip install 'qiskit[all]' qiskit-nature qiskit-machine-learning qiskit-optimization
```
### Standard Imports
```python
# Core 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
# Quantum algorithms
from qiskit.algorithms import VQE, QAOA, Grover, Shor
from qiskit.algorithms.optimizers import SLSQP, COBYLA, SPSA
# Quantum info
from qiskit.quantum_info import Statevector, DensityMatrix, Operator
from qiskit.quantum_info import entropy, entanglement_of_formation
# Circuit library
from qiskit.circuit.library import QFT, RealAmplitudes, EfficientSU2
```
### Basic Pattern - Circuit Building
```python
from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
# Create circuit
qc = QuantumCircuit(2, 2)
# Add gates
qc.h(0) # Hadamard on qubit 0
qc.cx(0, 1) # CNOT from 0 to 1
# Measure
qc.measure([0, 1], [0, 1])
# Simulate
simulator = AerSimulator()
job = simulator.run(qc, shots=1000)
result = job.result()
counts = result.get_counts()
print(f"Results: {counts}")
```
### Basic Pattern - Quantum Algorithm
```python
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
# Define Hamiltonian
hamiltonian = SparsePauliOp(['ZZ', 'IZ', 'ZI'], coeffs=[1.0, -0.5, -0.5])
# Create ansatz
ansatz = RealAmplitudes(num_qubits=2, reps=1)
# Setup VQE
optimizer = SLSQP(maxiter=100)
estimator = Estimator()
vqe = VQE(estimator, ansatz, optimizer)
# Run
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)
```python
from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
from qiskit.primitives import Estimator
# ❌ BAD: No measurement
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
# Forgot qc.measure()!
# ✅ GOOD: Always measure when needed
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0, 1], [0, 1])
# ❌ BAD: Using deprecated execute()
from qiskit import execute
result = execute(qc, backend, shots=1024).result()
# ✅ GOOD: Use new run() method
simulator = AerSimulator()
job = simulator.run(qc, shots=1024)
result = job.result()
# ❌ BAD: Assuming perfect measurement
counts = result.get_counts()
# Assuming exactly 50/50 split!
assert counts['00'] == 512
# ✅ GOOD: Handle statistical variation
counts = result.get_counts()
ratio = counts.get('00', 0) / sum(counts.values())
print(f"Measured |00⟩ with probability {ratio:.3f}")
# ❌ BAD: Not checking circuit properties
qc = QuantumCircuit(20) # Many qubits!
# Adding many gates...
# Trying to simulate without checking depth/size!
# ✅ GOOD: Check circuit properties
qc = QuantumCircuit(20)
# ... add gates ...
print(f"Circuit depth: {qc.depth()}")
print(f"Gate count: {len(qc.data)}")
print(f"Qubits: {qc.num_qubits}")
# ❌ BAD: Ignoring transpilation
job = backend.run(qc) # May fail on real hardware!
# ✅ GOOD: Transpile for backend
from qiskit import transpile
transpiled_qc = transpile(qc, backend=backend, optimization_level=3)
job = backend.run(transpiled_qc)
```
## Quantum Circuits (qiskit.QuantumCircuit)
### Basic Circuit Construction
```python
from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister
import numpy as np
# Method 1: Simple initialization
qc = QuantumCircuit(3, 3) # 3 qubits, 3 classical bits
# Method 2: Using registers
qr = QuantumRegister(3, 'q')
cr = ClassicalRegister(3, 'c')
qc = QuantumCircuit(qr, cr)
# Method 3: Multiple registers
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
```python
from qiskit import QuantumCircuit
import numpy as np
qc = QuantumCircuit(1)
# Pauli gates
qc.x(0) # Pauli X (NOT gate)
qc.y(0) # Pauli Y
qc.z(0) # Pauli Z
# Hadamard gate
qc.h(0) # Creates superposition
# Phase gates
qc.s(0) # S gate (π/2 phase)
qc.t(0) # T gate (π/4 phase)
qc.sdg(0) # S dagger
qc.tdg(0) # T dagger
# Rotation gates
qc.rx(np.pi/4, 0) # Rotation around X
qc.ry(np.pi/4, 0) # Rotation around Y
qc.rz(np.pi/4, 0) # Rotation around Z
# General rotation
qc.u(np.pi/4, np.pi/2, np.pi, 0) # U gate
# Identity (wait)
qc.id(0)
print(f"Gate count: {len(qc.data)}")
```
### Two-Qubit Gates
```python
from qiskit import QuantumCircuit
import numpy as np
qc = QuantumCircuit(2)
# CNOT (Controlled-NOT)
qc.cx(0, 1) # Control: 0, Target: 1
# Other controlled gates
qc.cy(0, 1) # Controlled-Y
qc.cz(0, 1) # Controlled-Z
qc.ch(0, 1) # Controlled-Hadamard
# SWAP gate
qc.swap(0, 1)
# Controlled phase
qc.cp(np.pi/4, 0, 1)
# Controlled-U
qc.cu(np.pi/4, np.pi/2, np.pi, 0, 0, 1)
# Toffoli (CCX) - needs 3 qubits
qc_3 = QuantumCircuit(3)
qc_3.ccx(0, 1, 2) # Controls: 0,1, Target: 2
print(qc.draw())
```
### Creating Entanglement
```python
from qiskit import QuantumCircuit
from qiskit.providers.aer import AerSimulator
from qiskit.quantum_info import Statevector
# Bell state (maximally entangled)
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}")
# GHZ state (3-qubit entanglement)
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}")
# W state (another type of 3-qubit entanglement)
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()
print(f"W state circuit depth: {w.depth()}")
```
### Parameterized Circuits
```python
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter, ParameterVector
import numpy as np
# Single parameter
theta = Parameter('θ')
qc = QuantumCircuit(1)
qc.ry(theta, 0)
# Bind parameter
bound_qc = qc.bind_parameters({theta: np.pi/4})
print(f"Unbound: {qc}")
print(f"Bound: {bound_qc}")
# Multiple parameters
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)
# Bind all parameters
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)
```python
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
# Define Hamiltonian (e.g., H2 molecule)
# H = -1.05 * ZZ + 0.39 * XX - 0.39 * YY - 0.01 * ZI
hamiltonian = SparsePauliOp(
['ZZ', 'XX', 'YY', 'ZI', 'IZ'],
coeffs=[-1.05, 0.39, -0.39, -0.01, -0.01]
)
# Create ansatz (variational form)
ansatz = RealAmplitudes(num_qubits=2, reps=2)
# Alternative: EfficientSU2
# ansatz = EfficientSU2(num_qubits=2, reps=2)
# Setup optimizer
optimizer = SLSQP(maxiter=100)
# Create estimator primitive
estimator = Estimator()
# Setup and run VQE
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}")
# Get optimal circuit
optimal_circuit = ansatz.bind_parameters(result.optimal_point)
print(f"\nOptimal circuit depth: {optimal_circuit.depth()}")
```
### QAOA (Quantum Approximate Optimization Algorithm)
```python
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
# Max-Cut problem on a triangle graph
View on GitHub