Files
pip/libs/main/math/pifftbase.h
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

119 lines
4.2 KiB
C++

//! \~\file pifft.h
//! \~\ingroup Math
//! \~\ingroup FFTW
//! \~\brief
//! \~english Base class for FFT, IFFT and Hilbert transformations
//! \~russian Базовый класс для БПФ, ОБПФ и преобразования Гильберта
/*
PIP - Platform Independent Primitives
Base class for FFT, IFFT and Hilbert transformations
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/>.
*/
#ifndef PIFFTBASE_H
#define PIFFTBASE_H
#include "pimathcomplex.h"
#include "pip_export.h"
#ifdef PIP_HAS_FFT
template<typename T>
class PIP_EXPORT PIFFTBase {
public:
virtual ~PIFFTBase() {}
//! \~english Calculates complex FFT for the input signal.
//! \~russian Вычисляет комплексное БПФ для входного сигнала.
virtual const PIVector<complex<T>> & calcFFT(const PIVector<complex<T>> & in) = 0;
//! \~english Calculates FFT for a real-valued input signal.
//! \~russian Вычисляет БПФ для вещественного входного сигнала.
virtual const PIVector<complex<T>> & calcFFT(const PIVector<T> & in) = 0;
//! \~english Calculates inverse FFT for a complex spectrum.
//! \~russian Вычисляет обратное БПФ для комплексного спектра.
virtual const PIVector<complex<T>> & calcFFTinverse(const PIVector<complex<T>> & in) = 0;
//! \~english Calculates the analytic signal using a Hilbert transform.
//! \~russian Вычисляет аналитический сигнал с помощью преобразования Гильберта.
const PIVector<complex<T>> & calcHilbert(const PIVector<T> & in) {
m_result.clear();
if (in.size_s() < 4) return m_result;
calcFFT(in);
size_t hsize = m_result.size() / 2;
for (size_t i = 0; i < hsize; i++)
m_result[i] = m_result[i] * T(2.);
for (size_t i = hsize; i < m_result.size(); i++)
m_result[i] = complex<T>();
auto tmp = m_result;
calcFFTinverse(tmp);
T div = in.size();
for (auto & i: m_result)
i /= div;
return m_result;
}
virtual bool prepareForSize(size_t count) {
calcFFT(PIVector<T>(count, T()));
return true;
}
//! \~english Returns last calculated result.
//! \~russian Возвращает последний вычисленный результат.
const PIVector<complex<T>> & getComplex() const { return m_result; }
//! \~english Returns magnitudes of the last calculated result.
//! \~russian Возвращает модули последнего вычисленного результата.
PIVector<T> getAmplitude() const {
PIVector<T> ret;
ret.resize(m_result.size());
for (size_t i = 0; i < m_result.size(); i++)
ret[i] = sqrt(m_result[i].real() * m_result[i].real() + m_result[i].imag() * m_result[i].imag());
return ret;
}
//! \~english Returns real parts of the last calculated result.
//! \~russian Возвращает действительные части последнего вычисленного результата.
PIVector<T> getReal() const {
PIVector<T> ret;
ret.resize(m_result.size());
for (size_t i = 0; i < m_result.size(); i++)
ret[i] = m_result[i].real();
return ret;
}
//! \~english Returns imaginary parts of the last calculated result.
//! \~russian Возвращает мнимые части последнего вычисленного результата.
PIVector<T> getImag() const {
PIVector<T> ret;
ret.resize(m_result.size());
for (size_t i = 0; i < m_result.size(); i++)
ret[i] = m_result[i].imag();
return ret;
}
protected:
PIVector<complex<T>> m_result;
};
#endif // PIP_HAS_FFT
#endif