1use scirs2_core::ndarray::{Array1, Array2};
2use scirs2_core::Complex64;
3use scirs2_core::parallel_ops::*;
4
5use quantrs2_core::qubit::QubitId;
6
7pub fn kron(a: &Array2<Complex64>, b: &Array2<Complex64>) -> Array2<Complex64> {
9 let a_shape = a.shape();
10 let b_shape = b.shape();
11
12 let rows = a_shape[0] * b_shape[0];
13 let cols = a_shape[1] * b_shape[1];
14
15 let mut result = Array2::zeros((rows, cols));
16
17 for i in 0..a_shape[0] {
18 for j in 0..a_shape[1] {
19 let a_val = a[[i, j]];
20 let i_offset = i * b_shape[0];
21 let j_offset = j * b_shape[1];
22
23 for k in 0..b_shape[0] {
24 for l in 0..b_shape[1] {
25 result[[i_offset + k, j_offset + l]] = a_val * b[[k, l]];
26 }
27 }
28 }
29 }
30
31 result
32}
33
34pub fn tensor_product(a: &Array1<Complex64>, b: &Array1<Complex64>) -> Array1<Complex64> {
36 let a_len = a.len();
37 let b_len = b.len();
38 let result_len = a_len * b_len;
39
40 let mut result = Array1::zeros(result_len);
41
42 for i in 0..a_len {
43 let a_val = a[i];
44 let offset = i * b_len;
45
46 for j in 0..b_len {
47 result[offset + j] = a_val * b[j];
48 }
49 }
50
51 result
52}
53
54pub fn int_to_bits(n: usize, num_bits: usize) -> Vec<u8> {
56 let mut bits = vec![0; num_bits];
57 for i in 0..num_bits {
58 bits[num_bits - 1 - i] = ((n >> i) & 1) as u8;
59 }
60 bits
61}
62
63pub fn bits_to_int(bits: &[u8]) -> usize {
65 bits.iter().fold(0, |acc, &bit| (acc << 1) | bit as usize)
66}
67
68pub fn flip_bit(index: usize, pos: usize) -> usize {
70 index ^ (1 << pos)
71}
72
73pub fn controlled_flip(index: usize, ctrl_pos: usize, target_pos: usize) -> usize {
77 if (index >> ctrl_pos) & 1 == 1 {
78 flip_bit(index, target_pos)
79 } else {
80 index
81 }
82}
83
84pub fn compute_index(qubit_indices: &[QubitId], state_bits: &[u8]) -> usize {
88 if qubit_indices.len() != state_bits.len() {
89 panic!("Mismatch between qubit indices and state bits");
90 }
91
92 let mut index = 0;
93 for (&qubit, &bit) in qubit_indices.iter().zip(state_bits.iter()) {
94 let q = qubit.id() as usize;
95 if bit != 0 {
96 index |= 1 << q;
97 }
98 }
99
100 index
101}
102
103pub fn par_indexed_map<F>(state: &mut [Complex64], f: F)
108where
109 F: Fn(usize, Complex64) -> Complex64 + Sync,
110{
111 state.par_iter_mut().enumerate().for_each(|(i, v)| {
112 *v = f(i, *v);
113 });
114}
115
116pub fn gate_vec_to_array2(matrix: &[Complex64], dim: usize) -> Array2<Complex64> {
118 let mut result = Array2::zeros((dim, dim));
119
120 for i in 0..dim {
121 for j in 0..dim {
122 result[[i, j]] = matrix[i * dim + j];
123 }
124 }
125
126 result
127}