Skip to content

Quick Start

FlagQuantum edited this page Oct 20, 2026 · 3 revisions

Quick Start

Build a Bell-state circuit, inspect its exact probabilities, and train a parameterized circuit with PyTorch.

Version: FlagQuantum 0.3.1. Examples verified on macOS Apple Silicon with Python 3.12.14 and PyTorch 2.14.1 using local CPU execution. Other platforms are covered by the installation guidance below, but were not used for this verification.

Requirements: Python 3.10–3.12 and an internet connection for installation. Both examples run locally without a GPU, cloud account, or quantum hardware.

Formula/code review — October 20, 2026: The equations are paired with code excerpts, and the local CPU examples were re-run with Python 3.12.14 and PyTorch 2.13.0. See the review record for executed commands, distributed checks, and untested hardware/provider paths. Earlier environment and output records are retained.

1. Create a Python Environment

Use a supported Python interpreter. On macOS or Linux, replace python3 with python3.12 if needed:

python3 --version
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip

On Windows PowerShell:

py -3.12 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install --upgrade pip

If PowerShell blocks activation, use .\.venv\Scripts\python.exe in place of python in the remaining commands. Activation is optional when using the full interpreter path.

2. Install FlagQuantum

macOS with Apple Silicon

python -m pip install "flagquantum==0.3.1" numpy

The documented macOS binary installation target is Apple Silicon. For other installation paths, consult the project installation instructions.

Linux or Windows with CPU-only PyTorch

python -m pip install "torch>=2.13,<2.15" --index-url https://download.pytorch.org/whl/cpu
python -m pip install "flagquantum==0.3.1" numpy

These commands are intended for a fresh environment. If you use a vendor-managed accelerator environment, follow the repository installation guidance to retain its supplied PyTorch runtime. NumPy is included here to avoid a missing-NumPy warning from PyTorch.

Verify your installation:

python -c "from importlib.metadata import version; import torch; import flagquantum as fq; print('FlagQuantum:', version('flagquantum')); print('PyTorch:', torch.__version__)"

Example output from the verification environment:

FlagQuantum: 0.3.1
PyTorch: 2.14.1

Your supported PyTorch version may differ.

3. Build and Simulate a Bell State

Create a file named bell_state.py and copy the complete script below:

import torch
import flagquantum as fq

circuit = fq.Circuit(2).h(0).cx(0, 1)
result = fq.run(circuit, outputs=fq.probabilities())
probabilities = result.probabilities[0]

for bitstring, probability in zip(("00", "01", "10", "11"), probabilities):
    print(f"P({bitstring}) = {probability.item():.6f}")

expected = torch.tensor([0.5, 0.0, 0.0, 0.5], dtype=probabilities.dtype)
assert torch.allclose(probabilities, expected, atol=1e-6)
print("Bell-state check passed.")

Run it:

python bell_state.py

Expected output:

P(00) = 0.500000
P(01) = 0.000000
P(10) = 0.000000
P(11) = 0.500000
Bell-state check passed.

What the Code Does

  1. fq.Circuit(2) creates two qubits initialized to |00>.
  2. .h(0) applies a Hadamard gate to qubit 0, creating a superposition.
  3. .cx(0, 1) applies a controlled-X with qubit 0 as the control and qubit 1 as the target. The resulting Bell state is (|00> + |11>) / sqrt(2).
  4. fq.probabilities() requests exact computational-basis probabilities.
  5. result.probabilities is a tensor property, not a method. Its shape here is (1, 4); [0] selects the single batch entry.

The results are exact simulator probabilities, subject to floating-point precision. They are not frequencies estimated from a finite number of measurement shots.

Qubit order: the entries are 00, 01, 10, 11, with qubit 0 on the left as the most-significant bit.

4. Train a Parameterized Circuit

Next, replace the fixed Hadamard gate with a trainable Y rotation. We minimize the expectation value of Pauli Z on qubit 0, written as <Z0>.

Read the Training Equations Beside the Code

Formula Code in train_circuit.py Meaning
$\lvert\psi(\theta)\rangle=\mathrm{CX}_{0\to1}(R_Y(\theta)\otimes I)\lvert00\rangle$ fq.Circuit(2).ry(0, parameters[0]).cx(0, 1) Builder prepares a trainable entangled state.
$z(\theta)=\langle Z_0\rangle=\cos\theta$ model() The module's default policy reads Z on qubit 0.
$L(\theta)=z(\theta)$ objective=lambda z: z.mean() Minimize the Z expectation itself; this example has no target-matching squared loss.
$dL/d\theta=-\sin\theta$ fq.train(...) The helper runs backward and optimizer steps; the detailed gradient check is in Training Parameterized Circuits.

See From Papers and Equations to FlagQuantum Code for explicit gradient and matrix checks. Here the training script verifies the learned expectation decreases and finishes below -0.99.

Create train_circuit.py:

import torch
import flagquantum as fq

def circuit(parameters):
    return fq.Circuit(2).ry(0, parameters[0]).cx(0, 1)

model = fq.Module(circuit, n_parameters=1, init=torch.tensor([0.25]))
measurement = fq.expectation(fq.Z(0))

def evaluate():
    parameters = next(model.parameters()).detach()
    return fq.run(circuit(parameters), outputs=measurement).expectation().item()

before = evaluate()
fq.train(
    model,
    optimizer=torch.optim.Adam(model.parameters(), lr=0.05),
    objective=lambda z: z.mean(),
    steps=100,
)
after = evaluate()

print(f"Initial <Z0>: {before:.6f}")
print(f"Final <Z0>:   {after:.6f}")
assert after < before
assert after < -0.99
print("Training check passed.")

Run it:

python train_circuit.py

Output recorded in the verification environment:

Initial <Z0>: 0.968912
Final <Z0>:   -0.999991
Training check passed.

The final decimal digits may vary across supported environments. The script checks that the objective decreases and finishes below -0.99.

What Training Means Here

  • fq.Module exposes the circuit parameter to PyTorch.
  • The initial rotation angle is 0.25 radians. For this circuit, <Z0> = cos(theta).
  • fq.train evaluates the differentiable model and applies Adam updates for 100 steps.
  • Minimizing <Z0> moves the rotation toward a value producing an expectation near -1. This is a small optimization demonstration, not a benchmark or a claim of quantum advantage.
  • .detach() is used only to evaluate a fixed parameter snapshot before and after training; it is not applied to the trainable parameter inside the circuit function.

5. Troubleshooting

Symptom What to check
ModuleNotFoundError: No module named flagquantum Activate the environment used for installation. Use python -m pip show flagquantum to check that interpreter.
No matching distribution or an unsupported Python error Check python --version, operating system, and architecture against the installation requirements.
Tensor object is not callable when reading probabilities Use result.probabilities, not result.probabilities().
A warning that NumPy is unavailable Install it in the same environment with python -m pip install numpy.
Training does not match the example Check the pinned FlagQuantum version, initial angle, learning rate, and 100-step count. Keep parameters[0] attached to autograd inside circuit.

If a problem persists, open an issue with package versions, platform details, the complete error, and a minimal reproducing script.

Next Steps

The repository main branch may contain changes newer than this tutorial. Use the v0.3.1 source when checking behavior for the pinned release.

Clone this wiki locally