stabilizer_ch_form_rust/form/
permute.rs

1use crate::{
2    StabilizerCHForm,
3    error::{Error, Result},
4};
5use ndarray::Axis;
6
7impl StabilizerCHForm {
8    /// Returns a new StabilizerCHForm with the qubits permuted.
9    ///
10    /// ## Arguments
11    /// * `axes` - A slice representing the new order of qubits. For `n` qubits,
12    ///   this must be a permutation of `[0, 1, ..., n-1]`.
13    ///
14    /// ## Returns
15    /// A [`Result`] containing the new `StabilizerCHForm` with permuted qubits.
16    pub fn permuted(&self, axes: &[usize]) -> Result<Self> {
17        if axes.len() != self.n {
18            return Err(Error::InvalidPermutationLength(axes.len(), self.n));
19        }
20        // Check that `axes` is a valid permutation of [0, 1, ..., n-1]
21        let mut check_vec = vec![false; self.n];
22        for &axis in axes {
23            if axis >= self.n || check_vec[axis] {
24                return Err(Error::InvalidPermutation(axes.to_vec()));
25            }
26            check_vec[axis] = true;
27        }
28
29        let mut new_state = StabilizerCHForm::new(self.n)?;
30
31        for (new_i, &old_i) in axes.iter().enumerate() {
32            for (new_j, &old_j) in axes.iter().enumerate() {
33                new_state.mat_g[[new_i, new_j]] = self.mat_g[[old_i, old_j]];
34                new_state.mat_f[[new_i, new_j]] = self.mat_f[[old_i, old_j]];
35                new_state.mat_m[[new_i, new_j]] = self.mat_m[[old_i, old_j]];
36            }
37        }
38
39        new_state.gamma = self.gamma.select(Axis(0), axes);
40        new_state.vec_v = self.vec_v.select(Axis(0), axes);
41        new_state.vec_s = self.vec_s.select(Axis(0), axes);
42
43        new_state.omega = self.omega;
44        new_state.phase_factor = self.phase_factor;
45
46        Ok(new_state)
47    }
48
49    /// Permutes the qubits of the state in-place.
50    ///
51    /// ## Arguments
52    /// * `axes` - A slice representing the new order of qubits. For `n` qubits,
53    ///   this must be a permutation of `[0, 1, ..., n-1]`.
54    ///
55    /// ## Returns
56    /// A [`Result`] indicating success or failure.
57    pub fn permute(&mut self, axes: &[usize]) -> Result<()> {
58        *self = self.permuted(axes)?;
59        Ok(())
60    }
61}