mirror of
https://github.com/K-Dense-AI/claude-scientific-skills.git
synced 2026-01-26 16:58:56 +08:00
9.2 KiB
9.2 KiB
Quantum Circuits in PennyLane
Table of Contents
- Basic Gates and Operations
- Multi-Qubit Gates
- Controlled Operations
- Measurements
- Circuit Construction Patterns
- Dynamic Circuits
- Circuit Inspection
Basic Gates and Operations
Single-Qubit Gates
import pennylane as qml
# Pauli gates
qml.PauliX(wires=0) # X gate (bit flip)
qml.PauliY(wires=0) # Y gate
qml.PauliZ(wires=0) # Z gate (phase flip)
# Hadamard gate (superposition)
qml.Hadamard(wires=0)
# Phase gates
qml.S(wires=0) # S gate (π/2 phase)
qml.T(wires=0) # T gate (π/4 phase)
qml.PhaseShift(phi, wires=0) # Arbitrary phase
# Rotation gates (parameterized)
qml.RX(theta, wires=0) # Rotation around X-axis
qml.RY(theta, wires=0) # Rotation around Y-axis
qml.RZ(theta, wires=0) # Rotation around Z-axis
# General single-qubit rotation
qml.Rot(phi, theta, omega, wires=0)
# Universal gate (any single-qubit unitary)
qml.U3(theta, phi, delta, wires=0)
Basis State Preparation
# Computational basis state
qml.BasisState([1, 0, 1], wires=[0, 1, 2]) # |101⟩
# Amplitude encoding
amplitudes = [0.5, 0.5, 0.5, 0.5] # Must be normalized
qml.MottonenStatePreparation(amplitudes, wires=[0, 1])
Multi-Qubit Gates
Two-Qubit Gates
# CNOT (Controlled-NOT)
qml.CNOT(wires=[0, 1]) # control=0, target=1
# CZ (Controlled-Z)
qml.CZ(wires=[0, 1])
# SWAP gate
qml.SWAP(wires=[0, 1])
# Controlled rotations
qml.CRX(theta, wires=[0, 1])
qml.CRY(theta, wires=[0, 1])
qml.CRZ(theta, wires=[0, 1])
# Ising coupling gates
qml.IsingXX(phi, wires=[0, 1])
qml.IsingYY(phi, wires=[0, 1])
qml.IsingZZ(phi, wires=[0, 1])
Multi-Qubit Gates
# Toffoli gate (CCNOT)
qml.Toffoli(wires=[0, 1, 2]) # control=0,1, target=2
# Multi-controlled X
qml.MultiControlledX(control_wires=[0, 1, 2], wires=3)
# Multi-qubit Pauli rotations
qml.MultiRZ(theta, wires=[0, 1, 2])
Controlled Operations
General Controlled Operations
# Apply controlled version of any operation
qml.ctrl(qml.RX(0.5, wires=1), control=0)
# Multiple control qubits
qml.ctrl(qml.RY(0.3, wires=2), control=[0, 1])
# Negative controls (activate when control is |0⟩)
qml.ctrl(qml.Hadamard(wires=2), control=0, control_values=[0])
Conditional Operations
@qml.qnode(dev)
def conditional_circuit():
qml.Hadamard(wires=0)
# Mid-circuit measurement
m = qml.measure(0)
# Apply gate conditionally
qml.cond(m, qml.PauliX)(wires=1)
return qml.expval(qml.PauliZ(1))
Measurements
Expectation Values
@qml.qnode(dev)
def measure_expectation():
qml.Hadamard(wires=0)
# Single observable
return qml.expval(qml.PauliZ(0))
@qml.qnode(dev)
def measure_tensor():
qml.Hadamard(wires=0)
qml.Hadamard(wires=1)
# Tensor product of observables
return qml.expval(qml.PauliZ(0) @ qml.PauliZ(1))
Probability Distributions
@qml.qnode(dev)
def measure_probabilities():
qml.Hadamard(wires=0)
qml.CNOT(wires=[0, 1])
# Probabilities of all basis states
return qml.probs(wires=[0, 1]) # Returns [p(|00⟩), p(|01⟩), p(|10⟩), p(|11⟩)]
Samples and Counts
@qml.qnode(dev)
def measure_samples(shots=1000):
qml.Hadamard(wires=0)
# Raw samples
return qml.sample(qml.PauliZ(0))
@qml.qnode(dev)
def measure_counts(shots=1000):
qml.Hadamard(wires=0)
qml.CNOT(wires=[0, 1])
# Count occurrences
return qml.counts(wires=[0, 1])
Variance
@qml.qnode(dev)
def measure_variance():
qml.RX(0.5, wires=0)
# Variance of observable
return qml.var(qml.PauliZ(0))
Mid-Circuit Measurements
@qml.qnode(dev)
def mid_circuit_measure():
qml.Hadamard(wires=0)
# Measure qubit 0 during circuit
m0 = qml.measure(0)
# Use measurement result
qml.cond(m0, qml.PauliX)(wires=1)
# Final measurement
return qml.expval(qml.PauliZ(1))
Circuit Construction Patterns
Layer-Based Construction
def layer(weights, wires):
"""Single layer of parameterized gates."""
for i, wire in enumerate(wires):
qml.RY(weights[i], wires=wire)
for wire in wires[:-1]:
qml.CNOT(wires=[wire, wire+1])
@qml.qnode(dev)
def layered_circuit(weights):
n_layers = len(weights)
wires = range(4)
for i in range(n_layers):
layer(weights[i], wires)
return qml.expval(qml.PauliZ(0))
Data Encoding
def angle_encoding(x, wires):
"""Encode classical data as rotation angles."""
for i, wire in enumerate(wires):
qml.RX(x[i], wires=wire)
def amplitude_encoding(x, wires):
"""Encode data as quantum state amplitudes."""
qml.MottonenStatePreparation(x, wires=wires)
def basis_encoding(x, wires):
"""Encode binary data in computational basis."""
for i, val in enumerate(x):
if val:
qml.PauliX(wires=i)
Ansatz Patterns
# Hardware-efficient ansatz
def hardware_efficient_ansatz(weights, wires):
n_layers = len(weights) // len(wires)
for layer in range(n_layers):
# Rotation layer
for i, wire in enumerate(wires):
qml.RY(weights[layer * len(wires) + i], wires=wire)
# Entanglement layer
for wire in wires[:-1]:
qml.CNOT(wires=[wire, wire+1])
# Alternating layered ansatz
def alternating_ansatz(weights, wires):
for w in weights:
for wire in wires:
qml.RX(w[wire], wires=wire)
for wire in wires[:-1]:
qml.CNOT(wires=[wire, wire+1])
Dynamic Circuits
For Loops
@qml.qnode(dev)
def dynamic_for_loop(n_iterations):
qml.Hadamard(wires=0)
# Dynamic for loop
for i in range(n_iterations):
qml.RX(0.1 * i, wires=0)
return qml.expval(qml.PauliZ(0))
While Loops (with Catalyst)
@qml.qjit # Just-in-time compilation
@qml.qnode(dev)
def dynamic_while_loop():
qml.Hadamard(wires=0)
# Dynamic while loop
@qml.while_loop(lambda i: i < 5)
def loop(i):
qml.RX(0.1, wires=0)
return i + 1
loop(0)
return qml.expval(qml.PauliZ(0))
Adaptive Circuits
@qml.qnode(dev)
def adaptive_circuit():
qml.Hadamard(wires=0)
# Measure and adapt
m = qml.measure(0)
# Different paths based on measurement
if m:
qml.RX(0.5, wires=1)
else:
qml.RY(0.5, wires=1)
return qml.expval(qml.PauliZ(1))
Circuit Inspection
Drawing Circuits
# Text representation
print(qml.draw(circuit)(params))
# ASCII art
print(qml.draw(circuit, wire_order=[0,1,2])(params))
# Matplotlib visualization
fig, ax = qml.draw_mpl(circuit)(params)
Analyzing Circuit Structure
# Get circuit specs
specs = qml.specs(circuit)(params)
print(f"Gates: {specs['gate_sizes']}")
print(f"Depth: {specs['depth']}")
print(f"Parameters: {specs['num_trainable_params']}")
# Resource estimation
resources = qml.resource.resource_estimation(circuit)(params)
print(f"Total gates: {resources['num_gates']}")
Tape Inspection
# Record operations
with qml.tape.QuantumTape() as tape:
qml.Hadamard(wires=0)
qml.CNOT(wires=[0, 1])
qml.expval(qml.PauliZ(0))
# Inspect tape contents
print("Operations:", tape.operations)
print("Measurements:", tape.measurements)
print("Wires used:", tape.wires)
Circuit Transformations
# Expand composite operations
expanded = qml.transforms.expand_tape(tape)
# Cancel adjacent operations
optimized = qml.transforms.cancel_inverses(tape)
# Commute measurements to end
commuted = qml.transforms.commute_controlled(tape)
Best Practices
- Use native gates - Prefer gates supported by target device
- Minimize circuit depth - Reduce decoherence effects
- Encode efficiently - Choose encoding matching data structure
- Reuse circuits - Cache compiled circuits when possible
- Validate measurements - Ensure observables are Hermitian
- Check qubit count - Verify device has sufficient wires
- Profile circuits - Use
qml.specs()to analyze complexity
Common Patterns
Bell State Preparation
@qml.qnode(dev)
def bell_state():
qml.Hadamard(wires=0)
qml.CNOT(wires=[0, 1])
return qml.state() # Returns |Φ+⟩ = (|00⟩ + |11⟩)/√2
GHZ State
@qml.qnode(dev)
def ghz_state(n_qubits):
qml.Hadamard(wires=0)
for i in range(n_qubits-1):
qml.CNOT(wires=[0, i+1])
return qml.state()
Quantum Fourier Transform
def qft(wires):
"""Quantum Fourier Transform."""
n_wires = len(wires)
for i in range(n_wires):
qml.Hadamard(wires=wires[i])
for j in range(i+1, n_wires):
qml.CRZ(np.pi / (2**(j-i)), wires=[wires[j], wires[i]])
Inverse QFT
def inverse_qft(wires):
"""Inverse Quantum Fourier Transform."""
n_wires = len(wires)
for i in range(n_wires-1, -1, -1):
for j in range(n_wires-1, i, -1):
qml.CRZ(-np.pi / (2**(j-i)), wires=[wires[j], wires[i]])
qml.Hadamard(wires=wires[i])