feat (solver/rk45): state copy is handled by simulation

This commit is contained in:
Henri Saudubray 2025-04-29 10:05:08 +02:00
parent 5bce9e5b01
commit 8497091d0c
Signed by: hms
GPG key ID: 7065F57ED8856128
5 changed files with 43 additions and 60 deletions

View file

@ -1,4 +1,3 @@
(library
(name hsim)
(libraries common solvers)
(modules_without_implementation types))
(libraries common solvers))

View file

@ -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

View file

@ -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

View file

@ -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 }