(* Example due to JB. Jeannin - zero-crossing detection *) (* the signal x(t) is expected to have a zero-crossing at [t = 0.3] *) (* to draw: ./main.exe -s sin_1_x -stop 2 -sample 10000 | feedgnuplot --stream --domain --lines *) open Hsim.Types open Solvers.Zls (* let hybrid sin_1_x() = let der t = 1.0 init 0.0 in let t = t -. 0.3 in let v = sin(1/t) in let o = t *. (v *. v) in [that is: t *. (sin(1/t)^2] present up(o) -> 1.0 else 0.0, o *) let of_array a = Bigarray.Array1.of_array Bigarray.Float64 Bigarray.c_layout a type ('a, 'b) state = { s_x: 'a; zin: 'b } let csize = 1 let zsize = 1 let fder _ _ yd = yd.{0} <- 1.0 let fzer _ y zout = let t = y.{0} in let t = t -. 0.3 in let v = sin(1.0 /. t) in let o = t *. (v *. v) in zout.{0} <- o let fout s y = let z = if s.zin.{0} = 1l then 1.0 else 0.0 in let t = y.{0} in let t = t -. 0.3 in let v = sin(1.0 /. t) in let o = t *. (v *. v) in of_array [| z; o |] let step ({ s_x; zin } as s) zfalse = let z = if zin.{0} = 1l then 1.0 else 0.0 in let t = s_x.{0} in let t = t -. 0.3 in let v = sin(1.0 /. t) in let o = t *. (v *. v) in of_array [| z; o |], { s with zin = zfalse } let reset _ s = s let cget { s_x; _ } = s_x let cset s l_x = { s with s_x = l_x } let zset s zin = { s with zin } let jump _ = true let horizon _ = max_float let sin_1_x () = let zfalse = zmake 1 in let yd = cmake 1 in let zout = cmake 1 in let fder _ _ y = fder 0.0 y yd; yd in let fzer _ _ y = fzer 0.0 y zout; zout in let fout s _ y = fout s y in let step s _ = step s zfalse in let state = { s_x = of_array [| 0.0 |]; zin = zfalse } in { state; fder; fzer; fout; step; reset; horizon; cset; cget; zset; csize; zsize; jump } let errmsg = "Too many arguments for the model (needed: 0)" let init = function | [] -> HNode (sin_1_x ()) | _ -> raise (Invalid_argument errmsg)