aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhayati ayguen <h_ayguen@web.de>2020-04-02 23:11:14 +0200
committerhayati ayguen <h_ayguen@web.de>2020-04-02 23:11:14 +0200
commit5553119edd8b4fbdcdd7770aea45246c32f97e26 (patch)
tree7795547312989d980cb32091f3041664c2846f02
parent2a5336ab689ab95a7fb3eebbbbbecae3a1db1c57 (diff)
downloadpffft-5553119edd8b4fbdcdd7770aea45246c32f97e26.tar.gz
define/use pffft::AlignedVector<> with example use in test_pffft.cpp
* examples: see test_pffft.cpp at begin of template function Ttest() * added typedef pffft::Fft<>::Complex besides Scalar Signed-off-by: hayati ayguen <h_ayguen@web.de>
-rw-r--r--pffft.hpp116
-rw-r--r--test_pffft.cpp50
2 files changed, 84 insertions, 82 deletions
diff --git a/pffft.hpp b/pffft.hpp
index 7a72c0e..3653fe4 100644
--- a/pffft.hpp
+++ b/pffft.hpp
@@ -44,18 +44,32 @@ namespace pffft {
// enum { PFFFT_REAL, PFFFT_COMPLEX }
typedef pffft_transform_t TransformType;
-template<typename T>
-class PFAlloc;
+// helper to define 'Scalar' and 'Complex' (in namespace pffft)
+template<typename T> struct Types {};
+template<> struct Types<float> { typedef float Scalar; typedef std::complex<Scalar> Complex; };
+template<> struct Types<double> { typedef double Scalar; typedef std::complex<Scalar> Complex; };
+template<> struct Types< std::complex<float> > { typedef float Scalar; typedef std::complex<float> Complex; };
+template<> struct Types< std::complex<double> > { typedef double Scalar; typedef std::complex<double> Complex; };
+
+// Allocator
+template<typename T> class PFAlloc;
namespace {
-template<typename T>
-class Setup;
+ template<typename T> class Setup;
}
-#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
+#if (__cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900))
template<typename T>
-using AlignedVector = typename std::vector< T, PFAlloc<T> > ;
+using AlignedVector = typename std::vector< T, PFAlloc<T> >;
+
+#else
+
+template <typename T>
+struct AlignedVector : public std::vector< T, PFAlloc<T> > {
+ AlignedVector() : std::vector< T, PFAlloc<T> >() { }
+ AlignedVector(int N) : std::vector< T, PFAlloc<T> >(N) { }
+};
#endif
@@ -64,23 +78,9 @@ template<typename T>
class Fft
{
public:
- typedef typename Setup<T>::Scalar Scalar;
typedef T value_type;
-
-#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
-
- using ValueVector = AlignedVector<T>;
- using ComplexVector = AlignedVector<std::complex<Scalar>>;
- using InternalLayoutVector = AlignedVector<Scalar>;
-
-#else
-
- typedef std::vector< T, PFAlloc<T> > ValueVector;
- typedef std::vector< std::complex<Scalar>, PFAlloc< std::complex<Scalar> > > ComplexVector;
- typedef std::vector< Scalar, PFAlloc<Scalar> > InternalLayoutVector;
-
-#endif
-
+ typedef typename Types<T>::Scalar Scalar;
+ typedef typename Types<T>::Complex Complex;
// static retrospection functions
@@ -117,11 +117,11 @@ public:
////
////////////////////////////////////////////
- ValueVector valueVector() const { return ValueVector(length); }
+ AlignedVector<T> valueVector() const { return AlignedVector<T>(length); }
- ComplexVector spectrumVector() const { return ComplexVector( getSpectrumSize() ); }
+ AlignedVector<Complex> spectrumVector() const { return AlignedVector<Complex>( getSpectrumSize() ); }
- InternalLayoutVector internalLayoutVector() const { return InternalLayoutVector( getInternalLayoutSize() ); }
+ AlignedVector<Scalar> internalLayoutVector() const { return AlignedVector<Scalar>( getInternalLayoutSize() ); }
////////////////////////////////////////////
// although using Vectors for output ..
@@ -129,10 +129,10 @@ public:
// core API, having the spectrum in canonical order
- ComplexVector& forward(const ValueVector& input, ComplexVector& spectrum)
+ AlignedVector<Complex> & forward(const AlignedVector<T> & input, AlignedVector<Complex> & spectrum)
{ forward( input.data(), spectrum.data() ); return spectrum; }
- ValueVector& inverse(const ComplexVector& spectrum, ValueVector& output)
+ AlignedVector<T> & inverse(const AlignedVector<Complex> & spectrum, AlignedVector<T> & output)
{ inverse( spectrum.data(), output.data() ); return output; }
// provide additional functions with spectrum in some internal Layout.
@@ -140,36 +140,36 @@ public:
// these are useful in special applications, like fast convolution,
// where inverse() is following anyway ..
- InternalLayoutVector& forwardToInternalLayout(
- const ValueVector& input,
- InternalLayoutVector& spectrum_internal_layout
+ AlignedVector<Scalar> & forwardToInternalLayout(
+ const AlignedVector<T> & input,
+ AlignedVector<Scalar> & spectrum_internal_layout
)
{ forwardToInternalLayout( input.data(), spectrum_internal_layout.data() ); return spectrum_internal_layout; }
- ValueVector& inverseFromInternalLayout(
- const InternalLayoutVector& spectrum_internal_layout,
- ValueVector& output
+ AlignedVector<T> & inverseFromInternalLayout(
+ const AlignedVector<Scalar> & spectrum_internal_layout,
+ AlignedVector<T> & output
)
{ inverseFromInternalLayout( spectrum_internal_layout.data(), output.data() ); return output; }
void reorderSpectrum(
- const InternalLayoutVector& input,
- ComplexVector &output
+ const AlignedVector<Scalar> & input,
+ AlignedVector<Complex> & output
)
{ reorderSpectrum( input.data(), output.data() ); }
- InternalLayoutVector& convolveAccumulate(
- const InternalLayoutVector& spectrum_internal_a,
- const InternalLayoutVector& spectrum_internal_b,
- InternalLayoutVector& spectrum_internal_ab,
+ AlignedVector<Scalar> & convolveAccumulate(
+ const AlignedVector<Scalar> & spectrum_internal_a,
+ const AlignedVector<Scalar> & spectrum_internal_b,
+ AlignedVector<Scalar> & spectrum_internal_ab,
const Scalar scaling
)
{ convolveAccumulate( spectrum_internal_a.data(), spectrum_internal_b.data(), spectrum_internal_ab.data(), scaling ); return spectrum_internal_ab; }
- InternalLayoutVector& convolve(
- const InternalLayoutVector& spectrum_internal_a,
- const InternalLayoutVector& spectrum_internal_b,
- InternalLayoutVector& spectrum_internal_ab,
+ AlignedVector<Scalar> & convolve(
+ const AlignedVector<Scalar> & spectrum_internal_a,
+ const AlignedVector<Scalar> & spectrum_internal_b,
+ AlignedVector<Scalar> & spectrum_internal_ab,
const Scalar scaling
)
{ convolve( spectrum_internal_a.data(), spectrum_internal_b.data(), spectrum_internal_ab.data(), scaling ); return spectrum_internal_ab; }
@@ -193,13 +193,13 @@ public:
static Scalar* alignedAllocScalar(int length);
- static std::complex<Scalar>* alignedAllocComplex(int length);
+ static Complex* alignedAllocComplex(int length);
// core API, having the spectrum in canonical order
- std::complex<Scalar>* forward(const T* input, std::complex<Scalar>* spectrum);
+ Complex* forward(const T* input, Complex* spectrum);
- T* inverse(const std::complex<Scalar>* spectrum, T* output);
+ T* inverse(const Complex* spectrum, T* output);
// provide additional functions with spectrum in some internal Layout.
@@ -212,7 +212,7 @@ public:
T* inverseFromInternalLayout(const Scalar* spectrum_internal_layout, T* output);
- void reorderSpectrum(const Scalar* input, std::complex<Scalar>* output );
+ void reorderSpectrum(const Scalar* input, Complex* output );
Scalar* convolveAccumulate(const Scalar* spectrum_internal_a,
const Scalar* spectrum_internal_b,
@@ -276,7 +276,7 @@ alignedFree(void* ptr)
namespace {
template<typename T>
-struct Setup
+class Setup
{};
template<>
@@ -285,8 +285,8 @@ class Setup<float>
PFFFT_Setup* self;
public:
- typedef float Scalar;
typedef float value_type;
+ typedef Types< value_type >::Scalar Scalar;
Setup()
: self(NULL)
@@ -358,8 +358,8 @@ class Setup< std::complex<float> >
PFFFT_Setup* self;
public:
- typedef float Scalar;
typedef std::complex<float> value_type;
+ typedef Types< value_type >::Scalar Scalar;
Setup()
: self(NULL)
@@ -423,8 +423,8 @@ class Setup<double>
PFFFTD_Setup* self;
public:
- typedef double Scalar;
typedef double value_type;
+ typedef Types< value_type >::Scalar Scalar;
Setup()
: self(NULL)
@@ -499,8 +499,8 @@ class Setup< std::complex<double> >
PFFFTD_Setup* self;
public:
- typedef double Scalar;
typedef std::complex<double> value_type;
+ typedef Types< value_type >::Scalar Scalar;
Setup()
: self(NULL)
@@ -611,8 +611,8 @@ Fft<T>::prepareLength(int newLength)
}
template<typename T>
-inline std::complex<typename Fft<T>::Scalar>*
-Fft<T>::forward(const T* input, std::complex<Scalar>* spectrum)
+inline typename Fft<T>::Complex *
+Fft<T>::forward(const T* input, Complex * spectrum)
{
setup.transform_ordered(reinterpret_cast<const Scalar*>(input),
reinterpret_cast<Scalar*>(spectrum),
@@ -623,7 +623,7 @@ Fft<T>::forward(const T* input, std::complex<Scalar>* spectrum)
template<typename T>
inline T*
-Fft<T>::inverse(std::complex<Scalar> const* spectrum, T* output)
+Fft<T>::inverse(Complex const* spectrum, T* output)
{
setup.transform_ordered(reinterpret_cast<const Scalar*>(spectrum),
reinterpret_cast<Scalar*>(output),
@@ -656,7 +656,7 @@ Fft<T>::inverseFromInternalLayout(const Scalar* spectrum_internal_layout, T* out
template<typename T>
inline void
-Fft<T>::reorderSpectrum( const Scalar* input, std::complex<Scalar>* output )
+Fft<T>::reorderSpectrum( const Scalar* input, Complex* output )
{
setup.reorder(input, reinterpret_cast<Scalar*>(output), PFFFT_FORWARD);
}
@@ -706,10 +706,10 @@ pffft::Fft<T>::alignedAllocScalar(int length)
}
template<typename T>
-inline std::complex<typename pffft::Fft<T>::Scalar>*
+inline typename Fft<T>::Complex *
Fft<T>::alignedAllocComplex(int length)
{
- return reinterpret_cast< std::complex<Scalar>* >( Setup<T>::allocate(2 * length) );
+ return reinterpret_cast< Complex* >( Setup<T>::allocate(2 * length) );
}
diff --git a/test_pffft.cpp b/test_pffft.cpp
index 08dbdaf..f245a1f 100644
--- a/test_pffft.cpp
+++ b/test_pffft.cpp
@@ -60,44 +60,46 @@ template<typename T>
bool
Ttest(int N, bool useOrdered)
{
- typedef typename pffft::Fft<T> Fft;
- typedef typename Fft::Scalar Scalar;
-
- const bool cplx = Fft::isComplexTransform();
+ typedef pffft::Fft<T> Fft;
+ typedef typename pffft::Fft<T>::Scalar FftScalar;
+ typedef typename Fft::Complex FftComplex;
+ const bool cplx = pffft::Fft<T>::isComplexTransform();
const double EXPECTED_DYN_RANGE = Fft::isDoubleScalar() ? 215.0 : 140.0;
- int k, j, m, iter, kmaxOther;
- bool retError = false;
- double freq, dPhi, phi, phi0;
- double pwr, pwrCar, pwrOther, err, errSum, mag, expextedMag;
- double amp = 1.0;
-
assert(pffft::isPowerOfTwo(N));
Fft fft = Fft(N); // instantiate and prepareLength() for length N
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)
- pffft::AlignedVector<T> X = fft.valueVector(); // for X = input vector
- pffft::AlignedVector<std::complex<Scalar>> Y = fft.spectrumVector(); // for Y = forward(X)
- pffft::AlignedVector<Scalar> R = fft.internalLayoutVector(); // for R = forwardInternalLayout(X)
- pffft::AlignedVector<T> Z = fft.valueVector(); // for Z = inverse(Y) = inverse( forward(X) )
- // or Z = inverseInternalLayout(R)
+ // possible ways to declare/instatiate aligned vectors with C++11
+ // some lines require a typedef of above
+ auto X = fft.valueVector(); // for X = input vector
+ pffft::AlignedVector<typename Fft::Complex> Y = fft.spectrumVector(); // for Y = forward(X)
+ pffft::AlignedVector<FftScalar> R = fft.internalLayoutVector(); // for R = forwardInternalLayout(X)
+ pffft::AlignedVector<T> Z = fft.valueVector(); // for Z = inverse(Y) = inverse( forward(X) )
+ // or Z = inverseInternalLayout(R)
#else
-// with C++11 and auto - this gets a bit easier
- typename Fft::ValueVector X = fft.valueVector(); // for X = input vector
- typename Fft::ComplexVector Y = fft.spectrumVector(); // for Y = forward(X)
- typename Fft::InternalLayoutVector R = fft.internalLayoutVector(); // for R = forwardInternalLayout(X)
- typename Fft::ValueVector Z = fft.valueVector(); // for Z = inverse(Y) = inverse( forward(X) )
- // or Z = inverseInternalLayout(R)
+ // possible ways to declare/instatiate aligned vectors with C++98
+ pffft::AlignedVector<T> X = fft.valueVector(); // for X = input vector
+ pffft::AlignedVector<FftComplex> Y = fft.spectrumVector(); // for Y = forward(X)
+ pffft::AlignedVector<typename Fft::Scalar> R = fft.internalLayoutVector(); // for R = forwardInternalLayout(X)
+ pffft::AlignedVector<T> Z = fft.valueVector(); // for Z = inverse(Y) = inverse( forward(X) )
+ // or Z = inverseInternalLayout(R)
#endif
// work with complex - without the capabilities of a higher c++ standard
- Scalar* Xs = reinterpret_cast<Scalar*>(X.data()); // for X = input vector
- Scalar* Ys = reinterpret_cast<Scalar*>(Y.data()); // for Y = forward(X)
- Scalar* Zs = reinterpret_cast<Scalar*>(Z.data()); // for Z = inverse(Y) = inverse( forward(X) )
+ FftScalar* Xs = reinterpret_cast<FftScalar*>(X.data()); // for X = input vector
+ FftScalar* Ys = reinterpret_cast<FftScalar*>(Y.data()); // for Y = forward(X)
+ FftScalar* Zs = reinterpret_cast<FftScalar*>(Z.data()); // for Z = inverse(Y) = inverse( forward(X) )
+
+ int k, j, m, iter, kmaxOther;
+ bool retError = false;
+ double freq, dPhi, phi, phi0;
+ double pwr, pwrCar, pwrOther, err, errSum, mag, expextedMag;
+ double amp = 1.0;
for (k = m = 0; k < (cplx ? N : (1 + N / 2)); k += N / 16, ++m) {
amp = ((m % 3) == 0) ? 1.0F : 1.1F;