symbolic mathematics engine in OCaml with differentiation, integration, simplification, and numerical methods
17

Configure Feed

Select the types of activity you want to include in your feed.

leibniz / lib / integrate.ml
4.9 kB 134 lines
1open Expr 2open Simplify 3open Diff 4open Substitute 5 6let rec integrate var = function 7 | Const c -> Some (Mul (Const c, Var var)) 8 | SymConst _ as s -> Some (Mul (s, Var var)) 9 | Var v when v = var -> Some (Div (Pow (Var var, Const 2.0), Const 2.0)) 10 | Var v -> Some (Mul (Var v, Var var)) 11 | Add (e1, e2) -> 12 (match (integrate var e1, integrate var e2) with 13 | Some i1, Some i2 -> Some (simplify (Add (i1, i2))) 14 | _ -> None) 15 | Sub (e1, e2) -> 16 (match (integrate var e1, integrate var e2) with 17 | Some i1, Some i2 -> Some (simplify (Sub (i1, i2))) 18 | _ -> None) 19 | Mul (Const c, e) | Mul (e, Const c) -> 20 (match integrate var e with 21 | Some i -> Some (simplify (Mul (Const c, i))) 22 | None -> None) 23 | Mul (SymConst s, e) | Mul (e, SymConst s) -> 24 (match integrate var e with 25 | Some i -> Some (simplify (Mul (SymConst s, i))) 26 | None -> None) 27 | Pow (Var v, Const n) when v = var && n <> -1.0 -> 28 let exp = n +. 1.0 in 29 Some (simplify (Div (Pow (Var var, Const exp), Const exp))) 30 | Div (Const 1.0, Var v) when v = var -> 31 Some (Ln (Abs (Var var))) 32 | Div (e, Var v) when v = var -> 33 (match e with 34 | Const c -> Some (simplify (Mul (Const c, Ln (Abs (Var var))))) 35 | _ -> None) 36 | Sin (Var v) when v = var -> 37 Some (Neg (Cos (Var var))) 38 | Cos (Var v) when v = var -> 39 Some (Sin (Var var)) 40 | Tan (Var v) when v = var -> 41 Some (Neg (Ln (Abs (Cos (Var var))))) 42 | Div (Const 1.0, Pow (Cos (Var v), Const 2.0)) when v = var -> 43 Some (Tan (Var var)) 44 | Sinh (Var v) when v = var -> 45 Some (Cosh (Var var)) 46 | Cosh (Var v) when v = var -> 47 Some (Sinh (Var var)) 48 | Tanh (Var v) when v = var -> 49 Some (Ln (Cosh (Var var))) 50 | Div (Const 1.0, Sqrt (Sub (Const 1.0, Pow (Var v, Const 2.0)))) when v = var -> 51 Some (Asin (Var var)) 52 | Neg (Div (Const 1.0, Sqrt (Sub (Const 1.0, Pow (Var v, Const 2.0))))) when v = var -> 53 Some (Acos (Var var)) 54 | Div (Const 1.0, Add (Const 1.0, Pow (Var v, Const 2.0))) when v = var -> 55 Some (Atan (Var var)) 56 | Exp (Var v) when v = var -> 57 Some (Exp (Var var)) 58 | Pow (Const a, Var v) when v = var -> 59 Some (simplify (Div (Pow (Const a, Var var), Ln (Const a)))) 60 | Pow (SymConst E, Var v) when v = var -> 61 Some (Exp (Var var)) 62 | e -> 63 match try_u_substitution var e with 64 | Some result -> Some result 65 | None -> try_by_parts var e 66 67and try_u_substitution var expr = 68 let rec find_inner = function 69 | Sin u | Cos u | Tan u | Sinh u | Cosh u | Tanh u 70 | Asin u | Acos u | Atan u | Exp u | Ln u | Sqrt u | Abs u -> Some u 71 | Pow (u, _) -> Some u 72 | Add (e1, e2) | Sub (e1, e2) | Mul (e1, e2) | Div (e1, e2) -> 73 (match find_inner e1 with 74 | Some _ as r -> r 75 | None -> find_inner e2) 76 | _ -> None 77 in 78 match find_inner expr with 79 | Some u when u <> Var var -> 80 let u_prime = diff var u in 81 let expr_simplified = simplify expr in 82 let test_expr = simplify (Div (expr_simplified, u_prime)) in 83 let substituted = substitute var (Var "u_temp") test_expr in 84 (match substituted with 85 | e when not (contains_var var e) -> 86 (match integrate "u_temp" e with 87 | Some integrated -> 88 let result = substitute "u_temp" u integrated in 89 Some (simplify result) 90 | None -> None) 91 | _ -> None) 92 | _ -> None 93 94and try_by_parts var = function 95 | Mul (e1, e2) -> 96 let priority = function 97 | Ln _ -> 5 98 | Asin _ | Acos _ | Atan _ -> 4 99 | Var _ | Pow (Var _, _) -> 3 100 | Sin _ | Cos _ | Tan _ | Sinh _ | Cosh _ | Tanh _ -> 2 101 | Exp _ -> 1 102 | _ -> 0 103 in 104 let (u, dv) = 105 if priority e1 >= priority e2 then (e1, e2) else (e2, e1) 106 in 107 (match integrate var dv with 108 | Some v -> 109 let du = diff var u in 110 (match integrate var (simplify (Mul (v, du))) with 111 | Some second_integral -> 112 Some (simplify (Sub (Mul (u, v), second_integral))) 113 | None -> None) 114 | None -> None) 115 | _ -> None 116 117and contains_var var = function 118 | Const _ | SymConst _ -> false 119 | Var v -> v = var 120 | Add (e1, e2) | Sub (e1, e2) | Mul (e1, e2) | Div (e1, e2) | Pow (e1, e2) -> 121 contains_var var e1 || contains_var var e2 122 | Neg e | Sin e | Cos e | Tan e | Sinh e | Cosh e | Tanh e 123 | Asin e | Acos e | Atan e | Exp e | Ln e | Sqrt e | Abs e -> 124 contains_var var e 125 | Atan2 (e1, e2) | Log (e1, e2) -> 126 contains_var var e1 || contains_var var e2 127 128let integrate_definite var lower upper expr = 129 match integrate var expr with 130 | None -> None 131 | Some antideriv -> 132 let upper_val = Eval.eval [(var, upper)] antideriv in 133 let lower_val = Eval.eval [(var, lower)] antideriv in 134 Some (upper_val -. lower_val)