File: siman.ml

package info (click to toggle)
ocamlgsl 1.24.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 1,244 kB
  • sloc: ml: 8,748; ansic: 7,395; makefile: 37
file content (64 lines) | stat: -rw-r--r-- 1,567 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
(* gsl-ocaml - OCaml interface to GSL                       *)
(* Copyright (©) 2002-2012 - Olivier Andrieu                *)
(* Distributed under the terms of the GPL version 3         *)

let () = Error.init ()

type params = {
    iters_fixed_T : int ;
    step_size     : float ;
    k             : float ;
    t_initial     : float ;
    mu_t          : float ;
    t_min         : float ;
  }

open Misc

let solve rng conf0 
    ~energ_func ~step_func
    ?print_func params =
  
  let best_energ = ref (energ_func conf0) in
  let best_x = ref conf0 in
  let energ = ref !best_energ in
  let x = ref !best_x in

  let t = ref params.t_initial in
  let n_iter = ref 0 in
  let n_eval = ref 1 in

  if is print_func
  then print_string "#-iter  #-evals   temperature     position   energy\n" ;

  while !t >= params.t_min do
    for _i=1 to params.iters_fixed_T do
      let new_x = step_func rng !x params.step_size in
      let new_energ = energ_func new_x in
      incr n_eval ;
      if new_energ <= !best_energ
      then begin
	best_energ := new_energ ;
	best_x := new_x
      end ;
      
      if new_energ < !energ ||
        ( let lim = exp (~-. (new_energ -. !energ) /. (!t *. params.k)) in
          Rng.uniform rng < lim )
      then begin
	energ := new_energ ;
	x := new_x ;
      end 
    done ;

    if is print_func
    then begin
      Printf.printf "%5d   %7d  %12g" !n_iter !n_eval !t ;
      may_apply print_func !x ;
      Printf.printf "  %12g\n" !energ
    end ;
      
    t := !t /. params.mu_t ;
    incr n_iter ;
  done ;
  !best_x