Evolution¶
- class Evolution(num_modes, operator, time=1.0, *, synthesis=None, atomic=False)¶
Bases:
FermionicGateImplements the time evolution of an operator.
Given a fermionic
operator\(H\) and an evolutiontime\(t\), this gate implements the unitary\[U = e^{-i t H}.\]For \(U\) to be unitary, \(H\) must be Hermitian. This is the caller’s responsibility and is not verified.
Note
Breaking this gate down in fermionic space (into a circuit of smaller
Evolutiongates) is optional, and it is what thesynthesisattribute governs. The gate can equally be handed straight to the fermion-to-qubit stage, which maps and synthesizes it whole, however many terms itsoperatorholds. Seesynthesis.When it is decomposed (by
decompose(), for instance)synthesisdecides how. It defaults toFermionicLieTrotter, which splits the evolution group-by-group when theoperatorhasgroupsassigned (see Group operator terms: use the operator structure), and term-by-term otherwise (exact only when the individual factors mutually commute). The transpilation process may further alter the decomposition;QDriftTrotterization, for example, replaces the evolution with a randomized sample of its terms.Note
The state-vector simulation path does not go through
synthesis: it exponentiates the wholeoperatorexactly. Simulating this gate therefore incurs no Trotter error, whereas a decomposed circuit generally does.Initializing an instance of this gate can be done with the arguments listed below.
- Parameters:
num_modes (int) – the number of fermionic modes on which this gate acts.
operator (OperatorTrait) – the Hermitian operator \(H\) under which to time evolve the acted-upon fermionic modes.
time (float) – the evolution time \(t\) entering the exponent of \(e^{-i t H}\). A negative value evolves backwards in time.
synthesis (FermionicEvolutionSynthesis | None) – the fermion-to-fermion synthesis method with which to decompose this gate, when it gets decomposed at all. If
None(the default), aFermionicLieTrotterinstance is used.atomic (bool) – whether this gate is a fully decomposed factor which must not be broken down any further in fermionic space. See
atomic.
Attributes
- atomic¶
Whether this gate is a factor that must not be decomposed any further.
A
FermionicEvolutionSynthesismarks the factors it emits as atomic, because they are the result of the split it chose to perform: breaking them down again would discard that choice. The evolution of a single operator term is atomic for the stronger reason that there is nothing left to split.An atomic gate has no definition at all, so
decompose()leaves it in place rather than expanding it. It still maps and synthesizes normally at the fermion-to-qubit level, which is where a factor is turned into actual operations.This is read-only, for the same reason as
synthesis.
- synthesis¶
The fermion-to-fermion synthesis method with which this gate is decomposed.
This is read-only: the gate’s definition is built once and then cached, so a synthesis method assigned after the fact could not take effect. Pass it to the constructor instead.
- operator¶
The operator under which to time evolve the acted-upon fermionic modes.
Methods
- inverse(annotated=False)¶
Returns the inverse of this gate, \(e^{+i t H}\).
- Parameters:
annotated (bool) – ignored. The inverse of this gate is another
Evolution, so it never needs to be anAnnotatedOperation.- Returns:
An
Evolutiongate evolving the same operator for the negated time.- Return type:
Protocol Methods
- _apply_unitary_placed_(vec, norb, nelec, copy, freg_indices)¶
Applies
exp(-i * time * operator)after relabeling the operator to global modes.The operator is relabeled onto its global modes, converted to an
ffsim.FermionOperatorand handed toffsim.linear_operator(), then applied to the vector viascipy.sparse.linalg.expm_multiply(). An operator that is not already aFermionOperatoris first converted through theSupportsFermionOperatorprotocol, so any operator type of this package can be evolved.- Parameters:
vec (np.ndarray) – the state vector to act on.
norb (int) – the number of spatial orbitals of the global state vector.
nelec (int | tuple[int, int]) – either a single integer for a spinless system, or a pair of integers storing the numbers of spin alpha and spin beta fermions. An integer selects the spinless mode interpretation (the operator’s
norbmodes are alpha orbitals); a pair selects the spinful(orb, spin)interpretation of the operator’s2 * norbmodes.copy (bool) – whether to copy the vector before operating on it.
freg_indices (list[int]) – the absolute (global) mode indices that this gate’s local modes map onto. The operator is relabeled from its local modes to these global modes before being applied, mirroring the transpiler’s synthesis pass.
- Returns:
The transformed vector.
- Raises:
MissingOptionalLibraryError – if ffsim is not installed.
ValueError – if the operator does not conserve the
(norb, nelec)sector. Evolving underexp(-i * time * operator)only yields a unitary whenoperatormaps the sector to itself, so ffsim rejects an operator that conserves neither particle number nor the z-component of spin.
- Return type:
np.ndarray