mirror of
https://gitlab.com/scemama/QCaml.git
synced 2024-12-22 04:13:33 +01:00
Improved Spindeterminant
This commit is contained in:
parent
13005634fb
commit
7dbbf1a352
@ -14,7 +14,7 @@ let add_nperm phase = function
|
|||||||
| (Pos,Pos) | (Neg,Neg) -> Pos
|
| (Pos,Pos) | (Neg,Neg) -> Pos
|
||||||
| _ -> Neg
|
| _ -> Neg
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
let pp_phase ppf = function
|
let pp_phase ppf = function
|
||||||
| Pos -> Format.fprintf ppf "@[<h>+1@]"
|
| Pos -> Format.fprintf ppf "@[<h>+1@]"
|
||||||
|
@ -1,15 +1,29 @@
|
|||||||
type t =
|
type s =
|
||||||
{
|
{
|
||||||
bitstring : Z.t ;
|
bitstring : Z.t ;
|
||||||
phase : Phase.t ;
|
phase : Phase.t ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type t = s option
|
||||||
|
|
||||||
|
let phase = function
|
||||||
|
| Some s -> s.phase
|
||||||
|
| None -> invalid_arg "Spindeterminant is None"
|
||||||
|
|
||||||
|
|
||||||
|
let is_none = function
|
||||||
|
| None -> true
|
||||||
|
| _ -> false
|
||||||
|
|
||||||
|
|
||||||
|
let bitstring = function
|
||||||
|
| Some s -> s.bitstring
|
||||||
|
| None -> invalid_arg "Spindeterminant is None"
|
||||||
|
|
||||||
|
|
||||||
let vac =
|
let vac =
|
||||||
Some { bitstring = Z.zero;
|
Some { bitstring = Z.zero;
|
||||||
phase = Phase.Pos;
|
phase = Phase.Pos; }
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let creation p = function
|
let creation p = function
|
||||||
| None -> None
|
| None -> None
|
||||||
@ -44,101 +58,96 @@ let annihilation q = function
|
|||||||
Some { bitstring ; phase }
|
Some { bitstring ; phase }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let of_list l =
|
let of_list l =
|
||||||
let result =
|
List.rev l
|
||||||
List.rev l
|
|> List.fold_left (fun accu p -> creation p accu) vac
|
||||||
|> List.fold_left (fun accu p -> creation p accu) vac
|
|
||||||
in
|
|
||||||
match result with
|
|
||||||
| None -> raise (Invalid_argument "Can't create determinant from list")
|
|
||||||
| Some x -> x
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let rec to_list spindet =
|
let rec to_list = function
|
||||||
let rec aux accu z =
|
| None -> []
|
||||||
if z <> Z.zero then
|
| Some spindet ->
|
||||||
let element = (Z.(trailing_zeros z)+1) in
|
let rec aux accu z =
|
||||||
aux (element::accu) Z.(z land (pred z))
|
if z <> Z.zero then
|
||||||
else List.rev accu
|
let element = (Z.(trailing_zeros z)+1) in
|
||||||
in aux [] spindet
|
aux (element::accu) Z.(z land (pred z))
|
||||||
|
else List.rev accu
|
||||||
|
in aux [] spindet.bitstring
|
||||||
|
|
||||||
|
|
||||||
let pp_bitstring ppf bs =
|
let pp_bitstring ppf bs =
|
||||||
String.init (Z.numbits bs) (fun i -> if (Z.testbit bs i) then '+' else '-')
|
String.init (Z.numbits bs) (fun i -> if (Z.testbit bs i) then '+' else '-')
|
||||||
|> Format.fprintf ppf "@[<h>%s@]"
|
|> Format.fprintf ppf "@[<h>%s@]"
|
||||||
|
|
||||||
let pp_spindet ppf s =
|
let pp_spindet ppf = function
|
||||||
Format.fprintf ppf "@[<h>%a %a@]" Phase.pp_phase s.phase pp_bitstring s.bitstring
|
| None -> Format.fprintf ppf "@[<h>None@]"
|
||||||
|
| Some s ->
|
||||||
|
Format.fprintf ppf "@[<h>%a %a@]" Phase.pp_phase s.phase pp_bitstring s.bitstring
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(*-----------------------------------------------------------------------------------*)
|
||||||
|
|
||||||
|
|
||||||
let test_case () =
|
let test_case () =
|
||||||
|
|
||||||
let test_creation () =
|
let test_creation () =
|
||||||
let l_a = [ 1 ; 2 ; 3 ; 5 ] in
|
let l_a = [ 1 ; 2 ; 3 ; 5 ] in
|
||||||
let det = of_list l_a in
|
let det = of_list l_a in
|
||||||
Alcotest.(check (list int )) "bitstring 1" (to_list det.bitstring) l_a;
|
Alcotest.(check (list int )) "bitstring 1" l_a (to_list det);
|
||||||
Alcotest.(check bool) "phase 2" true (det.phase = Phase.Pos);
|
Alcotest.(check bool) "phase 2" true (phase det = Phase.Pos);
|
||||||
let l_b = [ 1 ; 3 ; 2 ; 5 ] in
|
let l_b = [ 1 ; 3 ; 2 ; 5 ] in
|
||||||
let det = of_list l_b in
|
let det = of_list l_b in
|
||||||
Alcotest.(check (list int )) "bitstring 2" (to_list det.bitstring) l_a;
|
Alcotest.(check (list int )) "bitstring 2" l_a (to_list det);
|
||||||
Alcotest.(check bool) "phase 2" true (det.phase = Phase.Neg);
|
Alcotest.(check bool) "phase 2" true (phase det = Phase.Neg);
|
||||||
in
|
in
|
||||||
|
|
||||||
let test_operators () =
|
let test_operators () =
|
||||||
let det =
|
let det =
|
||||||
creation 5 @@ creation 2 @@ creation 2 @@ creation 1 @@ vac
|
creation 5 @@ creation 2 @@ creation 2 @@ creation 1 @@ vac
|
||||||
in
|
in
|
||||||
Alcotest.(check bool) "none 1" true (det = None);
|
Alcotest.(check bool) "none 1" true (is_none det);
|
||||||
|
|
||||||
let det =
|
let det =
|
||||||
match (creation 5 @@ creation 3 @@ creation 2 @@ creation 1 @@ vac) with
|
creation 5 @@ creation 3 @@ creation 2 @@ creation 1 @@ vac
|
||||||
| Some x -> x
|
in
|
||||||
| None -> assert false
|
let l_a = [ 1 ; 2 ; 3 ; 5 ] in
|
||||||
in
|
Alcotest.(check (list int )) "bitstring 1" l_a (to_list det);
|
||||||
let l_a = [ 1 ; 2 ; 3 ; 5 ] in
|
Alcotest.(check bool) "phase 1" true (phase det = Phase.Pos);
|
||||||
Alcotest.(check (list int )) "bitstring 1" l_a (to_list det.bitstring);
|
|
||||||
Alcotest.(check bool) "phase 1" true (det.phase = Phase.Pos);
|
|
||||||
|
|
||||||
let det =
|
let det =
|
||||||
match (creation 1 @@ creation 3 @@ creation 2 @@ creation 5 @@ vac) with
|
creation 1 @@ creation 3 @@ creation 2 @@ creation 5 @@ vac
|
||||||
| Some x -> x
|
in
|
||||||
| None -> assert false
|
Alcotest.(check (list int )) "bitstring 2" l_a (to_list det);
|
||||||
in
|
Alcotest.(check bool) "phase 2" true (phase det = Phase.Neg);
|
||||||
Alcotest.(check (list int )) "bitstring 2" l_a (to_list det.bitstring);
|
|
||||||
Alcotest.(check bool) "phase 2" true (det.phase = Phase.Neg);
|
|
||||||
|
|
||||||
let l_b = [ 1 ; 3 ; 2 ; 5 ] in
|
let l_b = [ 1 ; 3 ; 2 ; 5 ] in
|
||||||
let det = of_list l_b in
|
let det = of_list l_b in
|
||||||
Alcotest.(check (list int )) "bitstring 3" l_a (to_list det.bitstring);
|
Alcotest.(check (list int )) "bitstring 3" l_a (to_list det);
|
||||||
Alcotest.(check bool) "phase 3" true (det.phase = Phase.Neg);
|
Alcotest.(check bool) "phase 3" true (phase det = Phase.Neg);
|
||||||
|
|
||||||
Alcotest.(check bool) "none 1" true (annihilation 4 (Some det) = None);
|
Alcotest.(check bool) "none 1" true (annihilation 4 det |> is_none);
|
||||||
|
|
||||||
let det =
|
let det =
|
||||||
match annihilation 1 (Some det) with
|
annihilation 1 det
|
||||||
| Some x -> x
|
in
|
||||||
| None -> assert false
|
Alcotest.(check (list int )) "bitstring 4" (List.tl l_a) (to_list det);
|
||||||
in
|
Alcotest.(check bool) "phase 4" true (phase det = Phase.Neg);
|
||||||
Alcotest.(check (list int )) "bitstring 4" (List.tl l_a) (to_list det.bitstring);
|
|
||||||
Alcotest.(check bool) "phase 4" true (det.phase = Phase.Neg);
|
|
||||||
|
|
||||||
let det =
|
let det =
|
||||||
match annihilation 3 (Some det) with
|
annihilation 3 det
|
||||||
| Some x -> x
|
in
|
||||||
| None -> assert false
|
Alcotest.(check (list int )) "bitstring 5" [ 2 ; 5 ] (to_list det);
|
||||||
in
|
Alcotest.(check bool) "phase 5" true (phase det = Phase.Pos);
|
||||||
Alcotest.(check (list int )) "bitstring 5" [ 2 ; 5 ] (to_list det.bitstring);
|
|
||||||
Alcotest.(check bool) "phase 5" true (det.phase = Phase.Pos);
|
|
||||||
|
|
||||||
let det =
|
let det =
|
||||||
match annihilation 5 @@ annihilation 2 (Some det) with
|
annihilation 5 @@ annihilation 2 det
|
||||||
| Some x -> x
|
in
|
||||||
| None -> assert false
|
Alcotest.(check (list int )) "bitstring 6" [] (to_list det);
|
||||||
in
|
Alcotest.(check bool) "phase 6" true (phase det = Phase.Pos);
|
||||||
Alcotest.(check (list int )) "bitstring 6" [] (to_list det.bitstring);
|
|
||||||
Alcotest.(check bool) "phase 6" true (det.phase = Phase.Pos);
|
|
||||||
|
|
||||||
in
|
in
|
||||||
[
|
[
|
||||||
@ -146,4 +155,4 @@ let test_case () =
|
|||||||
"Operators", `Quick, test_operators;
|
"Operators", `Quick, test_operators;
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
50
CI/Spindeterminant.mli
Normal file
50
CI/Spindeterminant.mli
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
(**
|
||||||
|
A spin-determinant is one of the two determinants in the Waller-Hartree
|
||||||
|
double determinant representation of a Slater determinant. It is represented
|
||||||
|
as a bit string and a phase factor.
|
||||||
|
*)
|
||||||
|
|
||||||
|
type t
|
||||||
|
|
||||||
|
(** {1 Accessors}. *)
|
||||||
|
|
||||||
|
val phase : t -> Phase.t
|
||||||
|
(** Phase factor.
|
||||||
|
@raise [Invalid_argument] if the spin-determinant is [None].
|
||||||
|
*)
|
||||||
|
|
||||||
|
val bitstring : t -> Z.t
|
||||||
|
(** Bit string.
|
||||||
|
@raise [Invalid_argument] if the spin-determinant is [None].
|
||||||
|
*)
|
||||||
|
|
||||||
|
val is_none : t -> bool
|
||||||
|
(** Tests if a spin-determinant is [None]. *)
|
||||||
|
|
||||||
|
|
||||||
|
(** {1 Second quantization operators} *)
|
||||||
|
val vac : t
|
||||||
|
(** Vacuum state, [vac = Some ]{% $|\rangle$ %} *)
|
||||||
|
|
||||||
|
val creation : int -> t -> t
|
||||||
|
(** [creation p] is the creation operator {% $a^\dagger_p$ %}. *)
|
||||||
|
|
||||||
|
val annihilation : int -> t -> t
|
||||||
|
(** [annihilation q] is the annihilation operator {% $a_q$ %}. *)
|
||||||
|
|
||||||
|
val of_list : int list -> t
|
||||||
|
(** Builds a spin-determinant from a list of orbital indices. If the creation of the
|
||||||
|
spin-determinant is not possible because of Pauli's exclusion principle, a [None]
|
||||||
|
spin-determinant is returned. *)
|
||||||
|
|
||||||
|
val to_list : t -> int list
|
||||||
|
(** Transforms a spin-determinant into a list of orbital indices. *)
|
||||||
|
|
||||||
|
(** {2 Printers}. *)
|
||||||
|
|
||||||
|
val pp_spindet : Format.formatter -> t -> unit
|
||||||
|
|
||||||
|
|
||||||
|
(** {2 Unit testing} *)
|
||||||
|
|
||||||
|
val test_case : unit -> (string * [> `Quick ] * (unit -> unit)) list
|
Loading…
Reference in New Issue
Block a user