open Lacaml.D module Ds = Determinant_space type t = { det_space : Ds.t ; h_matrix : Mat.t lazy_t ; s2_matrix : Mat.t lazy_t ; eigensystem : (Mat.t * Vec.t) lazy_t; } let det_space t = t.det_space let h_matrix t = Lazy.force t.h_matrix let s2_matrix t = Lazy.force t.s2_matrix let eigensystem t = Lazy.force t.eigensystem let eigenvectors t = let (x,_) = eigensystem t in x let eigenvalues t = let (_,x) = eigensystem t in x let h_integrals mo_basis = let one_e_ints = MOBasis.one_e_ints mo_basis and two_e_ints = MOBasis.two_e_ints mo_basis in ( (fun i j _ -> one_e_ints.{i,j}), (fun i j k l s s' -> if s' = Spin.other s then ERI.get_phys two_e_ints i j k l else (ERI.get_phys two_e_ints i j k l) -. (ERI.get_phys two_e_ints i j l k) ) ) let h_ij mo_basis ki kj = let integrals = List.map (fun f -> f mo_basis) [ h_integrals ] in CIMatrixElement.make integrals ki kj |> List.hd let make det_space = let ndet = Ds.size det_space in let det = Ds.determinants det_space in let mo_basis = Ds.mo_basis det_space in let h_matrix = lazy ( Array.init ndet (fun i -> let ki = det.(i) in Array.init ndet (fun j -> let kj = det.(j) in h_ij mo_basis ki kj )) |> Mat.of_array ) in let s2_matrix = lazy ( Array.init ndet (fun i -> let ki = det.(i) in Array.init ndet (fun j -> let kj = det.(j) in CIMatrixElement.make_s2 ki kj )) |> Mat.of_array ) in let eigensystem = lazy ( Lazy.force h_matrix |> Util.diagonalize_symm ) in { det_space ; h_matrix ; s2_matrix ; eigensystem }