41 lines
1.3 KiB
OCaml
41 lines
1.3 KiB
OCaml
open Expr
|
|
open Diff
|
|
open Simplify
|
|
|
|
let gradient vars expr =
|
|
List.map (fun v -> diff v expr) vars
|
|
|
|
let jacobian vars exprs =
|
|
List.map (fun expr -> gradient vars expr) exprs
|
|
|
|
let hessian vars expr =
|
|
let grad = gradient vars expr in
|
|
List.map (fun deriv -> List.map (fun v -> diff v deriv) vars) grad
|
|
|
|
let divergence vars vector_field =
|
|
if List.length vars <> List.length vector_field then
|
|
failwith "divergence: dimension mismatch"
|
|
else
|
|
let terms = List.map2 (fun v e -> diff v e) vars vector_field in
|
|
let sum = List.fold_left (fun acc t -> Add (acc, t)) (Const 0.0) terms in
|
|
simplify sum
|
|
|
|
let curl vector_field =
|
|
match vector_field with
|
|
| [fx; fy; fz] ->
|
|
let dfz_dy = diff "y" fz in
|
|
let dfy_dz = diff "z" fy in
|
|
let dfx_dz = diff "z" fx in
|
|
let dfz_dx = diff "x" fz in
|
|
let dfy_dx = diff "x" fy in
|
|
let dfx_dy = diff "y" fx in
|
|
[simplify (Sub (dfz_dy, dfy_dz));
|
|
simplify (Sub (dfx_dz, dfz_dx));
|
|
simplify (Sub (dfy_dx, dfx_dy))]
|
|
| _ -> failwith "curl: requires exactly 3 components"
|
|
|
|
let laplacian vars expr =
|
|
let hess = hessian vars expr in
|
|
let diagonal = List.mapi (fun i row -> List.nth row i) hess in
|
|
let sum = List.fold_left (fun acc t -> Add (acc, t)) (Const 0.0) diagonal in
|
|
simplify sum
|