Skip to content

Commit 68c3d7b

Browse files
committed
fft span fix
1 parent 613ee38 commit 68c3d7b

File tree

8 files changed

+37
-37
lines changed

8 files changed

+37
-37
lines changed

include/dsplib/fft.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,7 @@ class FftPlanC
2121
* @param x [in] input array[n]
2222
* @param r [out] result array[n]
2323
*/
24-
virtual void solve(span_t<cmplx_t> x, mut_span_t<cmplx_t> r) const {
25-
//default implementation
26-
const int n = this->size();
27-
DSPLIB_ASSERT(x.size() == r.size(), "input size error");
28-
DSPLIB_ASSERT(x.size() == n, "input size error");
29-
const auto y = this->solve(x);
30-
std::memcpy(r.data(), y.data(), n * sizeof(r[0]));
31-
}
24+
virtual void solve(span_t<cmplx_t> x, mut_span_t<cmplx_t> r) const = 0;
3225

3326
[[nodiscard]] virtual int size() const noexcept = 0;
3427
};
@@ -48,14 +41,7 @@ class FftPlanR
4841
* @param x [in] input array[n]
4942
* @param r [out] result array[n]
5043
*/
51-
virtual void solve(span_t<real_t> x, mut_span_t<cmplx_t> r) const {
52-
//TODO: support n/2+1 output size
53-
const int n = this->size();
54-
DSPLIB_ASSERT(x.size() == r.size(), "input size error");
55-
DSPLIB_ASSERT(x.size() == n, "input size error");
56-
const auto y = this->solve(x);
57-
std::memcpy(r.data(), y.data(), n * sizeof(r[0]));
58-
}
44+
virtual void solve(span_t<real_t> x, mut_span_t<cmplx_t> r) const = 0;
5945

6046
[[nodiscard]] virtual int size() const noexcept = 0;
6147
};

include/dsplib/ifft.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,7 @@ class IfftPlanR
2323
* @param x [in] input array[n]
2424
* @param r [out] result array[n]
2525
*/
26-
virtual void solve(span_t<cmplx_t> x, mut_span_t<real_t> r) const {
27-
const int n = this->size();
28-
DSPLIB_ASSERT(x.size() == r.size(), "input size error");
29-
DSPLIB_ASSERT(x.size() == n, "input size error");
30-
const auto y = this->solve(x);
31-
std::memcpy(r.data(), y.data(), n * sizeof(r[0]));
32-
}
26+
virtual void solve(span_t<cmplx_t> x, mut_span_t<real_t> r) const = 0;
3327

3428
[[nodiscard]] virtual int size() const noexcept = 0;
3529
};

lib/fft/fact-fft.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class FactorFFTPlan : public FftPlanC
1515
public:
1616
explicit FactorFFTPlan(int n);
1717
~FactorFFTPlan() override = default;
18+
1819
[[nodiscard]] arr_cmplx solve(span_t<cmplx_t> x) const final;
1920
void solve(span_t<cmplx_t> x, mut_span_t<cmplx_t> r) const final;
2021
[[nodiscard]] int size() const noexcept final;
@@ -32,13 +33,17 @@ class FactorFFTPlanR : public FftPlanR
3233
: _plan{n} {
3334
}
3435

35-
~FactorFFTPlanR() = default;
36+
~FactorFFTPlanR() override = default;
3637

3738
[[nodiscard]] arr_cmplx solve(span_t<real_t> x) const final {
3839
//TODO: real optimization (for odd sizes)
3940
return _plan.solve(complex(x));
4041
}
4142

43+
void solve(span_t<real_t> x, mut_span_t<cmplx_t> r) const final {
44+
_plan.solve(complex(x), r);
45+
}
46+
4247
[[nodiscard]] int size() const noexcept final {
4348
return _plan.size();
4449
}

lib/fft/primes-fft.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ class PrimesFftR : public FftPlanR
102102
return plan_.solve(complex(x));
103103
}
104104

105+
void solve(span_t<real_t> x, mut_span_t<cmplx_t> r) const final {
106+
plan_.solve(complex(x), r);
107+
}
108+
105109
[[nodiscard]] int size() const noexcept final {
106110
return plan_.size();
107111
}

lib/fft/real-fft.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,39 +14,43 @@ RealFftPlan::RealFftPlan(int n)
1414
}
1515

1616
arr_cmplx RealFftPlan::solve(span_t<real_t> x) const {
17+
arr_cmplx r(n_);
18+
this->solve(x, r);
19+
return r;
20+
}
21+
22+
void RealFftPlan::solve(span_t<real_t> x, mut_span_t<cmplx_t> r) const {
1723
using namespace std::complex_literals;
1824
DSPLIB_ASSERT(x.size() == n_, "Input size must be equal FFT size");
25+
//TODO: n/2+1 size support
26+
DSPLIB_ASSERT(r.size() == n_, "Output size must be equal FFT size");
1927
const int n2 = n_ / 2;
2028

2129
arr_cmplx z(span(reinterpret_cast<const cmplx_t*>(x.data()), n2));
2230
const auto Z = fft_->solve(z * 0.5);
2331

24-
arr_cmplx res(n_);
25-
2632
{
2733
const auto Xe = Z[0] + conj(Z[0]);
2834
const auto Xo = (conj(Z[0]) - Z[0]) * w_[0];
29-
res[0].re = Xe.re - Xo.im;
30-
res[0].im = Xe.im + Xo.re;
35+
r[0].re = Xe.re - Xo.im;
36+
r[0].im = Xe.im + Xo.re;
3137
}
3238

3339
for (int i = 1; i < n2; ++i) {
3440
const auto Zc = conj(Z[n2 - i]);
3541
const auto Xe = Z[i] + Zc;
3642
const auto Xo = (Zc - Z[i]) * w_[i];
37-
res[i].re = Xe.re - Xo.im;
38-
res[i].im = Xe.im + Xo.re;
39-
res[n_ - i].re = res[i].re;
40-
res[n_ - i].im = -res[i].im;
43+
r[i].re = Xe.re - Xo.im;
44+
r[i].im = Xe.im + Xo.re;
45+
r[n_ - i].re = r[i].re;
46+
r[n_ - i].im = -r[i].im;
4147
}
4248

4349
{
4450
const auto Xe = Z[0] + conj(Z[0]);
4551
const auto Xo = conj(Z[0]) - Z[0];
46-
res[n2] = Xe.re + Xo.im;
52+
r[n2] = Xe.re + Xo.im;
4753
}
48-
49-
return res;
5054
}
5155

5256
int RealFftPlan::size() const noexcept {

lib/fft/real-fft.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class RealFftPlan : public FftPlanR
99
public:
1010
explicit RealFftPlan(int n);
1111
[[nodiscard]] arr_cmplx solve(span_t<real_t> x) const final;
12+
void solve(span_t<real_t> x, mut_span_t<cmplx_t> r) const final;
1213
[[nodiscard]] int size() const noexcept final;
1314

1415
private:

lib/fft/real-ifft.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,15 @@ RealIfftPlan::RealIfftPlan(int n)
3232
}
3333

3434
arr_real RealIfftPlan::solve(span_t<cmplx_t> x) const {
35+
arr_real r(n_);
36+
this->solve(x, r);
37+
return r;
38+
}
39+
40+
void RealIfftPlan::solve(span_t<cmplx_t> x, mut_span_t<real_t> r) const {
3541
assert(n_ % 2 == 0);
3642
DSPLIB_ASSERT((x.size() == n_) || (x.size() == n_ / 2 + 1), "input size must be n/2+1 or n");
43+
DSPLIB_ASSERT(r.size() == n_, "output size must be n");
3744

3845
const real_t dn = real_t(1) / n_;
3946
std::vector<cmplx_t> Z(n_ / 2);
@@ -46,12 +53,10 @@ arr_real RealIfftPlan::solve(span_t<cmplx_t> x) const {
4653
}
4754

4855
const auto z = fft_->solve(Z);
49-
std::vector<real_t> r(n_);
5056
for (int i = 0; i < n_ / 2; ++i) {
5157
r[2 * i] = z[i].re;
5258
r[2 * i + 1] = -z[i].im;
5359
}
54-
return r;
5560
}
5661

5762
int RealIfftPlan::size() const noexcept {

lib/fft/real-ifft.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class RealIfftPlan : public IfftPlanR
1010
public:
1111
explicit RealIfftPlan(int n);
1212
[[nodiscard]] arr_real solve(span_t<cmplx_t>) const final;
13+
void solve(span_t<cmplx_t> x, mut_span_t<real_t> r) const final;
1314
[[nodiscard]] int size() const noexcept final;
1415

1516
private:

0 commit comments

Comments
 (0)