opensrdk_symbolic_computation/expression/
differential.rs1use 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}