22#include < dsplib/fft.h>
33#include < dsplib/math.h>
44
5- namespace dsplib {
6-
7- namespace {
5+ #include " fft/factory.h"
86
9- void _inplace_conj (arr_cmplx& x) {
10- for (auto & v : x) {
11- v.im = -v.im ;
12- }
13- }
14-
15- std::vector<cmplx_t > _irfft_coeffs (int n) noexcept {
16- assert (n % 4 == 0 );
17- const int n4 = n / 4 ;
18- const int n2 = n / 2 ;
19- std::vector<cmplx_t > res (n / 2 );
20- res[0 ] = {1 , 0 };
21- res[n4] = {0 , 1 };
22- // use only first n/4 samples
23- for (int i = 1 ; i < n4; ++i) {
24- const auto v = std::cos (2 * pi * i / n);
25- res[i].re = v;
26- res[n2 - i].re = -v;
27- res[n4 + i].im = v;
28- res[n4 - i].im = v;
29- }
30- return res;
31- }
32-
33- } // namespace
7+ namespace dsplib {
348
359// ---------------------------------------------------------------------------------
3610IfftPlan::IfftPlan (int n)
37- : _d{std::make_shared<FftPlan> (n)} {
11+ : ifft_{ create_ifft_plan (n)} {
3812}
3913
4014arr_cmplx IfftPlan::operator ()(const arr_cmplx& x) const {
4115 return this ->solve (x);
4216}
4317
4418arr_cmplx IfftPlan::solve (const arr_cmplx& x) const {
45- const real_t m = real_t (1 ) / x.size ();
46- arr_cmplx y = x * m;
47- _inplace_conj (y);
48- y = _d->solve (y);
49- _inplace_conj (y);
50- return y;
19+ return ifft_->solve (x);
5120}
5221
5322int IfftPlan::size () const noexcept {
54- return _d ->size ();
23+ return ifft_ ->size ();
5524}
5625
5726// ---------------------------------------------------------------------------------
5827IfftPlanR::IfftPlanR (int n)
59- : _n{n}
60- , _d{std::make_shared<FftPlan>(n / 2 )}
61- , _w(_irfft_coeffs(n)) {
62- DSPLIB_ASSERT (n % 2 == 0 , " ifft size must be even" );
28+ : ifft_{create_irfft_plan (n)} {
6329}
6430
6531arr_real IfftPlanR::operator ()(const arr_cmplx& x) const {
6632 return this ->solve (x);
6733}
6834
6935arr_real IfftPlanR::solve (const arr_cmplx& x) const {
70- assert (_n % 2 == 0 );
71- DSPLIB_ASSERT ((x.size () == _n) || (x.size () == _n / 2 + 1 ), " input size must be n/2+1 or n" );
72-
73- const real_t dn = real_t (1 ) / _n;
74- std::vector<cmplx_t > Z (_n / 2 );
75- for (int i = 0 ; i < _n / 2 ; ++i) {
76- const auto v = conj (x[_n / 2 - i]);
77- const cmplx_t Xe = (x[i] + v) * dn;
78- const cmplx_t Xo = (x[i] - v) * dn * _w[i];
79- Z[i].re = Xe.re - Xo.im ;
80- Z[i].im = -Xe.im - Xo.re ;
81- }
82-
83- const auto z = _d->solve (Z);
84- std::vector<real_t > r (_n);
85- for (int i = 0 ; i < _n / 2 ; ++i) {
86- r[2 * i] = z[i].re ;
87- r[2 * i + 1 ] = -z[i].im ;
88- }
89- return r;
36+ return ifft_->solve (x);
9037}
9138
9239int IfftPlanR::size () const noexcept {
93- return _n ;
40+ return ifft_-> size () ;
9441}
9542
9643// ---------------------------------------------------------------------------------
@@ -104,7 +51,6 @@ arr_real irfft(const arr_cmplx& x) {
10451}
10552
10653arr_real irfft (const arr_cmplx& x, int n) {
107- // FIXIT: _irfft_coeffs overhead, use cache
10854 IfftPlanR plan (n);
10955 return plan (x);
11056}
0 commit comments