1use std::f64::consts::FRAC_1_SQRT_2;
4
5use faer::{Mat, mat};
6use num_complex::Complex;
7use pretty::RcDoc;
8use winnow::{
9 LocatingSlice, ModalResult, Parser,
10 combinator::{alt, delimited, repeat},
11};
12
13use crate::text::{HasParser, ToDoc};
14
15#[derive(Clone, Copy, Debug, PartialEq)]
17pub enum KetState {
18 Zero,
20 One,
22 Plus,
24 Minus,
26}
27
28const CISQRT2: Complex<f64> = Complex::new(FRAC_1_SQRT_2, 0.0);
29
30impl KetState {
31 pub fn compl(self) -> Self {
34 match self {
35 KetState::Zero => KetState::One,
36 KetState::One => KetState::Zero,
37 KetState::Plus => KetState::Minus,
38 KetState::Minus => KetState::Plus,
39 }
40 }
41
42 pub fn to_char(&self) -> char {
44 match self {
45 KetState::Zero => '0',
46 KetState::One => '1',
47 KetState::Plus => '+',
48 KetState::Minus => '-',
49 }
50 }
51 pub fn to_state(self) -> Mat<Complex<f64>> {
53 match self {
54 KetState::Zero => mat![[Complex::ONE], [Complex::ZERO]],
55 KetState::One => mat![[Complex::ZERO], [Complex::ONE]],
56 KetState::Plus => mat![[CISQRT2], [CISQRT2]],
57 KetState::Minus => mat![[CISQRT2], [-CISQRT2]],
58 }
59 }
60}
61
62#[derive(Clone, Debug, PartialEq)]
64pub struct CompKetState(Vec<KetState>);
65
66impl CompKetState {
67 pub fn qubits(&self) -> usize {
69 self.0.len()
70 }
71
72 pub fn iter(&self) -> impl Iterator<Item = &KetState> {
74 self.0.iter()
75 }
76
77 pub fn new(states: Vec<KetState>) -> Self {
79 CompKetState(states)
80 }
81
82 pub fn single(state: KetState) -> Self {
84 CompKetState::new(vec![state])
85 }
86}
87
88impl ToDoc for CompKetState {
89 fn to_doc(&self) -> RcDoc<'_> {
90 RcDoc::text("|")
91 .append(self.0.iter().map(KetState::to_char).collect::<String>())
92 .append(">")
93 }
94}
95
96impl HasParser for CompKetState {
97 fn parser(input: &mut LocatingSlice<&str>) -> ModalResult<Self> {
98 delimited(
99 "|",
100 repeat(
101 1..,
102 alt((
103 "0".value(KetState::Zero),
104 "1".value(KetState::One),
105 "+".value(KetState::Plus),
106 "-".value(KetState::Minus),
107 )),
108 ),
109 ">",
110 )
111 .map(CompKetState)
112 .parse_next(input)
113 }
114}