stabilizer_ch_form_rust/form/
mod.rs1use ndarray::{Array1, Array2};
2use num_complex::Complex64;
3
4use crate::{
5 circuit::{CliffordCircuit, CliffordGate},
6 error::{Error, Result},
7};
8
9use types::PhaseFactor;
10
11#[derive(Debug, Clone)]
12pub struct StabilizerCHForm {
13 pub(crate) n: usize,
14 pub(crate) mat_g: Array2<bool>,
15 pub(crate) mat_f: Array2<bool>,
16 pub(crate) mat_m: Array2<bool>,
17 pub(crate) gamma: Array1<PhaseFactor>,
18 pub(crate) vec_v: Array1<bool>,
19 pub(crate) vec_s: Array1<bool>,
20 pub(crate) omega: Complex64,
21 pub(crate) phase_factor: PhaseFactor,
22}
23
24mod amplitude;
25mod discard;
26mod gate_application;
27mod get_qubit_state;
28mod inner_product;
29mod kron;
30mod left_multiplication;
31mod matrix_operations;
32mod measure;
33mod permute;
34mod project;
35mod resolve_superposition;
36mod right_multiplication;
37mod statevector;
38mod types;
39
40impl StabilizerCHForm {
41 pub fn new(n: usize) -> Result<Self> {
45 if n == 0 {
46 return Err(Error::InvalidNumQubits(n));
47 }
48
49 Ok(Self {
50 n,
51 mat_g: Array2::from_shape_fn((n, n), |(i, j)| i == j),
53 mat_f: Array2::from_shape_fn((n, n), |(i, j)| i == j),
54 mat_m: Array2::from_elem((n, n), false),
55 gamma: Array1::from_elem(n, PhaseFactor::PLUS_ONE),
57 vec_v: Array1::from_elem(n, false),
59 vec_s: Array1::from_elem(n, false),
60 omega: Complex64::new(1.0, 0.0),
62 phase_factor: PhaseFactor::PLUS_ONE,
64 })
65 }
66
67 pub fn num_qubits(&self) -> usize {
69 self.n
70 }
71
72 pub fn set_global_phase(&mut self, phase: Complex64) {
77 if (phase.norm_sqr() - 1.0).abs() > 1e-8 {
78 panic!("Global phase must be a unit complex number.");
79 }
80 self.omega = phase;
81 }
82
83 pub fn global_phase(&self) -> Complex64 {
88 self.omega
89 }
90
91 pub fn from_clifford_circuit(circuit: &CliffordCircuit) -> Result<Self> {
99 let mut ch_form = StabilizerCHForm::new(circuit.num_qubits)?;
100
101 for gate in &circuit.gates {
102 match gate {
103 CliffordGate::H(q) => ch_form.left_multiply_h(*q)?,
104 CliffordGate::S(q) => ch_form.left_multiply_s(*q)?,
105 CliffordGate::Sdg(q) => ch_form.left_multiply_sdg(*q)?,
106 CliffordGate::X(q) => ch_form.left_multiply_x(*q)?,
107 CliffordGate::Y(q) => ch_form.left_multiply_y(*q)?,
108 CliffordGate::Z(q) => ch_form.left_multiply_z(*q)?,
109 CliffordGate::SqrtX(q) => ch_form.left_multiply_sqrt_x(*q)?,
110 CliffordGate::SqrtXdg(q) => ch_form.left_multiply_sqrt_xdg(*q)?,
111 CliffordGate::CX(control, target) => ch_form.left_multiply_cx(*control, *target)?,
112 CliffordGate::CZ(control, target) => ch_form.left_multiply_cz(*control, *target)?,
113 CliffordGate::Swap(q1, q2) => ch_form.left_multiply_swap(*q1, *q2)?,
114 }
115 }
116 Ok(ch_form)
117 }
118}