10
1
mirror of https://gitlab.com/scemama/QCaml.git synced 2024-06-26 15:12:05 +02:00
QCaml/CI/Spindeterminant.ml

65 lines
1.5 KiB
OCaml

type t =
{
bitstring : Z.t ;
phase : Phase.t ;
}
let of_list l =
let rec aux accu nperm = function
| [] -> { bitstring = accu;
phase = Phase.of_nperm nperm; }
| i :: rest ->
let i = pred i in
let x = Z.(shift_left one i) in
let accu = Z.logor accu x in
let nperm =
let mask = Z.(x-one) in
let r = Z.logand accu mask in
if r = Z.zero then
nperm
else
nperm + (Z.popcount r)
in
aux accu nperm rest
in
List.rev l
|> aux Z.zero 0
(* TODO Phase *)
let rec to_list spindet =
let rec aux accu z =
if z <> Z.zero then
let element = (Z.(trailing_zeros z)+1) in
aux (element::accu) Z.(z land (pred z))
else List.rev accu
in aux [] spindet
let pp_bitstring ppf bs =
String.init (Z.numbits bs) (fun i -> if (Z.testbit bs i) then '+' else '-')
|> Format.fprintf ppf "@[<h>%s@]"
let pp_spindet ppf s =
Format.fprintf ppf "@[<h>%a %a@]" Phase.pp_phase s.phase pp_bitstring s.bitstring
let test_case () =
let test_creation () =
let l_a = [ 1 ; 2 ; 3 ; 5 ] in
let det = of_list l_a in
Alcotest.(check (list int )) "bitstring" (to_list det.bitstring) l_a;
Alcotest.(check bool) "phase" (det.phase = Phase.Pos) true;
let l_b = [ 1 ; 3 ; 2 ; 5 ] in
let det = of_list l_b in
Alcotest.(check (list int )) "bitstring" (to_list det.bitstring) l_a;
Alcotest.(check bool) "phase" (det.phase = Phase.Neg) true;
in
[
"Creation", `Quick, test_creation;
]