Tutorials
Step-by-step guides for CV cluster state design and optimization
Beginner
Your First Cluster State
Create a simple 4-mode square cluster state and verify entanglement through nullifier variance.
from cv_cluster import ClusterCompiler
from cv_cluster.graph import GraphState
# Define square graph
graph = GraphState.square(4)
print(f"Adjacency matrix:\n{graph.adjacency_matrix}")
# Create compiler
compiler = ClusterCompiler(
graph=graph,
squeezing_dB=6.0,
mesh_architecture="clements"
)
# Compute nullifier variances
variances = compiler.compute_nullifier_variances()
print(f"Nullifier variances: {variances}")
print(f"All < 1 SNU: {all(v < 1 for v in variances)}")
Understanding Nullifiers
Deep dive into CV nullifier operators and their physical interpretation for cluster states.
# Nullifier: δ_j = p_j - Σ_k A_jk x_k
# For mode 0 in a square graph:
# δ_0 = p_0 - A_01*x_1 - A_03*x_3
import numpy as np
# Get nullifier coefficients
coeffs = graph.nullifier_coefficients(mode=0)
print(f"c = {coeffs}") # [0,0,0,0, 1,-1,0,-1]
# Variance: ⟨δ²⟩ = c^T V c
V = compiler.get_covariance_matrix()
variance = coeffs @ V @ coeffs
print(f"⟨δ_0²⟩ = {variance:.4f} SNU")
Interferometer Mesh Basics
Learn how Clements and Reck decompositions implement arbitrary unitaries for cluster generation.
from cv_cluster.mesh import MeshOptimizer
# Clements mesh: O(N²) beamsplitters
mesh = MeshOptimizer(num_modes=4, architecture="clements")
print(f"Number of phases: {mesh.num_phases}")
# Get symplectic matrix for random phases
phases = np.random.uniform(0, 2*np.pi, mesh.num_phases)
S = mesh.symplectic_matrix(phases)
print(f"Symplectic shape: {S.shape}") # (8, 8)
# Verify symplecticity: S Ω S^T = Ω
Omega = mesh.symplectic_form()
check = S @ Omega @ S.T
print(f"Symplectic: {np.allclose(check, Omega)}")
Visualizing Cluster States
Plot Wigner functions, covariance matrices, and graph representations for your cluster states.
from cv_cluster.viz import plot_wigner, plot_graph
# Plot single-mode marginal Wigner
plot_wigner(compiler, mode=0, resolution=100)
# Plot two-mode correlations
plot_wigner(compiler, modes=[0, 1], projection="x1-x2")
# Visualize graph structure
plot_graph(graph, show_weights=True)
# Covariance matrix heatmap
V = compiler.get_covariance_matrix()
plot_covariance(V, labels=['x0','p0','x1','p1',...])
Intermediate
Phase Optimization
Use gradient-based optimization to find optimal interferometer phases that minimize nullifier variances.
# Define cost function
def cost(phases):
vars = compiler.compute_nullifier_variances(phases)
return np.mean(vars)
# Optimize with L-BFGS-B
result = compiler.optimize_phases(
method="L-BFGS-B",
tol=1e-8,
maxiter=1000
)
print(f"Initial variance: {result.initial_cost:.4f}")
print(f"Final variance: {result.final_cost:.4f}")
print(f"Iterations: {result.iterations}")
print(f"Optimal phases: {result.optimal_phases}")
Custom Graph Topologies
Design custom graph adjacency matrices for specialized cluster state applications.
# Weighted graph for error correction
adj = np.array([
[0, 1, 0, 0.5],
[1, 0, 1, 0],
[0, 1, 0, 1],
[0.5, 0, 1, 0]
])
graph = GraphState.from_adjacency(adj)
# Validate graph properties
print(f"Symmetric: {graph.is_symmetric}")
print(f"Connected: {graph.is_connected}")
print(f"Edge count: {graph.num_edges}")
# Build hierarchical graph
g1 = GraphState.line(3)
g2 = GraphState.line(3)
combined = GraphState.connect(g1, g2, [(2, 0)])
Loss Modeling
Incorporate realistic optical losses and find the critical threshold for entanglement preservation.
from cv_cluster.loss import LossSimulator
# Configure per-layer loss
loss_sim = LossSimulator(
compiler,
loss_per_layer_dB=0.5,
num_layers=4
)
# Analyze mode-wise degradation
result = loss_sim.analyze()
for i, var in enumerate(result.mode_variances):
status = "✓" if var < 1 else "✗"
print(f"Mode {i}: {var:.3f} SNU {status}")
# Find critical threshold
threshold = loss_sim.find_critical_loss()
print(f"Critical: {threshold:.2f} dB/layer")
Monte Carlo Tolerance Analysis
Run statistical simulations to assess fabrication tolerance impact on cluster state quality.
from cv_cluster.analysis import MonteCarloAnalyzer
mc = MonteCarloAnalyzer(compiler)
# Configure error distributions
result = mc.run(
num_trials=1000,
phase_error_std=0.5, # degrees
bs_imbalance_std=0.02, # fraction
threshold=1.2 # SNU
)
print(f"Success rate: {result.success_rate:.1%}")
print(f"Mean variance: {result.mean_variance:.4f}")
print(f"95th percentile: {result.percentile_95:.4f}")
# Sweep phase error
sweep = mc.sweep_phase_error(errors=np.linspace(0,3,31))
plt.plot(sweep.errors, sweep.success_rates)
Advanced
MBQC Gate Implementation
Implement measurement-based quantum gates using CV cluster states with proper basis corrections.
from cv_cluster.mbqc import MBQCGate
# Create wire cluster for identity
wire = GraphState.line(3)
compiler = ClusterCompiler(wire, squeezing_dB=10)
# Implement Fourier transform
fourier = MBQCGate(
cluster=compiler,
measurement_bases=["p", "x"], # First two modes
feedforward=True
)
# Simulate gate
output = fourier.apply(input_state)
fidelity = fourier.compute_fidelity(ideal_output)
print(f"Gate fidelity: {fidelity:.4f}")
Multi-Objective Optimization
Jointly optimize for minimal variance, loss tolerance, and fabrication robustness.
from cv_cluster.optimize import MultiObjective
# Define objectives
def variance_cost(phases):
return compiler.compute_nullifier_variances(phases).mean()
def robustness_cost(phases):
mc = MonteCarloAnalyzer(compiler)
return 1 - mc.quick_success_rate(phases)
# Pareto optimization
optimizer = MultiObjective(
objectives=[variance_cost, robustness_cost],
weights=[0.7, 0.3]
)
pareto_front = optimizer.optimize(population=100, generations=50)
print(f"Pareto solutions: {len(pareto_front)}")