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 / limits.ml
2.2 kB 70 lines
1open Expr 2open Simplify 3open Diff 4open Substitute 5 6type direction = FromLeft | FromRight | Bidirectional 7 8let rec limit expr var point direction = 9 let try_direct_sub () = 10 try 11 let substituted = substitute var point expr in 12 let simplified = simplify substituted in 13 match simplified with 14 | Const c when not (Float.is_nan c || Float.is_infinite c) -> Some simplified 15 | _ -> None 16 with _ -> None 17 in 18 19 let try_lhopital () = 20 let numerator, denominator = match expr with 21 | Div (n, d) -> (n, d) 22 | _ -> (expr, Const 1.0) 23 in 24 25 let num_at_point = substitute var point numerator |> simplify in 26 let den_at_point = substitute var point denominator |> simplify in 27 28 match (num_at_point, den_at_point) with 29 | (Const 0.0, Const 0.0) -> 30 let num_deriv = diff var numerator in 31 let den_deriv = diff var denominator in 32 let new_expr = Div (num_deriv, den_deriv) in 33 limit new_expr var point direction 34 | _ -> None 35 in 36 37 let try_series_expansion () = 38 None 39 in 40 41 match try_direct_sub () with 42 | Some result -> Some result 43 | None -> 44 match try_lhopital () with 45 | Some result -> Some result 46 | None -> try_series_expansion () 47 48let limit_at_infinity expr var = 49 let rec find_highest_power = function 50 | Pow (Var v, Const n) when v = var -> Some (int_of_float n) 51 | Div (num, den) -> 52 let num_pow = find_highest_power num |> Option.value ~default:0 in 53 let den_pow = find_highest_power den |> Option.value ~default:0 in 54 Some (num_pow - den_pow) 55 | Add (e1, e2) | Sub (e1, e2) -> 56 let p1 = find_highest_power e1 |> Option.value ~default:0 in 57 let p2 = find_highest_power e2 |> Option.value ~default:0 in 58 Some (max p1 p2) 59 | Mul (e1, e2) -> 60 let p1 = find_highest_power e1 |> Option.value ~default:0 in 61 let p2 = find_highest_power e2 |> Option.value ~default:0 in 62 Some (p1 + p2) 63 | _ -> None 64 in 65 66 match find_highest_power expr with 67 | Some p when p > 0 -> Some (SymConst E) 68 | Some p when p < 0 -> Some (Const 0.0) 69 | Some _ -> Some (Const 1.0) 70 | None -> None