monoprop

MonomialPropagator

Abstract base for the classical monomial-propagation simulators.

The propagation graph owns the gate information; evaluation methods (expectation_value, gradient, ...) take only parameters. Concrete subclasses implement __init__ (resolving their operator family to a monoprop.majorana.MajoranaOperator and calling _init_simulator) and _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 build_graph / 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 contract_partially / 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 expectation_value. This is the graph's native (per-monomial) mapping, which is finer-grained than the per-gate mapping of the authoring 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; 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 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 evolved_operator (or 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 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=None) -> 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 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 | None
= None

If provided, 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=None) -> None

Evolve and contract immediately, without storing a graph.

More memory-efficient than 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 monoprop.circuit.Circuit.

paramonly_rotate_len_kint | None
= None

See 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 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 expectation_value).

Returns

float

A tuple (expectation_value, gradient), where gradient is a NumPy array in the canonical parameter-axis order.

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

Compute the gradient at parameters.

Note

Internally calls expectation_value_and_gradient and returns only its gradient component.

paramself
paramparametersParameterValues
= None

Variational parameter values (see expectation_value).

Returns

numpy.ndarray

The gradient as a NumPy array of float64 values, in canonical parameter-axis order.

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 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 expectation_value_functional.

Returns

collections.abc.Callable

A callable fn(parameters=None) -> (float, np.ndarray), where the gradient is in canonical parameter-axis order.

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 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 Schrodinger picture these are the evolved-state coefficients; in the Heisenberg picture, the evolved-operator coefficients.

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 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 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 picture) as a dict mapping Majorana-index tuples to complex coefficients.

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 representation.

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 number of cycles in the MP graph.

On this page