open Common type t = { alfa : Spindeterminant.t ; beta : Spindeterminant.t ; } type hole = int type particle = int let alfa t = t.alfa let beta t = t.beta let vac n = { alfa = Spindeterminant.vac n; beta = Spindeterminant.vac n; } let phase t = match Spindeterminant.(phase t.alfa, phase t.beta) with | Phase.Pos, Phase.Pos | Phase.Neg, Phase.Neg -> Phase.Pos | _ -> Phase.Neg let of_spindeterminants a b = { alfa = a ; beta = b } let is_none t = Spindeterminant.(is_none t.alfa || is_none t.beta) let negate_phase t = { t with alfa = Spindeterminant.negate_phase t.alfa } let set_phase p t = { alfa = Spindeterminant.set_phase p t.alfa ; beta = Spindeterminant.set_phase Phase.Pos t.beta } let excitation_level_alfa t t' = Spindeterminant.excitation_level t.alfa t'.alfa let excitation_level_beta t t' = Spindeterminant.excitation_level t.beta t'.beta let excitation_levels t t' = excitation_level_alfa t t', excitation_level_beta t t' let excitation_level t t' = (excitation_level_alfa t t') + (excitation_level_beta t t') let of_lists n a b = let alfa = Spindeterminant.of_list n a and beta = Spindeterminant.of_list n b in of_spindeterminants alfa beta let to_lists t = Spindeterminant.to_list t.alfa, Spindeterminant.to_list t.beta let creation spin p t = match spin with | Spin.Alfa -> { t with alfa = Spindeterminant.creation p t.alfa } | Spin.Beta -> { t with beta = Spindeterminant.creation p t.beta } let annihilation spin h t = match spin with | Spin.Alfa -> { t with alfa = Spindeterminant.annihilation h t.alfa } | Spin.Beta -> { t with beta = Spindeterminant.annihilation h t.beta } let single_excitation spin h p t = assert (h <> p); match spin with | Spin.Alfa -> { t with alfa = Spindeterminant.single_excitation h p t.alfa } | Spin.Beta -> { t with beta = Spindeterminant.single_excitation h p t.beta } let double_excitation spin h p spin' h' p' t = assert (h <> p); assert (h' <> p'); match spin, spin' with | Spin.(Alfa, Beta) -> { alfa = Spindeterminant.single_excitation h p t.alfa ; beta = Spindeterminant.single_excitation h' p' t.beta } | Spin.(Beta, Alfa) -> { beta = Spindeterminant.single_excitation h p t.beta ; alfa = Spindeterminant.single_excitation h' p' t.alfa } | Spin.(Alfa, Alfa) -> { t with alfa = Spindeterminant.double_excitation h p h' p' t.alfa } | Spin.(Beta, Beta) -> { t with beta = Spindeterminant.double_excitation h p h' p' t.beta } let compare = compare let pp ppf t = Format.fprintf ppf "@[@[phase:%a@]@;@[a:%a@]@;@[b:%a@]@]@." Phase.pp (phase t) Spindeterminant.pp t.alfa Spindeterminant.pp t.beta