arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/cplx/cplx_common.c
poulpy-backend/src/cpu_spqlios/spqlios-arithmetic/spqlios/cplx/cplx_common.cRaw
 1#include "cplx_fft_internal.h"
 2
 3void cplx_set(CPLX r, const CPLX a) {
 4  r[0] = a[0];
 5  r[1] = a[1];
 6}
 7void cplx_neg(CPLX r, const CPLX a) {
 8  r[0] = -a[0];
 9  r[1] = -a[1];
10}
11void cplx_add(CPLX r, const CPLX a, const CPLX b) {
12  r[0] = a[0] + b[0];
13  r[1] = a[1] + b[1];
14}
15void cplx_sub(CPLX r, const CPLX a, const CPLX b) {
16  r[0] = a[0] - b[0];
17  r[1] = a[1] - b[1];
18}
19void cplx_mul(CPLX r, const CPLX a, const CPLX b) {
20  double re = a[0] * b[0] - a[1] * b[1];
21  r[1] = a[0] * b[1] + a[1] * b[0];
22  r[0] = re;
23}
24
25/**
26 * @brief splits 2h evaluations of one polynomials into 2 times h evaluations of even/odd polynomial
27 * Input:  Q_0(y),...,Q_{h-1}(y),Q_0(-y),...,Q_{h-1}(-y)
28 * Output: P_0(z),...,P_{h-1}(z),P_h(z),...,P_{2h-1}(z)
29 * where Q_i(X)=P_i(X^2)+X.P_{h+i}(X^2) and y^2 = z
30 * @param h number of "coefficients" h >= 1
31 * @param data 2h complex coefficients interleaved and 256b aligned
32 * @param powom y represented as (yre,yim)
33 */
34EXPORT void cplx_split_fft_ref(int32_t h, CPLX* data, const CPLX powom) {
35  CPLX* d0 = data;
36  CPLX* d1 = data + h;
37  for (uint64_t i = 0; i < h; ++i) {
38    CPLX diff;
39    cplx_sub(diff, d0[i], d1[i]);
40    cplx_add(d0[i], d0[i], d1[i]);
41    cplx_mul(d1[i], diff, powom);
42  }
43}
44
45/**
46 * @brief Do two layers of itwiddle (i.e. split).
47 * Input/output:  d0,d1,d2,d3 of length h
48 * Algo:
49 *   itwiddle(d0,d1,om[0]),itwiddle(d2,d3,i.om[0])
50 *   itwiddle(d0,d2,om[1]),itwiddle(d1,d3,om[1])
51 * @param h number of "coefficients" h >= 1
52 * @param data 4h complex coefficients interleaved and 256b aligned
53 * @param powom om[0] (re,im) and om[1] where om[1]=om[0]^2
54 */
55EXPORT void cplx_bisplit_fft_ref(int32_t h, CPLX* data, const CPLX powom[2]) {
56  CPLX* d0 = data;
57  CPLX* d2 = data + 2 * h;
58  const CPLX* om0 = powom;
59  CPLX iom0;
60  iom0[0] = powom[0][1];
61  iom0[1] = -powom[0][0];
62  const CPLX* om1 = powom + 1;
63  cplx_split_fft_ref(h, d0, *om0);
64  cplx_split_fft_ref(h, d2, iom0);
65  cplx_split_fft_ref(2 * h, d0, *om1);
66}
67
68/**
69 * Input: Q(y),Q(-y)
70 * Output: P_0(z),P_1(z)
71 * where Q(X)=P_0(X^2)+X.P_1(X^2) and y^2 = z
72 * @param data 2 complexes coefficients interleaved and 256b aligned
73 * @param powom (z,-z) interleaved: (zre,zim,-zre,-zim)
74 */
75void split_fft_last_ref(CPLX* data, const CPLX powom) {
76  CPLX diff;
77  cplx_sub(diff, data[0], data[1]);
78  cplx_add(data[0], data[0], data[1]);
79  cplx_mul(data[1], diff, powom);
80}