38 #define G_OP_ADD "GFft::operator+=(GFft&)"
39 #define G_OP_SUB "GFft::operator-=(GFft&)"
40 #define G_OP_MUL "GFft::operator*=(GFft&)"
41 #define G_OP_DIV "GFft::operator/=(GFft&)"
42 #define G_FORWARD "GFft::forward(GNdarray&)"
43 #define G_BACKWARD "GFft::backward()"
164 for (
int i = 0; i <
m_size; ++i) {
188 for (
int i = 0; i <
m_size; ++i) {
212 for (
int i = 0; i <
m_size; ++i) {
236 for (
int i = 0; i <
m_size; ++i) {
258 for (
int i = 0; i < fft.
size(); ++i) {
297 return new GFft(*
this);
337 if (array.
dim() == 1) {
342 else if (array.
dim() == 2) {
345 for (
int row = 0; row <
m_shape[1]; ++row) {
351 for (
int col = 0; col < m_shape[0]; ++col) {
360 std::string msg =
"Fast Fourier Transformation for "+
410 std::complex<double>* data =
new std::complex<double>[
m_size];
411 for (
int i = 0; i <
m_size; ++i) {
416 if (array.
dim() == 1) {
425 for (
int i = 0; i <
m_size; ++i) {
426 array(i) = (data+i)->real() *
norm;
432 else if (array.
dim() == 2) {
435 for (
int row = 0; row <
m_shape[1]; ++row) {
441 for (
int col = 0; col < m_shape[0]; ++col) {
447 const double norm = 1.0 / double(m_shape[0]*m_shape[1]);
450 for (
int i = 0; i <
m_size; ++i) {
451 array(i) = (data+i)->real() *
norm;
463 std::string msg =
"Fast Fourier Transformation for "+
494 result.append(
"=== GFft ===");
501 for (
int i = 0; i <
dim(); ++i) {
514 for (
int i = 0; i <
size(); ++i) {
569 for (
int i = 0; i <
m_size; ++i) {
610 if (array.
size() > 0) {
619 for (
int i = 0; i <
m_size; ++i) {
620 *(
m_data+i) = std::complex<double>(array(i), 0.0);
628 for (
int i = 0; i <
m_shape.size(); ++i) {
654 for (
int i = 0; i <
m_shape.size(); ++i) {
677 const GFft& fft)
const
683 std::string msg =
"Incompatible FFT dimensions (";
684 for (
int i = 0; i <
m_shape.size(); ++i) {
691 for (
int i = 0; i < fft.
m_shape.size(); ++i) {
725 std::complex<double>* scratch =
new std::complex<double>[n];
726 std::complex<double> zero(0.0, 0.0);
727 for (
int i = 0; i < n; ++i) {
741 for (
int i = 0; i < wavetable.
factors(); ++i) {
744 int factor = wavetable.
factor(i);
745 int index = wavetable.
index(i);
751 std::complex<double>* in;
752 std::complex<double>* out;
772 factor2(in, istride, out, ostride, wavetable, sign, product, n, index);
774 else if (factor == 3) {
775 factor3(in, istride, out, ostride, wavetable, sign, product, n, index);
777 else if (factor == 4) {
778 factor4(in, istride, out, ostride, wavetable, sign, product, n, index);
780 else if (factor == 5) {
781 factor5(in, istride, out, ostride, wavetable, sign, product, n, index);
783 else if (factor == 6) {
784 factor6(in, istride, out, ostride, wavetable, sign, product, n, index);
786 else if (factor == 7) {
787 factor7(in, istride, out, ostride, wavetable, sign, product, n, index);
790 factorn(in, istride, out, ostride, wavetable, sign, factor, product, n, index);
799 for (
int i = 0; i < n; ++i) {
800 *(data+stride*i) = *(scratch+i);
827 std::complex<double>* out,
836 const int factor = 2;
837 const int m = n / factor;
838 const int q = n / product;
839 const int p_1 = product / factor;
840 const int jump = (factor - 1) * p_1;
843 for (
int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
846 std::vector<std::complex<double> > w =
get_w(wavetable, index, k, q, 1, sign);
849 for (
int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
852 const std::complex<double> z0 = *(in+istride*i);
853 const std::complex<double> z1 = *(in+istride*(i+m));
856 const std::complex<double> x0 = z0 + z1;
857 const std::complex<double> x1 = z0 - z1;
860 *(out+ostride*j) = x0;
861 *(out+ostride*(j+p_1)) = w[0] * x1;
887 std::complex<double>* out,
896 const int factor = 3;
897 const int m = n / factor;
898 const int q = n / product;
899 const int p_1 = product / factor;
900 const int jump = (factor - 1) * p_1;
907 for (
int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
910 std::vector<std::complex<double> > w =
get_w(wavetable, index, k, q, 2, sign);
913 for (
int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
916 const std::complex<double> z0 = *(in+istride*i);
917 const std::complex<double> z1 = *(in+istride*(i+m));
918 const std::complex<double> z2 = *(in+istride*(i+2*m));
921 const std::complex<double> t1 = z1 + z2;
922 const std::complex<double> t2 = z0 - t1/2.0;
923 const std::complex<double> t3 = double((
int)sign) * tau * (z1 - z2);
926 const std::complex<double> x0 = z0 + t1;
927 const std::complex<double> x1 = t2 +
timesi(t3);
928 const std::complex<double> x2 = t2 -
timesi(t3);
931 *(out+ostride*j) = x0;
932 *(out+ostride*(j+p_1)) = w[0] * x1;
933 *(out+ostride*(j+2*p_1)) = w[1] * x2;
959 std::complex<double>* out,
968 const int factor = 4;
969 const int m = n / factor;
970 const int q = n / product;
971 const int p_1 = product / factor;
972 const int jump = (factor - 1) * p_1;
975 for (
int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
978 std::vector<std::complex<double> > w =
get_w(wavetable, index, k, q, 3, sign);
981 for (
int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
984 const std::complex<double> z0 = *(in+istride*i);
985 const std::complex<double> z1 = *(in+istride*(i+m));
986 const std::complex<double> z2 = *(in+istride*(i+2*m));
987 const std::complex<double> z3 = *(in+istride*(i+3*m));
990 const std::complex<double> t1 = z0 + z2;
991 const std::complex<double> t2 = z1 + z3;
992 const std::complex<double> t3 = z0 - z2;
993 const std::complex<double> t4 = double((
int)sign) * (z1 - z3);
996 const std::complex<double> x0 = t1 + t2;
997 const std::complex<double> x1 = t3 +
timesi(t4);
998 const std::complex<double> x2 = t1 - t2;
999 const std::complex<double> x3 = t3 -
timesi(t4);
1002 *(out+ostride*j) = x0;
1003 *(out+ostride*(j+p_1)) = w[0] * x1;
1004 *(out+ostride*(j+2*p_1)) = w[1] * x2;
1005 *(out+ostride*(j+3*p_1)) = w[2] * x3;
1031 std::complex<double>* out,
1040 const int factor = 5;
1041 const int m = n / factor;
1042 const int q = n / product;
1043 const int p_1 = product / factor;
1044 const int jump = (factor - 1) * p_1;
1049 const double tau =
std::sqrt(5.0) / 4.0;
1052 for (
int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
1055 std::vector<std::complex<double> > w =
get_w(wavetable, index, k, q, 4, sign);
1058 for (
int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
1061 const std::complex<double> z0 = *(in+istride*i);
1062 const std::complex<double> z1 = *(in+istride*(i+m));
1063 const std::complex<double> z2 = *(in+istride*(i+2*m));
1064 const std::complex<double> z3 = *(in+istride*(i+3*m));
1065 const std::complex<double> z4 = *(in+istride*(i+4*m));
1068 const std::complex<double> t1 = z1 + z4;
1069 const std::complex<double> t2 = z2 + z3;
1070 const std::complex<double> t3 = z1 - z4;
1071 const std::complex<double> t4 = z2 - z3;
1072 const std::complex<double> t5 = t1 + t2;
1073 const std::complex<double> t6 = tau * (t1 - t2);
1074 const std::complex<double> t7 = z0 - t5/4.0;
1075 const std::complex<double> t8 = t7 + t6;
1076 const std::complex<double> t9 = t7 - t6;
1077 const std::complex<double> t10 = double((
int)sign) *
1078 (sin_2pi_by_5*t3 + sin_2pi_by_10*t4);
1079 const std::complex<double> t11 = double((
int)sign) *
1080 (sin_2pi_by_10*t3 - sin_2pi_by_5*t4);
1083 const std::complex<double> x0 = z0 + t5;
1084 const std::complex<double> x1 = t8 +
timesi(t10);
1085 const std::complex<double> x2 = t9 +
timesi(t11);
1086 const std::complex<double> x3 = t9 -
timesi(t11);
1087 const std::complex<double> x4 = t8 -
timesi(t10);
1090 *(out+ostride*j) = x0;
1091 *(out+ostride*(j+p_1)) = w[0] * x1;
1092 *(out+ostride*(j+2*p_1)) = w[1] * x2;
1093 *(out+ostride*(j+3*p_1)) = w[2] * x3;
1094 *(out+ostride*(j+4*p_1)) = w[3] * x4;
1120 std::complex<double>* out,
1129 const int factor = 6;
1130 const int m = n / factor;
1131 const int q = n / product;
1132 const int p_1 = product / factor;
1133 const int jump = (factor - 1) * p_1;
1136 const double tau =
std::sqrt(3.0) / 2.0;
1139 for (
int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
1142 std::vector<std::complex<double> > w =
get_w(wavetable, index, k, q, 5, sign);
1146 for (
int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
1149 const std::complex<double> z0 = *(in+istride*i);
1150 const std::complex<double> z1 = *(in+istride*(i+m));
1151 const std::complex<double> z2 = *(in+istride*(i+2*m));
1152 const std::complex<double> z3 = *(in+istride*(i+3*m));
1153 const std::complex<double> z4 = *(in+istride*(i+4*m));
1154 const std::complex<double> z5 = *(in+istride*(i+5*m));
1157 const std::complex<double> ta1 = z2 + z4;
1158 const std::complex<double> ta2 = z0 - ta1/2.0;
1159 const std::complex<double> ta3 = double((
int)sign) * tau * (z2 - z4);
1162 const std::complex<double> a0 = z0 + ta1;
1163 const std::complex<double> a1 = ta2 +
timesi(ta3);
1164 const std::complex<double> a2 = ta2 -
timesi(ta3);
1167 const std::complex<double> tb1 = z5 + z1;
1168 const std::complex<double> tb2 = z3 - tb1/2.0;
1169 const std::complex<double> tb3 = double((
int)sign) * tau * (z5 - z1);
1172 const std::complex<double> b0 = z3 + tb1;
1173 const std::complex<double> b1 = tb2 +
timesi(tb3);
1174 const std::complex<double> b2 = tb2 -
timesi(tb3);
1177 const std::complex<double> x0 = a0 + b0;
1178 const std::complex<double> x1 = a1 - b1;
1179 const std::complex<double> x2 = a2 + b2;
1180 const std::complex<double> x3 = a0 - b0;
1181 const std::complex<double> x4 = a1 + b1;
1182 const std::complex<double> x5 = a2 - b2;
1185 *(out+ostride*j) = x0;
1186 *(out+ostride*(j+p_1)) = w[0] * x1;
1187 *(out+ostride*(j+2*p_1)) = w[1] * x2;
1188 *(out+ostride*(j+3*p_1)) = w[2] * x3;
1189 *(out+ostride*(j+4*p_1)) = w[3] * x4;
1190 *(out+ostride*(j+5*p_1)) = w[4] * x5;
1216 std::complex<double>* out,
1225 const int factor = 7;
1226 const int m = n / factor;
1227 const int q = n / product;
1228 const int p_1 = product / factor;
1229 const int jump = (factor - 1) * p_1;
1233 static const double c1 =
std::cos(1.0 * twopi7);
1234 static const double c2 =
std::cos(2.0 * twopi7);
1235 static const double c3 =
std::cos(3.0 * twopi7);
1236 static const double s1 =
std::sin(1.0 * twopi7);
1237 static const double s2 =
std::sin(2.0 * twopi7);
1238 static const double s3 =
std::sin(3.0 * twopi7);
1239 static const double tau1 = (c1 + c2 + c3) / 3.0 - 1.0;
1240 static const double tau2 = (2.0 * c1 - c2 - c3) / 3.0;
1241 static const double tau3 = (c1 - 2.0*c2 + c3) / 3.0;
1242 static const double tau4 = (c1 + c2 - 2.0 * c3) / 3.0;
1243 static const double tau5 = (s1 + s2 - s3) / 3.0;
1244 static const double tau6 = (2.0 * s1 - s2 + s3) / 3.0;
1245 static const double tau7 = (s1 - 2.0 * s2 - s3) / 3.0;
1246 static const double tau8 = (s1 + s2 + 2.0 * s3) / 3.0;
1249 for (
int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
1252 std::vector<std::complex<double> > w =
get_w(wavetable, index, k, q, 6, sign);
1255 for (
int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
1258 const std::complex<double> z0 = *(in+istride*i);
1259 const std::complex<double> z1 = *(in+istride*(i+m));
1260 const std::complex<double> z2 = *(in+istride*(i+2*m));
1261 const std::complex<double> z3 = *(in+istride*(i+3*m));
1262 const std::complex<double> z4 = *(in+istride*(i+4*m));
1263 const std::complex<double> z5 = *(in+istride*(i+5*m));
1264 const std::complex<double> z6 = *(in+istride*(i+6*m));
1267 const std::complex<double> t0 = z1 + z6;
1268 const std::complex<double> t1 = z1 - z6;
1269 const std::complex<double> t2 = z2 + z5;
1270 const std::complex<double> t3 = z2 - z5;
1271 const std::complex<double> t4 = z4 + z3;
1272 const std::complex<double> t5 = z4 - z3;
1273 const std::complex<double> t6 = t2 + t0;
1274 const std::complex<double> t7 = t5 + t3;
1277 const std::complex<double> b0 = z0 + t6 + t4;
1278 const std::complex<double> b1 = tau1 * (t6 + t4);
1279 const std::complex<double> b2 = tau2 * (t0 - t4);
1280 const std::complex<double> b3 = tau3 * (t4 - t2);
1281 const std::complex<double> b4 = tau4 * (t2 - t0);
1282 const std::complex<double> b5 = double(-(
int)sign) * tau5 * (t7 + t1);
1283 const std::complex<double> b6 = double(-(
int)sign) * tau6 * (t1 - t5);
1284 const std::complex<double> b7 = double(-(
int)sign) * tau7 * (t5 - t3);
1285 const std::complex<double> b8 = double(-(
int)sign) * tau8 * (t3 - t1);
1288 const std::complex<double> T0 = b0 + b1;
1289 const std::complex<double> T1 = b2 + b3;
1290 const std::complex<double> T2 = b4 - b3;
1291 const std::complex<double> T3 = -b2 - b4;
1292 const std::complex<double> T4 = b6 + b7;
1293 const std::complex<double> T5 = b8 - b7;
1294 const std::complex<double> T6 = -b8 - b6;
1295 const std::complex<double> T7 = T0 + T1;
1296 const std::complex<double> T8 = T0 + T2;
1297 const std::complex<double> T9 = T0 + T3;
1298 const std::complex<double> T10 = T4 + b5;
1299 const std::complex<double> T11 = T5 + b5;
1300 const std::complex<double> T12 = T6 + b5;
1303 const std::complex<double> x0 = b0;
1304 const std::complex<double> x1 = T7 -
timesi(T10);
1305 const std::complex<double> x2 = T9 -
timesi(T12);
1306 const std::complex<double> x3 = T8 +
timesi(T11);
1307 const std::complex<double> x4 = T8 -
timesi(T11);
1308 const std::complex<double> x5 = T9 +
timesi(T12);
1309 const std::complex<double> x6 = T7 +
timesi(T10);
1312 *(out+ostride*j) = x0;
1313 *(out+ostride*(j+p_1)) = w[0] * x1;
1314 *(out+ostride*(j+2*p_1)) = w[1] * x2;
1315 *(out+ostride*(j+3*p_1)) = w[2] * x3;
1316 *(out+ostride*(j+4*p_1)) = w[3] * x4;
1317 *(out+ostride*(j+5*p_1)) = w[4] * x5;
1318 *(out+ostride*(j+6*p_1)) = w[5] * x6;
1345 std::complex<double>* out,
1355 const int m = n / factor;
1356 const int q = n / product;
1357 const int p_1 = product / factor;
1358 const int jump = (factor - 1) * p_1;
1361 for (
int i = 0; i < m; ++i) {
1362 *(out+ostride*i) = *(in+istride*i);
1366 for (
int e = 1; e < (factor - 1) / 2 + 1; ++e) {
1367 for (
int i = 0; i < m; ++i) {
1368 const int idx = i + e * m;
1369 const int idxc = i + (factor - e) * m;
1370 *(out+ostride*idx) = *(in+istride*idx) + *(in+istride*idxc);
1371 *(out+ostride*idxc) = *(in+istride*idx) - *(in+istride*idxc);
1376 for (
int i = 0; i < m; ++i) {
1377 *(in+istride*i) = *(out+ostride*i);
1379 for (
int e = 1; e < (factor - 1) / 2 + 1; ++e) {
1380 for (
int i = 0; i < m; ++i) {
1381 const int idx = i + e * m;
1382 *(in+istride*i) += *(out+ostride*idx);
1387 for (
int e = 1; e < (factor-1)/2 + 1; ++e) {
1391 const int idx_step = e * q;
1394 double w_real, w_imag;
1397 const int em = e * m;
1398 const int ecm = (factor - e) * m;
1401 for (
int i = 0; i < m; ++i) {
1402 *(in+istride*(i+em)) = *(out+ostride*i);
1403 *(in+istride*(i+ecm)) = *(out+ostride*i);
1407 for (
int e1 = 1; e1 < (factor - 1) / 2 + 1; ++e1) {
1417 int twiddle = index + idx - 1;
1421 w_real = wavetable[twiddle].real();
1422 w_imag = wavetable[twiddle].imag();
1427 w_real = wavetable[twiddle].real();
1428 w_imag = -wavetable[twiddle].imag();
1433 for (
int i = 0; i < m; ++i) {
1436 const double xp_real = (out+ostride*(i + e1 * m))->real();
1437 const double xp_imag = (out+ostride*(i + e1 * m))->imag();
1438 const double xm_real = (out+ostride*(i + (factor-e1)*m))->real();
1439 const double xm_imag = (out+ostride*(i + (factor-e1)*m))->imag();
1442 const double ap = w_real * xp_real;
1443 const double am = w_imag * xm_imag;
1446 double sum_real = ap - am;
1447 double sumc_real = ap + am;
1450 const double bp = w_real * xp_imag;
1451 const double bm = w_imag * xm_real;
1454 double sum_imag = bp + bm;
1455 double sumc_imag = bp - bm;
1458 *(in+istride*(i+em)) = std::complex<double>((in+istride*(i+em))->real() + sum_real,
1459 (in+istride*(i+em))->imag() + sum_imag);
1460 *(in+istride*(i+ecm)) = std::complex<double>((in+istride*(i+ecm))->real() + sumc_real,
1461 (in+istride*(i+ecm))->imag() + sumc_imag);
1475 for (
int k1 = 0; k1 < p_1; ++k1) {
1476 *(out+ostride*k1) = *(in+istride*k1);
1480 for (
int e1 = 1; e1 < factor; ++e1) {
1481 for (
int k1 = 0; k1 < p_1; ++k1) {
1482 *(out+ostride*(k1 + e1 * p_1)) = *(in+istride*(k1 + e1 * m));
1487 for (
int k = 1, i = p_1, j = product; k < q; ++k, j += jump) {
1488 for (
int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
1489 *(out+ostride*j) = *(in+istride*i);
1494 for (
int k = 1, i = p_1, j = product; k < q; ++k, j += jump) {
1496 for (
int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
1498 for (
int e1 = 1; e1 < factor; ++e1) {
1501 std::complex<double> x = *(in+istride*(i + e1 * m));
1504 int twiddle = index + (e1-1)*q + k-1;
1507 std::complex<double> w = (sign == -1)
1508 ? wavetable[twiddle]
1509 : std::conj(wavetable[twiddle]);
1512 *(out+ostride*(j + e1 * p_1)) = w * x;
1540 const int&
sign)
const
1543 std::vector<std::complex<double> > w(n);
1548 w.assign(n, std::complex<double>(1.0, 0.0));
1555 int twiddle = index + k - 1;
1559 for (
int i = 0; i < n; ++i, twiddle += q) {
1560 w[i] = wavetable[twiddle];
1567 for (
int i = 0; i < n; ++i, twiddle += q) {
1568 w[i] = std::conj(wavetable[twiddle]);
std::vector< int > m_shape
Array dimensions.
void factor3(const std::complex< double > *in, const int &istride, std::complex< double > *out, const int &ostride, const GFftWavetable &wavetable, const int &sign, const int &product, const int &n, const int &index)
Compute FFT for factor 3.
void factorn(std::complex< double > *in, const int &istride, std::complex< double > *out, const int &ostride, const GFftWavetable &wavetable, const int &sign, const int &factor, const int &product, const int &n, const int &index)
Compute FFT for arbitrary factor.
void set_data(const GNdarray &array)
Set data from n-dimensional array.
double norm(const GVector &vector)
Computes vector norm.
const std::vector< int > & strides(void) const
Return strides of array.
void forward(const GNdarray &array)
Forward Fast Fourier Transform.
GFft * clone(void) const
Clone Fast Fourier Transform.
std::string print(const GChatter &chatter=NORMAL) const
Print Fast Fourier Transform information.
std::complex< double > timesi(const std::complex< double > &value) const
Return complex value times i.
std::vector< std::complex< double > > get_w(const GFftWavetable &wavetable, const int &index, const int &k, const int &q, const int &n, const int &sign) const
Extract coefficients from wavetable.
void clear(void)
Clear Fast Fourier Transform.
GVector cos(const GVector &vector)
Computes cosine of vector elements.
std::complex< double > * m_data
Pointer on array data.
void factor5(const std::complex< double > *in, const int &istride, std::complex< double > *out, const int &ostride, const GFftWavetable &wavetable, const int &sign, const int &product, const int &n, const int &index)
Compute FFT for factor 5.
void init_members(void)
Initialise class members.
GFft & operator/=(const GFft &fft)
Unary division operator.
virtual ~GFft(void)
Destructor.
Lookup table class for Fast Fourier Transformation.
void transform(std::complex< double > *data, const int &stride, const int &n, const GFftWavetable &wavetable, const bool &forward=true)
Perform Fast Fourier Transform.
const std::vector< int > & shape(void) const
Return shape of array.
int size(void) const
Return number of elements in array.
GNdarray backward(void) const
Backward Fast Fourier Transform.
int m_size
Size of data array.
int factor(const int &index) const
Return factorisation factor.
GFft & operator-=(const GFft &fft)
Unary subtraction operator.
bool has_same_shape(const GFft &fft) const
Check if FFT has the same shape.
void free_members(void)
Delete class members.
GFft & operator=(const GFft &fft)
Assignment operator.
GFft & operator+=(const GFft &fft)
Unary addition operator.
void copy_members(const GFft &fft)
Copy class members.
GFft(void)
Void constructor.
std::vector< GFftWavetable > m_wavetable
Trigonometric coefficients.
GVector sqrt(const GVector &vector)
Computes square root of vector elements.
int factors(void) const
Return number of factorisation factors.
GFft & operator*=(const GFft &fft)
Unary multiplication operator.
N-dimensional array class interface definition.
Fast Fourier Transformation class.
void factor7(const std::complex< double > *in, const int &istride, std::complex< double > *out, const int &ostride, const GFftWavetable &wavetable, const int &sign, const int &product, const int &n, const int &index)
Compute FFT for factor 7.
std::vector< int > m_strides
Steps in each dimension.
GNdarray sign(const GNdarray &array)
Computes sign of array elements.
int size(void) const
Return number of elements in array.
void require_same_shape(const std::string &method, const GFft &fft) const
Throw exception if FFT shapes differ.
const int & index(const int &factor) const
Return start index for a given factor.
N-dimensional array class.
GFft operator-(void) const
Unary minus operator.
Fast Fourier transformation class interface definition.
const std::vector< int > & shape(void) const
Return shape of array.
void factor2(const std::complex< double > *in, const int &istride, std::complex< double > *out, const int &ostride, const GFftWavetable &wavetable, const int &sign, const int &product, const int &n, const int &index)
Compute FFT for factor 2.
int dim(void) const
Return dimension of Fast Fourier Transformation.
GVector sin(const GVector &vector)
Computes sine of vector elements.
Exception handler interface definition.
void factor6(const std::complex< double > *in, const int &istride, std::complex< double > *out, const int &ostride, const GFftWavetable &wavetable, const int &sign, const int &product, const int &n, const int &index)
Compute FFT for factor 6.
std::string parformat(const std::string &s, const int &indent=0)
Convert string in parameter format.
int dim(void) const
Return dimension of array.
void factor4(const std::complex< double > *in, const int &istride, std::complex< double > *out, const int &ostride, const GFftWavetable &wavetable, const int &sign, const int &product, const int &n, const int &index)
Compute FFT for factor 4.
Mathematical function definitions.
std::string str(const unsigned short int &value)
Convert unsigned short integer value into string.