pub fn propagate<const W: usize, T>(
circuit: &Circuit<W>,
initial: PauliSum<W>,
policy: &T,
direction: Direction,
) -> PauliSum<W>where
T: TruncationPolicy<W>,Expand description
Propagate initial through circuit under policy.
Iterates the circuit’s channels — in order for Direction::Forward, in
reverse for Direction::Heisenberg, calling Channel::apply_adjoint
in the latter case (default = self-adjoint; overridden on
PauliRotation and
Clifford1Q).
§Examples
use paulistrings::{
BuildAccumulator, Circuit, Direction, PauliString, Phase, TruncationPolicy,
channel::Clifford1Q, propagate,
};
use num_complex::Complex64;
let mut acc = BuildAccumulator::<1>::new(1);
acc.add_term(PauliString::<1>::z(0), Phase::ONE, Complex64::new(1.0, 0.0));
let observable = acc.finalize();
let mut circuit = Circuit::<1>::new(1);
circuit.push(Clifford1Q::h(0));
struct KeepAll;
impl<const W: usize> TruncationPolicy<W> for KeepAll {}
// H conjugates Z to X, so propagating Z₀ through H gives X₀.
let evolved = propagate(&circuit, observable, &KeepAll, Direction::Heisenberg);
assert_eq!(evolved.len(), 1);
assert_eq!(evolved.x()[0], [1]);
assert_eq!(evolved.z()[0], [0]);See design doc §8.1.