Repository navigation
From Papers and Equations to FlagQuantum Code
Turn a paper's mathematical model into a runnable FlagQuantum experiment, with a traceable correspondence between equations, tensors, circuit operations, and numerical checks.
Version: FlagQuantum 0.3.1, reference commit 5714b569cfc94e212b6d175eb7c87e1f36d8cf9d.
Verified: October 20, 2026, macOS Apple Silicon, Python 3.12.14, PyTorch 2.13.0, CPU, float64 parameters and complex128 statevectors. All three Python files below were executed. They use deterministic, noiseless statevector expectations; no hardware, shots, or accelerator access is required.
Scope: The worked model is a deliberately small teaching example, not a reproduction of a particular paper. Its equations are derived here. Reproducing a published experiment additionally requires its actual architecture, data, initialization, measurement protocol, and evaluation procedure.
Before starting, read Core Concepts and Qubit Ordering and Result Conventions. For environment setup, use Installation and Compatibility.
Use a Python 3.12 virtual environment. For example, on macOS or Linux:
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install "flagquantum==0.3.1" "torch==2.13.0"
python -c "import flagquantum as fq, torch; print(fq.__version__, torch.__version__)"The version check should report FlagQuantum 0.3.1 and PyTorch 2.13.0 (a platform-specific PyTorch build suffix may appear). Windows activation and alternative supported environments are covered in Installation and Compatibility. Save the three files below in one working directory and run them with this environment's Python.
Start with the paper's definitions and assumptions, then derive the computation before selecting API calls:
Paper definitions → mathematical derivation → tensor shapes and conventions → FlagQuantum implementation → independent numerical checks.
Read each derivation together with the equation/code table immediately below it. The tables show implementation excerpts; the complete runnable files follow the derivations. Matching equation numbers also appear in the script comments.
For each equation, record its equation number, the symbols it introduces, its inputs and outputs, and the code that implements it. Keep fixed constants, trainable parameters, classical inputs, and random variables distinct.
| Mathematical object | Implementation in this guide | What to verify |
|---|---|---|
| Initial state |
Default initial state of fq.Circuit(2)
|
Basis ordering and normalization |
| Variational parameters |
torch.nn.Parameter, shape (2,)
|
Units, initialization, and gradient connection |
| Unitary |
.ry(...).ry(...).cx(...) |
Gate order, wires, angle convention |
| Pauli products |
fq.Z(0), fq.X(0) @ fq.X(1)
|
Tensor-product convention |
| Expectations |
Named fq.expectation(...) requests |
Result names and batch dimension |
| Energy |
Weighted sum of expectation tensors in PyTorch | Coefficients, signs, real scalar objective |
| Gradient |
torch.autograd.grad or loss.backward()
|
Closed-form, matrix, and parameter-shift checks |
| Update |
torch.optim.Adam([theta], ...) |
Fresh forward pass and post-update evaluation |
This example assembles the Hamiltonian's weighted sum in PyTorch. It does not require an additional Hamiltonian-sum API.
| Convention | Used here | Translation risk |
|---|---|---|
| Basis |
00, 01, 10, 11; qubit 0 is most significant |
Another framework may reverse wire-to-bit mapping |
| Tensor product |
|
Swapping factors changes observables |
| Angles | Radians; |
Some papers use |
| Circuit order | Appended gates execute from left to right | Matrix products act on a ket from right to left |
| Parameter shape |
(2,) means two circuit parameters in this example |
Do not assume this is a batch of two circuits |
| Result shapes | State (1, 4), each expectation (1,), stacked terms (1, 4), energy (1,)
|
Preserve the leading circuit-batch dimension |
| Numerical types | Real parameters float64, complex states complex128
|
Lower precision needs different tolerances |
| Measurement | Exact simulator expectation | Finite-shot estimates have sampling error |
The one-element batch is reduced to a scalar with .squeeze(0) for checking or .mean() for training. Extending to multiple circuits requires a deliberate batching and loss-reduction policy. The examples below accept a single two-parameter vector.
For the computational basis and the usual Pauli
Therefore,
| Equation | Corresponding Python | Meaning |
|---|---|---|
circuit = fq.Circuit(1, dtype=torch.complex128).ry(0, theta) |
Apply the paper's rotation to the default zero state. | |
request = fq.expectation(fq.Z(0), name="z")energy = fq.run(circuit, outputs=request, options=options).expectation("z").squeeze(0)
|
Request the observable, then read a scalar expectation. | |
torch.testing.assert_close(energy, theta.cos()) |
Compare the simulator value with the derived expression. | |
gradient, = torch.autograd.grad(energy, theta)torch.testing.assert_close(gradient, -theta.sin())
|
Differentiate the implementation and check the derivative. |
If a paper instead defines ry(0, 2 * theta). The chain rule gives
| Paper convention | Code that preserves the chain rule |
|---|---|
paper_energy = z_expectation(2 * theta) |
|
paper_gradient, = torch.autograd.grad(paper_energy, theta)torch.testing.assert_close(paper_gradient, -2 * (2 * theta).sin())
|
Passing theta directly to ry would implement a different model. Converting 2 * theta to a Python number would disconnect its gradient.
Save the following as rotation_translation.py:
import torch
import flagquantum as fq
options = fq.ExecutionOptions(
mode="statevector", backend="pytorch", device="cpu",
precision="complex128", allow_backend_fallback=False,
allow_approximate=False,
)
def z_expectation(angle):
circuit = fq.Circuit(1, dtype=torch.complex128).ry(0, angle)
return fq.run(
circuit, outputs=fq.expectation(fq.Z(0), name="z"), options=options,
).expectation("z").squeeze(0)
theta = torch.tensor(0.6, dtype=torch.float64, requires_grad=True)
energy = z_expectation(theta)
gradient, = torch.autograd.grad(energy, theta)
torch.testing.assert_close(energy, theta.cos())
torch.testing.assert_close(gradient, -theta.sin())
print(f"RY(theta): expectation={energy.item():.6f}, gradient={gradient.item():.6f}")
# The paper defines U(theta) = exp(-i * theta * Y), without the factor 1/2.
# Preserve 2 * theta inside the computation graph.
paper_energy = z_expectation(2 * theta)
paper_gradient, = torch.autograd.grad(paper_energy, theta)
torch.testing.assert_close(paper_energy, (2 * theta).cos())
torch.testing.assert_close(paper_gradient, -2 * (2 * theta).sin())
print(f"exp(-i*theta*Y): expectation={paper_energy.item():.6f}, "
f"gradient={paper_gradient.item():.6f}")
print("Rotation convention checks passed.")Run:
python rotation_translation.pyExpected output, rounded to six decimals:
RY(theta): expectation=0.825336, gradient=-0.564642
exp(-i*theta*Y): expectation=0.362358, gradient=-1.864078
Rotation convention checks passed.
Consider the dimensionless Hamiltonian
Equation (1).
| Mathematical term | Observable request in evaluate
|
Coefficient |
|---|---|---|
fq.expectation(fq.Z(0), name="z0") |
0.7 |
|
fq.expectation(fq.Z(1), name="z1") |
0.2 |
|
fq.expectation(fq.X(0) @ fq.X(1), name="xx") |
0.4 |
|
fq.expectation(fq.Z(0) @ fq.Z(1), name="zz") |
-0.3 |
The requests and COEFFICIENTS = torch.tensor([0.7, 0.2, 0.4, -0.3], dtype=REAL) use the same term order. Swapping result order without swapping coefficients changes the Hamiltonian.
We minimize its energy over the trial state
Equation (2).
| Formula operation, in execution order | Circuit code |
|---|---|
| Prepare |
circuit = fq.Circuit(2, dtype=COMPLEX) |
| Apply |
circuit.ry(0, theta[0]).ry(1, theta[1]) |
| Apply |
circuit.cx(0, 1) |
The last two code rows are chained together in the complete script. Parameter theta[0], and theta[1].
Equation (2) becomes .ry(0, theta[0]).ry(1, theta[1]).cx(0, 1): rotations execute first, then controlled-X. The first two gates commute because they act on different qubits; moving controlled-X ahead of them would generally change the model.
Let 10 and 11, giving
Equation (3).
| State entry | Statevector position | Analytical value |
|---|---|---|
Amplitude of 00
|
state[0] |
c0 * c1 |
Amplitude of 01
|
state[1] |
c0 * s1 |
Amplitude of 10
|
state[2] |
s0 * s1 |
Amplitude of 11
|
state[3] |
s0 * c1 |
Here state = result.statevector().squeeze(0), c0, c1 = (theta / 2).cos().unbind(), and s0, s1 = (theta / 2).sin().unbind(). The validation below constructs this analytical state and compares all four amplitudes, then checks an independent dense matrix implementation.
For real amplitudes
Equation (4).
| Derived expectation | Simulator result | Analytical reference in expected_terms
|
|---|---|---|
result.expectation("z0") |
a.cos() |
|
result.expectation("z1") |
a.cos() * b.cos() |
|
result.expectation("xx") |
a.sin() |
|
result.expectation("zz") |
b.cos() |
In the script, a, b = theta.unbind() gives the scalar tensors for torch.stack(..., dim=-1) preserves the result order and builds terms with shape (1, 4).
For general complex amplitudes, use absolute squares for probabilities and the real part of conjugate overlap terms for
Substituting (4) into (1) gives an independently checkable energy:
Equation (5).
| Formula step | Corresponding code | Shape |
|---|---|---|
| Collect |
terms = torch.stack([result.expectation(name) for name in NAMES], dim=-1) |
(1, 4) |
| Multiply each term by |
terms * COEFFICIENTS |
(1, 4) |
| Sum over terms: |
energy = (terms * COEFFICIENTS).sum(dim=-1) |
(1,) |
| Select the single-circuit scalar | scalar = energy.squeeze(0) |
() |
| Check equation (5) | torch.testing.assert_close(scalar, closed_form(theta), rtol=1e-9, atol=1e-9) |
Scalar comparison |
closed_form translates the trigonometric expression literally; evaluate obtains the same quantity by executing the circuit. Keeping these two paths separate makes their agreement meaningful.
Differentiate (5) term by term:
Equation (6).
| Derivative | Literal formula implementation in closed_gradient
|
|---|---|
-0.7 * a.sin() - 0.2 * a.sin() * b.cos() + 0.4 * a.cos() |
|
-0.2 * a.cos() * b.sin() + 0.3 * b.sin() |
|
| Simulator gradient |
gradient, = torch.autograd.grad(scalar, theta) |
| Compare both derivatives | torch.testing.assert_close(gradient, closed_gradient(theta), rtol=1e-9, atol=1e-9) |
The first two rows are stacked into a (2,) tensor. Autograd differentiates the executed circuit path, while closed_gradient implements the paper-style derivation explicitly.
| Equation | Code location below |
|---|---|
| (1): coefficients and Pauli products |
COEFFICIENTS, named requests in evaluate, and hamiltonian in dense_reference
|
| (2): ansatz | Circuit construction in evaluate; matrix product in dense_reference
|
| (3): state amplitudes |
result.statevector() compared with the independent matrix state |
| (4): individual expectations |
expected_terms compared with the named results |
| (5): energy | Weighted sum in evaluate, closed_form, and dense torch.vdot
|
| (6): derivatives |
closed_gradient compared with autograd and parameter shift |
Save the following as paper_model.py, in the same directory as the later training script. Running it performs the validation; importing it provides the reusable model functions.
import torch
import flagquantum as fq
REAL = torch.float64
COMPLEX = torch.complex128
OPTIONS = fq.ExecutionOptions(
mode="statevector", backend="pytorch", device="cpu",
precision="complex128", allow_backend_fallback=False,
allow_approximate=False,
)
# Eq. (1): coefficients in z0, z1, xx, zz order.
COEFFICIENTS = torch.tensor([0.7, 0.2, 0.4, -0.3], dtype=REAL)
NAMES = ("z0", "z1", "xx", "zz")
def evaluate(theta):
# Rebuild the circuit for every forward pass; theta stays in the graph.
circuit = fq.Circuit(2, dtype=COMPLEX)
# Eq. (2): rotations execute before controlled-X.
circuit.ry(0, theta[0]).ry(1, theta[1]).cx(0, 1)
result = fq.run(circuit, outputs=[
fq.expectation(fq.Z(0), name="z0"),
fq.expectation(fq.Z(1), name="z1"),
fq.expectation(fq.X(0) @ fq.X(1), name="xx"),
fq.expectation(fq.Z(0) @ fq.Z(1), name="zz"),
], options=OPTIONS)
terms = torch.stack([result.expectation(name) for name in NAMES], dim=-1)
# Eq. (5): sum the weighted expectation values.
energy = (terms * COEFFICIENTS).sum(dim=-1)
return energy, terms, result
def closed_form(theta):
# Eq. (5): independently derived scalar expression.
a, b = theta.unbind()
return (0.7 * a.cos() + 0.2 * a.cos() * b.cos()
+ 0.4 * a.sin() - 0.3 * b.cos())
def closed_gradient(theta):
# Eq. (6): explicit derivatives with respect to theta[0] and theta[1].
a, b = theta.unbind()
return torch.stack([
-0.7 * a.sin() - 0.2 * a.sin() * b.cos() + 0.4 * a.cos(),
-0.2 * a.cos() * b.sin() + 0.3 * b.sin(),
])
def dense_reference(theta):
# Independent dense matrix implementation, using |q0 q1> ordering.
identity = torch.eye(2, dtype=COMPLEX)
x = torch.tensor([[0, 1], [1, 0]], dtype=COMPLEX)
z = torch.diag(torch.tensor([1, -1], dtype=COMPLEX))
hamiltonian = (0.7 * torch.kron(z, identity)
+ 0.2 * torch.kron(identity, z)
+ 0.4 * torch.kron(x, x) - 0.3 * torch.kron(z, z))
def ry(angle):
c, s = (angle / 2).cos(), (angle / 2).sin()
return torch.stack([torch.stack([c, -s]),
torch.stack([s, c])]).to(COMPLEX)
cx = torch.tensor([[1, 0, 0, 0], [0, 1, 0, 0],
[0, 0, 0, 1], [0, 0, 1, 0]], dtype=COMPLEX)
zero = torch.tensor([1, 0, 0, 0], dtype=COMPLEX)
state = cx @ torch.kron(ry(theta[0]), ry(theta[1])) @ zero
energy = torch.vdot(state, hamiltonian @ state).real
return energy, state, hamiltonian
if __name__ == "__main__":
torch.set_printoptions(precision=6, sci_mode=False)
theta = torch.tensor([0.6, -0.4], dtype=REAL, requires_grad=True)
energy, terms, result = evaluate(theta)
scalar = energy.squeeze(0) # One circuit: batch size is one.
gradient, = torch.autograd.grad(scalar, theta)
reference_energy, reference_state, _ = dense_reference(theta)
dense_gradient, = torch.autograd.grad(reference_energy, theta)
a, b = theta.unbind()
# Eq. (4): check each observable before checking their weighted sum.
expected_terms = torch.stack([a.cos(), a.cos() * b.cos(),
a.sin(), b.cos()]).unsqueeze(0)
torch.testing.assert_close(terms, expected_terms, rtol=1e-9, atol=1e-9)
# Eq. (3): compare all four amplitudes in |q0 q1> order.
c0, c1 = (theta / 2).cos().unbind()
s0, s1 = (theta / 2).sin().unbind()
analytical_state = torch.stack([c0*c1, c0*s1, s0*s1, s0*c1]).to(COMPLEX)
torch.testing.assert_close(result.statevector().squeeze(0), analytical_state,
rtol=1e-9, atol=1e-9)
torch.testing.assert_close(result.statevector().squeeze(0), reference_state,
rtol=1e-9, atol=1e-9)
torch.testing.assert_close(scalar, closed_form(theta), rtol=1e-9, atol=1e-9)
torch.testing.assert_close(scalar, reference_energy, rtol=1e-9, atol=1e-9)
torch.testing.assert_close(gradient, closed_gradient(theta), rtol=1e-9, atol=1e-9)
torch.testing.assert_close(gradient, dense_gradient, rtol=1e-9, atol=1e-9)
with torch.no_grad():
# Eq. (7): independent plus/minus gate-angle evaluations.
shifted = []
for index in range(theta.numel()):
shift = torch.zeros_like(theta)
shift[index] = torch.pi / 2
plus = evaluate(theta + shift)[0].squeeze(0)
minus = evaluate(theta - shift)[0].squeeze(0)
shifted.append((plus - minus) / 2)
shift_gradient = torch.stack(shifted)
torch.testing.assert_close(gradient, shift_gradient, rtol=1e-9, atol=1e-9)
# Additional points avoid validating only one accidental agreement.
for angles in ([0.0, 0.0], [1.1, 0.8], [-0.7, 2.0]):
point = torch.tensor(angles, dtype=REAL, requires_grad=True)
value = evaluate(point)[0].squeeze(0)
derivative, = torch.autograd.grad(value, point)
torch.testing.assert_close(value, dense_reference(point)[0], rtol=1e-9, atol=1e-9)
torch.testing.assert_close(derivative, closed_gradient(point), rtol=1e-9, atol=1e-9)
print("terms:", terms.detach())
print(f"energy: {scalar.item():.6f}")
print("autograd:", gradient)
print("parameter shift:", shift_gradient)
print("State, observable, energy, and gradient checks passed.")Run:
python paper_model.pyExpected output:
terms: tensor([[0.825336, 0.760184, 0.564642, 0.921061]], dtype=torch.float64)
energy: 0.679311
autograd: tensor([-0.169130, -0.052545], dtype=torch.float64)
parameter shift: tensor([-0.169130, -0.052545], dtype=torch.float64)
State, observable, energy, and gradient checks passed.
The assertions use absolute and relative tolerances of 1e-9, rather than testing rounded printed values. State, individual observables, energy, and derivatives are checked at the initial point; energy and derivatives are also checked at three additional points. These are focused consistency checks, not a proof that an arbitrary paper implementation is correct.
Each parameter occurs in exactly one gate
Equation (7).
| Formula component | Code inside the parameter-shift loop |
|---|---|
shift = torch.zeros_like(theta)shift[index] = torch.pi / 2
|
|
plus = evaluate(theta + shift)[0].squeeze(0) |
|
minus = evaluate(theta - shift)[0].squeeze(0) |
|
shifted.append((plus - minus) / 2) |
The script evaluates these shifted circuits explicitly. This check does not imply that the selected simulator's autograd internally uses parameter shift.
If a paper reuses one parameter in several gates, differentiate each occurrence and sum the chain-rule contributions. Shifting the shared parameter globally by
For a normalized pure state and Hermitian
Equation (8).
Here 00, 11) and odd basis (01, 10), its two blocks are
The smaller eigenvalues are
Equation (9).
| Mathematical check | Corresponding code in the training script |
|---|---|
| Find |
exact_ground = torch.linalg.eigvalsh(hamiltonian).min() |
| Check equation (8), allowing roundoff | assert final_energy >= exact_ground - 1e-9 |
| Check that training reaches equation (9) | torch.testing.assert_close(final_energy, exact_ground, rtol=0, atol=1e-6) |
The ansatz can reach this ground state: setting
| Mathematical operation | PyTorch code | Interpretation |
|---|---|---|
| Initialize |
theta = torch.nn.Parameter(torch.tensor([0.6, -0.4], dtype=REAL)) |
Register the two trainable angles. |
| Define |
loss = evaluate(theta)[0].mean() |
For the one-circuit batch, the mean is its energy. |
| Clear the previous gradient | optimizer.zero_grad(set_to_none=True) |
Each iteration uses its own gradient. |
| Compute |
loss.backward() |
The gradient is accumulated into theta.grad. |
| Apply the Adam update | optimizer.step() |
Use Adam's moment estimates and learning rate to update theta. |
| Evaluate |
final_energy = evaluate(theta)[0].mean() |
Recompute after the last parameter update. |
A formula such as torch.optim.SGD([theta], lr=eta) with its default zero momentum. The complete example uses Adam, whose update also depends on gradient history; matching a paper requires matching its actual optimizer.
Save as train_paper_model.py, alongside paper_model.py:
import torch
from paper_model import REAL, evaluate, dense_reference
theta = torch.nn.Parameter(torch.tensor([0.6, -0.4], dtype=REAL))
optimizer = torch.optim.Adam([theta], lr=0.05)
initial_energy = evaluate(theta)[0].mean().item()
for _ in range(300):
optimizer.zero_grad(set_to_none=True)
loss = evaluate(theta)[0].mean() # Mean over the one-element batch.
loss.backward()
optimizer.step()
# Recompute after the last update, rather than printing a pre-update loss.
with torch.no_grad():
final_energy = evaluate(theta)[0].mean()
_, _, hamiltonian = dense_reference(theta)
exact_ground = torch.linalg.eigvalsh(hamiltonian).min()
assert final_energy >= exact_ground - 1e-9
torch.testing.assert_close(final_energy, exact_ground, rtol=0, atol=1e-6)
print(f"initial energy: {initial_energy:.6f}")
print(f"final energy: {final_energy.item():.6f}")
print(f"exact ground energy: {exact_ground.item():.6f}")
print(f"energy gap below 1e-6: {abs((final_energy - exact_ground).item()) < 1e-6}")
print("Training and variational-bound checks passed.")Run from the directory containing both files:
python train_paper_model.pyExpected output:
initial energy: 0.679311
final energy: -1.284886
exact ground energy: -1.284886
energy gap below 1e-6: True
Training and variational-bound checks passed.
The final energy is checked against dense exact diagonalization with an absolute tolerance of 1e-6. Small numerical differences across platforms are possible. The fixed starting point and 300 Adam steps were verified in the environment above; they are not a convergence guarantee for other models or settings. Equivalent angles can represent the same physical state, so compare energies and observables before requiring parameters to match.
Dense reference matrices require storage exponential in qubit count. Use them for small correctness cases, not as a scalable implementation strategy. For larger experiments, validate small reductions first and then follow Choosing a Simulation Method.
For a complete source-based case study, follow Reproducing Molecular Hydrogen VQE, including corrected paper data, a 54-geometry energy curve, and independently checked gradients.
First identify exactly what you intend to reproduce: a mathematical identity, an equivalent circuit, a reported experiment, or a performance result. Agreement at one level does not establish agreement at the others.
Use this template when documenting each translation:
# Paper-to-Code Experiment: <Short Title>
## Source and Scope
- Paper: <title, authors, persistent URL, version/date>
- Equations/figures implemented: <numbers and page references>
- Target claim: <specific observable, accuracy, energy, or runtime result>
- Assumptions: <pure/mixed state, noise, boundary conditions, approximations>
- Not reproduced: <explicit omissions or deviations>
## Equation-to-Code Map
| Source equation | Meaning and assumptions | Shapes/conventions | Code function | Independent check |
| --- | --- | --- | --- | --- |
| <Eq. N> | <definition> | <basis, units, dimensions> | <function> | <identity/reference> |
## Experiment Specification
- FlagQuantum: <release and/or full commit>
- Environment: <Python, PyTorch, OS, hardware, backend, precision>
- State preparation and circuit: <wires, gate order, depth>
- Parameters: <initialization, sharing, random seeds>
- Inputs/data: <source, preprocessing, train/test split, access requirements>
- Observables/objective: <coefficients, normalization, reduction>
- Gradients/optimizer: <method, learning rate, steps, stopping rule>
- Measurement: <exact expectations or shots, noise, grouping, readout>
## Runnable Implementation
<Complete files, dependency setup, and exact execution commands.>
## Validation and Results
- Small analytical or dense reference: <expected and observed>
- State/observable/energy/gradient checks: <tolerances and observed errors>
- Paper comparison: <reported value, reproduced value, uncertainty, deviations>
- Performance claims: <warmup, synchronization, repeats, timing boundary>
## Limitations and Evidence
<Unsupported features, failed checks, approximation effects, and scope of evidence.>For sampled measurements, compare statistical estimates with suitable uncertainty and repeat counts; deterministic 1e-9 assertions are unsuitable. For noisy or open systems, use the density-matrix or trajectory formulation appropriate to the model rather than assuming the pure-state equations above still apply. A matching energy alone can hide incorrect states or observables, which is why this guide checks several layers.
| Symptom | Check |
|---|---|
| Values look plausible but disagree with the paper | Angle half-factor, coefficient signs, identity offsets, units, and wire order |
| Correct expectations but wrong probabilities | Expectation versus bit probability; for one Pauli-Z measurement, |
| Correct energy but wrong state | Degeneracy, global phase, hidden basis permutations, and incomplete observable checks |
| Gradient is missing or unexpectedly zero | Tensor detachment, .item() in the forward path, parameter sharing, and stationary initialization |
| Gradient differs by a constant factor | Rescaled angles and sum-versus-mean loss reduction |
| Parameter-shift and autograd disagree | Generator spectrum, repeated parameters, nonlinear loss, shifts, or shot noise |
| Printed final loss is stale | Recompute the forward pass after the last optimizer update |
| Tiny example agrees but a larger run does not | Backend, precision, approximation tolerance, measurement protocol, and model scaling |
Physical pure states are equivalent up to global phase. The direct statevector equality in this guide is appropriate because both implementations use the same explicit gate matrices and initial state; when comparing other implementations, align global phase or compare fidelity and observables.
Release-pinned implementation references:
Continue with Training Parameterized Circuits, Hybrid Classical-Quantum Models, Noise and Open-System Simulation, and Reproducibility and Benchmarks. Use Documentation Guide to maintain source references, runnable examples, and version labels.
- Installation and Compatibility
- Quick Start
- Install and Run
- Qubit Ordering and Result Conventions
- Runnable Examples
- Building and Simulating Circuits
- Training Parameterized Circuits
- Hybrid Classical-Quantum Models
- Core Concepts
- From Papers and Equations to FlagQuantum Code
- Reproducing Molecular Hydrogen VQE
- Fundamentals
- Tutorials
- Choosing a Simulation Method
- Accelerator Setup
- Distributed Simulation and Training
- Execution
- Circuit Compilation and Interoperability
- Noise and Open-System Simulation
- Quantum Error Correction Experiments
- Cloud and Quantum Hardware Execution
- QPU Digital Twins
- Advanced Topics
- Support and Contribution
All 21 guides are linked in the navigation sections. The Wiki Directory lists published guides and current repository resources.
- Troubleshooting and FAQ
- Reproducibility and Benchmarks
- Development and Contribution Guide
- Documentation Guide
Documentation, capability, and contribution links in this section follow current main; the guides above target 0.3.1.