mirror of
https://github.com/K-Dense-AI/claude-scientific-skills.git
synced 2026-01-26 16:58:56 +08:00
308 lines
5.8 KiB
Markdown
308 lines
5.8 KiB
Markdown
# Building Quantum Circuits
|
|
|
|
This guide covers circuit construction in Cirq, including qubits, gates, operations, and circuit patterns.
|
|
|
|
## Basic Circuit Construction
|
|
|
|
### Creating Circuits
|
|
|
|
```python
|
|
import cirq
|
|
|
|
# Create a circuit
|
|
circuit = cirq.Circuit()
|
|
|
|
# Create qubits
|
|
q0 = cirq.GridQubit(0, 0)
|
|
q1 = cirq.GridQubit(0, 1)
|
|
q2 = cirq.LineQubit(0)
|
|
|
|
# Add gates to circuit
|
|
circuit.append([
|
|
cirq.H(q0),
|
|
cirq.CNOT(q0, q1),
|
|
cirq.measure(q0, q1, key='result')
|
|
])
|
|
```
|
|
|
|
### Qubit Types
|
|
|
|
**GridQubit**: 2D grid topology for hardware-like layouts
|
|
```python
|
|
qubits = cirq.GridQubit.square(2) # 2x2 grid
|
|
qubit = cirq.GridQubit(row=0, col=1)
|
|
```
|
|
|
|
**LineQubit**: 1D linear topology
|
|
```python
|
|
qubits = cirq.LineQubit.range(5) # 5 qubits in a line
|
|
qubit = cirq.LineQubit(3)
|
|
```
|
|
|
|
**NamedQubit**: Custom-named qubits
|
|
```python
|
|
qubit = cirq.NamedQubit('my_qubit')
|
|
```
|
|
|
|
## Common Gates and Operations
|
|
|
|
### Single-Qubit Gates
|
|
|
|
```python
|
|
# Pauli gates
|
|
cirq.X(qubit) # NOT gate
|
|
cirq.Y(qubit)
|
|
cirq.Z(qubit)
|
|
|
|
# Hadamard
|
|
cirq.H(qubit)
|
|
|
|
# Rotation gates
|
|
cirq.rx(angle)(qubit) # Rotation around X-axis
|
|
cirq.ry(angle)(qubit) # Rotation around Y-axis
|
|
cirq.rz(angle)(qubit) # Rotation around Z-axis
|
|
|
|
# Phase gates
|
|
cirq.S(qubit) # √Z gate
|
|
cirq.T(qubit) # ⁴√Z gate
|
|
```
|
|
|
|
### Two-Qubit Gates
|
|
|
|
```python
|
|
# CNOT (Controlled-NOT)
|
|
cirq.CNOT(control, target)
|
|
cirq.CX(control, target) # Alias
|
|
|
|
# CZ (Controlled-Z)
|
|
cirq.CZ(q0, q1)
|
|
|
|
# SWAP
|
|
cirq.SWAP(q0, q1)
|
|
|
|
# iSWAP
|
|
cirq.ISWAP(q0, q1)
|
|
|
|
# Controlled rotations
|
|
cirq.CZPowGate(exponent=0.5)(q0, q1)
|
|
```
|
|
|
|
### Measurement Operations
|
|
|
|
```python
|
|
# Measure single qubit
|
|
cirq.measure(qubit, key='m')
|
|
|
|
# Measure multiple qubits
|
|
cirq.measure(q0, q1, q2, key='result')
|
|
|
|
# Measure all qubits in circuit
|
|
circuit.append(cirq.measure(*qubits, key='final'))
|
|
```
|
|
|
|
## Advanced Circuit Construction
|
|
|
|
### Parameterized Gates
|
|
|
|
```python
|
|
import sympy
|
|
|
|
# Create symbolic parameters
|
|
theta = sympy.Symbol('theta')
|
|
phi = sympy.Symbol('phi')
|
|
|
|
# Use in gates
|
|
circuit = cirq.Circuit(
|
|
cirq.rx(theta)(q0),
|
|
cirq.ry(phi)(q1),
|
|
cirq.CNOT(q0, q1)
|
|
)
|
|
|
|
# Resolve parameters later
|
|
resolved = cirq.resolve_parameters(circuit, {'theta': 0.5, 'phi': 1.2})
|
|
```
|
|
|
|
### Custom Gates via Unitaries
|
|
|
|
```python
|
|
import numpy as np
|
|
|
|
# Define unitary matrix
|
|
unitary = np.array([
|
|
[1, 0, 0, 0],
|
|
[0, 1, 0, 0],
|
|
[0, 0, 0, 1],
|
|
[0, 0, 1, 0]
|
|
]) / np.sqrt(2)
|
|
|
|
# Create gate from unitary
|
|
gate = cirq.MatrixGate(unitary)
|
|
operation = gate(q0, q1)
|
|
```
|
|
|
|
### Gate Decomposition
|
|
|
|
```python
|
|
# Define custom gate with decomposition
|
|
class MyGate(cirq.Gate):
|
|
def _num_qubits_(self):
|
|
return 1
|
|
|
|
def _decompose_(self, qubits):
|
|
q = qubits[0]
|
|
return [cirq.H(q), cirq.T(q), cirq.H(q)]
|
|
|
|
def _circuit_diagram_info_(self, args):
|
|
return 'MyGate'
|
|
|
|
# Use the custom gate
|
|
my_gate = MyGate()
|
|
circuit.append(my_gate(q0))
|
|
```
|
|
|
|
## Circuit Organization
|
|
|
|
### Moments
|
|
|
|
Circuits are organized into moments (parallel operations):
|
|
|
|
```python
|
|
# Explicit moment construction
|
|
circuit = cirq.Circuit(
|
|
cirq.Moment([cirq.H(q0), cirq.H(q1)]),
|
|
cirq.Moment([cirq.CNOT(q0, q1)]),
|
|
cirq.Moment([cirq.measure(q0, key='m0'), cirq.measure(q1, key='m1')])
|
|
)
|
|
|
|
# Access moments
|
|
for i, moment in enumerate(circuit):
|
|
print(f"Moment {i}: {moment}")
|
|
```
|
|
|
|
### Circuit Operations
|
|
|
|
```python
|
|
# Concatenate circuits
|
|
circuit3 = circuit1 + circuit2
|
|
|
|
# Insert operations
|
|
circuit.insert(index, operation)
|
|
|
|
# Append with strategy
|
|
circuit.append(operations, strategy=cirq.InsertStrategy.NEW_THEN_INLINE)
|
|
```
|
|
|
|
## Circuit Patterns
|
|
|
|
### Bell State Preparation
|
|
|
|
```python
|
|
def bell_state_circuit():
|
|
q0, q1 = cirq.LineQubit.range(2)
|
|
return cirq.Circuit(
|
|
cirq.H(q0),
|
|
cirq.CNOT(q0, q1)
|
|
)
|
|
```
|
|
|
|
### GHZ State
|
|
|
|
```python
|
|
def ghz_circuit(qubits):
|
|
circuit = cirq.Circuit()
|
|
circuit.append(cirq.H(qubits[0]))
|
|
for i in range(len(qubits) - 1):
|
|
circuit.append(cirq.CNOT(qubits[i], qubits[i+1]))
|
|
return circuit
|
|
```
|
|
|
|
### Quantum Fourier Transform
|
|
|
|
```python
|
|
def qft_circuit(qubits):
|
|
circuit = cirq.Circuit()
|
|
for i, q in enumerate(qubits):
|
|
circuit.append(cirq.H(q))
|
|
for j in range(i + 1, len(qubits)):
|
|
circuit.append(cirq.CZPowGate(exponent=1/2**(j-i))(qubits[j], q))
|
|
|
|
# Reverse qubit order
|
|
for i in range(len(qubits) // 2):
|
|
circuit.append(cirq.SWAP(qubits[i], qubits[len(qubits) - i - 1]))
|
|
|
|
return circuit
|
|
```
|
|
|
|
## Circuit Import/Export
|
|
|
|
### OpenQASM
|
|
|
|
```python
|
|
# Export to QASM
|
|
qasm_str = circuit.to_qasm()
|
|
|
|
# Import from QASM
|
|
from cirq.contrib.qasm_import import circuit_from_qasm
|
|
circuit = circuit_from_qasm(qasm_str)
|
|
```
|
|
|
|
### Circuit JSON
|
|
|
|
```python
|
|
import json
|
|
|
|
# Serialize
|
|
json_str = cirq.to_json(circuit)
|
|
|
|
# Deserialize
|
|
circuit = cirq.read_json(json_text=json_str)
|
|
```
|
|
|
|
## Working with Qudits
|
|
|
|
Qudits are higher-dimensional quantum systems (qutrits, ququarts, etc.):
|
|
|
|
```python
|
|
# Create qutrit (3-level system)
|
|
qutrit = cirq.LineQid(0, dimension=3)
|
|
|
|
# Custom qutrit gate
|
|
class QutritXGate(cirq.Gate):
|
|
def _qid_shape_(self):
|
|
return (3,)
|
|
|
|
def _unitary_(self):
|
|
return np.array([
|
|
[0, 0, 1],
|
|
[1, 0, 0],
|
|
[0, 1, 0]
|
|
])
|
|
|
|
gate = QutritXGate()
|
|
circuit = cirq.Circuit(gate(qutrit))
|
|
```
|
|
|
|
## Observables
|
|
|
|
Create observables from Pauli operators:
|
|
|
|
```python
|
|
# Single Pauli observable
|
|
obs = cirq.Z(q0)
|
|
|
|
# Pauli string
|
|
obs = cirq.X(q0) * cirq.Y(q1) * cirq.Z(q2)
|
|
|
|
# Linear combination
|
|
from cirq import PauliSum
|
|
obs = 0.5 * cirq.X(q0) + 0.3 * cirq.Z(q1)
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
1. **Use appropriate qubit types**: GridQubit for hardware-like topologies, LineQubit for 1D problems
|
|
2. **Keep circuits modular**: Build reusable circuit functions
|
|
3. **Use symbolic parameters**: For parameter sweeps and optimization
|
|
4. **Label measurements clearly**: Use descriptive keys for measurement results
|
|
5. **Document custom gates**: Include circuit diagram information for visualization
|