pub fn apply_fixed_unitary<const UN: usize>(
        &self,
        u: &Matrix<UN>,
        indicies: [usize; simple_log_2(UN)],
    ) -> Box<dyn QuantumSimulator> {
        let swap_list = make_swap_list::<N, {simple_log_2(UN)}>(indicies);

        // Create an iterator with those swaps applied
        let swapped_iter = self.iter().map(|(pre_bv, val)| {
            let mut bv = pre_bv;
            for &(i, j) in &swap_list {
                let bits_xor = bv[i] ^ bv[j];
                bv.set(i, bits_xor ^ bv[i]);
                bv.set(j, bits_xor ^ bv[j]);
            }
            (bv, val)
        });

        // Apply the unitary to every element of that iterartor
        // which passes the control test (just return the elements that fail)
        let applied_iter = swapped_iter.flat_map(|(bv, val)| {
            // Multiply bv by u <tensor product> identity

            // The basis vector picks out a column in that unitary.
            // The column is of the form [0 block][u column][0 block].
            // So we need to return a new iterator of the basis vectors
            // for u_column * val_u_column * val.
            let index_column = bv % UN;
            let base_basis_vector = bv - index_column;
            u[index_column].into_iter().enumerate().map(move |(i_col, val_u_col)| {
                let bv_col = (base_basis_vector + i_col).into();
                let val = val_u_col * val;
                (bv_col, val)
            })
        });

        // Swap the basis elements back
        let output_iter = applied_iter.map(|(mut bv, val): (BasisVector<N>, _)| {
            for &(i, j) in swap_list.iter().rev() {
                let bits_xor = bv[i] ^ bv[j];
                bv.set(i, bits_xor ^ bv[i]);
                bv.set(j, bits_xor ^ bv[j]);
            }
            (bv, val)
        });

        Box::new(self.child(output_iter))
    }
/// Indicies in order of low to high bits (when using them to index matrix cols)
Indicies in order of low to high bits (when using them to index matrix cols)
Indicies in order of low to high bits ( when using them to index matrix cols )
pub fn apply_fixed_unitary<const UN: usize>(
        &self,
        u: &Matrix<UN>,
        indicies: [usize; simple_log_2(UN)],
    ) -> Box<dyn QuantumSimulator> {
        let swap_list = make_swap_list::<N, {simple_log_2(UN)}>(indicies);
        // Create an iterator with those swaps applied
        let swapped_iter = self.iter().map(|(pre_bv, val)| {
            let mut bv = pre_bv;
            for &(i, j) in &swap_list {
                let bits_xor = bv[i] ^ bv[j];
                bv.set(i, bits_xor ^ bv[i]);
                bv.set(j, bits_xor ^ bv[j]);
            }
            (bv, val)
        });
        // Apply the unitary to every element of that iterartor
        // which passes the control test (just return the elements that fail)
        let applied_iter = swapped_iter.flat_map(|(bv, val)| {
            // Multiply bv by u <tensor product> identity
            // The basis vector picks out a column in that unitary.
            // The column is of the form [0 block][u column][0 block].
            // So we need to return a new iterator of the basis vectors
            // for u_column * val_u_column * val.
            let index_column = bv % UN;
            let base_basis_vector = bv - index_column;
            u[index_column].into_iter().enumerate().map(move |(i_col, val_u_col)| {
                let bv_col = (base_basis_vector + i_col).into();
                let val = val_u_col * val;
                (bv_col, val)
            })
        });
        // Swap the basis elements back
        let output_iter = applied_iter.map(|(mut bv, val): (BasisVector<N>, _)| {
            for &(i, j) in swap_list.iter().rev() {
                let bits_xor = bv[i] ^ bv[j];
                bv.set(i, bits_xor ^ bv[i]);
                bv.set(j, bits_xor ^ bv[j]);
            }
            (bv, val)
        });
        Box::new(self.child(output_iter))
    }
pub fn apply_fixed_unitary < const UN : usize > ( & self , u : & Matrix < UN > , indicies : [ usize ; simple_log_2 ( UN ) ] , ) -> Box < dyn QuantumSimulator > { let swap_list = make_swap_list :: < N , { simple_log_2 ( UN ) } > ( indicies ) ; // Create an iterator with those swaps applied let swapped_iter = self . iter ( ) . map ( | ( pre_bv , val ) | { let mut bv = pre_bv ; for & ( i , j ) in & swap_list { let bits_xor = bv [ i ] ^ bv [ j ] ; bv . set ( i , bits_xor ^ bv [ i ] ) ; bv . set ( j , bits_xor ^ bv [ j ] ) ; } ( bv , val ) } ) ; // Apply the unitary to every element of that iterartor // which passes the control test (just return the elements that fail) let applied_iter = swapped_iter . flat_map ( | ( bv , val ) | { // Multiply bv by u <tensor product> identity // The basis vector picks out a column in that unitary. // The column is of the form [0 block][u column][0 block]. // So we need to return a new iterator of the basis vectors // for u_column * val_u_column * val. let index_column = bv % UN ; let base_basis_vector = bv - index_column ; u [ index_column ] . into_iter ( ) . enumerate ( ) . map ( move | ( i_col , val_u_col ) | { let bv_col = ( base_basis_vector + i_col ) . into ( ) ; let val = val_u_col * val ; ( bv_col , val ) } ) } ) ; // Swap the basis elements back let output_iter = applied_iter . map ( | ( mut bv , val ) : ( BasisVector < N > , _ ) | { for & ( i , j ) in swap_list . iter ( ) . rev ( ) { let bits_xor = bv [ i ] ^ bv [ j ] ; bv . set ( i , bits_xor ^ bv [ i ] ) ; bv . set ( j , bits_xor ^ bv [ j ] ) ; } ( bv , val ) } ) ; Box :: new ( self . child ( output_iter ) ) }
Indicies in order of low to high bits (when using them to index matrix cols)
Indicies in order of low to high bits ( when using them to index matrix cols )
&self
u
&Matrix<UN>
indicies
[usize; simple_log_2(UN)]
&self
u
&Matrix<UN>
indicies
[usize; simple_log_2(UN)]