Trait exmex::Differentiate

source ·
pub trait Differentiate<'a, T>
where T: DiffDataType, <T as FromStr>::Err: Debug, Self: Sized + Express<'a, T> + Display + Debug,
{ // Provided methods fn partial(self, var_idx: usize) -> ExResult<Self> { ... } fn partial_relaxed( self, var_idx: usize, missing_op_mode: MissingOpMode ) -> ExResult<Self> { ... } fn partial_nth(self, var_idx: usize, n: usize) -> ExResult<Self> { ... } fn partial_nth_relaxed( self, var_idx: usize, n: usize, missing_op_mode: MissingOpMode ) -> ExResult<Self> { ... } fn partial_iter<I>(self, var_idxs: I) -> ExResult<Self> where I: Iterator<Item = usize> + Clone { ... } fn partial_iter_relaxed<I>( self, var_idxs: I, missing_op_mode: MissingOpMode ) -> ExResult<Self> where I: Iterator<Item = usize> + Clone { ... } }
Expand description

feature = "partial" - Trait for partial differentiation. This is implemented for expressions with datatypes that implement DiffDataType.

Provided Methods§

source

fn partial(self, var_idx: usize) -> ExResult<Self>

feature = "partial" - This method computes a new expression that is the partial derivative of self with default operators.

Example
use exmex::prelude::*;

let expr = FlatEx::<f64>::parse("sin(1+y^2)*x")?;
let dexpr_dx = expr.partial(0)?;

assert!((dexpr_dx.eval(&[9e5, 2.0])? - (5.0 as f64).sin()).abs() < 1e-12);
//                        |    
//           The partial derivative dexpr_dx does depend on x. Still, it
//           expects the same number of parameters as the corresponding
//           antiderivative. Hence, you can pass any number for x.  
Arguments
  • var_idx - variable with respect to which the partial derivative is computed
Errors
  • If you use custom operators this might not work as expected. It could return an ExError if an operator is not found or compute a wrong result if an operator is defined in an un-expected way.
source

fn partial_relaxed( self, var_idx: usize, missing_op_mode: MissingOpMode ) -> ExResult<Self>

Like Differentiate::partial. The only difference is that in case there is no differentation defined for a binary operator this will not necessarily throw an error depending on missing_op_mode, see MissingOpMode.

source

fn partial_nth(self, var_idx: usize, n: usize) -> ExResult<Self>

feature = "partial" - Computes the nth partial derivative with respect to one variable

Example
use exmex::prelude::*;

let mut expr = FlatEx::<f64>::parse("x^4+y^4")?;

let dexpr_dxx_nth = expr.clone().partial_nth(0, 2)?;

let dexpr_dx = expr.partial(0)?;
let dexpr_dxx_2step = dexpr_dx.partial(0)?;

assert!((dexpr_dxx_2step.eval(&[4.3, 2.1])? - dexpr_dxx_nth.eval(&[4.3, 2.1])?).abs() < 1e-12);
Arguments
  • var_idx - variable with respect to which the partial derivative is computed
  • n - order of derivation
Errors
  • If you use custom operators this might not work as expected. It could return an ExError if an operator is not found or compute a wrong result if an operator is defined in an un-expected way.
source

fn partial_nth_relaxed( self, var_idx: usize, n: usize, missing_op_mode: MissingOpMode ) -> ExResult<Self>

Like Differentiate::partial_nth. The only difference is that in case there is no differentation defined for a binary operator this will not necessarily throw an error depending on missing_op_mode, see MissingOpMode.

source

fn partial_iter<I>(self, var_idxs: I) -> ExResult<Self>
where I: Iterator<Item = usize> + Clone,

feature = "partial" - Computes a chain of partial derivatives with respect to the variables passed as iterator

Example
use exmex::prelude::*;

let mut expr = FlatEx::<f64>::parse("x^4+y^4")?;

let dexpr_dxy_iter = expr.clone().partial_iter([0, 1].iter().copied())?;

let dexpr_dx = expr.partial(0)?;
let dexpr_dxy_2step = dexpr_dx.partial(1)?;

assert!((dexpr_dxy_2step.eval(&[4.3, 2.1])? - dexpr_dxy_iter.eval(&[4.3, 2.1])?).abs() < 1e-12);
Arguments
  • var_idxs - variables with respect to which the partial derivative is computed
  • n - order of derivation
Errors
  • If you use custom operators this might not work as expected. It could return an ExError if an operator is not found or compute a wrong result if an operator is defined in an un-expected way.
source

fn partial_iter_relaxed<I>( self, var_idxs: I, missing_op_mode: MissingOpMode ) -> ExResult<Self>
where I: Iterator<Item = usize> + Clone,

Like Differentiate::partial_iter. The only difference is that in case there is no differentation defined for a binary this will not necessarily throw an error depending on missing_op_mode, see MissingOpMode.

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<'a, T, OF, LM> Differentiate<'a, T> for FlatEx<T, OF, LM>
where T: DiffDataType, OF: MakeOperators<T> + Debug, LM: MatchLiteral + Debug, <T as FromStr>::Err: Debug,

source§

impl<'a, T, OF, LM> Differentiate<'a, T> for DeepEx<'a, T, OF, LM>
where T: DiffDataType, OF: MakeOperators<T> + Debug, LM: MatchLiteral + Debug, <T as FromStr>::Err: Debug,