symbolic mathematics engine in OCaml with differentiation, integration, simplification, and numerical methods
1open Expr
2open Diff
3open Eval
4
5type condition = expr
6type piece = condition * expr
7type piecewise = piece list * expr
8
9let create pieces default =
10 (pieces, default)
11
12let eval_piecewise env (pieces, default) =
13 let rec find_first = function
14 | [] -> eval env default
15 | (cond, value) :: rest ->
16 let cond_val = eval env cond in
17 if cond_val <> 0.0 then eval env value
18 else find_first rest
19 in
20 find_first pieces
21
22let diff_piecewise var (pieces, default) =
23 let diff_pieces = List.map (fun (cond, expr) ->
24 (cond, diff var expr)
25 ) pieces in
26 (diff_pieces, diff var default)
27
28let to_expr (_pieces, default) =
29 default
30
31let heaviside x =
32 create [(Add (x, Const 0.0), Const 1.0)] (Const 0.0)
33
34let signum x =
35 create [
36 (Add (x, Const 0.0), Const 1.0);
37 (Sub (Const 0.0, x), Const (-1.0))
38 ] (Const 0.0)
39
40let abs_as_piecewise x =
41 create [
42 (Add (x, Const 0.0), x)
43 ] (Neg x)
44
45let max_expr e1 e2 =
46 create [(Sub (e1, e2), e1)] e2
47
48let min_expr e1 e2 =
49 create [(Sub (e2, e1), e1)] e2
50
51let continuous_extension expr _var _point =
52 expr
53
54let piecewise_to_string (pieces, default) =
55 let piece_strs = List.map (fun (cond, value) ->
56 Printf.sprintf " %s if %s" (to_string value) (to_string cond)
57 ) pieces in
58 String.concat "\n" piece_strs ^ "\n " ^ to_string default ^ " otherwise"