diff --git a/ocaml/Input_determinants_by_hand.ml b/ocaml/Input_determinants_by_hand.ml index eecd87f0..6d48c917 100644 --- a/ocaml/Input_determinants_by_hand.ml +++ b/ocaml/Input_determinants_by_hand.ml @@ -16,6 +16,7 @@ module Determinants_by_hand : sig val to_string : t -> string val to_rst : t -> Rst_string.t val of_rst : Rst_string.t -> t option + val read_n_int : unit -> N_int_number.t end = struct type t = { n_int : N_int_number.t; @@ -157,58 +158,44 @@ end = struct let read_psi_det () = - let n_int = - read_n_int () - and alpha = - Ezfio.get_electrons_elec_alpha_num () + let n_int = read_n_int () + and n_alpha = Ezfio.get_electrons_elec_alpha_num () |> Elec_alpha_number.of_int - and beta = - Ezfio.get_electrons_elec_beta_num () + and n_beta = Ezfio.get_electrons_elec_beta_num () |> Elec_beta_number.of_int - in - if not (Ezfio.has_determinants_psi_det ()) then - begin - let mo_tot_num = - MO_number.get_max () - in - let rec build_data accu = function - | 0 -> accu - | n -> build_data ((MO_number.of_int ~max:mo_tot_num n)::accu) (n-1) - in - let det_a = - build_data [] (Elec_alpha_number.to_int alpha) - |> Bitlist.of_mo_number_list n_int - and det_b = - build_data [] (Elec_beta_number.to_int beta) - |> Bitlist.of_mo_number_list n_int - in - let data = - ( (Bitlist.to_int64_list det_a) @ - (Bitlist.to_int64_list det_b) ) - in - Ezfio.ezfio_array_of_list ~rank:3 ~dim:[| N_int_number.to_int n_int ; 2 ; 1 |] ~data:data - |> Ezfio.set_determinants_psi_det ; - end ; - let n_int_i = - N_int_number.to_int n_int in - let psi_det_array = - Ezfio.get_determinants_psi_det () - in - let dim = - psi_det_array.Ezfio.dim - and data = - Ezfio.flattened_ezfio psi_det_array - in - assert (n_int_i = dim.(0)); - assert (dim.(1) = 2); - assert (dim.(2) = (Det_number.to_int (read_n_det ()))); - let len = - 2 * n_int_i - in - Array.init dim.(2) ~f:(fun i -> - Array.sub ~pos:(len * i) ~len data - |> Determinant.of_int64_array ~n_int ~alpha ~beta - ) + in + if not (Ezfio.has_determinants_psi_det ()) then + begin + let mo_tot_num = MO_number.get_max () in + let rec build_data accu = function + | 0 -> accu + | n -> build_data ((MO_number.of_int ~max:mo_tot_num n)::accu) (n-1) + in + let det_a = build_data [] (Elec_alpha_number.to_int n_alpha) + |> Bitlist.of_mo_number_list n_int + and det_b = build_data [] (Elec_beta_number.to_int n_beta) + |> Bitlist.of_mo_number_list n_int + in + let data = ( (Bitlist.to_int64_list det_a) @ + (Bitlist.to_int64_list det_b) ) + in + Ezfio.ezfio_array_of_list ~rank:3 ~dim:[| N_int_number.to_int n_int ; 2 ; 1 |] ~data:data + |> Ezfio.set_determinants_psi_det ; + end ; + let n_int = N_int_number.to_int n_int in + let psi_det_array = Ezfio.get_determinants_psi_det () in + let dim = psi_det_array.Ezfio.dim + and data = Ezfio.flattened_ezfio psi_det_array + in + assert (n_int = dim.(0)); + assert (dim.(1) = 2); + assert (dim.(2) = (Det_number.to_int (read_n_det ()))); + List.init dim.(2) ~f:(fun i -> + Array.sub ~pos:(2*n_int*i) ~len:(2*n_int) data) + |> List.map ~f:(Determinant.of_int64_array + ~n_int:(N_int_number.of_int n_int) + ~alpha:n_alpha ~beta:n_beta ) + |> Array.of_list ;; let write_psi_det ~n_int ~n_det d = @@ -286,9 +273,13 @@ end = struct |> String.concat_array ~sep:"\t" in Array.init ndet ~f:(fun i -> - String.concat [ " " ; - (coefs_string i) ; "\n" ; - (Determinant.to_string ~mo_tot_num b.psi_det.(i)) ; "\n" ] + Printf.sprintf " %s\n%s\n" + (coefs_string i) + (Determinant.to_string ~mo_tot_num:mo_tot_num b.psi_det.(i) + |> String.split ~on:'\n' + |> List.map ~f:(fun x -> " "^x) + |> String.concat ~sep:"\n" + ) ) |> String.concat_array ~sep:"\n" in @@ -334,18 +325,18 @@ psi_det = %s ;; let of_rst r = - let dets = Rst_string.to_string r + let r = Rst_string.to_string r in (* Split into header and determinants data *) - let idx = String.substr_index_exn dets ~pos:0 ~pattern:"\nDeterminants" + let idx = String.substr_index_exn r ~pos:0 ~pattern:"\nDeterminants" in - let header = - String.prefix dets idx + let (header, dets) = + (String.prefix r idx, String.suffix r ((String.length r)-idx) ) in (* Handle header *) - let header = header + let header = r |> String.split ~on:'\n' |> List.filter ~f:(fun line -> if (line = "") then @@ -361,117 +352,91 @@ psi_det = %s |> String.concat in - (* Handle determinants and coefs *) - let dets_stream = - - let ipos, jmax = - ref idx, String.length dets - in - let next_line = - Stream.from (fun _ -> - let rec loop line = - let j = - !ipos + 1 - in - ipos := j; - if (j < jmax) then - match dets.[j] with - | '\n' -> Some (String.of_char_list @@ List.rev line ) - | ' ' -> loop line - | c -> loop (c :: line) - else - None - in loop [] - ) - in - ignore @@ Stream.next next_line; (* Determinants :: *) - ignore @@ Stream.next next_line; (* *) - Stream.from (fun _ -> - try - begin - let result = - let coefs = - let line = - Stream.next next_line - in - String.split ~on:'\t' line - |> Array.of_list - |> Array.map ~f:(fun x -> Det_coef.of_float @@ Float.of_string x) - in - Some (coefs, - Stream.next next_line |> String.rev, - Stream.next next_line |> String.rev ) - in - ignore @@ Stream.next next_line; - result - end - with - | Stream.Failure -> None - ) + (* Handle determinant coefs *) + let dets = match ( dets + |> String.split ~on:'\n' + |> List.map ~f:(String.strip) + ) with + | _::lines -> lines + | _ -> failwith "Error in determinants" in - - - - let psi_coef, psi_det = - let alpha = - Ezfio.get_electrons_elec_alpha_num () - |> Elec_alpha_number.of_int - and beta = - Ezfio.get_electrons_elec_beta_num () - |> Elec_beta_number.of_int - and n_int = - N_int_number.get_max () - |> N_int_number.of_int - in - - let rec read coefs dets_bit = function - | None -> (List.rev coefs), (List.rev dets_bit) - | Some (c, alpha_str, beta_str) -> - begin - ignore @@ Stream.next dets_stream; - let new_coefs = - c :: coefs - and new_dets = - let newdet = - (Bitlist.of_string_mp alpha_str, Bitlist.of_string_mp beta_str) - |> Determinant.of_bitlist_couple ~n_int ~alpha ~beta - in - newdet :: dets_bit - in - read new_coefs new_dets (Stream.peek dets_stream) - end - in - - let coefs, dets_bit = - read [] [] (Stream.peek dets_stream) - in - let nstates = - List.hd_exn coefs |> Array.length + let psi_coef = + let rec read_coefs accu = function + | [] -> List.rev accu + | ""::""::tail -> read_coefs accu tail + | ""::c::tail -> + let c = + String.split ~on:'\t' c + |> List.map ~f:(fun x -> Det_coef.of_float (Float.of_string x)) + |> Array.of_list + in + read_coefs (c::accu) tail + | _::tail -> read_coefs accu tail in let a = - let extract_state i = - let i = - i-1 + let buffer = + read_coefs [] dets + in + let nstates = + List.hd_exn buffer + |> Array.length + in + let extract_state i = + let i = + i-1 + in + List.map ~f:(fun x -> Det_coef.to_string x.(i)) buffer + |> String.concat ~sep:" " + in + let rec build_result = function + | 1 -> extract_state 1 + | i -> (build_result (i-1))^" "^(extract_state i) + in + build_result nstates + in + "(psi_coef ("^a^"))" + in + + (* Handle determinants *) + let psi_det = + let n_alpha = Ezfio.get_electrons_elec_alpha_num () + |> Elec_alpha_number.of_int + and n_beta = Ezfio.get_electrons_elec_beta_num () + |> Elec_beta_number.of_int + in + let rec read_dets accu = function + | [] -> List.rev accu + | ""::_::alpha::beta::tail -> + begin + let newdet = + (Bitlist.of_string ~zero:'-' ~one:'+' alpha , + Bitlist.of_string ~zero:'-' ~one:'+' beta) + |> Determinant.of_bitlist_couple ~alpha:n_alpha ~beta:n_beta + |> Determinant.sexp_of_t + |> Sexplib.Sexp.to_string in - List.map ~f:(fun x -> x.(i)) coefs - in - let rec build_result accu = function - | 0 -> accu - | i -> - let new_accu = - (extract_state i) :: accu - in - build_result new_accu (i-1) - in - build_result [] nstates + read_dets (newdet::accu) tail + end + | _::tail -> read_dets accu tail in - let new_coefs = - List.concat a |> Array.of_list - and new_dets = - Array.of_list dets_bit + let dets = + List.map ~f:String.rev dets in - new_coefs, new_dets + let sze = + List.fold ~init:0 ~f:(fun accu x -> accu + (String.length x)) dets + in + let control = + Gc.get () + in + Gc.tune ~minor_heap_size:(sze) ~space_overhead:(sze/10) + ~max_overhead:100000 ~major_heap_increment:(sze/10) (); + let a = + read_dets [] dets + |> String.concat + in + Gc.set control; + "(psi_det ("^a^"))" in @@ -481,16 +446,11 @@ psi_det = %s and n_int = Printf.sprintf "(n_int %d)" (N_int_number.get_max ()) in - let s = - [ header ; bitkind ; n_int ; "(psi_coef ())" ; "(psi_det ())"] - |> String.concat + let s = + String.concat [ header ; bitkind ; n_int ; psi_coef ; psi_det] in - let result = - Generic_input_of_rst.evaluate_sexp t_of_sexp s - in - match result with - | Some x -> Some { x with psi_coef ; psi_det } - | None -> None + + Generic_input_of_rst.evaluate_sexp t_of_sexp s ;; end