feat (solver/rk45): state copy is handled by simulation
This commit is contained in:
parent
5bce9e5b01
commit
8497091d0c
5 changed files with 43 additions and 60 deletions
|
|
@ -1,4 +1,3 @@
|
|||
(library
|
||||
(name hsim)
|
||||
(libraries common solvers)
|
||||
(modules_without_implementation types))
|
||||
(libraries common solvers))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ open State
|
|||
module LazySim (S : SimState) =
|
||||
struct
|
||||
|
||||
(** "Lazy" simulation of a model with an appropriate solver. *)
|
||||
(** "Lazy" simulation of a model with any solver. *)
|
||||
let run
|
||||
(HNode model : ('p, 'a, 'b, 'y, 'yder, 'zin, 'zout) hnode)
|
||||
(DNode solver : ('y, 'yder, 'zin, 'zout) solver)
|
||||
|
|
@ -63,6 +63,7 @@ module LazySim (S : SimState) =
|
|||
let ms = model.reset pm (S.get_mstate s) in
|
||||
let ss = solver.reset ps (S.get_sstate s) in
|
||||
S.update ms ss (S.set_idle s) in
|
||||
|
||||
DNode { state; step; reset }
|
||||
|
||||
(** Run the model on the given input until the end of the input or until the
|
||||
|
|
@ -79,7 +80,7 @@ module LazySim (S : SimState) =
|
|||
loop (DNode { sim with state })
|
||||
|
||||
(** Run the model on multiple inputs. *)
|
||||
let run_on_multiple model solver inputs use =
|
||||
let run_on_n model solver inputs use =
|
||||
ignore @@ List.fold_left (fun (DNode sim) i ->
|
||||
Common.Debug.print
|
||||
(Format.sprintf "New input: %.10e\t%.10e\n" i.start i.length);
|
||||
|
|
@ -97,20 +98,19 @@ module LazySim (S : SimState) =
|
|||
let run_until model solver length =
|
||||
run_on model solver { start = 0.0; length; u = fun _ -> () }
|
||||
|
||||
let run_until_multiple model solver length steps =
|
||||
(** Run the model autonomously until [length], split in multiple [steps]. *)
|
||||
let run_until_n model solver length steps =
|
||||
let step = length /. (float_of_int steps) in
|
||||
let inputs = List.init steps (fun s ->
|
||||
let start = float_of_int s *. step in
|
||||
let stop = min (float_of_int (s+1) *. step) length in
|
||||
let length = stop -. start in
|
||||
{ start; length; u = fun _ -> () }) in
|
||||
run_on_multiple model solver inputs
|
||||
|
||||
{ start; length = stop -. start; u = fun _ -> () }) in
|
||||
run_on_n model solver inputs
|
||||
end
|
||||
|
||||
module GreedySim (S : SimState) =
|
||||
struct
|
||||
|
||||
(** "Greedy" simulation of a model with an appropriate solver. *)
|
||||
let run
|
||||
(HNode model : ('p, 'a, 'b, 'y, 'yder, 'zin, 'zout) hnode)
|
||||
(DNodeC solver : ('y, 'yder, 'zin, 'zout) solver_c)
|
||||
|
|
@ -146,8 +146,6 @@ module GreedySim (S : SimState) =
|
|||
{ start = i.start +. now; length = 0.0; u = fun _ -> o }::rest, s
|
||||
| Continuous ->
|
||||
let (h, f, z), ss = solver.step ss stop in
|
||||
(* Copy the state to allow [f] to remain independent from further
|
||||
modifications. *)
|
||||
let ss = solver.copy ss in
|
||||
let ms = model.cset ms (f h) in
|
||||
let fout t = model.fout ms (i.u (now +. t)) (f (now +. t)) in
|
||||
|
|
@ -184,8 +182,8 @@ module GreedySim (S : SimState) =
|
|||
let o, _ = sim.step sim.state input in
|
||||
List.iter use o
|
||||
|
||||
(** Run the model on the given input list. *)
|
||||
let run_on_multiple model solver inputs use =
|
||||
(** Run the model on multiple inputs. *)
|
||||
let run_on_n model solver inputs use =
|
||||
let o, _ = List.fold_left (fun (acc, DNode sim) i ->
|
||||
Common.Debug.print
|
||||
(Format.sprintf "new input: %.10e\t%.10e\n" i.start i.length);
|
||||
|
|
@ -199,13 +197,11 @@ module GreedySim (S : SimState) =
|
|||
run_on model solver { start = 0.0; length; u = fun _ -> () }
|
||||
|
||||
(** Run the model autonomously until [length], split in multiple [steps]. *)
|
||||
let run_until_multiple model solver length steps =
|
||||
let run_until_n model solver length steps =
|
||||
let step = length /. (float_of_int steps) in
|
||||
let inputs = List.init steps (fun s ->
|
||||
let start = float_of_int s *. step in
|
||||
let stop = min (float_of_int (s+1) *. step) length in
|
||||
let length = stop -. start in
|
||||
{ start; length; u = fun _ -> () }) in
|
||||
run_on_multiple model solver inputs
|
||||
|
||||
{ start; length = stop -. start; u = fun _ -> () }) in
|
||||
run_on_n model solver inputs
|
||||
end
|
||||
|
|
|
|||
|
|
@ -60,14 +60,11 @@ module InPlace =
|
|||
let step ({ state; vec=v } as s) h =
|
||||
let y_nv = vec v in
|
||||
let h = step state h y_nv in
|
||||
let state = copy state in
|
||||
let get_dky t = get_dky state y_nv t 0; unvec y_nv in
|
||||
(h, get_dky), s in
|
||||
|
||||
let copy { state; vec } =
|
||||
let vec' = Zls.cmake 0 in
|
||||
Zls.blit vec vec';
|
||||
{ state; vec = vec' } in
|
||||
{ state = copy state; vec = Zls.copy vec } in
|
||||
|
||||
DNodeC { state; reset; step; copy }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -64,3 +64,8 @@ type ('p, 'a, 'b) lazy_sim =
|
|||
subsystem steps as needed to reach the input's horizon. *)
|
||||
type ('p, 'a, 'b) greedy_sim =
|
||||
('p, 'a value, 'b value list) dnode
|
||||
|
||||
(** Utils *)
|
||||
|
||||
let d_of_dc (DNodeC { state; step; reset; _ }) =
|
||||
DNode { state; step; reset }
|
||||
Loading…
Add table
Add a link
Reference in a new issue