diff --git a/CI/CI.ml b/CI/CI.ml index 29680b3..e222865 100644 --- a/CI/CI.ml +++ b/CI/CI.ml @@ -118,8 +118,11 @@ let make det_space = let m_H = lazy ( let v = Vec.make0 ndet in Array.init ndet (fun i -> let ki = det.(i) in - Array.iteri (fun j kj -> - v.{j+1} <- h_ij mo_basis ki kj) det; + Printf.eprintf "%8d / %8d\r%!" i ndet; + let j = ref 1 in + Ds.determinant_stream det_space + |> Stream.iter (fun kj -> + v.{!j} <- h_ij mo_basis ki kj ; incr j); Vector.sparse_of_vec v) |> Matrix.sparse_of_vector_array ) diff --git a/CI/Determinant_space.ml b/CI/Determinant_space.ml index f149c63..3eefe87 100644 --- a/CI/Determinant_space.ml +++ b/CI/Determinant_space.ml @@ -1,20 +1,81 @@ +type determinant_storage = +| Arbitrary of Determinant.t array +| Spin of (Spindeterminant.t array * Spindeterminant.t array) + type t = { n_alfa : int ; n_beta : int ; mo_class : MOClass.t ; mo_basis : MOBasis.t ; - determinants : Determinant.t array; + determinants : determinant_storage; } + module Ss = Spindeterminant_space let n_alfa t = t.n_alfa let n_beta t = t.n_beta let mo_class t = t.mo_class let mo_basis t = t.mo_basis -let determinants t = t.determinants -let size t = Array.length t.determinants + + +let size t = + match t.determinants with + | Arbitrary a -> Array.length a + | Spin (a,b) -> (Array.length a) * (Array.length b) + + +let determinant_stream t = + let imax = size t in + match t.determinants with + | Arbitrary a -> + Stream.from (fun i -> + if i < imax then Some a.(i) else None) + | Spin (a,b) -> + let na = Array.length a + and nb = Array.length b in + let i = ref 0 + and j = ref 0 in + Stream.from (fun k -> + if !j < nb then + let result = + Determinant.of_spindeterminants a.(!i) b.(!j) + in + incr i; + if !i = na then (i := 0 ; incr j); + Some result + else + None) + + +let determinants t = + match t.determinants with + | Arbitrary a -> a + | Spin (a,b) -> + let s = determinant_stream t in + Array.init (Array.length a * Array.length b) (fun _ -> + Stream.next s) + (* + Array.to_list b + |> List.map (fun det_b -> + Array.map (fun det_a -> + Determinant.of_spindeterminants det_a det_b + ) a + ) + |> Array.concat + *) + + +let determinant t i = + match t.determinants with + | Arbitrary a -> a.(i) + | Spin (a,b) -> + let nb = Array.length b in + let k = i / nb in + let j = i - k * nb in + Determinant.of_spindeterminants a.(j) b.(k) + let fci_of_mo_basis ?(frozen_core=true) mo_basis = let s = MOBasis.simulation mo_basis in @@ -30,20 +91,16 @@ let fci_of_mo_basis ?(frozen_core=true) mo_basis = let determinants = let a = Ss.spin_determinants det_a and b = Ss.spin_determinants det_b - in - let sb = Ss.size det_b in - Array.to_list a - |> List.map (fun a_i -> - Array.init sb (fun j -> - Determinant.of_spindeterminants a_i b.(j)) ) - |> Array.concat + in Spin (a,b) in { n_alfa ; n_beta ; mo_class ; mo_basis ; determinants } let pp_det_space ppf t = Format.fprintf ppf "@[[ "; - Array.iteri (fun i d -> Format.fprintf ppf "@[@[%8d@]@;@[%a@]@]@;" i - (Determinant.pp_det (MOBasis.size (mo_basis t))) d) t.determinants ; + let i = ref 0 in + determinant_stream t + |> Stream.iter (fun d -> Format.fprintf ppf "@[@[%8d@]@;@[%a@]@]@;" !i + (Determinant.pp_det (MOBasis.size (mo_basis t))) d; incr i) ; Format.fprintf ppf "]@]" diff --git a/CI/Determinant_space.mli b/CI/Determinant_space.mli index 31d03d9..c12b456 100644 --- a/CI/Determinant_space.mli +++ b/CI/Determinant_space.mli @@ -21,6 +21,9 @@ val mo_basis : t -> MOBasis.t val determinants : t -> Determinant.t array (** All the determinants belonging to the space. *) +val determinant_stream : t -> Determinant.t Stream.t +(** All the determinants belonging to the space, as a stream. *) + val size : t -> int (** Size of the determinant space *)