pub struct Parameter { /* private fields */ }Expand description
A symbolic or numeric parameter used to represent gate angles and other continuous values in a quantum circuit.
Parameter is a thin, cheaply-cloneable wrapper around symb_anafis::Expr.
It supports the full suite of arithmetic operators (+, -, *, /)
between Parameter values as well as between Parameter and primitive numeric types
(f64, f32, i32, u32).
The mathematical constants π and e are always available as free
symbols and are automatically resolved during Parameter::evaluate.
Implementations§
Source§impl Parameter
impl Parameter
Sourcepub fn new(expr: Expr) -> Self
pub fn new(expr: Expr) -> Self
Creates a new Parameter directly from a symb_anafis::Expr node.
Prefer Parameter::symbol for named variables or the From<f64> / From<i32>
impls for numeric constants.
Sourcepub fn symbol(name: &str) -> Self
pub fn symbol(name: &str) -> Self
Creates a symbolic parameter representing a free variable with the
given name.
§Examples
use cqlib_core::circuit::Parameter;
let theta = Parameter::symbol("θ");
assert_eq!(theta.get_symbols().contains("θ"), true);Sourcepub fn evaluate(
&self,
bindings: &Option<HashMap<&str, f64>>,
) -> Result<f64, ParameterError>
pub fn evaluate( &self, bindings: &Option<HashMap<&str, f64>>, ) -> Result<f64, ParameterError>
Evaluates the expression to a concrete f64 value.
The mathematical constants π and e are injected automatically, so
callers do not need to supply them. Additional variable bindings are
provided through bindings.
Returns ParameterError::NaN if the expression still contains
unbound free variables after applying the supplied bindings.
§Examples
use cqlib_core::circuit::Parameter;
use std::collections::HashMap;
// Numeric constant — no bindings needed.
let p = Parameter::from(std::f64::consts::PI);
assert!((p.evaluate(&None).unwrap() - std::f64::consts::PI).abs() < 1e-10);
// Symbolic expression with a user-supplied binding.
let theta = Parameter::symbol("θ");
let expr = theta * Parameter::from(2.0);
let mut bindings = HashMap::new();
bindings.insert("θ", 1.0_f64);
assert!((expr.evaluate(&Some(bindings)).unwrap() - 2.0).abs() < 1e-10);Sourcepub fn simplify(&self) -> Result<Self, ParameterError>
pub fn simplify(&self) -> Result<Self, ParameterError>
Returns an algebraically simplified form of this parameter.
Simplification is performed in a domain-safe mode to avoid invalid
transformations (e.g. taking the log of a potentially negative number).
For affine sums, scalar products and division by numeric constants,
nonzero f64 coefficients and cancellation results are preserved without
tolerance pruning. Numeric literals are retained exactly. Floating-point
rounding, overflow and underflow still apply. Parsing and general
nonlinear simplification use the symbolic engine’s own numeric policy.
§Examples
use cqlib_core::circuit::Parameter;
let theta = Parameter::symbol("θ");
let expr = theta.clone() * Parameter::from(1.0); // θ * 1
let simplified = expr.simplify().unwrap();
assert_eq!(simplified.to_string(), "θ");Sourcepub fn canonicalized(&self) -> Result<Self, ParameterError>
pub fn canonicalized(&self) -> Result<Self, ParameterError>
Returns the canonical storage form of this parameter expression.
A constant expression is evaluated before symbolic simplification. If
simplification eliminates all symbols, the result is also evaluated and
rebuilt as a finite numeric parameter. This also normalizes -0.0 to
0.0, giving circuit operation storage a stable representation for
equivalent constants.
Symbolic expressions are returned in their simplified form. This method
does not intern symbolic parameters into any circuit; use
Circuit::map_param when a
CircuitParam is needed for operation
storage.
§Errors
Returns ParameterError if simplification fails, a constant expression
cannot be evaluated, or the evaluated constant is not finite.
Sourcepub fn is_exact_zero(&self) -> Result<bool, ParameterError>
pub fn is_exact_zero(&self) -> Result<bool, ParameterError>
Returns whether this parameter is exactly the numeric constant 0.0.
This is stricter than Parameter::is_zero: symbolic parameters return
false, and constants are compared exactly after evaluation rather than
with an epsilon tolerance. Compiler canonicalization uses this predicate
when deciding whether a no-op is represented exactly as zero.
§Errors
Returns ParameterError if a constant parameter cannot be evaluated.
Sourcepub fn derivative(&self, var: &str) -> Result<Self, ParameterError>
pub fn derivative(&self, var: &str) -> Result<Self, ParameterError>
Computes the symbolic partial derivative of this expression with
respect to the variable var.
Returns ParameterError if differentiation is not supported for
the expression.
§Examples
use cqlib_core::circuit::Parameter;
let theta = Parameter::symbol("θ");
let expr = theta.clone() * theta.clone(); // θ²
let deriv = expr.derivative("θ").unwrap(); // 2θ
let val = deriv.evaluate(&Some([("θ", 3.0)].iter().cloned().collect())).unwrap();
assert!((val - 6.0).abs() < 1e-10);Sourcepub fn get_symbols(&self) -> HashSet<String>
pub fn get_symbols(&self) -> HashSet<String>
Returns the set of free variable names present in this expression.
The built-in constants π and e may appear here if the expression
was constructed symbolically (e.g. via Parameter::pi), but they are
resolved automatically during Parameter::evaluate.
§Examples
use cqlib_core::circuit::Parameter;
let expr = Parameter::symbol("θ") + Parameter::symbol("φ");
let syms = expr.get_symbols();
assert!(syms.contains("θ"));
assert!(syms.contains("φ"));Sourcepub fn log(&self, base: impl Into<Self>) -> Self
pub fn log(&self, base: impl Into<Self>) -> Self
Returns a new parameter representing the logarithm log_base(x).
§Examples
use cqlib_core::circuit::Parameter;
// log base 2 of x
let x = Parameter::symbol("x");
let log2 = x.log(Parameter::from(2.0));
let val = log2.evaluate(&Some([("x", 8.0)].iter().cloned().collect())).unwrap();
assert!((val - 3.0).abs() < 1e-10);Sourcepub fn pi() -> Self
pub fn pi() -> Self
Returns the mathematical constant π as a symbolic parameter.
The symbol "π" is resolved to std::f64::consts::PI automatically
inside Parameter::evaluate.
Sourcepub fn e() -> Self
pub fn e() -> Self
Returns the mathematical constant e (Euler’s number) as a symbolic parameter.
The symbol "e" is resolved to std::f64::consts::E automatically
inside Parameter::evaluate.
Sourcepub fn pow(&self, exp: impl Into<Self>) -> Self
pub fn pow(&self, exp: impl Into<Self>) -> Self
Returns a new parameter representing self raised to the power exp.
§Examples
use cqlib_core::circuit::Parameter;
let x = Parameter::symbol("x");
let x3 = x.pow(Parameter::from(3.0)); // x³
let val = x3.evaluate(&Some([("x", 2.0)].iter().cloned().collect())).unwrap();
assert!((val - 8.0).abs() < 1e-10);Sourcepub fn replace(&self, symbol: &str, param: impl Into<Self>) -> Self
pub fn replace(&self, symbol: &str, param: impl Into<Self>) -> Self
Substitutes every occurrence of symbol in this expression with
param, returning the resulting expression.
The inserted expression is not visited again; the original is unchanged.
§Examples
use cqlib_core::circuit::Parameter;
let expr = Parameter::symbol("θ") * Parameter::from(2.0); // θ * 2
let replaced = expr.replace("θ", Parameter::pi()); // π * 2
let val = replaced.evaluate(&None).unwrap();
assert!((val - 2.0 * std::f64::consts::PI).abs() < 1e-10);Sourcepub fn as_symbol(&self) -> Option<String>
pub fn as_symbol(&self) -> Option<String>
Returns the symbol name if this parameter is exactly one free symbol.
This is intentionally conservative: expressions containing one symbol are accepted only when they are structurally equal to that symbol after optional simplification.
Sourcepub fn substitute_many(&self, bindings: &HashMap<String, Parameter>) -> Self
pub fn substitute_many(&self, bindings: &HashMap<String, Parameter>) -> Self
Simultaneously substitutes bound symbols and simplifies when possible.
Replacement expressions are inserted as-is, without applying other bindings to them. The result is independent of binding iteration order, and the original expression is unchanged.
Sourcepub fn provably_equal(&self, other: &Self, tolerance: f64) -> bool
pub fn provably_equal(&self, other: &Self, tolerance: f64) -> bool
Returns whether two parameters are provably equal within tolerance.
This is a conservative symbolic check. It accepts structural equality after simplification and concrete numeric equality, but it does not try to prove arbitrary symbolic identities.
Sourcepub fn provably_equal_modulo(
&self,
other: &Self,
modulus: &Self,
tolerance: f64,
) -> bool
pub fn provably_equal_modulo( &self, other: &Self, modulus: &Self, tolerance: f64, ) -> bool
Returns whether two parameters are provably equal modulo modulus.
Fully numeric parameters take a fast path with plain floating-point math, without building or simplifying a symbolic difference expression. Only expressions with unbound symbols fall back to the symbolic path, where the expression difference and modulus must both evaluate without extra bindings for the numeric modulo check to apply.
Sourcepub fn is_constant(&self) -> bool
pub fn is_constant(&self) -> bool
Returns true if this parameter is a constant (has no free variables).
§Examples
use cqlib_core::circuit::Parameter;
let constant = Parameter::from(3.14);
assert!(constant.is_constant());
let symbolic = Parameter::symbol("x");
assert!(!symbolic.is_constant());Sourcepub fn is_zero(&self) -> bool
pub fn is_zero(&self) -> bool
Returns true if this parameter evaluates to zero.
Returns false if the parameter cannot be evaluated (contains unbound symbols).
§Examples
use cqlib_core::circuit::Parameter;
let zero = Parameter::from(0.0);
assert!(zero.is_zero());
let non_zero = Parameter::from(1.0);
assert!(!non_zero.is_zero());Sourcepub fn is_one(&self) -> bool
pub fn is_one(&self) -> bool
Returns true if this parameter evaluates to one.
Returns false if the parameter cannot be evaluated (contains unbound symbols).
§Examples
use cqlib_core::circuit::Parameter;
let one = Parameter::from(1.0);
assert!(one.is_one());
let non_one = Parameter::from(2.0);
assert!(!non_one.is_one());Trait Implementations§
impl Eq for Parameter
Source§impl From<&Parameter> for ParameterValue
impl From<&Parameter> for ParameterValue
Source§impl From<&ParameterValue> for Parameter
impl From<&ParameterValue> for Parameter
Source§fn from(para: &ParameterValue) -> Parameter
fn from(para: &ParameterValue) -> Parameter
Source§impl From<Parameter> for ParameterValue
impl From<Parameter> for ParameterValue
Source§impl From<ParameterValue> for Parameter
impl From<ParameterValue> for Parameter
Source§fn from(para: ParameterValue) -> Parameter
fn from(para: ParameterValue) -> Parameter
Source§impl FromStr for Parameter
impl FromStr for Parameter
Source§fn from_str(expr: &str) -> Result<Self, Self::Err>
fn from_str(expr: &str) -> Result<Self, Self::Err>
Parses a symbolic expression from a string.
Returns ParameterError::ParseError if the string cannot be parsed
as a valid expression.
§Examples
use cqlib_core::circuit::Parameter;
use std::str::FromStr;
let p = Parameter::from_str("θ * 2 + π").unwrap();
let bad = Parameter::from_str("@@@");
assert!(bad.is_err());Source§type Err = ParameterError
type Err = ParameterError
Source§impl PartialEq for Parameter
impl PartialEq for Parameter
Source§impl TryFrom<&str> for Parameter
impl TryFrom<&str> for Parameter
Source§fn try_from(expr: &str) -> Result<Self, Self::Error>
fn try_from(expr: &str) -> Result<Self, Self::Error>
Parses a symbolic expression from a string slice.
Returns ParameterError::ParseError if the string cannot be parsed
as a valid expression.
§Examples
use cqlib_core::circuit::Parameter;
let p = Parameter::try_from("θ * 2 + π").unwrap();
let bad = Parameter::try_from("@@@");
assert!(bad.is_err());Source§type Error = ParameterError
type Error = ParameterError
Auto Trait Implementations§
impl Freeze for Parameter
impl RefUnwindSafe for Parameter
impl Send for Parameter
impl Sync for Parameter
impl Unpin for Parameter
impl UnsafeUnpin for Parameter
impl UnwindSafe for Parameter
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
Source§impl<T> CallHasher for T
impl<T> CallHasher for 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<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
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> StdoutFmt for Twhere
T: Display,
impl<T> StdoutFmt for Twhere
T: Display,
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.