opensrdk_symbolic_computation/expression/
differential.rs

1use crate::Expression;
2
3impl Expression {
4    pub fn differential(&self, variable_ids: &[&str]) -> Vec<Expression> {
5        match self {
6            Expression::Variable(id, sizes) => Expression::diff_variable(id, sizes, variable_ids),
7            Expression::Constant(_) => vec![0.0.into(); variable_ids.len()],
8            Expression::PartialVariable(v) => Expression::diff_partial_variable(v, variable_ids),
9            Expression::Add(l, r) => Expression::diff_add(l, r, variable_ids),
10            Expression::Sub(l, r) => Expression::diff_sub(l, r, variable_ids),
11            Expression::Mul(l, r) => Expression::diff_mul(l, r, variable_ids),
12            Expression::Div(l, r) => Expression::diff_div(l, r, variable_ids),
13            Expression::Neg(v) => Expression::diff_neg(v, variable_ids),
14            Expression::Transcendental(v) => v.differential(variable_ids),
15            Expression::Tensor(v) => v.differential(variable_ids),
16            Expression::Matrix(v) => v.differential(variable_ids),
17        }
18    }
19}
20
21#[cfg(test)]
22mod tests {
23    use crate::*;
24    use std::iter::once;
25
26    #[test]
27    fn it_works() {
28        let x = new_variable("x".to_string());
29
30        let expression = x.clone().pow(2.0.into());
31        let diff = expression.differential(&["x"])[0].clone();
32
33        println!("{:#?}", diff);
34    }
35
36    #[test]
37    fn it_works2() {
38        let x = new_variable("x".to_string());
39
40        let expression = (2.0 * x.clone()).exp();
41        let diff = expression.differential(&["x"])[0].clone();
42
43        println!("{:#?}", diff);
44    }
45
46    #[test]
47    fn it_works3() {
48        let x = new_variable("x".to_string());
49
50        let expression = x.clone().sin() + x.clone().cos().exp();
51        let diff = expression.differential(&["x"])[0].clone();
52
53        println!("{:#?}", diff);
54    }
55
56    #[test]
57    fn it_works4() {
58        let x = new_variable("x".to_string());
59
60        let expression = x.clone().pow(2.0.into());
61        let diff = expression.differential(&["x"])[0].clone();
62
63        println!(
64            "{:#?}",
65            expression.assign(&once(("x", ConstantValue::Scalar(3.0))).collect())
66        );
67
68        println!(
69            "{:#?}",
70            diff.assign(&once(("x", ConstantValue::Scalar(3.0))).collect())
71        );
72    }
73    #[test]
74    fn it_works5() {
75        let x = new_variable("x".to_string());
76        let mu = new_variable("mu".to_string());
77        let sigma = new_variable("sigma".to_string());
78        let expression = -(x - mu).pow(2.0.into()) / (2.0 * sigma.pow(2.0.into()));
79        let diff_x = expression.differential(&["x"])[0].clone();
80        let diff_mu = expression.differential(&["mu"])[0].clone();
81        let diff_sigma = expression.differential(&["sigma"])[0].clone();
82        let diff_anpan = expression.differential(&["anpan"])[0].clone();
83
84        let tex_symbols = vec![("x", "x"), ("mu", r"\mu"), ("sigma", r"\Sigma")]
85            .into_iter()
86            .collect();
87
88        println!("{:#?}", diff_x.tex_code(&tex_symbols));
89        println!("{:#?}", diff_mu.tex_code(&tex_symbols));
90        println!("{:#?}", diff_sigma.tex_code(&tex_symbols));
91        println!("{:#?}", diff_anpan.tex_code(&tex_symbols));
92    }
93}