symbolic mathematics engine in OCaml with differentiation, integration, simplification, and numerical methods
1open Expr
2open Simplify
3
4let rec diff var = function
5 | Const _ -> Const 0.0
6 | SymConst _ -> Const 0.0
7 | Var v -> if v = var then Const 1.0 else Const 0.0
8 | Add (e1, e2) -> simplify (Add (diff var e1, diff var e2))
9 | Sub (e1, e2) -> simplify (Sub (diff var e1, diff var e2))
10 | Mul (e1, e2) ->
11 simplify (Add (Mul (diff var e1, e2), Mul (e1, diff var e2)))
12 | Div (e1, e2) ->
13 let num = Sub (Mul (diff var e1, e2), Mul (e1, diff var e2)) in
14 let den = Pow (e2, Const 2.0) in
15 simplify (Div (num, den))
16 | Pow (e, Const n) ->
17 simplify (Mul (Mul (Const n, Pow (e, Const (n -. 1.0))), diff var e))
18 | Pow (e1, e2) ->
19 let term1 = Mul (e2, Mul (Pow (e1, Sub (e2, Const 1.0)), diff var e1)) in
20 let term2 = Mul (Pow (e1, e2), Mul (Ln e1, diff var e2)) in
21 simplify (Add (term1, term2))
22 | Neg e -> simplify (Neg (diff var e))
23 | Sin e -> simplify (Mul (Cos e, diff var e))
24 | Cos e -> simplify (Neg (Mul (Sin e, diff var e)))
25 | Tan e ->
26 let sec2 = Div (Const 1.0, Pow (Cos e, Const 2.0)) in
27 simplify (Mul (sec2, diff var e))
28 | Sinh e -> simplify (Mul (Cosh e, diff var e))
29 | Cosh e -> simplify (Mul (Sinh e, diff var e))
30 | Tanh e ->
31 let sech2 = Sub (Const 1.0, Pow (Tanh e, Const 2.0)) in
32 simplify (Mul (sech2, diff var e))
33 | Asin e ->
34 let denom = Sqrt (Sub (Const 1.0, Pow (e, Const 2.0))) in
35 simplify (Div (diff var e, denom))
36 | Acos e ->
37 let denom = Sqrt (Sub (Const 1.0, Pow (e, Const 2.0))) in
38 simplify (Neg (Div (diff var e, denom)))
39 | Atan e ->
40 let denom = Add (Const 1.0, Pow (e, Const 2.0)) in
41 simplify (Div (diff var e, denom))
42 | Atan2 (y, x) ->
43 let num = Sub (Mul (x, diff var y), Mul (y, diff var x)) in
44 let denom = Add (Pow (x, Const 2.0), Pow (y, Const 2.0)) in
45 simplify (Div (num, denom))
46 | Exp e -> simplify (Mul (Exp e, diff var e))
47 | Ln e -> simplify (Div (diff var e, e))
48 | Log (base_e, arg) ->
49 let denom = Mul (arg, Ln base_e) in
50 simplify (Div (diff var arg, denom))
51 | Sqrt e ->
52 let denom = Mul (Const 2.0, Sqrt e) in
53 simplify (Div (diff var e, denom))
54 | Abs e ->
55 let sgn = Div (e, Abs e) in
56 simplify (Mul (sgn, diff var e))
57
58let rec diff_n var n expr =
59 if n <= 0 then expr
60 else diff_n var (n - 1) (diff var expr)
61
62let partial vars expr =
63 List.fold_left (fun e v -> diff v e) expr vars