Configuring Simulation Parameters¶
YAQS separates what you evolve (State, circuits, Hamiltonians) from how you truncate and sample via parameter objects passed to run():
Class |
Use when |
|---|---|
Open-system or unitary time evolution (TDVP / BUG, MCWF trajectories, Lindblad-style paths). |
|
Noisy strong digital simulation (per-trajectory MPS evolution with observables). |
|
Noisy weak digital simulation (shot-based sampling; you set |
This page shows how to construct each class. For Simulator execution options (parallelism, progress bars), see Configuring the Simulator.
Start with a preset¶
You do not need to tune every numerical knob before running a simulation. Pick a preset and let it fill in the truncation and sampling settings you may be unfamiliar with (svd_threshold, max_bond_dim, num_traj on analog/strong runs, and krylov_tol).
All three *SimParams classes accept a keyword-only preset argument (default "balanced"):
|
|
|
|
|
|---|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"fast"— qualitative exploration and quick tests; not intended for strict dense comparisons."balanced"— recommended default for exploratory work."accurate"— high-quality production settings."exact"— strict reference/debug preset with minimal internal numerical relaxation. Stochastic trajectory sampling, finite time steps, and model error still apply; this is not mathematically exact.
svd_threshold controls tensor-network SVD truncation (bond truncation). krylov_tol controls the adaptive Krylov/Lanczos matrix exponential inside TDVP updates. These are independent: tightening one does not change the other. min_bond_dim (default 2) and trunc_mode (default "discarded_weight") are unchanged across presets. The chosen preset name is stored on the object as params.preset.
Override only what you need¶
Explicit constructor arguments override the preset; everything you omit keeps the preset value.
That is the intended workflow when you know some settings but not all:
Choose the closest preset (
"fast","balanced","accurate", or"exact").Pass only the fields you want to change.
Leave the rest unset — they stay at the preset defaults.
Overridable preset fields:
Argument |
What it controls |
|---|---|
|
SVD bond truncation during MPS/MPO updates |
|
Hard cap on bond dimension ( |
|
Trajectory count (analog / strong only) |
|
Adaptive Krylov/Lanczos matrix exponential in TDVP |
WeakSimParams always requires shots separately; shots is not part of any preset.
If you omit an overridable argument, the preset supplies it. If you pass a value explicitly, that value wins for that field only — the other preset fields are unchanged. For max_bond_dim, omit the argument to keep the preset cap; pass None explicitly to remove the cap.
Recommended usage¶
1from mqt.yaqs.core.data_structures.simulation_parameters import (
2 SIMULATION_PRESETS,
3 AnalogSimParams,
4 Observable,
5 StrongSimParams,
6 WeakSimParams,
7)
8from mqt.yaqs.core.libraries.gate_library import Z
9
10
11def _trunc_summary(params: AnalogSimParams | StrongSimParams | WeakSimParams) -> dict[str, object]:
12 """Collect preset-related fields for display."""
13 out: dict[str, object] = {
14 "preset": params.preset,
15 "svd_threshold": params.svd_threshold,
16 "max_bond_dim": params.max_bond_dim,
17 "krylov_tol": params.krylov_tol,
18 }
19 if isinstance(params, WeakSimParams):
20 out["shots"] = params.shots
21 else:
22 out["num_traj"] = params.num_traj
23 return out
Pick a preset — no other truncation arguments required:
1# Default: balanced preset fills in all truncation settings
2analog_params = AnalogSimParams()
3print("default", _trunc_summary(analog_params))
4
5for name in ("fast", "balanced", "accurate", "exact"):
6 params = AnalogSimParams(preset=name)
7 print(name, _trunc_summary(params))
default {'preset': 'balanced', 'svd_threshold': 1e-06, 'max_bond_dim': 128, 'krylov_tol': 0.0001, 'num_traj': 256}
fast {'preset': 'fast', 'svd_threshold': 0.001, 'max_bond_dim': 16, 'krylov_tol': 0.001, 'num_traj': 128}
balanced {'preset': 'balanced', 'svd_threshold': 1e-06, 'max_bond_dim': 128, 'krylov_tol': 0.0001, 'num_traj': 256}
accurate {'preset': 'accurate', 'svd_threshold': 1e-09, 'max_bond_dim': 4096, 'krylov_tol': 1e-06, 'num_traj': 1024}
exact {'preset': 'exact', 'svd_threshold': 1e-13, 'max_bond_dim': None, 'krylov_tol': 1e-12, 'num_traj': 1024}
Override one field; the rest stay from "balanced":
1balanced = AnalogSimParams(preset="balanced")
2tighter_krylov = AnalogSimParams(preset="balanced", krylov_tol=1e-8)
3
4print("balanced preset only", _trunc_summary(balanced))
5print("override krylov_tol only", _trunc_summary(tighter_krylov))
6# svd_threshold, max_bond_dim, and num_traj still come from "balanced"
7assert tighter_krylov.svd_threshold == balanced.svd_threshold
8assert tighter_krylov.max_bond_dim == balanced.max_bond_dim
9assert tighter_krylov.num_traj == balanced.num_traj
balanced preset only {'preset': 'balanced', 'svd_threshold': 1e-06, 'max_bond_dim': 128, 'krylov_tol': 0.0001, 'num_traj': 256}
override krylov_tol only {'preset': 'balanced', 'svd_threshold': 1e-06, 'max_bond_dim': 128, 'krylov_tol': 1e-08, 'num_traj': 256}
Override several fields when you know exactly what you want; the remaining preset fields still apply:
1custom_params = AnalogSimParams(
2 preset="fast", # start from fast defaults for everything else
3 max_bond_dim=512,
4 num_traj=32,
5)
6_trunc_summary(custom_params)
{'preset': 'fast',
'svd_threshold': 0.001,
'max_bond_dim': 512,
'krylov_tol': 0.001,
'num_traj': 32}
Weak simulation: set shots yourself, use a preset for truncation:
1weak_params = WeakSimParams(
2 shots=1024,
3 preset="fast",
4)
5_trunc_summary(weak_params)
{'preset': 'fast',
'svd_threshold': 0.001,
'max_bond_dim': 16,
'krylov_tol': 0.001,
'shots': 1024}
AnalogSimParams¶
Besides the preset (and any overrides), you typically set the time grid (elapsed_time, dt), observables, and whether to record intermediate times (sample_timesteps).
1L = 4
2observables = [Observable(Z(), site) for site in range(L)]
3
4analog = AnalogSimParams(
5 observables=observables,
6 elapsed_time=0.2,
7 dt=0.05,
8 preset="accurate",
9)
10_trunc_summary(analog)
{'preset': 'accurate',
'svd_threshold': 1e-09,
'max_bond_dim': 4096,
'krylov_tol': 1e-06,
'num_traj': 1024}
Need a smaller bond cap for a quick test, but keep the rest of "accurate"?
1analog_quick = AnalogSimParams(
2 observables=observables,
3 elapsed_time=0.2,
4 dt=0.05,
5 preset="accurate",
6 max_bond_dim=256,
7)
8_trunc_summary(analog_quick)
{'preset': 'accurate',
'svd_threshold': 1e-09,
'max_bond_dim': 256,
'krylov_tol': 1e-06,
'num_traj': 1024}
Pass the resulting object to run() together with a State and Hamiltonian (see Noisy Analog Simulation).
StrongSimParams¶
Used for noisy strong circuit simulation. Provide observables and optionally enable layer sampling (see Strong Circuit Simulation (Observable)).
Two-qubit gate mode (gate_mode)¶
Digital circuit simulation on an MPS uses a TEBD/SVD two-qubit update by default (gate_mode="tebd").
You can also set gate_mode="hybrid" to use TEBD/SVD for nearest-neighbor gates (adjacent in the internal MPS site order after bit reversal) while keeping the existing generator MPO + two-site TDVP path for long-range gates.
Set gate_mode="tdvp" to apply TDVP to every two-qubit gate. Set gate_mode="tebd" to use TEBD/SVD for all two-qubit gates; long-range gates are implemented by adjacent SWAP insertion before and after the update.
1strong = StrongSimParams(
2 observables=[Observable(Z(), 0)],
3 preset="accurate",
4)
5_trunc_summary(strong)
{'preset': 'accurate',
'svd_threshold': 1e-09,
'max_bond_dim': 4096,
'krylov_tol': 1e-06,
'num_traj': 1024}
WeakSimParams¶
Used for noisy weak simulation. shots is always required and is not part of the preset.
YAQS stores weak-simulation measurement histograms in Result.counts as a dict[int, int]. The integer key encodes the measured bitstring with site 0 as the least-significant bit (little-endian). This matches Qiskit’s default convention if you interpret Qiskit bitstrings (c_{n-1}...c_0) via int(bitstring, 2).
1weak_balanced = WeakSimParams(shots=1000)
2weak_exact = WeakSimParams(shots=1000, preset="exact")
3print("balanced", _trunc_summary(weak_balanced))
4print("exact", _trunc_summary(weak_exact))
balanced {'preset': 'balanced', 'svd_threshold': 1e-06, 'max_bond_dim': 128, 'krylov_tol': 0.0001, 'shots': 1000}
exact {'preset': 'exact', 'svd_threshold': 1e-13, 'max_bond_dim': None, 'krylov_tol': 1e-12, 'shots': 1000}
See Weak Circuit Simulation (Shots) for a full example with measurement histograms.
Reference: preset table in code¶
The built-in values are defined in SIMULATION_PRESETS:
1SIMULATION_PRESETS
{'fast': {'svd_threshold': 0.001,
'max_bond_dim': 16,
'num_traj': 128,
'krylov_tol': 0.001},
'balanced': {'svd_threshold': 1e-06,
'max_bond_dim': 128,
'num_traj': 256,
'krylov_tol': 0.0001},
'accurate': {'svd_threshold': 1e-09,
'max_bond_dim': 4096,
'num_traj': 1024,
'krylov_tol': 1e-06},
'exact': {'svd_threshold': 1e-13,
'max_bond_dim': None,
'num_traj': 1024,
'krylov_tol': 1e-12}}