pub struct FermionicOp { /* private fields */ }Expand description
A finite complex linear combination of ordered fermionic products.
The declared mode count is retained even for zero and identity operators.
Equal ordered products are merged automatically; only exact zero coefficients
are removed. Products are not automatically normal ordered. Use Self::chop
for explicit numerical truncation and Self::equiv for algebraic equivalence.
Structural equality also compares the declared mode count.
Fallible arithmetic operators return Result, for example (&a + &b)?.
Implementations§
Source§impl FermionicOp
impl FermionicOp
Sourcepub fn new(num_modes: usize) -> Self
pub fn new(num_modes: usize) -> Self
Creates the zero operator on the declared mode space, including zero modes.
Sourcepub fn identity(num_modes: usize) -> Self
pub fn identity(num_modes: usize) -> Self
Creates the identity. An empty product is the identity, not the zero operator.
Sourcepub fn from_term(
num_modes: usize,
term: impl IntoIterator<Item = FermionicLadder>,
coefficient: Complex64,
) -> Result<Self, QisError>
pub fn from_term( num_modes: usize, term: impl IntoIterator<Item = FermionicLadder>, coefficient: Complex64, ) -> Result<Self, QisError>
Creates a weighted ordered product. Even zero-weight terms are validated.
Sourcepub fn from_terms(
num_modes: usize,
terms: impl IntoIterator<Item = (Vec<FermionicLadder>, Complex64)>,
) -> Result<Self, QisError>
pub fn from_terms( num_modes: usize, terms: impl IntoIterator<Item = (Vec<FermionicLadder>, Complex64)>, ) -> Result<Self, QisError>
Creates a sum of products, merging duplicates without numerical truncation.
Sourcepub fn add_term(
&mut self,
term: impl IntoIterator<Item = FermionicLadder>,
coefficient: Complex64,
) -> Result<(), QisError>
pub fn add_term( &mut self, term: impl IntoIterator<Item = FermionicLadder>, coefficient: Complex64, ) -> Result<(), QisError>
Adds a weighted product atomically; an error leaves this operator unchanged.
Sourcepub fn creation(num_modes: usize, mode: usize) -> Result<Self, QisError>
pub fn creation(num_modes: usize, mode: usize) -> Result<Self, QisError>
Creates a single creation operator.
Sourcepub fn annihilation(num_modes: usize, mode: usize) -> Result<Self, QisError>
pub fn annihilation(num_modes: usize, mode: usize) -> Result<Self, QisError>
Creates a single annihilation operator.
Sourcepub fn number(num_modes: usize, mode: usize) -> Result<Self, QisError>
pub fn number(num_modes: usize, mode: usize) -> Result<Self, QisError>
Creates the number operator a†_p a_p.
Sourcepub fn total_number(num_modes: usize) -> Self
pub fn total_number(num_modes: usize) -> Self
Creates the total particle-number operator, or zero for zero modes.
Sourcepub fn excitation_generator(
num_modes: usize,
sources: &[usize],
targets: &[usize],
) -> Result<Self, QisError>
pub fn excitation_generator( num_modes: usize, sources: &[usize], targets: &[usize], ) -> Result<Self, QisError>
Creates the unit-weight Hermitian excitation generator G = i(T - T†).
For sources = [i_0, ..., i_{r-1}] and targets = [a_0, ..., a_{r-1}],
the ordered excitation is
T = a†_{a_0} ... a†_{a_{r-1}} a_{i_{r-1}} ... a_{i_0}.
The rightmost operator acts first. Thus [i, j] -> [a, b] means
T = a†_a a†_b a_j a_i.
Input order is preserved, without implicit sorting or normal ordering.
An odd permutation of either list negates G; applying odd permutations
to both lists preserves it. Explicit Self::normal_order preserves
these fermionic signs. No factorial or other normalization is applied.
Mapping G and evolving it with crate::circuit::ansatz::PauliEvolutionAnsatz
implements exp(-i θ G) = exp(θ (T - T†)). The evolution parameter belongs
to the ansatz, not this operator. The generator conserves total particle
number. Reference occupations and spin interpretations are caller choices.
§Errors
Returns QisError::InvalidParameterValue if the lists are empty, have
unequal lengths, contain repeated modes, or overlap. Returns
QisError::ModeOutOfBounds if an index is outside 0..num_modes.
§Example
use cqlib_core::qis::FermionicOp;
let single = FermionicOp::excitation_generator(4, &[0], &[2])?;
let double = FermionicOp::excitation_generator(4, &[0, 1], &[2, 3])?;
assert!(single.is_hermitian(0.0)?);
assert!(double.is_hermitian(0.0)?);Sourcepub fn terms(
&self,
) -> impl ExactSizeIterator<Item = (&[FermionicLadder], Complex64)> + '_
pub fn terms( &self, ) -> impl ExactSizeIterator<Item = (&[FermionicLadder], Complex64)> + '_
Iterates over products and their coefficients in deterministic structural order.
Sourcepub fn is_zero(&self) -> bool
pub fn is_zero(&self) -> bool
Reports whether the stored sum is zero. Algebraic cancellations require normal ordering.
Sourcepub fn try_add(&self, other: &Self) -> Result<Self, QisError>
pub fn try_add(&self, other: &Self) -> Result<Self, QisError>
Adds operators on the same mode space, without modifying either operand.
Sourcepub fn try_sub(&self, other: &Self) -> Result<Self, QisError>
pub fn try_sub(&self, other: &Self) -> Result<Self, QisError>
Subtracts operators on the same mode space.
Sourcepub fn try_mul(&self, other: &Self) -> Result<Self, QisError>
pub fn try_mul(&self, other: &Self) -> Result<Self, QisError>
Forms self * other; the right operand acts first. Does not normal order.
Sourcepub fn scaled(&self, factor: Complex64) -> Result<Self, QisError>
pub fn scaled(&self, factor: Complex64) -> Result<Self, QisError>
Scales all coefficients. The factor is validated even for the zero operator.
Sourcepub fn adjoint(&self) -> Self
pub fn adjoint(&self) -> Self
Takes the conjugate transpose, reversing each product without reordering it.
Sourcepub fn normal_order(&self) -> Result<Self, QisError>
pub fn normal_order(&self) -> Result<Self, QisError>
Expands using the canonical anticommutation relations.
Creators precede annihilators; each group uses ascending mode indices.
This is an equivalent operator expansion, including contraction terms:
a_p a†_p = I - a†_p a_p. Small nonzero coefficients are retained.
An explicit work stack avoids recursion in long products.
Sorting a branch of k ladders takes O(k²) comparisons; contractions can
produce additional branches.
Sourcepub fn chop(&mut self, atol: f64) -> Result<(), QisError>
pub fn chop(&mut self, atol: f64) -> Result<(), QisError>
Explicitly removes coefficients whose complex magnitude is at most atol.
Invalid tolerances leave the operator unchanged.
Trait Implementations§
Source§impl Add for FermionicOp
impl Add for FermionicOp
Source§impl Add<&FermionicOp> for &FermionicOp
impl Add<&FermionicOp> for &FermionicOp
Source§impl Add<&FermionicOp> for FermionicOp
impl Add<&FermionicOp> for FermionicOp
Source§impl Add<FermionicOp> for &FermionicOp
impl Add<FermionicOp> for &FermionicOp
Source§impl Clone for FermionicOp
impl Clone for FermionicOp
Source§impl Debug for FermionicOp
impl Debug for FermionicOp
Source§impl Mul for FermionicOp
impl Mul for FermionicOp
Source§impl Mul<&FermionicOp> for &FermionicOp
impl Mul<&FermionicOp> for &FermionicOp
Source§impl Mul<&FermionicOp> for FermionicOp
impl Mul<&FermionicOp> for FermionicOp
Source§impl Mul<&FermionicOp> for f64
impl Mul<&FermionicOp> for f64
Source§impl Mul<&FermionicOp> for Complex64
impl Mul<&FermionicOp> for Complex64
Source§impl Mul<FermionicOp> for &FermionicOp
impl Mul<FermionicOp> for &FermionicOp
Source§impl Mul<FermionicOp> for f64
impl Mul<FermionicOp> for f64
Source§impl Mul<FermionicOp> for Complex64
impl Mul<FermionicOp> for Complex64
Source§impl Mul<f64> for &FermionicOp
impl Mul<f64> for &FermionicOp
Source§impl Mul<f64> for FermionicOp
impl Mul<f64> for FermionicOp
Source§impl Neg for &FermionicOp
impl Neg for &FermionicOp
Source§impl Neg for FermionicOp
impl Neg for FermionicOp
Source§impl PartialEq for FermionicOp
impl PartialEq for FermionicOp
impl StructuralPartialEq for FermionicOp
Source§impl Sub for FermionicOp
impl Sub for FermionicOp
Source§impl Sub<&FermionicOp> for &FermionicOp
impl Sub<&FermionicOp> for &FermionicOp
Source§impl Sub<&FermionicOp> for FermionicOp
impl Sub<&FermionicOp> for FermionicOp
Source§impl Sub<FermionicOp> for &FermionicOp
impl Sub<FermionicOp> for &FermionicOp
Auto Trait Implementations§
impl Freeze for FermionicOp
impl RefUnwindSafe for FermionicOp
impl Send for FermionicOp
impl Sync for FermionicOp
impl Unpin for FermionicOp
impl UnsafeUnpin for FermionicOp
impl UnwindSafe for FermionicOp
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.impl<T, U> Imply<T> for U
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.