1use crate::{
2 Elementary::{self, *},
3 Error, Function,
4};
5use std::{f64::consts::E, sync::Arc};
6impl Elementary {
7 fn differentiate(self) -> Self {
8 match self {
9 Sin(func) => Mul(
10 Arc::new(Cos(func.clone())),
11 Arc::new((*func).clone().differentiate()),
12 ), Cos(func) => Mul(
14 Arc::new(Mul(Arc::new(Sin(func.clone())), Arc::new(Con(-1.)))),
15 Arc::new((*func).clone().differentiate()),
16 ), Tan(func) => Mul(
18 Arc::new(Div(
19 Arc::new(Con(1.)),
20 Arc::new(Pow(Arc::new(Cos(Arc::new(X))), Arc::new(Con(2.)))),
21 )),
22 Arc::new((*func).clone().differentiate()),
23 ), Sec(func) => (*func).clone().differentiate() * Tan(func.clone()) * Sec(func.to_owned()),
26 Csc(func) => {
27 (*func).clone().differentiate()
28 * Cot(func.clone())
29 * Csc(func.to_owned())
30 * (-1 as f64)
31 }
32 Cot(func) => {
33 (*func).clone().differentiate()
34 * (-1 as f64)
35 * Pow(Arc::new(Csc(func.to_owned())), Arc::new(Con(2.)))
36 }
37
38 Asin(func) => Div(
39 Arc::new((*func).clone().differentiate()),
40 Arc::new(Pow(
41 Arc::new(Sub(
42 Arc::new(Con(1.)),
43 Arc::new(Pow(func.clone(), Arc::new(Con(2.)))),
44 )),
45 Arc::new(Con(0.5)),
46 )),
47 ),
48 Acos(func) => Mul(
49 Arc::new(Div(
50 Arc::new((*func).clone().differentiate()),
51 Arc::new(Pow(
52 Arc::new(Sub(
53 Arc::new(Con(1.)),
54 Arc::new(Pow(func.clone(), Arc::new(Con(2.)))),
55 )),
56 Arc::new(Con(0.5)),
57 )),
58 )),
59 Arc::new(Con(-1.)),
60 ),
61 Atan(func) => Div(
62 Arc::new((*func).clone().differentiate()),
63 Arc::new(Add(
64 Arc::new(Pow(func.clone(), Arc::new(Con(2.)))),
65 Arc::new(Con(1.)),
66 )),
67 ),
68 Sinh(func) => Mul(
69 Arc::new(Cosh(func.clone())),
70 Arc::new((*func).clone().differentiate()),
71 ),
72 Cosh(func) => Mul(
73 Arc::new(Sinh(func.clone())),
74 Arc::new((*func).clone().differentiate()),
75 ),
76 Tanh(func) => Div(
77 Arc::new((*func).clone().differentiate()),
78 Arc::new(Pow(Arc::new(Cosh(func.clone())), Arc::new(Con(2.)))),
79 ),
80
81 Add(func1, func2) => Add(
82 Arc::new((*func1).clone().differentiate()),
83 Arc::new((*func2).clone().differentiate()),
84 ), Sub(func1, func2) => Sub(
86 Arc::new((*func1).clone().differentiate()),
87 Arc::new((*func2).clone().differentiate()),
88 ), Mul(func1, func2) => Add(
90 Arc::new(Mul(
91 Arc::new((*func1).clone().differentiate()),
92 func2.clone(),
93 )),
94 Arc::new(Mul(
95 Arc::new((*func2).clone().differentiate()),
96 func1.clone(),
97 )),
98 ), Div(func1, func2) => Div(
100 Arc::new(Sub(
101 Arc::new(Mul(
102 Arc::new((*func1).clone().differentiate()),
103 func2.clone(),
104 )),
105 Arc::new(Mul(
106 Arc::new((*func2).clone().differentiate()),
107 func1.clone(),
108 )),
109 )),
110 Arc::new(Pow((func2).clone(), Arc::new(Con(2.)))),
111 ), Pow(func1, func2) => Mul(
113 Arc::new(Pow(
114 func1.clone(),
115 Arc::new(Sub(func2.clone(), Arc::new(Con(1.)))),
116 )), Arc::new(Add(
118 Arc::new(Mul(
119 func2.clone(),
120 Arc::new((*func1).clone().differentiate()),
121 )), Arc::new(Mul(
123 func1.clone(), Arc::new(Mul(
125 Arc::new(Log(Arc::new(Con(E)), func1.clone())), Arc::new((*func2).clone().differentiate()),
127 )),
128 )),
129 )),
130 ), Log(func1, func2) => Div(
133 Arc::new(Sub(
134 Arc::new(Div(
135 Arc::new(Mul(
136 Arc::new(Log(Arc::new(Con(E)), func1.clone())),
137 Arc::new((*func2).clone().differentiate()),
138 )),
139 func2.clone(),
140 )),
141 Arc::new(Div(
142 Arc::new(Mul(
143 Arc::new(Log(Arc::new(Con(E)), func2.clone())),
144 Arc::new((*func1).clone().differentiate()),
145 )),
146 func1.clone(),
147 )),
148 )),
149 Arc::new(Pow(
150 Arc::new(Log(Arc::new(Con(E)), func1.clone())),
151 Arc::new(Con(2.)),
152 )),
153 ),
154
155 Factorial(func) => {
157 (*func).clone().differentiate()
158 * Factorial(func.clone())
159 * Polygamma((func + Con(1.)).into(), 0)
160 }
161
162 Gamma(func) => {
164 (*func).clone().differentiate() * Gamma(func.clone()) * Polygamma(func, 0)
165 }
166 Polygamma(func, order) => (*func).clone().differentiate() * Polygamma(func, order + 1),
168
169 Abs(func) => Div(
170 Arc::new(Mul(func.clone(), Arc::new((*func).clone().differentiate()))),
171 Arc::new(Abs(func)),
172 ),
173 Con(_) => Con(0.),
174 X => Con(1.),
175 }
176 }
177 pub fn derivative(self) -> Result<Elementary, Error> {
178 self.differentiate().simplify()
179 }
180 pub fn derivative_unsimplified(self) -> Elementary {
181 self.differentiate()
182 }
183}
184
185pub fn derivative_of(input_func: &Function) -> Function {
197 let elem_derivative = input_func.elementary().clone().differentiate();
198 Function::from(elem_derivative)
199}