arnaucube
arnaucube/poulpyPublic Self-hosted repository
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;
  2
  3#[inline(always)]
  4pub fn reim4_extract_1blk_from_reim_ref(m: usize, rows: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
  5    let mut offset: usize = blk << 2;
  6
  7    debug_assert!(blk < (m >> 2));
  8    debug_assert!(dst.len() >= 2 * rows * 4);
  9
 10    for chunk in dst.chunks_exact_mut(4).take(2 * rows) {
 11        chunk.copy_from_slice(&src[offset..offset + 4]);
 12        offset += m
 13    }
 14}
 15
 16#[inline(always)]
 17pub fn reim4_save_1blk_to_reim_ref<const OVERWRITE: bool>(m: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
 18    let mut offset: usize = blk << 2;
 19
 20    debug_assert!(blk < (m >> 2));
 21    debug_assert!(dst.len() >= offset + m + 4);
 22    debug_assert!(src.len() >= 8);
 23
 24    let dst_off = &mut dst[offset..offset + 4];
 25
 26    if OVERWRITE {
 27        dst_off.copy_from_slice(&src[0..4]);
 28    } else {
 29        dst_off[0] += src[0];
 30        dst_off[1] += src[1];
 31        dst_off[2] += src[2];
 32        dst_off[3] += src[3];
 33    }
 34
 35    offset += m;
 36
 37    let dst_off = &mut dst[offset..offset + 4];
 38    if OVERWRITE {
 39        dst_off.copy_from_slice(&src[4..8]);
 40    } else {
 41        dst_off[0] += src[4];
 42        dst_off[1] += src[5];
 43        dst_off[2] += src[6];
 44        dst_off[3] += src[7];
 45    }
 46}
 47
 48#[inline(always)]
 49pub fn reim4_save_2blk_to_reim_ref<const OVERWRITE: bool>(m: usize, blk: usize, dst: &mut [f64], src: &[f64]) {
 50    let mut offset: usize = blk << 2;
 51
 52    debug_assert!(blk < (m >> 2));
 53    debug_assert!(dst.len() >= offset + 3 * m + 4);
 54    debug_assert!(src.len() >= 16);
 55
 56    let dst_off = &mut dst[offset..offset + 4];
 57    if OVERWRITE {
 58        dst_off.copy_from_slice(&src[0..4]);
 59    } else {
 60        dst_off[0] += src[0];
 61        dst_off[1] += src[1];
 62        dst_off[2] += src[2];
 63        dst_off[3] += src[3];
 64    }
 65
 66    offset += m;
 67    let dst_off = &mut dst[offset..offset + 4];
 68    if OVERWRITE {
 69        dst_off.copy_from_slice(&src[4..8]);
 70    } else {
 71        dst_off[0] += src[4];
 72        dst_off[1] += src[5];
 73        dst_off[2] += src[6];
 74        dst_off[3] += src[7];
 75    }
 76
 77    offset += m;
 78
 79    let dst_off = &mut dst[offset..offset + 4];
 80    if OVERWRITE {
 81        dst_off.copy_from_slice(&src[8..12]);
 82    } else {
 83        dst_off[0] += src[8];
 84        dst_off[1] += src[9];
 85        dst_off[2] += src[10];
 86        dst_off[3] += src[11];
 87    }
 88
 89    offset += m;
 90    let dst_off = &mut dst[offset..offset + 4];
 91    if OVERWRITE {
 92        dst_off.copy_from_slice(&src[12..16]);
 93    } else {
 94        dst_off[0] += src[12];
 95        dst_off[1] += src[13];
 96        dst_off[2] += src[14];
 97        dst_off[3] += src[15];
 98    }
 99}
100
101#[inline(always)]
102pub fn reim4_vec_mat1col_product_ref(
103    nrows: usize,
104    dst: &mut [f64], // 8 doubles: [re1(4), im1(4)]
105    u: &[f64],       // nrows * 8 doubles: [ur(4) | ui(4)] per row
106    v: &[f64],       // nrows * 8 doubles: [ar(4) | ai(4)] per row
107) {
108    #[cfg(debug_assertions)]
109    {
110        assert!(dst.len() >= 8, "dst must have at least 8 doubles");
111        assert!(u.len() >= nrows * 8, "u must be at least nrows * 8 doubles");
112        assert!(v.len() >= nrows * 8, "v must be at least nrows * 8 doubles");
113    }
114
115    let mut acc: [f64; 8] = [0f64; 8];
116    let mut j = 0;
117    for _ in 0..nrows {
118        reim4_add_mul(&mut acc, as_arr(&u[j..]), as_arr(&v[j..]));
119        j += 8;
120    }
121    dst[0..8].copy_from_slice(&acc);
122}
123
124#[inline(always)]
125pub fn reim4_vec_mat2cols_product_ref(
126    nrows: usize,
127    dst: &mut [f64], // 16 doubles: [re1(4), im1(4), re2(4), im2(4)]
128    u: &[f64],       // nrows * 8 doubles: [ur(4) | ui(4)] per row
129    v: &[f64],       // nrows * 16 doubles: [ar(4) | ai(4) | br(4) | bi(4)] per row
130) {
131    #[cfg(debug_assertions)]
132    {
133        assert_eq!(dst.len(), 16, "dst must have 16 doubles");
134        assert!(u.len() >= nrows * 8, "u must be at least nrows * 8 doubles");
135        assert!(
136            v.len() >= nrows * 16,
137            "v must be at least nrows * 16 doubles"
138        );
139    }
140
141    // zero accumulators
142    let mut acc_0: [f64; 8] = [0f64; 8];
143    let mut acc_1: [f64; 8] = [0f64; 8];
144    for i in 0..nrows {
145        let _1j: usize = i << 3;
146        let _2j: usize = i << 4;
147        let u_j: &[f64; 8] = as_arr(&u[_1j..]);
148        reim4_add_mul(&mut acc_0, u_j, as_arr(&v[_2j..]));
149        reim4_add_mul(&mut acc_1, u_j, as_arr(&v[_2j + 8..]));
150    }
151    dst[0..8].copy_from_slice(&acc_0);
152    dst[8..16].copy_from_slice(&acc_1);
153}
154
155#[inline(always)]
156pub fn reim4_vec_mat2cols_2ndcol_product_ref(
157    nrows: usize,
158    dst: &mut [f64], // 8 doubles: [re1(4), im1(4), re2(4), im2(4)]
159    u: &[f64],       // nrows * 8 doubles: [ur(4) | ui(4)] per row
160    v: &[f64],       // nrows * 16 doubles: [x | x | br(4) | bi(4)] per row
161) {
162    #[cfg(debug_assertions)]
163    {
164        assert!(
165            dst.len() >= 8,
166            "dst must be at least 8 doubles but is {}",
167            dst.len()
168        );
169        assert!(
170            u.len() >= nrows * 8,
171            "u must be at least nrows={} * 8 doubles but is {}",
172            nrows,
173            u.len()
174        );
175        assert!(
176            v.len() >= nrows * 16,
177            "v must be at least nrows={} * 16 doubles but is {}",
178            nrows,
179            v.len()
180        );
181    }
182
183    // zero accumulators
184    let mut acc: [f64; 8] = [0f64; 8];
185    for i in 0..nrows {
186        let _1j: usize = i << 3;
187        let _2j: usize = i << 4;
188        reim4_add_mul(&mut acc, as_arr(&u[_1j..]), as_arr(&v[_2j + 8..]));
189    }
190    dst[0..8].copy_from_slice(&acc);
191}
192
193#[inline(always)]
194pub fn reim4_add_mul(dst: &mut [f64; 8], a: &[f64; 8], b: &[f64; 8]) {
195    for k in 0..4 {
196        let ar: f64 = a[k];
197        let br: f64 = b[k];
198        let ai: f64 = a[k + 4];
199        let bi: f64 = b[k + 4];
200        dst[k] += ar * br - ai * bi;
201        dst[k + 4] += ar * bi + ai * br;
202    }
203}