leibniz/lib/ode.ml
2026-01-19 03:37:26 +00:00

78 lines
2.1 KiB
OCaml

open Expr
open Simplify
open Integrate
type ode = {
equation: expr;
dependent: string;
independent: string;
}
let dsolve ode_eq dep_var indep_var =
let try_separation_of_variables () =
match ode_eq with
| Mul (f_y, g_x) ->
(match (integrate indep_var g_x, integrate dep_var f_y) with
| Some int_g, Some int_f ->
Some (simplify (Sub (int_f, int_g)))
| _ -> None)
| _ -> None
in
let try_linear_first_order () =
None
in
let try_exact_equation () =
None
in
let try_integrating_factor () =
None
in
match try_separation_of_variables () with
| Some sol -> Some sol
| None ->
match try_linear_first_order () with
| Some sol -> Some sol
| None ->
match try_exact_equation () with
| Some sol -> Some sol
| None -> try_integrating_factor ()
let solve_second_order coeff_y'' coeff_y' coeff_y rhs var =
let a = coeff_y'' in
let b = coeff_y' in
let c = coeff_y in
match (a, b, c) with
| (Const a_val, Const b_val, Const c_val) when rhs = Const 0.0 ->
let discriminant = b_val *. b_val -. 4.0 *. a_val *. c_val in
if discriminant > 0.0 then
let r1 = (-.b_val +. sqrt discriminant) /. (2.0 *. a_val) in
let r2 = (-.b_val -. sqrt discriminant) /. (2.0 *. a_val) in
Some (Add (
Mul (Var "C1", Exp (Mul (Const r1, Var var))),
Mul (Var "C2", Exp (Mul (Const r2, Var var)))
))
else if discriminant = 0.0 then
let r = -.b_val /. (2.0 *. a_val) in
Some (Mul (
Add (Var "C1", Mul (Var "C2", Var var)),
Exp (Mul (Const r, Var var))
))
else
let real_part = -.b_val /. (2.0 *. a_val) in
let imag_part = sqrt (-.discriminant) /. (2.0 *. a_val) in
Some (Mul (
Exp (Mul (Const real_part, Var var)),
Add (
Mul (Var "C1", Cos (Mul (Const imag_part, Var var))),
Mul (Var "C2", Sin (Mul (Const imag_part, Var var)))
)
))
| _ -> None
let solve_system _odes _indep_var =
[]