Files
pip/libs/main/math/pifft.cpp
peri4 06fffeb976 fix small mistakes
PIFFTW now save all 3 plans, with fast flag
PIFFTBase::calcHibert now normalized
add -fexception for pifft.cpp
2026-10-18 20:31:21 +03:00

111 lines
3.6 KiB
C++

/*
PIP - Platform Independent Primitives
Class for FFT, IFFT and Hilbert transformations
Andrey Bychkov work.a.b@yandex.ru, Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pifft.h"
#ifdef PIP_HAS_FFT
# define POCKETFFT_NO_MULTITHREADING
# define POCKETFFT_CACHE_SIZE 32
# include "3rd/pocketfft/pocketfft_hdronly.h"
// FFT with PocketFFT
template<typename T>
class PocketFFT {
public:
PocketFFT() { stride_out[0] = sizeof(complex<T>); }
void c2c(const PIVector<complex<T>> & in, PIVector<complex<T>> & out, bool direction) {
stride_in[0] = sizeof(complex<T>);
shape[0] = in.size();
out.resize(in.size());
pocketfft::c2c<T>(shape, stride_in, stride_out, axes, direction, in.data(), out.data(), 1.);
}
void r2c(const PIVector<T> & in, PIVector<complex<T>> & out, bool direction) {
stride_in[0] = sizeof(T);
shape[0] = in.size();
out.resize(in.size());
pocketfft::r2c<T>(shape, stride_in, stride_out, axes, direction, in.data(), out.data(), 1.);
}
pocketfft::shape_t shape{1}, axes{0};
pocketfft::stride_t stride_in{0}, stride_out{0};
};
PRIVATE_DEFINITION_START(PIFFT<float>)
PocketFFT<float> pfft;
PRIVATE_DEFINITION_END(PIFFT<float>)
PRIVATE_DEFINITION_START(PIFFT<double>)
PocketFFT<double> pfft;
PRIVATE_DEFINITION_END(PIFFT<double>)
PRIVATE_DEFINITION_START(PIFFT<ldouble>)
PocketFFT<ldouble> pfft;
PRIVATE_DEFINITION_END(PIFFT<ldouble>)
const PIVector<complex<float>> & PIFFT<float>::calcFFT(const PIVector<complex<float>> & in) {
PRIVATE->pfft.c2c(in, m_result, pocketfft::FORWARD);
return m_result;
}
const PIVector<complex<float>> & PIFFT<float>::calcFFT(const PIVector<float> & in) {
PRIVATE->pfft.r2c(in, m_result, pocketfft::FORWARD);
return m_result;
}
const PIVector<complex<float>> & PIFFT<float>::calcFFTinverse(const PIVector<complex<float>> & in) {
PRIVATE->pfft.c2c(in, m_result, pocketfft::BACKWARD);
return m_result;
}
const PIVector<complex<double>> & PIFFT<double>::calcFFT(const PIVector<complex<double>> & in) {
PRIVATE->pfft.c2c(in, m_result, pocketfft::FORWARD);
return m_result;
}
const PIVector<complex<double>> & PIFFT<double>::calcFFT(const PIVector<double> & in) {
PRIVATE->pfft.r2c(in, m_result, pocketfft::FORWARD);
return m_result;
}
const PIVector<complex<double>> & PIFFT<double>::calcFFTinverse(const PIVector<complex<double>> & in) {
PRIVATE->pfft.c2c(in, m_result, pocketfft::BACKWARD);
return m_result;
}
const PIVector<complex<ldouble>> & PIFFT<ldouble>::calcFFT(const PIVector<complex<ldouble>> & in) {
PRIVATE->pfft.c2c(in, m_result, pocketfft::FORWARD);
return m_result;
}
const PIVector<complex<ldouble>> & PIFFT<ldouble>::calcFFT(const PIVector<ldouble> & in) {
PRIVATE->pfft.r2c(in, m_result, pocketfft::FORWARD);
return m_result;
}
const PIVector<complex<ldouble>> & PIFFT<ldouble>::calcFFTinverse(const PIVector<complex<ldouble>> & in) {
PRIVATE->pfft.c2c(in, m_result, pocketfft::BACKWARD);
return m_result;
}
#endif // PIP_HAS_FFT