poulpy/poulpy-hal/src/reference/fft64/reim4/arithmetic_ref.rs
poulpy-hal/src/reference/fft64/reim4/arithmetic_ref.rsRaw
1use crate::reference::fft64::reim::{as_arr, as_arr_mut, reim_zero_ref};
2
3#[inline(always)]
4pub fn reim4_extract_1blk_from_reim_contiguous_ref(m: usize, rows: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
5 debug_assert!(blk < (m >> 2));
6 debug_assert!(dst.len() >= 2 * rows * 4);
7
8 let offset: usize = blk << 2;
9
10 // src = 4-values chunks spaced by m, dst = sequential 4-values chunks
11 let src_rows = src.chunks_exact(m).take(2 * rows);
12 let dst_chunks = dst.chunks_exact_mut(4).take(2 * rows);
13
14 for (dst_chunk, src_row) in dst_chunks.zip(src_rows) {
15 dst_chunk.copy_from_slice(&src_row[offset..offset + 4]);
16 }
17}
18
19#[inline(always)]
20pub fn reim4_save_1blk_to_reim_contiguous_ref(m: usize, rows: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
21 debug_assert!(blk < (m >> 2));
22 debug_assert!(src.len() >= 2 * rows * 4);
23
24 let offset: usize = blk << 2;
25
26 // dst = 4-values chunks spaced by m, src = sequential 4-values chunks
27 let dst_rows = dst.chunks_exact_mut(m).take(2 * rows);
28 let src_chunks = src.chunks_exact(4).take(2 * rows);
29
30 for (dst_row, src_chunk) in dst_rows.zip(src_chunks) {
31 dst_row[offset..offset + 4].copy_from_slice(src_chunk);
32 }
33}
34
35#[inline(always)]
36pub fn reim4_save_1blk_to_reim_ref<const OVERWRITE: bool>(m: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
37 let mut offset: usize = blk << 2;
38
39 debug_assert!(blk < (m >> 2));
40 debug_assert!(dst.len() >= offset + m + 4);
41 debug_assert!(src.len() >= 8);
42
43 let dst_off = &mut dst[offset..offset + 4];
44
45 if OVERWRITE {
46 dst_off.copy_from_slice(&src[0..4]);
47 } else {
48 dst_off[0] += src[0];
49 dst_off[1] += src[1];
50 dst_off[2] += src[2];
51 dst_off[3] += src[3];
52 }
53
54 offset += m;
55
56 let dst_off = &mut dst[offset..offset + 4];
57 if OVERWRITE {
58 dst_off.copy_from_slice(&src[4..8]);
59 } else {
60 dst_off[0] += src[4];
61 dst_off[1] += src[5];
62 dst_off[2] += src[6];
63 dst_off[3] += src[7];
64 }
65}
66
67#[inline(always)]
68pub fn reim4_save_2blk_to_reim_ref<const OVERWRITE: bool>(m: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
69 let mut offset: usize = blk << 2;
70
71 debug_assert!(blk < (m >> 2));
72 debug_assert!(dst.len() >= offset + 3 * m + 4);
73 debug_assert!(src.len() >= 16);
74
75 let dst_off: &mut [f64] = &mut dst[offset..offset + 4];
76 if OVERWRITE {
77 dst_off.copy_from_slice(&src[0..4]);
78 } else {
79 dst_off[0] += src[0];
80 dst_off[1] += src[1];
81 dst_off[2] += src[2];
82 dst_off[3] += src[3];
83 }
84
85 offset += m;
86 let dst_off: &mut [f64] = &mut dst[offset..offset + 4];
87 if OVERWRITE {
88 dst_off.copy_from_slice(&src[4..8]);
89 } else {
90 dst_off[0] += src[4];
91 dst_off[1] += src[5];
92 dst_off[2] += src[6];
93 dst_off[3] += src[7];
94 }
95
96 offset += m;
97
98 let dst_off: &mut [f64] = &mut dst[offset..offset + 4];
99 if OVERWRITE {
100 dst_off.copy_from_slice(&src[8..12]);
101 } else {
102 dst_off[0] += src[8];
103 dst_off[1] += src[9];
104 dst_off[2] += src[10];
105 dst_off[3] += src[11];
106 }
107
108 offset += m;
109 let dst_off: &mut [f64] = &mut dst[offset..offset + 4];
110 if OVERWRITE {
111 dst_off.copy_from_slice(&src[12..16]);
112 } else {
113 dst_off[0] += src[12];
114 dst_off[1] += src[13];
115 dst_off[2] += src[14];
116 dst_off[3] += src[15];
117 }
118}
119
120#[inline(always)]
121pub fn reim4_vec_mat1col_product_ref(
122 nrows: usize,
123 dst: &mut [f64], // 8 doubles: [re1(4), im1(4)]
124 u: &[f64], // nrows * 8 doubles: [ur(4) | ui(4)] per row
125 v: &[f64], // nrows * 8 doubles: [ar(4) | ai(4)] per row
126) {
127 #[cfg(debug_assertions)]
128 {
129 assert!(dst.len() >= 8, "dst must have at least 8 doubles");
130 assert!(u.len() >= nrows * 8, "u must be at least nrows * 8 doubles");
131 assert!(v.len() >= nrows * 8, "v must be at least nrows * 8 doubles");
132 }
133
134 let mut acc: [f64; 8] = [0f64; 8];
135 let mut j = 0;
136 for _ in 0..nrows {
137 reim4_add_mul(&mut acc, as_arr(&u[j..]), as_arr(&v[j..]));
138 j += 8;
139 }
140 dst[0..8].copy_from_slice(&acc);
141}
142
143#[inline(always)]
144pub fn reim4_vec_mat2cols_product_ref(
145 nrows: usize,
146 dst: &mut [f64], // 16 doubles: [re1(4), im1(4), re2(4), im2(4)]
147 u: &[f64], // nrows * 8 doubles: [ur(4) | ui(4)] per row
148 v: &[f64], // nrows * 16 doubles: [ar(4) | ai(4) | br(4) | bi(4)] per row
149) {
150 #[cfg(debug_assertions)]
151 {
152 assert_eq!(dst.len(), 16, "dst must have 16 doubles");
153 assert!(u.len() >= nrows * 8, "u must be at least nrows * 8 doubles");
154 assert!(v.len() >= nrows * 16, "v must be at least nrows * 16 doubles");
155 }
156
157 // zero accumulators
158 let mut acc_0: [f64; 8] = [0f64; 8];
159 let mut acc_1: [f64; 8] = [0f64; 8];
160 for i in 0..nrows {
161 let _1j: usize = i << 3;
162 let _2j: usize = i << 4;
163 let u_j: &[f64; 8] = as_arr(&u[_1j..]);
164 reim4_add_mul(&mut acc_0, u_j, as_arr(&v[_2j..]));
165 reim4_add_mul(&mut acc_1, u_j, as_arr(&v[_2j + 8..]));
166 }
167 dst[0..8].copy_from_slice(&acc_0);
168 dst[8..16].copy_from_slice(&acc_1);
169}
170
171#[inline(always)]
172pub fn reim4_vec_mat2cols_2ndcol_product_ref(
173 nrows: usize,
174 dst: &mut [f64], // 8 doubles: [re1(4), im1(4), re2(4), im2(4)]
175 u: &[f64], // nrows * 8 doubles: [ur(4) | ui(4)] per row
176 v: &[f64], // nrows * 16 doubles: [x | x | br(4) | bi(4)] per row
177) {
178 #[cfg(debug_assertions)]
179 {
180 assert!(dst.len() >= 8, "dst must be at least 8 doubles but is {}", dst.len());
181 assert!(
182 u.len() >= nrows * 8,
183 "u must be at least nrows={} * 8 doubles but is {}",
184 nrows,
185 u.len()
186 );
187 assert!(
188 v.len() >= nrows * 16,
189 "v must be at least nrows={} * 16 doubles but is {}",
190 nrows,
191 v.len()
192 );
193 }
194
195 // zero accumulators
196 let mut acc: [f64; 8] = [0f64; 8];
197 for i in 0..nrows {
198 let _1j: usize = i << 3;
199 let _2j: usize = i << 4;
200 reim4_add_mul(&mut acc, as_arr(&u[_1j..]), as_arr(&v[_2j + 8..]));
201 }
202 dst[0..8].copy_from_slice(&acc);
203}
204
205#[inline(always)]
206pub fn reim4_add_mul(dst: &mut [f64; 8], a: &[f64; 8], b: &[f64; 8]) {
207 for k in 0..4 {
208 let ar: f64 = a[k];
209 let br: f64 = b[k];
210 let ai: f64 = a[k + 4];
211 let bi: f64 = b[k + 4];
212 dst[k] += ar * br - ai * bi;
213 dst[k + 4] += ar * bi + ai * br;
214 }
215}
216
217#[inline(always)]
218pub fn reim4_convolution_1coeff_ref(k: usize, dst: &mut [f64; 8], a: &[f64], a_size: usize, b: &[f64], b_size: usize) {
219 reim_zero_ref(dst);
220
221 if k >= a_size + b_size {
222 return;
223 }
224 let j_min: usize = k.saturating_sub(a_size - 1);
225 let j_max: usize = (k + 1).min(b_size);
226
227 for j in j_min..j_max {
228 reim4_add_mul(dst, as_arr(&a[8 * (k - j)..]), as_arr(&b[8 * j..]));
229 }
230}
231
232#[inline(always)]
233pub fn reim4_convolution_2coeffs_ref(k: usize, dst: &mut [f64; 16], a: &[f64], a_size: usize, b: &[f64], b_size: usize) {
234 reim4_convolution_1coeff_ref(k, as_arr_mut(dst), a, a_size, b, b_size);
235 reim4_convolution_1coeff_ref(k + 1, as_arr_mut(&mut dst[8..]), a, a_size, b, b_size);
236}
237
238#[inline(always)]
239pub fn reim4_add_mul_b_real_const(dst: &mut [f64; 8], a: &[f64; 8], b: f64) {
240 for k in 0..4 {
241 let ar: f64 = a[k];
242 let ai: f64 = a[k + 4];
243 dst[k] += ar * b;
244 dst[k + 4] += ai * b;
245 }
246}
247
248#[inline(always)]
249pub fn reim4_convolution_by_real_const_1coeff_ref(k: usize, dst: &mut [f64; 8], a: &[f64], a_size: usize, b: &[f64]) {
250 reim_zero_ref(dst);
251
252 let b_size: usize = b.len();
253
254 if k >= a_size + b_size {
255 return;
256 }
257 let j_min: usize = k.saturating_sub(a_size - 1);
258 let j_max: usize = (k + 1).min(b_size);
259
260 for j in j_min..j_max {
261 reim4_add_mul_b_real_const(dst, as_arr(&a[8 * (k - j)..]), b[j]);
262 }
263}
264
265#[inline(always)]
266pub fn reim4_convolution_by_real_const_2coeffs_ref(k: usize, dst: &mut [f64; 16], a: &[f64], a_size: usize, b: &[f64]) {
267 reim4_convolution_by_real_const_1coeff_ref(k, as_arr_mut(dst), a, a_size, b);
268 reim4_convolution_by_real_const_1coeff_ref(k + 1, as_arr_mut(&mut dst[8..]), a, a_size, b);
269}