add pffft
This commit is contained in:
63
pffft/examples/CMakeLists.txt
Normal file
63
pffft/examples/CMakeLists.txt
Normal file
@@ -0,0 +1,63 @@
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(examples)
|
||||
|
||||
if ( CMAKE_C_COMPILER_ID MATCHES "MSVC" )
|
||||
# using Visual Studio C++
|
||||
message(STATUS "INFO: detected MSVC: will not link math lib m")
|
||||
set(MATHLIB "")
|
||||
add_definitions("/D_CRT_SECURE_NO_WARNINGS")
|
||||
set(MSVC_DISABLED_WARNINGS_LIST "C4996")
|
||||
else()
|
||||
if(PFFFT_DISABLE_LINK_WITH_M)
|
||||
else()
|
||||
message(STATUS "INFO: detected NO MSVC: ${CMAKE_C_COMPILER_ID}: will link math lib m")
|
||||
set(MATHLIB "m")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(STDCXXLIB "")
|
||||
if (MINGW)
|
||||
set(STDCXXLIB "stdc++")
|
||||
endif()
|
||||
|
||||
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
|
||||
if (PFFFT_USE_TYPE_DOUBLE)
|
||||
add_executable(example_cpp11_real_dbl_fwd example_cpp11_real_dbl_fwd.cpp)
|
||||
target_compile_definitions(example_cpp11_real_dbl_fwd PRIVATE PFFFT_ENABLE_DOUBLE)
|
||||
target_link_libraries(example_cpp11_real_dbl_fwd PFFFT ${STDCXXLIB} ${MATHLIB})
|
||||
set_property(TARGET example_cpp11_real_dbl_fwd PROPERTY CXX_STANDARD 11)
|
||||
set_property(TARGET example_cpp11_real_dbl_fwd PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_executable(example_cpp11_cplx_dbl_fwd example_cpp11_cplx_dbl_fwd.cpp)
|
||||
target_compile_definitions(example_cpp11_cplx_dbl_fwd PRIVATE PFFFT_ENABLE_DOUBLE)
|
||||
target_link_libraries(example_cpp11_cplx_dbl_fwd PFFFT ${STDCXXLIB} ${MATHLIB})
|
||||
set_property(TARGET example_cpp11_cplx_dbl_fwd PROPERTY CXX_STANDARD 11)
|
||||
set_property(TARGET example_cpp11_cplx_dbl_fwd PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_executable(example_c_cplx_dbl_fwd example_c_cplx_dbl_fwd.c)
|
||||
target_compile_definitions(example_c_cplx_dbl_fwd PRIVATE PFFFT_ENABLE_FLOAT)
|
||||
target_link_libraries(example_c_cplx_dbl_fwd PFFFT ${MATHLIB})
|
||||
endif()
|
||||
|
||||
|
||||
if (PFFFT_USE_TYPE_FLOAT)
|
||||
add_executable(example_cpp98_real_flt_fwd example_cpp98_real_flt_fwd.cpp)
|
||||
target_compile_definitions(example_cpp98_real_flt_fwd PRIVATE PFFFT_ENABLE_FLOAT)
|
||||
target_link_libraries(example_cpp98_real_flt_fwd PFFFT ${STDCXXLIB} ${MATHLIB})
|
||||
set_property(TARGET example_cpp98_real_flt_fwd PROPERTY CXX_STANDARD 98)
|
||||
set_property(TARGET example_cpp98_real_flt_fwd PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_executable(example_cpp98_cplx_flt_fwd example_cpp98_cplx_flt_fwd.cpp)
|
||||
target_compile_definitions(example_cpp98_cplx_flt_fwd PRIVATE PFFFT_ENABLE_FLOAT)
|
||||
target_link_libraries(example_cpp98_cplx_flt_fwd PFFFT ${STDCXXLIB} ${MATHLIB})
|
||||
set_property(TARGET example_cpp98_cplx_flt_fwd PROPERTY CXX_STANDARD 98)
|
||||
set_property(TARGET example_cpp98_cplx_flt_fwd PROPERTY CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
add_executable(example_c_real_flt_fwd example_c_real_flt_fwd.c)
|
||||
target_compile_definitions(example_c_real_flt_fwd PRIVATE PFFFT_ENABLE_FLOAT)
|
||||
target_link_libraries(example_c_real_flt_fwd PFFFT ${MATHLIB})
|
||||
endif()
|
||||
|
||||
69
pffft/examples/example_c_cplx_dbl_fwd.c
Normal file
69
pffft/examples/example_c_cplx_dbl_fwd.c
Normal file
@@ -0,0 +1,69 @@
|
||||
|
||||
#include "pffft_double.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
void c_forward_complex_double(const int transformLen)
|
||||
{
|
||||
printf("running %s()\n", __FUNCTION__);
|
||||
|
||||
/* first check - might be skipped */
|
||||
if (transformLen < pffftd_min_fft_size(PFFFT_COMPLEX))
|
||||
{
|
||||
fprintf(stderr, "Error: minimum FFT transformation length is %d\n", pffftd_min_fft_size(PFFFT_COMPLEX));
|
||||
return;
|
||||
}
|
||||
|
||||
/* instantiate FFT and prepare transformation for length N */
|
||||
PFFFTD_Setup *ffts = pffftd_new_setup(transformLen, PFFFT_COMPLEX);
|
||||
|
||||
/* one more check */
|
||||
if (!ffts)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Error: transformation length %d is not decomposable into small prime factors. "
|
||||
"Next valid transform size is: %d ; next power of 2 is: %d\n",
|
||||
transformLen,
|
||||
pffftd_nearest_transform_size(transformLen, PFFFT_COMPLEX, 1),
|
||||
pffftd_next_power_of_two(transformLen) );
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate aligned vectors for input X and output Y */
|
||||
double *X = (double*)pffftd_aligned_malloc(transformLen * 2 * sizeof(double)); /* complex: re/im interleaved */
|
||||
double *Y = (double*)pffftd_aligned_malloc(transformLen * 2 * sizeof(double)); /* complex: re/im interleaved */
|
||||
double *W = (double*)pffftd_aligned_malloc(transformLen * 2 * sizeof(double));
|
||||
|
||||
/* prepare some input data */
|
||||
for (int k = 0; k < 2 * transformLen; k += 4)
|
||||
{
|
||||
X[k] = k / 2; /* real */
|
||||
X[k+1] = (k / 2) & 1; /* imag */
|
||||
|
||||
X[k+2] = -1 - k / 2; /* real */
|
||||
X[k+3] = (k / 2) & 1; /* imag */
|
||||
}
|
||||
|
||||
/* do the forward transform; write complex spectrum result into Y */
|
||||
pffftd_transform_ordered(ffts, X, Y, W, PFFFT_FORWARD);
|
||||
|
||||
/* print spectral output */
|
||||
printf("output should be complex spectrum with %d complex bins\n", transformLen);
|
||||
for (int k = 0; k < 2 * transformLen; k += 2)
|
||||
printf("Y[%d] = %f + i * %f\n", k/2, Y[k], Y[k+1]);
|
||||
|
||||
pffftd_aligned_free(W);
|
||||
pffftd_aligned_free(Y);
|
||||
pffftd_aligned_free(X);
|
||||
pffftd_destroy_setup(ffts);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int N = (1 < argc) ? atoi(argv[1]) : 16;
|
||||
c_forward_complex_double(N);
|
||||
return 0;
|
||||
}
|
||||
66
pffft/examples/example_c_real_flt_fwd.c
Normal file
66
pffft/examples/example_c_real_flt_fwd.c
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
#include "pffft.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
void c_forward_real_float(const int transformLen)
|
||||
{
|
||||
printf("running %s()\n", __FUNCTION__);
|
||||
|
||||
/* first check - might be skipped */
|
||||
if (transformLen < pffft_min_fft_size(PFFFT_REAL))
|
||||
{
|
||||
fprintf(stderr, "Error: minimum FFT transformation length is %d\n", pffft_min_fft_size(PFFFT_REAL));
|
||||
return;
|
||||
}
|
||||
|
||||
/* instantiate FFT and prepare transformation for length N */
|
||||
PFFFT_Setup *ffts = pffft_new_setup(transformLen, PFFFT_REAL);
|
||||
|
||||
/* one more check */
|
||||
if (!ffts)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Error: transformation length %d is not decomposable into small prime factors. "
|
||||
"Next valid transform size is: %d ; next power of 2 is: %d\n",
|
||||
transformLen,
|
||||
pffft_nearest_transform_size(transformLen, PFFFT_REAL, 1),
|
||||
pffft_next_power_of_two(transformLen) );
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate aligned vectors for input X and output Y */
|
||||
float *X = (float*)pffft_aligned_malloc(transformLen * sizeof(float));
|
||||
float *Y = (float*)pffft_aligned_malloc(transformLen * sizeof(float)); /* complex: re/im interleaved */
|
||||
float *W = (float*)pffft_aligned_malloc(transformLen * sizeof(float));
|
||||
|
||||
/* prepare some input data */
|
||||
for (int k = 0; k < transformLen; k += 2)
|
||||
{
|
||||
X[k] = k;
|
||||
X[k+1] = -1-k;
|
||||
}
|
||||
|
||||
/* do the forward transform; write complex spectrum result into Y */
|
||||
pffft_transform_ordered(ffts, X, Y, W, PFFFT_FORWARD);
|
||||
|
||||
/* print spectral output */
|
||||
printf("output should be complex spectrum with %d complex bins\n", transformLen /2);
|
||||
for (int k = 0; k < transformLen; k += 2)
|
||||
printf("Y[%d] = %f + i * %f\n", k/2, Y[k], Y[k+1]);
|
||||
|
||||
pffft_aligned_free(W);
|
||||
pffft_aligned_free(Y);
|
||||
pffft_aligned_free(X);
|
||||
pffft_destroy_setup(ffts);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int N = (1 < argc) ? atoi(argv[1]) : 32;
|
||||
c_forward_real_float(N);
|
||||
return 0;
|
||||
}
|
||||
66
pffft/examples/example_cpp11_cplx_dbl_fwd.cpp
Normal file
66
pffft/examples/example_cpp11_cplx_dbl_fwd.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
#include "pffft.hpp"
|
||||
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
void cxx11_forward_complex_double(const int transformLen)
|
||||
{
|
||||
std::cout << "running " << __FUNCTION__ << "()" << std::endl;
|
||||
|
||||
// first check - might be skipped
|
||||
using FFT_T = pffft::Fft< std::complex<double> >;
|
||||
if (transformLen < FFT_T::minFFtsize())
|
||||
{
|
||||
std::cerr << "Error: minimum FFT transformation length is " << FFT_T::minFFtsize() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// instantiate FFT and prepare transformation for length N
|
||||
pffft::Fft< std::complex<double> > fft(transformLen);
|
||||
|
||||
// one more check
|
||||
if (!fft.isValid())
|
||||
{
|
||||
std::cerr << "Error: transformation length " << transformLen << " is not decomposable into small prime factors. "
|
||||
<< "Next valid transform size is: " << FFT_T::nearestTransformSize(transformLen)
|
||||
<< "; next power of 2 is: " << FFT_T::nextPowerOfTwo(transformLen) << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// allocate aligned vectors for input X and output Y
|
||||
auto X = fft.valueVector();
|
||||
auto Y = fft.spectrumVector();
|
||||
|
||||
// alternative access: get raw pointers to aligned vectors
|
||||
std::complex<double> *Xs = X.data();
|
||||
std::complex<double> *Ys = Y.data();
|
||||
|
||||
// prepare some input data
|
||||
for (int k = 0; k < transformLen; k += 2)
|
||||
{
|
||||
X[k] = std::complex<double>(k, k&1); // access through AlignedVector<double>
|
||||
Xs[k+1] = std::complex<double>(-1-k, k&1); // access through raw pointer
|
||||
}
|
||||
|
||||
// do the forward transform; write complex spectrum result into Y
|
||||
fft.forward(X, Y);
|
||||
|
||||
// print spectral output
|
||||
std::cout << "output should be complex spectrum with " << fft.getSpectrumSize() << " bins" << std::endl;
|
||||
std::cout << "output vector has size " << Y.size() << " (complex bins):" << std::endl;
|
||||
for (unsigned k = 0; k < Y.size(); k += 2)
|
||||
{
|
||||
std::cout << "Y[" << k << "] = " << Y[k] << std::endl;
|
||||
std::cout << "Y[" << k+1 << "] = " << Ys[k+1] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int N = (1 < argc) ? atoi(argv[1]) : 16;
|
||||
cxx11_forward_complex_double(N);
|
||||
return 0;
|
||||
}
|
||||
66
pffft/examples/example_cpp11_real_dbl_fwd.cpp
Normal file
66
pffft/examples/example_cpp11_real_dbl_fwd.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
#include "pffft.hpp"
|
||||
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
void cxx11_forward_real_double(const int transformLen)
|
||||
{
|
||||
std::cout << "running " << __FUNCTION__ << "()" << std::endl;
|
||||
|
||||
// first check - might be skipped
|
||||
using FFT_T = pffft::Fft<double>;
|
||||
if (transformLen < FFT_T::minFFtsize())
|
||||
{
|
||||
std::cerr << "Error: minimum FFT transformation length is " << FFT_T::minFFtsize() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// instantiate FFT and prepare transformation for length N
|
||||
pffft::Fft<double> fft { transformLen };
|
||||
|
||||
// one more check
|
||||
if (!fft.isValid())
|
||||
{
|
||||
std::cerr << "Error: transformation length " << transformLen << " is not decomposable into small prime factors. "
|
||||
<< "Next valid transform size is: " << FFT_T::nearestTransformSize(transformLen)
|
||||
<< "; next power of 2 is: " << FFT_T::nextPowerOfTwo(transformLen) << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// allocate aligned vectors for (real) input X and (complex) output Y
|
||||
auto X = fft.valueVector(); // input vector; type is AlignedVector<double>
|
||||
auto Y = fft.spectrumVector(); // output vector; type is AlignedVector< std::complex<double> >
|
||||
|
||||
// alternative access: get raw pointers to aligned vectors
|
||||
double *Xs = X.data();
|
||||
std::complex<double> *Ys = Y.data();
|
||||
|
||||
// prepare some input data
|
||||
for (int k = 0; k < transformLen; k += 2)
|
||||
{
|
||||
X[k] = k; // access through AlignedVector<double>
|
||||
Xs[k+1] = -1-k; // access through raw pointer
|
||||
}
|
||||
|
||||
// do the forward transform; write complex spectrum result into Y
|
||||
fft.forward(X, Y);
|
||||
|
||||
// print spectral output
|
||||
std::cout << "output should be complex spectrum with " << fft.getSpectrumSize() << " bins" << std::endl;
|
||||
std::cout << "output vector has size " << Y.size() << " (complex bins):" << std::endl;
|
||||
for (unsigned k = 0; k < Y.size(); k += 2)
|
||||
{
|
||||
std::cout << "Y[" << k << "] = " << Y[k] << std::endl;
|
||||
std::cout << "Y[" << k+1 << "] = " << Ys[k+1] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int N = (1 < argc) ? atoi(argv[1]) : 32;
|
||||
cxx11_forward_real_double(N);
|
||||
return 0;
|
||||
}
|
||||
66
pffft/examples/example_cpp98_cplx_flt_fwd.cpp
Normal file
66
pffft/examples/example_cpp98_cplx_flt_fwd.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
#include "pffft.hpp"
|
||||
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
void cxx98_forward_complex_float(const int transformLen)
|
||||
{
|
||||
std::cout << "running " << __FUNCTION__ << "()" << std::endl;
|
||||
|
||||
// first check - might be skipped
|
||||
typedef pffft::Fft< std::complex<float> > FFT_T;
|
||||
if (transformLen < FFT_T::minFFtsize())
|
||||
{
|
||||
std::cerr << "Error: minimum FFT transformation length is " << FFT_T::minFFtsize() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// instantiate FFT and prepare transformation for length N
|
||||
pffft::Fft< std::complex<float> > fft(transformLen);
|
||||
|
||||
// one more check
|
||||
if (!fft.isValid())
|
||||
{
|
||||
std::cerr << "Error: transformation length " << transformLen << " is not decomposable into small prime factors. "
|
||||
<< "Next valid transform size is: " << FFT_T::nearestTransformSize(transformLen)
|
||||
<< "; next power of 2 is: " << FFT_T::nextPowerOfTwo(transformLen) << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// allocate aligned vectors for input X and output Y
|
||||
pffft::AlignedVector< std::complex<float> > X = fft.valueVector();
|
||||
pffft::AlignedVector< std::complex<float> > Y = fft.spectrumVector();
|
||||
|
||||
// alternative access: get raw pointers to aligned vectors
|
||||
std::complex<float> *Xs = X.data();
|
||||
std::complex<float> *Ys = Y.data();
|
||||
|
||||
// prepare some input data
|
||||
for (int k = 0; k < transformLen; k += 2)
|
||||
{
|
||||
X[k] = std::complex<float>(k, k&1); // access through AlignedVector<float>
|
||||
Xs[k+1] = std::complex<float>(-1-k, k&1); // access through raw pointer
|
||||
}
|
||||
|
||||
// do the forward transform; write complex spectrum result into Y
|
||||
fft.forward(X, Y);
|
||||
|
||||
// print spectral output
|
||||
std::cout << "output should be complex spectrum with " << fft.getSpectrumSize() << " bins" << std::endl;
|
||||
std::cout << "output vector has size " << Y.size() << " (complex bins):" << std::endl;
|
||||
for (unsigned k = 0; k < Y.size(); k += 2)
|
||||
{
|
||||
std::cout << "Y[" << k << "] = " << Y[k] << std::endl;
|
||||
std::cout << "Y[" << k+1 << "] = " << Ys[k+1] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int N = (1 < argc) ? atoi(argv[1]) : 16;
|
||||
cxx98_forward_complex_float(N);
|
||||
return 0;
|
||||
}
|
||||
66
pffft/examples/example_cpp98_real_flt_fwd.cpp
Normal file
66
pffft/examples/example_cpp98_real_flt_fwd.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
#include "pffft.hpp"
|
||||
|
||||
#include <complex>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
void cxx98_forward_real_float(const int transformLen)
|
||||
{
|
||||
std::cout << "running " << __FUNCTION__ << "()" << std::endl;
|
||||
|
||||
// first check - might be skipped
|
||||
typedef pffft::Fft<float> FFT_T;
|
||||
if (transformLen < FFT_T::minFFtsize())
|
||||
{
|
||||
std::cerr << "Error: minimum FFT transformation length is " << FFT_T::minFFtsize() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// instantiate FFT and prepare transformation for length N
|
||||
pffft::Fft<float> fft(transformLen);
|
||||
|
||||
// one more check
|
||||
if (!fft.isValid())
|
||||
{
|
||||
std::cerr << "Error: transformation length " << transformLen << " is not decomposable into small prime factors. "
|
||||
<< "Next valid transform size is: " << FFT_T::nearestTransformSize(transformLen)
|
||||
<< "; next power of 2 is: " << FFT_T::nextPowerOfTwo(transformLen) << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// allocate aligned vectors for input X and output Y
|
||||
pffft::AlignedVector<float> X = fft.valueVector();
|
||||
pffft::AlignedVector< std::complex<float> > Y = fft.spectrumVector();
|
||||
|
||||
// alternative access: get raw pointers to aligned vectors
|
||||
float *Xs = X.data();
|
||||
std::complex<float> *Ys = Y.data();
|
||||
|
||||
// prepare some input data
|
||||
for (int k = 0; k < transformLen; k += 2)
|
||||
{
|
||||
X[k] = k; // access through AlignedVector<float>
|
||||
Xs[k+1] = -1-k; // access through raw pointer
|
||||
}
|
||||
|
||||
// do the forward transform; write complex spectrum result into Y
|
||||
fft.forward(X, Y);
|
||||
|
||||
// print spectral output
|
||||
std::cout << "output should be complex spectrum with " << fft.getSpectrumSize() << " bins" << std::endl;
|
||||
std::cout << "output vector has size " << Y.size() << " (complex bins):" << std::endl;
|
||||
for (unsigned k = 0; k < Y.size(); k += 2)
|
||||
{
|
||||
std::cout << "Y[" << k << "] = " << Y[k] << std::endl;
|
||||
std::cout << "Y[" << k+1 << "] = " << Ys[k+1] << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int N = (1 < argc) ? atoi(argv[1]) : 32;
|
||||
cxx98_forward_real_float(N);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user