Hello World in Strawberry Fields
Your first photonic quantum program using Xanadu's Strawberry Fields, a fundamentally different model of quantum computing based on light and continuous variables.
Strawberry Fields is Xanadu’s Python library designed for photonic quantum computing. This approach represents a fundamentally different method compared to qubit-based systems such as Qiskit or Cirq. Rather than using qubits, which represent discrete 0/1 states, photonic computing utilizes optical modes-quantum states of light described by continuous variables. The central quantities here are the quadratures of the electromagnetic field: position (X) and momentum (P), which are analogous to the real and imaginary parts of a quantum harmonic oscillator. This continuous-variable approach offers several practical advantages. For instance, photonic quantum computers can operate at room temperature, eliminating the need for cryogenic cooling. They are also naturally suited for Gaussian Boson Sampling, a problem believed to demonstrate quantum advantage. Xanadu’s Borealis photonic processor demonstrated quantum advantage in 2022. Because of its nature, continuous-variable systems perform exceptionally well in fields like optimization, molecular simulation, and quantum machine learning.
Installation
pip install strawberryfields
For the TensorFlow backend (needed for quantum machine learning):
pip install strawberryfields[tf]
Understanding the Basics
Strawberry Fields programs operate using quantum optical modes, not qubits. You can configure the system to handle two, four, or eight modes.
The available gates correspond to specific optical operations. The Sgate(r) operation squeezes the state, reducing uncertainty in one quadrature, which is analogous to a rotation on the Bloch sphere in qubit systems. The Dgate(α) shifts the state in phase space, similar to a shift operation. For two modes, the BSgate(θ, φ) acts as a beamsplitter, mixing the two modes and serving as an analogy for a two-qubit gate. Two-mode squeezing, implemented by S2gate(r), creates entanglement and is somewhat comparable to a CNOT gate. Finally, Rgate(φ) performs a phase rotation, equivalent to a Z rotation.
When running simulations, you select a backend based on what the system needs to model. The "gaussian" backend is efficient for simulating only Gaussian states, relying on classical simulation methods. If you require full Fock (photon-number) states, the "fock" backend provides an exact, though computationally expensive, simulation. For machine learning applications, the "tf" backend is available, as it is differentiable using TensorFlow.
Single-Mode Squeezed State
The simplest non-trivial program involves squeezing the vacuum state and then displacing it.
import strawberryfields as sf
from strawberryfields.ops import Sgate, Dgate, MeasureX
# Create a program with 1 optical mode
prog = sf.Program(1)
with prog.context as q:
Sgate(0.5) | q[0] # Squeeze vacuum by r=0.5 (reduces position uncertainty)
Dgate(1.0, 0) | q[0] # Displace by α=1.0 (real part)
MeasureX | q[0] # Measure the X (position) quadrature
# Run on the Gaussian backend
eng = sf.Engine("gaussian")
result = eng.run(prog, shots=5)
print(result.samples)
# e.g. [[1.23], [0.91], [1.45], [0.78], [1.12]]
# Continuous values near 1.0 (our displacement), with reduced spread (squeezing)
The vacuum state, , serves as the starting point for every mode: zero photons, minimum uncertainty. Applying performs a squeeze, which reduces position uncertainty by while increasing momentum uncertainty. Next, shifts the entire state to a position near in phase space. Finally, samples the position quadrature, yielding a continuous value rather than a simple or .
This approach allows us to create a Bell state analog. By using two-mode squeezing, we generate continuous-variable entanglement, which is known as an EPR state.
import strawberryfields as sf
from strawberryfields.ops import S2gate, MeasureX, MeasureP
prog = sf.Program(2)
with prog.context as q:
S2gate(1.0) | (q[0], q[1]) # Two-mode squeezing: entangle modes 0 and 1
MeasureX | q[0] # Measure position of mode 0
MeasureP | q[1] # Measure momentum of mode 1
eng = sf.Engine("gaussian")
result = eng.run(prog, shots=10)
print(result.samples)
# Each row: [x_mode0, p_mode1]
# x_mode0 and x_mode1 will be correlated (EPR state property)
The two-mode squeezed state serves as the continuous-variable equivalent of an entangled Bell state. When the squeezing parameter approaches infinity (r → ∞), measuring one mode’s position yields precise knowledge of the other mode’s position, and measuring momentum gives anti-correlated results. This behavior is the continuous-variable analog of quantum entanglement.
The beamsplitter functions as a two-mode gate. It mixes two modes, much like a half-silvered mirror in optics. This gate is a primary component in photonic computing.
import strawberryfields as sf
from strawberryfields.ops import Sgate, BSgate, MeasureFock
import numpy as np
# Hong-Ou-Mandel effect: two photons → bunch together
prog = sf.Program(2)
with prog.context as q:
# Put one photon in each mode (displaced squeezed states approximate this)
Sgate(2) | q[0]
Sgate(2) | q[1]
# 50/50 beamsplitter (θ = π/4)
BSgate(np.pi / 4, 0) | (q[0], q[1])
# Measure photon number in each mode
MeasureFock() | q
eng = sf.Engine("fock", backend_options={"cutoff_dim": 6})
result = eng.run(prog, shots=10)
print(result.samples)
# With two photons hitting a 50/50 beamsplitter:
# Hong-Ou-Mandel effect: both photons tend to exit the same port
# You'll see (0,2) and (2,0) much more than (1,1)
Gaussian Boson Sampling (GBS) is a method developed by Xanadu. It addresses a problem believed to be classically hard, but which photonic quantum computers can solve efficiently. The process samples from the output distribution of squeezed light passing through a random interferometer.
import strawberryfields as sf
from strawberryfields.ops import Sgate, BSgate, MeasureFock
import numpy as np
# Small 4-mode GBS circuit
prog = sf.Program(4)
with prog.context as q:
# Squeeze each mode
Sgate(1.0) | q[0]
Sgate(1.0) | q[1]
Sgate(1.0) | q[2]
Sgate(1.0) | q[3]
# Random interferometer (beamsplitters + phases)
BSgate(np.pi/4, 0) | (q[0], q[1])
BSgate(np.pi/4, 0) | (q[2], q[3])
BSgate(np.pi/3, np.pi/6) | (q[1], q[2])
BSgate(np.pi/4, 0) | (q[0], q[1])
BSgate(np.pi/4, 0) | (q[2], q[3])
MeasureFock() | q
eng = sf.Engine("fock", backend_options={"cutoff_dim": 5})
result = eng.run(prog, shots=20)
print(result.samples)
# Rows like: [0, 1, 2, 0], [1, 0, 0, 2], [0, 2, 0, 1]
# Each value is the photon count in that mode
The sampling distribution relates to hafnians of submatrices: these are #P-hard to compute classically, yet easy to sample from using photonic hardware.
When using the Gaussian backend, a key advantage is that you can query properties of the state without collapsing it.
import strawberryfields as sf
from strawberryfields.ops import Sgate, Dgate
import numpy as np
prog = sf.Program(1)
with prog.context as q:
Sgate(0.5) | q[0]
Dgate(1.0, 0.5) | q[0]
eng = sf.Engine("gaussian")
result = eng.run(prog)
state = result.state
# Wigner function value at a point in phase space
W = state.wigner(0, np.arange(-3, 3, 0.1), np.arange(-3, 3, 0.1))
print(f"Wigner function computed over {W.shape} grid points")
# Mean photon number
n_mean = state.mean_photon(0)
print(f"Mean photon number in mode 0: {n_mean[0]:.3f}")
# Covariance matrix (describes Gaussian state fully)
cov = state.cov()
print(f"Covariance matrix shape: {cov.shape}")
The Wigner function is a phase-space representation of a quantum state. It is positive everywhere for classical-like states, yet it becomes negative in regions corresponding to non-classical states (such as Schrödinger cat states).
Xanadu’s Borealis photonic processor is accessible through the Xanadu Cloud.
import strawberryfields as sf
# Connect to Xanadu Cloud (requires account + API key)
# sf.store_account("YOUR_API_KEY")
# Run on real photonic hardware
eng = sf.RemoteEngine("borealis")
# Your program here - limited to GBS-compatible circuits
# result = eng.run(prog, shots=100)
Borealis utilizes time-multiplexed photonic loops containing 216 squeezed modes. Xanadu demonstrated in 2022 that sampling the output on Borealis takes seconds, a performance vastly superior to the estimated 9,000 years required for the same problem using classical supercomputers.
Photonic quantum computing, exemplified by systems like Strawberry Fields, differs significantly from traditional qubit approaches. When comparing properties, the state space is continuous (quadratures) for photonics, versus discrete (0/1) for qubits. Measurement similarly yields continuous values or photon counts in the photonic approach, compared to binary 0 or 1 for qubits. Photonic systems can operate at room temperature, while superconducting systems require millikelvin cooling. In terms of natural applications, photonics excels at Gaussian boson sampling (GBS), optimization, and machine learning, while qubits are suited for general algorithms such as Shor’s or Grover’s. Entanglement is modeled using two-mode squeezing in photonics, whereas qubits use gates like CNOT. The noise model also differs: photonics deals with photon loss, while qubits face decoherence and gate errors. The key metric for photonic systems is squeezing strength (dB), contrasted with gate fidelity for qubits.
For further exploration, users can consult the Strawberry Fields documentation. To explore differentiable quantum programming and quantum machine learning, PennyLane, also from Xanadu, is available. The GBS applications library provides tools for graph optimization, molecular vibrational spectra, and point process sampling. Finally, the pip install thewalrus command installs Xanadu’s library for handling hafnians and Gaussian boson sampling mathematics.
Was this tutorial helpful?