70 lines
2.1 KiB
OCaml
70 lines
2.1 KiB
OCaml
open Expr
|
|
open Simplify
|
|
open Diff
|
|
open Substitute
|
|
|
|
type direction = FromLeft | FromRight | Bidirectional
|
|
|
|
let rec limit expr var point direction =
|
|
let try_direct_sub () =
|
|
try
|
|
let substituted = substitute var point expr in
|
|
let simplified = simplify substituted in
|
|
match simplified with
|
|
| Const c when not (Float.is_nan c || Float.is_infinite c) -> Some simplified
|
|
| _ -> None
|
|
with _ -> None
|
|
in
|
|
|
|
let try_lhopital () =
|
|
let numerator, denominator = match expr with
|
|
| Div (n, d) -> (n, d)
|
|
| _ -> (expr, Const 1.0)
|
|
in
|
|
|
|
let num_at_point = substitute var point numerator |> simplify in
|
|
let den_at_point = substitute var point denominator |> simplify in
|
|
|
|
match (num_at_point, den_at_point) with
|
|
| (Const 0.0, Const 0.0) ->
|
|
let num_deriv = diff var numerator in
|
|
let den_deriv = diff var denominator in
|
|
let new_expr = Div (num_deriv, den_deriv) in
|
|
limit new_expr var point direction
|
|
| _ -> None
|
|
in
|
|
|
|
let try_series_expansion () =
|
|
None
|
|
in
|
|
|
|
match try_direct_sub () with
|
|
| Some result -> Some result
|
|
| None ->
|
|
match try_lhopital () with
|
|
| Some result -> Some result
|
|
| None -> try_series_expansion ()
|
|
|
|
let limit_at_infinity expr var =
|
|
let rec find_highest_power = function
|
|
| Pow (Var v, Const n) when v = var -> Some (int_of_float n)
|
|
| Div (num, den) ->
|
|
let num_pow = find_highest_power num |> Option.value ~default:0 in
|
|
let den_pow = find_highest_power den |> Option.value ~default:0 in
|
|
Some (num_pow - den_pow)
|
|
| Add (e1, e2) | Sub (e1, e2) ->
|
|
let p1 = find_highest_power e1 |> Option.value ~default:0 in
|
|
let p2 = find_highest_power e2 |> Option.value ~default:0 in
|
|
Some (max p1 p2)
|
|
| Mul (e1, e2) ->
|
|
let p1 = find_highest_power e1 |> Option.value ~default:0 in
|
|
let p2 = find_highest_power e2 |> Option.value ~default:0 in
|
|
Some (p1 + p2)
|
|
| _ -> None
|
|
in
|
|
|
|
match find_highest_power expr with
|
|
| Some p when p > 0 -> Some (SymConst E)
|
|
| Some p when p < 0 -> Some (Const 0.0)
|
|
| Some _ -> Some (Const 1.0)
|
|
| None -> None
|