monoprop

MonomialPropagator

Abstract base for the classical monomial-propagation simulators.

The propagation graph owns the gate information; evaluation methods (:meth:expectation_value, :meth:gradient, ...) take only parameters. Concrete subclasses implement :meth:__init__ (resolving their operator family to a :class:~monoprop.majorana.MajoranaOperator and calling :meth:_init_simulator) and :meth:_circuit_gates (validating the circuit's gate family).

.. note:: Incremental building and gate order. In the Heisenberg picture the Heisenberg evolution applies gates back-to-front, so each :meth:build_graph / :meth:propagate call consumes its gate sequence in reverse. Splitting one circuit into forward chunks across several calls is therefore not equivalent to a single call with the whole sequence: the chunks are each reversed but not globally reordered. In the Schrodinger picture gates are applied front-to-back, so a forward split is equivalent. When you need incremental building to reproduce a single-call result, use the Schrodinger picture (or pass the full sequence in one call).

Attributes

attributen_parametersint

Number of distinct variational parameters seen while building the graph.

attributen_gatesint

Number of authoring gates ingested into the graph.

A single-term gate expands to one graph layer; a multi-term gate expands to several layers sharing one gate, so n_gates \<= graph_layers. Stays correct after a graph prefix is consumed by :meth:contract_partially / :meth:propagate.

attributeparameter_mappinglist[int]

The parameter mapping owned by the graph, one entry per graph layer.

Entry i is the variational-parameter index driving the i-th graph layer (a generated Majorana monomial), in the same order as the parameter vector passed to :meth:expectation_value. This is the graph's native (per-monomial) mapping, which is finer-grained than the per-gate mapping of the authoring :class:~monoprop.circuit.Circuit when gates bundle several monomials.

attributenum_modesint

Number of fermionic modes for the simulator.

attributegraph_layersint

Number of evolved Majoranas (graph layers).

attributeschrodingerbool

Whether the simulator is in the Schrodinger picture (else Heisenberg).

attributecutoffint

Current cutoff value for the simulation.

attributelower_atolNone | float

Current lower absolute tolerance for the cutoff function (None if unset).

attributeupper_atolNone | float

Current upper absolute tolerance for the cutoff function (None if unset).

attributecutoff_typestr

Current cutoff type ("length" or "support").

Read-only on the base; :class:~monoprop.majorana_propagator.MajoranaPropagator exposes a setter since either scheme is valid there.

Functions

funcfrom_circuit(cls, circuit, initial_operator, **config) -> Self

Construct a propagator from a circuit and propagate it in one step.

Uses circuit.initial_state as the reference state and evolves circuit in place via :meth:propagate -- a one-shot contraction that stores no graph. The observable (initial_operator) and truncation settings (cutoff and the rest of config) are supplied separately -- they are not part of the circuit.

Read the result off the evolved operator/state with :meth:evolved_operator (or :meth:expectation_value) taking no parameters -- the circuit's angles are already applied. This is the memory-lean path for a single evaluation; if you instead need a reusable graph to re-evaluate at many angles (or to take gradients), construct the propagator directly and call :meth:build_graph.

paramcls
paramcircuitCircuit

The circuit whose gates and initial state define the evolution.

paraminitial_operatorobject

The observable to propagate.

paramconfigobject
= {}

Returns

typing.Self

A propagator with circuit already evolved into its state (no graph stored).

funcbuild_graph(self, circuit, *, seed_parameters=None, only_rotate_len_k=0) -> None

Append a circuit to the propagation graph.

Builds (or extends) the reusable evolution graph, recording each layer's gate information (the parameter that drives it and its generator coefficient) so that later evaluation takes only parameters. The circuit's angle indices are local (0-based); when extending a non-empty graph they are shifted up onto the accumulated parameter axis automatically, so each call's circuit is authored independently.

paramself
paramcircuitCircuit

Gates to append, as a :class:~monoprop.circuit.Circuit.

paramseed_parametersParameterValues
= None

The full parameter vector covering the whole accumulated graph, used to regenerate the coefficient seed (by contracting the existing graph) so coefficient truncation sees realistic coefficients when extending. Only needed when extending a non-empty graph with coefficient-informed truncation; on the first (or a single) call it defaults to the circuit's own parameters. When omitted while extending, the new layers are built structurally (coefficient truncation is skipped for them); the engine validates the length of an explicit seed.

paramonly_rotate_len_kint
= 0

If > 0, apply gates to monomials of length <= k in the evolved operator even if they anticommute. Useful when many free-fermionic gates (generators that are length-2 Majorana monomials) are applied before expectation-value estimation in Schrodinger-picture simulations.

Returns

None
funcpropagate(self, circuit, *, only_rotate_len_k=0) -> None

Evolve and contract immediately, without storing a graph.

More memory-efficient than :meth:build_graph because it does not retain the propagation graph; use it for a single contraction at the circuit's parameters rather than repeated re-evaluation.

paramself
paramcircuitCircuit

Gates to apply and the angle values to apply them at, as a :class:~monoprop.circuit.Circuit.

paramonly_rotate_len_kint
= 0

See :meth:build_graph.

Returns

None
funcexpectation_value(self, parameters=None) -> float

Compute the expectation value at parameters.

Replays the stored graph against the current initial operator and reference state. This is a convenience wrapper that builds and immediately evaluates an expectation-value functional with no paring.

paramself
paramparametersParameterValues
= None

Variational parameter values, as a sequence in parameter-index order, or a :class:~monoprop.circuit.Circuit (its parameters are used). None evaluates the current operator with an empty parameter vector.

Returns

float

The expectation value as a float.

funcexpectation_value_and_gradient(self, parameters=None) -> tuple[float, np.ndarray]

Compute the expectation value and gradient at parameters.

Both quantities are computed in a single backward pass over the graph.

paramself
paramparametersParameterValues
= None

Variational parameter values (see :meth:expectation_value).

Returns

float

A tuple (expectation_value, gradient), where gradient is a NumPy

funcgradient(self, parameters=None) -> np.ndarray

Compute the gradient at parameters.

Note

Internally calls :meth:expectation_value_and_gradient and returns only its gradient component.

paramself
paramparametersParameterValues
= None

Variational parameter values (see :meth:expectation_value).

Returns

numpy.ndarray

The gradient as a NumPy array of float64 values, in canonical

funcexpectation_value_functional(self, pare_threshold=None) -> Callable[..., float]

Return a reusable callable computing the expectation value from parameters.

Returns a callable that accepts a parameter vector (a sequence, or None) and returns the expectation value, replaying the current evolution graph. Build it once and call it repeatedly across many parameter values.

paramself
parampare_thresholdfloat | None
= None

Edge-retention cutoff for a masked execution plan built for this functional: edges whose contribution falls below the threshold are pared away so they are skipped during replay (a speed-up for sparse graphs, at the cost of some memory and accuracy). None (the default) disables paring.

Returns

collections.abc.Callable

A callable fn(parameters=None) -> float.

funcexpectation_value_and_gradient_functional(self, pare_threshold=None) -> Callable[..., tuple]

Return a reusable callable computing (expectation value, gradient).

Like :meth:expectation_value_functional, but the returned callable computes both the expectation value and the full parameter gradient in a single backward pass over the graph.

paramself
parampare_thresholdfloat | None
= None

See :meth:expectation_value_functional.

Returns

collections.abc.Callable

A callable fn(parameters=None) -> (float, np.ndarray), where the

funccontract_partially(self, parameters=None, *, inplace=True) -> np.ndarray

Contract the graph into the operator/state at parameters.

Permanently folds the stored gates, evaluated at parameters, into the operand: the initial operator in the Heisenberg picture, or the reference state in the Schrodinger picture. This shrinks the graph that remains to be replayed, which is useful when a prefix of the circuit is fixed and its contribution can be baked in once instead of being replayed on every evaluation.

paramself
paramparametersParameterValues
= None

Variational parameter values (see :meth:expectation_value).

paraminplacebool
= True

If True (default), update the internal state, consuming the graph. If False, leave the stored graph untouched and only return the contracted coefficients, so the same graph can be reused with other parameters.

Returns

numpy.ndarray

The evolved coefficients (core term excluded) as a NumPy array. In the

funcevolved_operator(self, parameters=None, *, atol=1e-12) -> dict[tuple[int, ...], complex]

Return the evolved operator/state as a dict, without modifying state.

Equivalent to :meth:contract_partially with inplace=False, returned as a mapping keyed by Majorana indices and without touching the simulator state.

paramself
paramparametersParameterValues
= None

Variational parameter values (see :meth:expectation_value).

paramatolfloat
= 1e-12

Absolute tolerance for filtering small coefficients; terms with |coeff| \< atol are dropped. Defaults to 1e-12; set to 0.0 to keep all terms.

Returns

dict

The evolved operator (Heisenberg picture) or the evolved state (Schrodinger

funcupdate_initial_operator(self, new_operator) -> None

Replace coefficients of the initial operator (existing terms only).

Re-weights the initial operator the graph is evaluated against, without touching the evolution graph or rebuilding the simulator. Only the initial operator is affected -- the gates and their generator coefficients are unchanged -- and only Majorana terms already present in the initial operator can be updated (no new terms are introduced).

paramself
paramnew_operatordict[tuple[int, ...], complex]

Mapping from Majorana-index tuples to their new complex coefficients.

Returns

None
funcsize(self) -> int

Number of Majorana terms currently tracked.

paramself

Returns

int

The number of distinct Majorana monomial terms in the simulator's current

funcgraph_size(self) -> tuple[int, int]

Size metrics of the evolution graph.

paramself

Returns

int

A tuple (n_cos_indices, n_cycles): the number of cosine indices and the

On this page