Build and test pass with clang 6.0.0.

topic/cross-compile
Vincent Samy 2020-03-30 17:15:34 +09:00
rodzic b12580b323
commit e6e370642e
14 zmienionych plików z 419 dodań i 283 usunięć

Wyświetl plik

@ -35,7 +35,7 @@ SET(PROJECT_DEBUG_POSTFIX "_d")
set(INSTALL_GENERATED_HEADERS OFF) set(INSTALL_GENERATED_HEADERS OFF)
set(DOXYGEN_USE_MATHJAX "NO") set(DOXYGEN_USE_MATHJAX "NO")
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 17)
option(BUILD_TESTING "Disable unit tests." ON) option(BUILD_TESTING "Disable unit tests." ON)
option(BUILD_TEST_STATIC_BOOST "Build unit tests with static boost libraries" OFF) option(BUILD_TEST_STATIC_BOOST "Build unit tests with static boost libraries" OFF)

Wyświetl plik

@ -60,9 +60,9 @@ void BaseFilter<T, Derived>::getCoeffs(vectX_t<T>& aCoeff, vectX_t<T>& bCoeff) c
template <typename T, typename Derived> template <typename T, typename Derived>
BaseFilter<T, Derived>::BaseFilter(const vectX_t<T>& aCoeff, const vectX_t<T>& bCoeff, FilterType type) BaseFilter<T, Derived>::BaseFilter(const vectX_t<T>& aCoeff, const vectX_t<T>& bCoeff, FilterType type)
: m_aCoeff(aCoeff) : m_type(type)
, m_aCoeff(aCoeff)
, m_bCoeff(bCoeff) , m_bCoeff(bCoeff)
, m_type(type)
, m_filteredData(aCoeff.size()) , m_filteredData(aCoeff.size())
, m_rawData(bCoeff.size()) , m_rawData(bCoeff.size())
{ {

Wyświetl plik

@ -131,7 +131,7 @@ void Butterworth<T>::computeDigitalRep(T fc)
} }
scaleAmplitude(aCoeff, bCoeff); scaleAmplitude(aCoeff, bCoeff);
setCoeffs(std::move(aCoeff), std::move(bCoeff)); this->setCoeffs(std::move(aCoeff), std::move(bCoeff));
} }
template <typename T> template <typename T>
@ -164,14 +164,14 @@ void Butterworth<T>::computeBandDigitalRep(T fLower, T fUpper)
else else
scaleAmplitude(aCoeff, bCoeff); scaleAmplitude(aCoeff, bCoeff);
setCoeffs(std::move(aCoeff), std::move(bCoeff)); this->setCoeffs(std::move(aCoeff), std::move(bCoeff));
} }
template <typename T> template <typename T>
std::complex<T> Butterworth<T>::generateAnalogPole(int k, T fpw1) std::complex<T> Butterworth<T>::generateAnalogPole(int k, T fpw1)
{ {
auto thetaK = [pi = pi<T>, order = m_order](int k) -> T { auto thetaK = [pi = pi<T>, order = m_order](int k) -> T {
return (2 * k - 1) * pi / (2 * order); return static_cast<float>(2 * k - 1) * pi / static_cast<float>(2 * order);
}; };
std::complex<T> analogPole(-std::sin(thetaK(k)), std::cos(thetaK(k))); std::complex<T> analogPole(-std::sin(thetaK(k)), std::cos(thetaK(k)));
@ -189,7 +189,7 @@ template <typename T>
std::pair<std::complex<T>, std::complex<T>> Butterworth<T>::generateBandAnalogPole(int k, T fpw0, T bw) std::pair<std::complex<T>, std::complex<T>> Butterworth<T>::generateBandAnalogPole(int k, T fpw0, T bw)
{ {
auto thetaK = [pi = pi<T>, order = m_order](int k) -> T { auto thetaK = [pi = pi<T>, order = m_order](int k) -> T {
return (2 * k - 1) * pi / (2 * order); return static_cast<float>(2 * k - 1) * pi / static_cast<float>(2 * order);
}; };
std::complex<T> analogPole(-std::sin(thetaK(k)), std::cos(thetaK(k))); std::complex<T> analogPole(-std::sin(thetaK(k)), std::cos(thetaK(k)));

Wyświetl plik

@ -33,6 +33,13 @@ namespace difi {
template <typename T> template <typename T>
class GenericFilter : public BaseFilter<T, GenericFilter<T>> { class GenericFilter : public BaseFilter<T, GenericFilter<T>> {
using Base = BaseFilter<T, GenericFilter<T>>;
using Base::m_isInitialized;
using Base::m_aCoeff;
using Base::m_bCoeff;
using Base::m_rawData;
using Base::m_filteredData;
public: public:
/*! \brief Filter a new data. /*! \brief Filter a new data.
* *
@ -54,12 +61,19 @@ public:
protected: protected:
GenericFilter() = default; GenericFilter() = default;
GenericFilter(const vectX_t<T>& aCoeff, const vectX_t<T>& bCoeff, FilterType type = FilterType::Backward) GenericFilter(const vectX_t<T>& aCoeff, const vectX_t<T>& bCoeff, FilterType type = FilterType::Backward)
: BaseFilter(aCoeff, bCoeff, type) : Base(aCoeff, bCoeff, type)
{} {}
}; };
template <typename T> template <typename T>
class TVGenericFilter : public BaseFilter<T, TVGenericFilter<T>> { class TVGenericFilter : public BaseFilter<T, TVGenericFilter<T>> {
using Base = BaseFilter<T, TVGenericFilter<T>>;
using Base::m_isInitialized;
using Base::m_aCoeff;
using Base::m_bCoeff;
using Base::m_rawData;
using Base::m_filteredData;
public: public:
/*! \brief Filter a new data. /*! \brief Filter a new data.
* *
@ -81,12 +95,12 @@ public:
protected: protected:
TVGenericFilter() = default; TVGenericFilter() = default;
TVGenericFilter(size_t differentialOrder, const vectX_t<T>& aCoeff, const vectX_t<T>& bCoeff, FilterType type = FilterType::Backward) TVGenericFilter(size_t differentialOrder, const vectX_t<T>& aCoeff, const vectX_t<T>& bCoeff, FilterType type = FilterType::Backward)
: BaseFilter() : Base()
, m_diffOrder(differentialOrder) , m_diffOrder(differentialOrder)
{ {
Expects(differentialOrder >= 1); Expects(differentialOrder >= 1);
setCoeffs(aCoeff, bCoeff); this->setCoeffs(aCoeff, bCoeff);
setType(type); this->setType(type);
} }
private: private:

Wyświetl plik

@ -50,16 +50,16 @@ public:
MovingAverage(int windowSize, FilterType type = FilterType::Backward) MovingAverage(int windowSize, FilterType type = FilterType::Backward)
{ {
setWindowSize(windowSize); setWindowSize(windowSize);
setType(type); this->setType(type);
} }
/*! \brief Set the size of the moving average window. */ /*! \brief Set the size of the moving average window. */
void setWindowSize(int windowSize) void setWindowSize(int windowSize)
{ {
Expects(windowSize > 0); Expects(windowSize > 0);
setCoeffs(vectX_t<T>::Constant(1, T(1)), vectX_t<T>::Constant(windowSize, T(1) / windowSize)); this->setCoeffs(vectX_t<T>::Constant(1, T(1)), vectX_t<T>::Constant(windowSize, T(1) / static_cast<T>(windowSize)));
} }
/*! \brief Get the size of the moving average window. */ /*! \brief Get the size of the moving average window. */
int windowSize() const noexcept { return bOrder(); } int windowSize() const noexcept { return this->bOrder(); }
}; };
} // namespace difi } // namespace difi

Wyświetl plik

@ -39,7 +39,7 @@ namespace details {
// N: Number of points // N: Number of points
// Centered differentiators: http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/central-differences/ // Centered differentiators: http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/central-differences/
template <typename T, size_t N> struct GetCDCoeffs { template <typename T, int N> struct GetCDCoeffs {
vectN_t<T, N> operator()() const; vectN_t<T, N> operator()() const;
}; };
template <typename T> struct GetCDCoeffs<T, 3> { template <typename T> struct GetCDCoeffs<T, 3> {
@ -56,18 +56,18 @@ template <typename T> struct GetCDCoeffs<T, 9> {
}; };
// Low-noise Lanczos differentiators: http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/lanczos-low-noise-differentiators/ // Low-noise Lanczos differentiators: http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/lanczos-low-noise-differentiators/
template <typename T, size_t N> template <typename T, int N>
struct GetLNLCoeffs { struct GetLNLCoeffs {
vectN_t<T, N> operator()() const vectN_t<T, N> operator()() const
{ {
static_assert(N > 2 && N % 2 == 1, "'N' must be odd."); static_assert(N > 2 && N % 2 == 1, "'N' must be odd.");
constexpr const size_t M = (N - 1) / 2; constexpr const int M = (N - 1) / 2;
constexpr const size_t Den = M * (M + 1) * (2 * M + 1); constexpr const int Den = M * (M + 1) * (2 * M + 1);
vectN_t<T, N> v{}; vectN_t<T, N> v{};
v(M) = T(0); v(M) = T(0);
for (size_t k = 0; k < M; ++k) { for (int k = 0; k < M; ++k) {
v(k) = T(3) * (M - k) / static_cast<T>(Den); v(k) = T(3) * static_cast<T>(M - k) / static_cast<T>(Den);
v(N - k - 1) = -v(k); v(N - k - 1) = -v(k);
} }
return v; return v;
@ -75,7 +75,7 @@ struct GetLNLCoeffs {
}; };
// Super Low-noise Lanczos differentiators: http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/lanczos-low-noise-differentiators/ // Super Low-noise Lanczos differentiators: http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/lanczos-low-noise-differentiators/
template <typename T, size_t N> struct GetSLNLCoeffs { template <typename T, int N> struct GetSLNLCoeffs {
vectN_t<T, N> operator()() const; vectN_t<T, N> operator()() const;
}; };
template <typename T> struct GetSLNLCoeffs<T, 7> { template <typename T> struct GetSLNLCoeffs<T, 7> {
@ -89,19 +89,19 @@ template <typename T> struct GetSLNLCoeffs<T, 11> {
}; };
// Backward Noise-Robust differentiators; http://www.holoborodko.com/pavel/wp-content/uploads/OneSidedNoiseRobustDifferentiators.pdf // Backward Noise-Robust differentiators; http://www.holoborodko.com/pavel/wp-content/uploads/OneSidedNoiseRobustDifferentiators.pdf
template <typename T, size_t N> template <typename T, int N>
struct GetFNRCoeffs { struct GetFNRCoeffs {
vectN_t<T, N> operator()() const vectN_t<T, N> operator()() const
{ {
static_assert(N >= 2, "N should be greater than 2"); static_assert(N >= 2, "N should be greater than 2");
constexpr const size_t BinCoeff = N - 2; constexpr const int BinCoeff = N - 2;
constexpr const size_t M = N / 2; constexpr const int M = N / 2;
vectN_t<T, N> v{}; vectN_t<T, N> v{};
v(0) = T(1); v(0) = T(1);
v(M) = T(0); v(M) = T(0);
v(N - 1) = T(-1); v(N - 1) = T(-1);
for (size_t i = 1; i < M; ++i) { for (int i = 1; i < M; ++i) {
v(i) = Binomial<T>(BinCoeff, i) - Binomial<T>(BinCoeff, i - 1); v(i) = Binomial<T>(BinCoeff, i) - Binomial<T>(BinCoeff, i - 1);
v(N - i - 1) = -v(i); v(N - i - 1) = -v(i);
} }
@ -112,7 +112,7 @@ struct GetFNRCoeffs {
}; };
// Backward Hybrid Noise-Robust differentiators; http://www.holoborodko.com/pavel/wp-content/uploads/OneSidedNoiseRobustDifferentiators.pdf // Backward Hybrid Noise-Robust differentiators; http://www.holoborodko.com/pavel/wp-content/uploads/OneSidedNoiseRobustDifferentiators.pdf
template <typename T, size_t N> struct GetFHNRCoeffs { template <typename T, int N> struct GetFHNRCoeffs {
vectN_t<T, N> operator()() const; vectN_t<T, N> operator()() const;
}; };
template <typename T> struct GetFHNRCoeffs<T, 4> { template <typename T> struct GetFHNRCoeffs<T, 4> {
@ -143,25 +143,25 @@ template <typename T> struct GetFHNRCoeffs<T, 16> {
vectN_t<T, 16> operator()() const { return (vectN_t<T, 16>() << T(322), T(217), T(110), T(35), T(-42), T(-87), T(-134), T(-149), T(-166), T(-151), T(-138), T(-93), T(-50), T(28), T(98), T(203)).finished() / T(2856); } vectN_t<T, 16> operator()() const { return (vectN_t<T, 16>() << T(322), T(217), T(110), T(35), T(-42), T(-87), T(-134), T(-149), T(-166), T(-151), T(-138), T(-93), T(-50), T(28), T(98), T(203)).finished() / T(2856); }
}; };
template <typename T, size_t N, typename BackwardCoeffs> vectN_t<T, N> GetBackwardISDCoeffs() template <typename T, int N, typename BackwardCoeffs> vectN_t<T, N> GetBackwardISDCoeffs()
{ {
vectN_t<T, N> v{}; vectN_t<T, N> v{};
const vectN_t<T, N> v0 = BackwardCoeffs{}(); const vectN_t<T, N> v0 = BackwardCoeffs{}();
for (Eigen::Index k = 0; k < N; ++k) for (Eigen::Index k = 0; k < N; ++k)
v(k) = k * v0(k); v(k) = k * v0(k);
return v(k); return v;
} }
// Backward Noise-Robust differentiators for irregular space data // Backward Noise-Robust differentiators for irregular space data
template <typename T, size_t N> struct GetFNRISDCoeffs { template <typename T, int N> struct GetFNRISDCoeffs {
vectN_t<T, N> operator()() const { return GetBackwardISDCoeffs<T, N, GetFNRCoeffs<T, N>>(); } vectN_t<T, N> operator()() const { return GetBackwardISDCoeffs<T, N, GetFNRCoeffs<T, N>>(); }
}; };
// Backward Hybrid Noise-Robust differentiators for irregular space data // Backward Hybrid Noise-Robust differentiators for irregular space data
template <typename T, size_t N> struct GetFHNRISDCoeffs { template <typename T, int N> struct GetFHNRISDCoeffs {
vectN_t<T, N> operator()() const { return GetBackwardISDCoeffs<T, N, GetFHNRCoeffs<T, N>>(); } vectN_t<T, N> operator()() const { return GetBackwardISDCoeffs<T, N, GetFHNRCoeffs<T, N>>(); }
}; };
// Centered Noise-Robust differentiators (tangency at 2nd order): http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/ // Centered Noise-Robust differentiators (tangency at 2nd order): http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
template <typename T, size_t N> template <typename T, int N>
struct GetCNR2Coeffs { struct GetCNR2Coeffs {
vectN_t<T, N> operator()() const vectN_t<T, N> operator()() const
{ {
@ -171,7 +171,7 @@ struct GetCNR2Coeffs {
}; };
// Centered Noise-Robust differentiators (tangency at 4th order): http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/ // Centered Noise-Robust differentiators (tangency at 4th order): http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
template <typename T, size_t N> struct GetCNR4Coeffs { template <typename T, int N> struct GetCNR4Coeffs {
vectN_t<T, N> operator()() const; vectN_t<T, N> operator()() const;
}; };
template <typename T> struct GetCNR4Coeffs<T, 7> { template <typename T> struct GetCNR4Coeffs<T, 7> {
@ -185,9 +185,9 @@ template <typename T> struct GetCNR4Coeffs<T, 11> {
}; };
// Centered Noise-Robust differentiators for irregular space data: http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/ // Centered Noise-Robust differentiators for irregular space data: http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
template <typename T, size_t N, typename CNRCoeffs> vectN_t<T, N> GetCNRISDCoeffs() template <typename T, int N, typename CNRCoeffs> vectN_t<T, N> GetCNRISDCoeffs()
{ {
constexpr const size_t M = (N - 1) / 2; constexpr const int M = (N - 1) / 2;
vectN_t<T, N> v{}; vectN_t<T, N> v{};
const vectN_t<T, N> v0 = CNRCoeffs{}(); const vectN_t<T, N> v0 = CNRCoeffs{}();
v(M) = 0; v(M) = 0;
@ -198,10 +198,10 @@ template <typename T, size_t N, typename CNRCoeffs> vectN_t<T, N> GetCNRISDCoeff
return v; return v;
} }
template <typename T, size_t N> struct GetCNR2ISDCoeffs { template <typename T, int N> struct GetCNR2ISDCoeffs {
vectN_t<T, N> operator()() const { return GetCNRISDCoeffs<T, N, GetCNR2Coeffs<T, N>>(); } vectN_t<T, N> operator()() const { return GetCNRISDCoeffs<T, N, GetCNR2Coeffs<T, N>>(); }
}; };
template <typename T, size_t N> struct GetCNR4ISDCoeffs { template <typename T, int N> struct GetCNR4ISDCoeffs {
vectN_t<T, N> operator()() const { return GetCNRISDCoeffs<T, N, GetCNR4Coeffs<T, N>>(); } vectN_t<T, N> operator()() const { return GetCNRISDCoeffs<T, N, GetCNR4Coeffs<T, N>>(); }
}; };
@ -210,7 +210,7 @@ template <typename T, size_t N> struct GetCNR4ISDCoeffs {
*/ */
template <typename T> template <typename T>
constexpr T GetSONRBaseCoeff(size_t N, size_t M, size_t k) constexpr T GetSONRBaseCoeff(int N, int M, int k)
{ {
if (k > M) if (k > M)
return T(0); return T(0);
@ -220,28 +220,28 @@ constexpr T GetSONRBaseCoeff(size_t N, size_t M, size_t k)
return ((T(2) * N - T(10)) * GetSONRBaseCoeff<T>(N, M, k + 1) - (N + T(2) * k + T(3)) * GetSONRBaseCoeff<T>(N, M, k + 2)) / (N - T(2) * k - T(1)); return ((T(2) * N - T(10)) * GetSONRBaseCoeff<T>(N, M, k + 1) - (N + T(2) * k + T(3)) * GetSONRBaseCoeff<T>(N, M, k + 2)) / (N - T(2) * k - T(1));
} }
template <typename T, size_t N> vectN_t<T, (N - 1) / 2 + 1> GetSONRBaseCoeffs() template <typename T, int N> vectN_t<T, (N - 1) / 2 + 1> GetSONRBaseCoeffs()
{ {
static_assert(N >= 5 && N % 2 == 1, "N must be a odd number >= 5"); static_assert(N >= 5 && N % 2 == 1, "N must be a odd number >= 5");
constexpr const size_t M = (N - 1) / 2; constexpr const int M = (N - 1) / 2;
vectN_t<T, M + 1> s{}; vectN_t<T, M + 1> s{};
for (size_t k = 0; k < M + 1; ++k) for (int k = 0; k < M + 1; ++k)
s(k) = GetSONRBaseCoeff<T>(N, M, k); s(k) = GetSONRBaseCoeff<T>(N, M, k);
return s; return s;
} }
// Second-Order Centered Noise-Robust differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf // Second-Order Centered Noise-Robust differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf
template <typename T, size_t N> template <typename T, int N>
struct GetSOCNRCoeffs { struct GetSOCNRCoeffs {
vectN_t<T, N> operator()() const vectN_t<T, N> operator()() const
{ {
constexpr const size_t M = (N - 1) / 2; constexpr const int M = (N - 1) / 2;
constexpr const T Den = pow(size_t(2), N - 3); constexpr const T Den = pow(2, N - 3);
vectN_t<T, N> v{}; vectN_t<T, N> v{};
vectN_t<T, M + 1> s = GetSONRBaseCoeffs<T, N>(); vectN_t<T, M + 1> s = GetSONRBaseCoeffs<T, N>();
v(M) = s(0); v(M) = s(0);
for (size_t k = 1; k < M + 1; ++k) { for (int k = 1; k < M + 1; ++k) {
v(M + k) = s(k); v(M + k) = s(k);
v(M - k) = s(k); v(M - k) = s(k);
} }
@ -251,25 +251,25 @@ struct GetSOCNRCoeffs {
} }
}; };
// Second-Order Backward Noise-Robust differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf // Second-Order Backward Noise-Robust differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf
template <typename T, size_t N> struct GetSOFNRCoeffs { template <typename T, int N> struct GetSOFNRCoeffs {
vectN_t<T, N> operator()() const { return GetSOCNRCoeffs<T, N>(); } vectN_t<T, N> operator()() const { return GetSOCNRCoeffs<T, N>(); }
}; // Coefficients are the same. }; // Coefficients are the same.
// Second-Order Centered Noise-Robust Irregular Space Data differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf // Second-Order Centered Noise-Robust Irregular Space Data differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf
template <typename T, size_t N> template <typename T, int N>
struct GetSOCNRISDCoeffs { struct GetSOCNRISDCoeffs {
vectN_t<T, N> operator()() const vectN_t<T, N> operator()() const
{ {
constexpr const size_t M = (N - 1) / 2; constexpr const int M = (N - 1) / 2;
constexpr const T Den = pow(size_t(2), N - 3); constexpr const T Den = pow(2, N - 3);
vectN_t<T, N> v{}; vectN_t<T, N> v{};
const vectN_t<T, M + 1> s = GetSONRBaseCoeffs<T, N>(); const vectN_t<T, M + 1> s = GetSONRBaseCoeffs<T, N>();
const auto alpha = [&s](size_t k) -> T { return T(4) * k * k * s(k); }; const auto alpha = [&s](int k) -> T { return T(4) * k * k * s(k); };
v(M) = T(0); v(M) = T(0);
for (size_t k = 1; k < M + 1; ++k) { for (int k = 1; k < M + 1; ++k) {
auto alph = alpha(k); auto alph = alpha(k);
v(M) -= T(2) * alph; v(M) -= T(2) * alph;
v(M + k) = alph; v(M + k) = alph;
@ -282,7 +282,7 @@ struct GetSOCNRISDCoeffs {
}; };
// Second-Order Backward Noise-Robust Irregular Space Data differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf // Second-Order Backward Noise-Robust Irregular Space Data differentiator: http://www.holoborodko.com/pavel/downloads/NoiseRobustSecondDerivative.pdf
template <typename T, size_t N> struct GetSOFNRISDCoeffs { template <typename T, int N> struct GetSOFNRISDCoeffs {
vectN_t<T, N> operator()() const { return GetSOCNRISDCoeffs<T, N>(); } vectN_t<T, N> operator()() const { return GetSOCNRISDCoeffs<T, N>(); }
}; // Same coefficients }; // Same coefficients
@ -290,7 +290,7 @@ template <typename T, size_t N> struct GetSOFNRISDCoeffs {
* Differentiator Generator * Differentiator Generator
*/ */
template <typename T, size_t N, int Order, typename CoeffGetter> template <typename T, int N, int Order, typename CoeffGetter>
class BackwardDifferentiator : public GenericFilter<T> { class BackwardDifferentiator : public GenericFilter<T> {
public: public:
BackwardDifferentiator() BackwardDifferentiator()
@ -299,11 +299,11 @@ public:
BackwardDifferentiator(T timestep) BackwardDifferentiator(T timestep)
: GenericFilter<T>(vectX_t<T>::Constant(1, T(1)), CoeffGetter{}() / std::pow(timestep, Order)) : GenericFilter<T>(vectX_t<T>::Constant(1, T(1)), CoeffGetter{}() / std::pow(timestep, Order))
{} {}
void setTimestep(T timestep) { setCoeffs(vectX_t<T>::Constant(1, T(1)), CoeffGetter{}() / std::pow(timestep, Order)); } void setTimestep(T timestep) { this->setCoeffs(vectX_t<T>::Constant(1, T(1)), CoeffGetter{}() / std::pow(timestep, Order)); }
T timestep() const noexcept { return std::pow(bCoeff()(0) / CoeffGetter{}()(0), T(1) / Order); } T timestep() const noexcept { return std::pow(this->bCoeff()(0) / CoeffGetter{}()(0), T(1) / Order); }
}; };
template <typename T, size_t N, int Order, typename CoeffGetter> template <typename T, int N, int Order, typename CoeffGetter>
class CenteredDifferentiator : public GenericFilter<T> { class CenteredDifferentiator : public GenericFilter<T> {
public: public:
CenteredDifferentiator() CenteredDifferentiator()
@ -312,11 +312,11 @@ public:
CenteredDifferentiator(T timestep) CenteredDifferentiator(T timestep)
: GenericFilter<T>(vectX_t<T>::Constant(1, T(1)), CoeffGetter{}() / std::pow(timestep, Order)) : GenericFilter<T>(vectX_t<T>::Constant(1, T(1)), CoeffGetter{}() / std::pow(timestep, Order))
{} {}
void setTimestep(T timestep) { setCoeffs(vectX_t<T>::Constant(1, T(1)), CoeffGetter{}() / std::pow(timestep, Order)); } void setTimestep(T timestep) { this->setCoeffs(vectX_t<T>::Constant(1, T(1)), CoeffGetter{}() / std::pow(timestep, Order)); }
T timestep() const noexcept { return std::pow(bCoeff()(0) / CoeffGetter{}()(0), T(1) / Order); } T timestep() const noexcept { return std::pow(this->bCoeff()(0) / CoeffGetter{}()(0), T(1) / Order); }
}; };
template <typename T, size_t N, int Order, typename CoeffGetter> template <typename T, int N, int Order, typename CoeffGetter>
class TVBackwardDifferentiator : public TVGenericFilter<T> { class TVBackwardDifferentiator : public TVGenericFilter<T> {
static_assert(Order >= 1, "Order must be greater or equal to 1"); static_assert(Order >= 1, "Order must be greater or equal to 1");
@ -326,7 +326,7 @@ public:
{} {}
}; };
template <typename T, size_t N, int Order, typename CoeffGetter> template <typename T, int N, int Order, typename CoeffGetter>
class TVCenteredDifferentiator : public TVGenericFilter<T> { class TVCenteredDifferentiator : public TVGenericFilter<T> {
static_assert(Order >= 1, "Order must be greater or equal to 1"); static_assert(Order >= 1, "Order must be greater or equal to 1");
@ -339,30 +339,30 @@ public:
} // namespace details } // namespace details
// Backward differentiators // Backward differentiators
template <typename T, size_t N> using BackwardDiffNoiseRobust = details::BackwardDifferentiator<T, N, 1, details::GetFNRCoeffs<T, N>>; template <typename T, int N> using BackwardDiffNoiseRobust = details::BackwardDifferentiator<T, N, 1, details::GetFNRCoeffs<T, N>>;
template <typename T, size_t N> using BackwardDiffHybridNoiseRobust = details::BackwardDifferentiator<T, N, 1, details::GetFHNRCoeffs<T, N>>; template <typename T, int N> using BackwardDiffHybridNoiseRobust = details::BackwardDifferentiator<T, N, 1, details::GetFHNRCoeffs<T, N>>;
// Time-Varying backward differentiators // Time-Varying backward differentiators
template <typename T, size_t N> using TVBackwardDiffNoiseRobust = details::TVBackwardDifferentiator<T, N, 1, details::GetFNRISDCoeffs<T, N>>; template <typename T, int N> using TVBackwardDiffNoiseRobust = details::TVBackwardDifferentiator<T, N, 1, details::GetFNRISDCoeffs<T, N>>;
template <typename T, size_t N> using TVBackwardDiffHybridNoiseRobust = details::TVBackwardDifferentiator<T, N, 1, details::GetFHNRISDCoeffs<T, N>>; template <typename T, int N> using TVBackwardDiffHybridNoiseRobust = details::TVBackwardDifferentiator<T, N, 1, details::GetFHNRISDCoeffs<T, N>>;
// Centered differentiators // Centered differentiators
template <typename T, size_t N> using CenteredDiffBasic = details::CenteredDifferentiator<T, N, 1, details::GetCDCoeffs<T, N>>; template <typename T, int N> using CenteredDiffBasic = details::CenteredDifferentiator<T, N, 1, details::GetCDCoeffs<T, N>>;
template <typename T, size_t N> using CenteredDiffLowNoiseLanczos = details::CenteredDifferentiator<T, N, 1, details::GetLNLCoeffs<T, N>>; template <typename T, int N> using CenteredDiffLowNoiseLanczos = details::CenteredDifferentiator<T, N, 1, details::GetLNLCoeffs<T, N>>;
template <typename T, size_t N> using CenteredDiffSuperLowNoiseLanczos = details::CenteredDifferentiator<T, N, 1, details::GetSLNLCoeffs<T, N>>; template <typename T, int N> using CenteredDiffSuperLowNoiseLanczos = details::CenteredDifferentiator<T, N, 1, details::GetSLNLCoeffs<T, N>>;
template <typename T, size_t N> using CenteredDiffNoiseRobust2 = details::CenteredDifferentiator<T, N, 1, details::GetCNR2Coeffs<T, N>>; template <typename T, int N> using CenteredDiffNoiseRobust2 = details::CenteredDifferentiator<T, N, 1, details::GetCNR2Coeffs<T, N>>;
template <typename T, size_t N> using CenteredDiffNoiseRobust4 = details::CenteredDifferentiator<T, N, 1, details::GetCNR4Coeffs<T, N>>; template <typename T, int N> using CenteredDiffNoiseRobust4 = details::CenteredDifferentiator<T, N, 1, details::GetCNR4Coeffs<T, N>>;
// Time-Varying centered differentiators // Time-Varying centered differentiators
template <typename T, size_t N> using TVCenteredDiffNoiseRobust2 = details::TVCenteredDifferentiator<T, N, 1, details::GetCNR2ISDCoeffs<T, N>>; template <typename T, int N> using TVCenteredDiffNoiseRobust2 = details::TVCenteredDifferentiator<T, N, 1, details::GetCNR2ISDCoeffs<T, N>>;
template <typename T, size_t N> using TVCenteredDiffNoiseRobust4 = details::TVCenteredDifferentiator<T, N, 1, details::GetCNR4ISDCoeffs<T, N>>; template <typename T, int N> using TVCenteredDiffNoiseRobust4 = details::TVCenteredDifferentiator<T, N, 1, details::GetCNR4ISDCoeffs<T, N>>;
// Second-order backward differentiators // Second-order backward differentiators
template <typename T, size_t N> using BackwardDiffSecondOrder = details::BackwardDifferentiator<T, N, 2, details::GetSOFNRCoeffs<T, N>>; template <typename T, int N> using BackwardDiffSecondOrder = details::BackwardDifferentiator<T, N, 2, details::GetSOFNRCoeffs<T, N>>;
// Second-order Time-Varying backward differentiators // Second-order Time-Varying backward differentiators
template <typename T, size_t N> using TVBackwardDiffSecondOrder = details::TVBackwardDifferentiator<T, N, 2, details::GetSOFNRISDCoeffs<T, N>>; template <typename T, int N> using TVBackwardDiffSecondOrder = details::TVBackwardDifferentiator<T, N, 2, details::GetSOFNRISDCoeffs<T, N>>;
// Second-order centered differentiators // Second-order centered differentiators
template <typename T, size_t N> using CenteredDiffSecondOrder = details::CenteredDifferentiator<T, N, 2, details::GetSOCNRCoeffs<T, N>>; template <typename T, int N> using CenteredDiffSecondOrder = details::CenteredDifferentiator<T, N, 2, details::GetSOCNRCoeffs<T, N>>;
// Second-order Time-Varying centered differentiators // Second-order Time-Varying centered differentiators
template <typename T, size_t N> using TVCenteredDiffSecondOrder = details::TVCenteredDifferentiator<T, N, 2, details::GetSOCNRISDCoeffs<T, N>>; template <typename T, int N> using TVCenteredDiffSecondOrder = details::TVCenteredDifferentiator<T, N, 2, details::GetSOCNRISDCoeffs<T, N>>;
} // namespace difi } // namespace difi

Wyświetl plik

@ -61,41 +61,41 @@ using BilinearTransformcf = BilinearTransform<std::complex<float>>;
using BilinearTransformcd = BilinearTransform<std::complex<double>>; using BilinearTransformcd = BilinearTransform<std::complex<double>>;
// 1st order centered differentiators // 1st order centered differentiators
template <size_t N> using CenteredDiffBasicf = CenteredDiffBasic<float, N>; template <int N> using CenteredDiffBasicf = CenteredDiffBasic<float, N>;
template <size_t N> using CenteredDiffBasicd = CenteredDiffBasic<double, N>; template <int N> using CenteredDiffBasicd = CenteredDiffBasic<double, N>;
template <size_t N> using CenteredDiffLowNoiseLanczosf = CenteredDiffLowNoiseLanczos<float, N>; template <int N> using CenteredDiffLowNoiseLanczosf = CenteredDiffLowNoiseLanczos<float, N>;
template <size_t N> using CenteredDiffLowNoiseLanczosd = CenteredDiffLowNoiseLanczos<double, N>; template <int N> using CenteredDiffLowNoiseLanczosd = CenteredDiffLowNoiseLanczos<double, N>;
template <size_t N> using CenteredDiffSuperLowNoiseLanczosf = CenteredDiffSuperLowNoiseLanczos<float, N>; template <int N> using CenteredDiffSuperLowNoiseLanczosf = CenteredDiffSuperLowNoiseLanczos<float, N>;
template <size_t N> using CenteredDiffSuperLowNoiseLanczosd = CenteredDiffSuperLowNoiseLanczos<double, N>; template <int N> using CenteredDiffSuperLowNoiseLanczosd = CenteredDiffSuperLowNoiseLanczos<double, N>;
template <size_t N> using CenteredDiffNoiseRobust2f = CenteredDiffNoiseRobust2<float, N>; template <int N> using CenteredDiffNoiseRobust2f = CenteredDiffNoiseRobust2<float, N>;
template <size_t N> using CenteredDiffNoiseRobust2d = CenteredDiffNoiseRobust2<double, N>; template <int N> using CenteredDiffNoiseRobust2d = CenteredDiffNoiseRobust2<double, N>;
template <size_t N> using CenteredDiffNoiseRobust4f = CenteredDiffNoiseRobust4<float, N>; template <int N> using CenteredDiffNoiseRobust4f = CenteredDiffNoiseRobust4<float, N>;
template <size_t N> using CenteredDiffNoiseRobust4d = CenteredDiffNoiseRobust4<double, N>; template <int N> using CenteredDiffNoiseRobust4d = CenteredDiffNoiseRobust4<double, N>;
template <size_t N> using TVCenteredDiffNoiseRobust2f = TVCenteredDiffNoiseRobust2<float, N>; template <int N> using TVCenteredDiffNoiseRobust2f = TVCenteredDiffNoiseRobust2<float, N>;
template <size_t N> using TVCenteredDiffNoiseRobust2d = TVCenteredDiffNoiseRobust2<double, N>; template <int N> using TVCenteredDiffNoiseRobust2d = TVCenteredDiffNoiseRobust2<double, N>;
template <size_t N> using TVCenteredDiffNoiseRobust4f = TVCenteredDiffNoiseRobust4<float, N>; template <int N> using TVCenteredDiffNoiseRobust4f = TVCenteredDiffNoiseRobust4<float, N>;
template <size_t N> using TVCenteredDiffNoiseRobust4d = TVCenteredDiffNoiseRobust4<double, N>; template <int N> using TVCenteredDiffNoiseRobust4d = TVCenteredDiffNoiseRobust4<double, N>;
// 2nd order centered differentiators // 2nd order centered differentiators
template <size_t N> using CenteredDiffSecondOrderf = CenteredDiffSecondOrder<float, N>; template <int N> using CenteredDiffSecondOrderf = CenteredDiffSecondOrder<float, N>;
template <size_t N> using CenteredDiffSecondOrderd = CenteredDiffSecondOrder<double, N>; template <int N> using CenteredDiffSecondOrderd = CenteredDiffSecondOrder<double, N>;
template <size_t N> using TVCenteredDiffSecondOrderf = TVCenteredDiffSecondOrder<float, N>; template <int N> using TVCenteredDiffSecondOrderf = TVCenteredDiffSecondOrder<float, N>;
template <size_t N> using TVCenteredDiffSecondOrderd = TVCenteredDiffSecondOrder<double, N>; template <int N> using TVCenteredDiffSecondOrderd = TVCenteredDiffSecondOrder<double, N>;
// 1st order backward differentiators // 1st order backward differentiators
template <size_t N> using BackwardDiffNoiseRobustf = BackwardDiffNoiseRobust<float, N>; template <int N> using BackwardDiffNoiseRobustf = BackwardDiffNoiseRobust<float, N>;
template <size_t N> using BackwardDiffNoiseRobustd = BackwardDiffNoiseRobust<double, N>; template <int N> using BackwardDiffNoiseRobustd = BackwardDiffNoiseRobust<double, N>;
template <size_t N> using BackwardDiffHybridNoiseRobustf = BackwardDiffHybridNoiseRobust<float, N>; template <int N> using BackwardDiffHybridNoiseRobustf = BackwardDiffHybridNoiseRobust<float, N>;
template <size_t N> using BackwardDiffHybridNoiseRobustd = BackwardDiffHybridNoiseRobust<double, N>; template <int N> using BackwardDiffHybridNoiseRobustd = BackwardDiffHybridNoiseRobust<double, N>;
template <size_t N> using TVBackwardDiffNoiseRobustf = TVBackwardDiffNoiseRobust<float, N>; template <int N> using TVBackwardDiffNoiseRobustf = TVBackwardDiffNoiseRobust<float, N>;
template <size_t N> using TVBackwardDiffNoiseRobustd = TVBackwardDiffNoiseRobust<double, N>; template <int N> using TVBackwardDiffNoiseRobustd = TVBackwardDiffNoiseRobust<double, N>;
template <size_t N> using TVBackwardDiffHybridNoiseRobustf = TVBackwardDiffHybridNoiseRobust<float, N>; template <int N> using TVBackwardDiffHybridNoiseRobustf = TVBackwardDiffHybridNoiseRobust<float, N>;
template <size_t N> using TVBackwardDiffHybridNoiseRobustd = TVBackwardDiffHybridNoiseRobust<double, N>; template <int N> using TVBackwardDiffHybridNoiseRobustd = TVBackwardDiffHybridNoiseRobust<double, N>;
// 2nd order backward differentiators // 2nd order backward differentiators
template <size_t N> using BackwardDiffSecondOrderf = BackwardDiffSecondOrder<float, N>; template <int N> using BackwardDiffSecondOrderf = BackwardDiffSecondOrder<float, N>;
template <size_t N> using BackwardDiffSecondOrderd = BackwardDiffSecondOrder<double, N>; template <int N> using BackwardDiffSecondOrderd = BackwardDiffSecondOrder<double, N>;
template <size_t N> using TVBackwardDiffSecondOrderf = TVBackwardDiffSecondOrder<float, N>; template <int N> using TVBackwardDiffSecondOrderf = TVBackwardDiffSecondOrder<float, N>;
template <size_t N> using TVBackwardDiffSecondOrderd = TVBackwardDiffSecondOrder<double, N>; template <int N> using TVBackwardDiffSecondOrderd = TVBackwardDiffSecondOrder<double, N>;
} // namespace difi } // namespace difi

Wyświetl plik

@ -32,7 +32,7 @@ namespace difi {
// https://stackoverflow.com/questions/44718971/calculate-binomial-coffeficient-very-reliably // https://stackoverflow.com/questions/44718971/calculate-binomial-coffeficient-very-reliably
template <typename T> template <typename T>
constexpr T Binomial(size_t n, size_t k) constexpr T Binomial(int n, int k)
{ {
if (k > n) if (k > n)
return T(0); return T(0);

Wyświetl plik

@ -44,7 +44,7 @@ addTest(GenericFilterTests)
addTest(polynome_functions_tests) addTest(polynome_functions_tests)
addTest(DigitalFilterTests) addTest(DigitalFilterTests)
addTest(MovingAverageFilterTests) addTest(MovingAverageFilterTests)
addTest(ButterWorthFilterTests) addTest(ButterworthFilterTests)
# Differentiators # Differentiators
addTest(differentiator_tests) addTest(differentiator_tests)

Wyświetl plik

@ -45,7 +45,7 @@ DISABLE_CONVERSION_WARNING_END
TEMPLATE_TEST_CASE_METHOD(System, "Digital filter", "[df]", float, double) TEMPLATE_TEST_CASE_METHOD(System, "Digital filter", "[df]", float, double)
{ {
System<TestType> s; System<TestType> s;
auto df = difi::DigitalFilter<TestType>(aCoeff, bCoeff); auto df = difi::DigitalFilter<TestType>(s.aCoeff, s.bCoeff);
test_coeffs(s.aCoeff, s.bCoeff, df, std::numeric_limits<TestType>::epsilon() * 10); test_coeffs(s.aCoeff, s.bCoeff, df, std::numeric_limits<TestType>::epsilon() * 10);
test_results(s.results, s.data, df, std::numeric_limits<TestType>::epsilon() * 10); test_results(s.results, s.data, df, std::numeric_limits<TestType>::epsilon() * 10);
} }

Wyświetl plik

@ -33,135 +33,245 @@
using namespace difi; using namespace difi;
template <typename T, typename Tuple, typename Derived> namespace tester {
class DiffTester {
friend Derived;
static constexpr const size_t TSize = std::tuple_size_v<Tuple>;
public: namespace details {
DiffTester(const Tuple& filters, const vectX_t<T>& f, const vectX_t<T>& df)
: m_filters(filters)
, m_f(f)
, m_df(df)
{}
void run(const std::array<T, TSize>& eps) { testRunner<TSize - 1>(eps); } template <typename Tuple, size_t Index>
struct set_time_step {
private: static void impl(Tuple& filters, double dt)
template <typename Filter>
void test(Filter& filt, T eps)
{ {
static_cast<Derived&>(*this).testFilter(filt, eps); std::get<Index>(filters).setTimestep(dt);
set_time_step<Tuple, Index - 1>::impl(filters, dt);
} }
template <size_t Index>
void testRunner(const std::array<T, TSize>& eps)
{
test(std::get<Index>(m_filters), eps[Index]);
testRunner<Index - 1>(eps);
}
template <>
void testRunner<0>(const std::array<T, TSize>& eps) { test(std::get<0>(m_filters), eps[0]); }
private:
vectX_t<T> m_f;
vectX_t<T> m_df;
Tuple m_filters;
}; };
template <typename T, typename Tuple> template <typename Tuple>
class TFDiffTester : public DiffTester<T, Tuple, TFDiffTester<T, Tuple>> { struct set_time_step<Tuple, 0> {
friend DiffTester<T, Tuple, TFDiffTester<T, Tuple>>; static void impl(Tuple& filters, double dt)
public:
TFDiffTester(const Tuple& filters, const vectX_t<T>& f, const vectX_t<T>& df)
: DiffTester(filters, f, df)
{}
void setFilterTimestep(T step) { setStep<TSize - 1>(step); }
private:
template <typename Filter>
void testFilter(Filter& filt, T eps)
{ {
for (int i = 0; i < 50; ++i) { std::get<0>(filters).setTimestep(dt);
auto value = filt.stepFilter(m_f(i)); // First initialize, some steps
value = 2.;
}
for (int i = 50; i < STEPS; ++i) {
auto value = filt.stepFilter(m_f(i));
REQUIRE_SMALL(std::abs(value - m_df(i - filt.center())), eps);
}
} }
template <size_t Index>
void setStep(T step)
{
std::get<Index>(m_filters).setTimestep(step);
setStep<Index - 1>(step);
}
template <>
void setStep<0>(T step) { std::get<0>(m_filters).setTimestep(step); }
}; };
template <typename T, typename Tuple> // For TF tests
class TVDiffTester : public DiffTester<T, Tuple, TVDiffTester<T, Tuple>> { template <typename Filter>
friend DiffTester<T, Tuple, TVDiffTester<T, Tuple>>; void test_filter(Filter& filt, const vectX_t<double>& f, const vectX_t<double>& df, double eps)
{
public: for (int i = 0; i < 50; ++i) {
TVDiffTester(const Tuple& filters, const vectX_t<T>& t, const vectX_t<T>& f, const vectX_t<T>& df) filt.stepFilter(f(i)); // First initialize, some steps
: DiffTester(filters, f, df) // auto value = filt.stepFilter(f(i)); // First initialize, some steps
, m_time(t) // value = 2.;
{}
private:
template <typename Filter>
void testFilter(Filter& filt, T eps)
{
for (int i = 0; i < 50; ++i) {
auto value = filt.stepFilter(m_time(i), m_f(i)); // First initialize, some steps
value = 2.;
}
for (int i = 50; i < STEPS; ++i) {
auto value = filt.stepFilter(m_time(i), m_f(i));
REQUIRE_SMALL(std::abs(value - m_df(i - filt.center())), eps);
}
} }
private: for (int i = 50; i < f.size(); ++i) {
vectX_t<T> m_time; auto value = filt.stepFilter(f(i));
REQUIRE_SMALL(std::abs(value - df(i - filt.center())), eps);
}
}
// For TV tests
template <typename Filter>
void test_filter(Filter& filt, const vectX_t<double>& t, const vectX_t<double>& f, const vectX_t<double>& df, double eps)
{
for (int i = 0; i < 50; ++i) {
filt.stepFilter(t(i), f(i)); // First initialize, some steps
// auto value = filt.stepFilter(f(i)); // First initialize, some steps
// value = 2.;
}
for (int i = 50; i < f.size(); ++i) {
auto value = filt.stepFilter(t(i), f(i));
REQUIRE_SMALL(std::abs(value - df(i - filt.center())), eps);
}
}
template <typename Tuple, size_t Index>
struct run_test {
static constexpr size_t ind = Index;
// For TF tests
static void impl(Tuple& filters, const vectX_t<double>& f, const vectX_t<double>& df, const vectX_t<double>& eps)
{
test_filter(std::get<Index>(filters), f, df, eps(ind));
run_test<Tuple, Index - 1>::impl(filters, f, df, eps);
}
// For TV tests
static void impl(Tuple& filters, const vectX_t<double>& t, const vectX_t<double>& f, const vectX_t<double>& df, const vectX_t<double>& eps)
{
test_filter(std::get<Index>(filters), t, f, df, eps(ind));
run_test<Tuple, Index - 1>::impl(filters, t, f, df, eps);
}
}; };
template <size_t N> template <typename Tuple>
struct run_test<Tuple, 0> {
// For TF tests
static void impl(Tuple& filters, const vectX_t<double>& f, const vectX_t<double>& df, const vectX_t<double>& eps)
{
test_filter(std::get<0>(filters), f, df, eps(0));
}
// For TV tests
static void impl(Tuple& filters, const vectX_t<double>& t, const vectX_t<double>& f, const vectX_t<double>& df, const vectX_t<double>& eps)
{
test_filter(std::get<0>(filters), t, f, df, eps(0));
}
};
} // namespace details
template <typename Tuple>
void set_time_steps(Tuple& filters, double dt)
{
details::set_time_step<Tuple, std::tuple_size<Tuple>::value - 1>::impl(filters, dt);
}
template <typename Tuple>
void run_tests(Tuple& filters, const vectX_t<double>& f, const vectX_t<double>& df, const vectX_t<double>& eps)
{
details::run_test<Tuple, std::tuple_size<Tuple>::value - 1>::impl(filters, f, df, eps);
}
template <typename Tuple>
void run_tests(Tuple& filters, const vectX_t<double>& t, const vectX_t<double>& f, const vectX_t<double>& df, const vectX_t<double>& eps)
{
details::run_test<Tuple, std::tuple_size<Tuple>::value - 1>::impl(filters, t, f, df, eps);
}
// template <typename T, typename Tuple, typename Derived>
// class DiffTester {
// friend Derived;
// static constexpr const size_t TSize = std::tuple_size_v<Tuple>;
// public:
// DiffTester(const Tuple& filters, const vectX_t<T>& f, const vectX_t<T>& df)
// : m_filters(filters)
// , m_f(f)
// , m_df(df)
// {}
// void run(const std::array<T, TSize>& eps) { testRunner<TSize - 1>(eps); }
// private:
// template <typename Filter>
// void test(Filter& filt, T eps)
// {
// static_cast<Derived&>(*this).testFilter(filt, eps);
// }
// template <size_t Index>
// void testRunner(const std::array<T, TSize>& eps)
// {
// test(std::get<Index>(m_filters), eps[Index]);
// testRunner<Index - 1>(eps);
// }
// template <>
// void testRunner<0>(const std::array<T, TSize>& eps) { test(std::get<0>(m_filters), eps[0]); }
// private:
// vectX_t<T> m_f;
// vectX_t<T> m_df;
// Tuple m_filters;
// };
// template <typename T, typename Tuple>
// class TFDiffTester : public DiffTester<T, Tuple, TFDiffTester<T, Tuple>> {
// friend DiffTester<T, Tuple, TFDiffTester<T, Tuple>>;
// public:
// TFDiffTester(const Tuple& filters, const vectX_t<T>& f, const vectX_t<T>& df)
// : DiffTester(filters, f, df)
// {}
// void setFilterTimestep(T step) { setStep<TSize - 1>(step); }
// private:
// template <typename Filter>
// void testFilter(Filter& filt, T eps)
// {
// for (int i = 0; i < 50; ++i) {
// auto value = filt.stepFilter(m_f(i)); // First initialize, some steps
// value = 2.;
// }
// for (int i = 50; i < STEPS; ++i) {
// auto value = filt.stepFilter(m_f(i));
// REQUIRE_SMALL(std::abs(value - m_df(i - filt.center())), eps);
// }
// }
// template <size_t Index>
// void setStep(T step)
// {
// std::get<Index>(m_filters).setTimestep(step);
// setStep<Index - 1>(step);
// }
// template <>
// void setStep<0>(T step) { std::get<0>(m_filters).setTimestep(step); }
// };
// template <typename T, typename Tuple>
// class TVDiffTester : public DiffTester<T, Tuple, TVDiffTester<T, Tuple>> {
// friend DiffTester<T, Tuple, TVDiffTester<T, Tuple>>;
// public:
// TVDiffTester(const Tuple& filters, const vectX_t<T>& t, const vectX_t<T>& f, const vectX_t<T>& df)
// : DiffTester(filters, f, df)
// , m_time(t)
// {}
// private:
// template <typename Filter>
// void testFilter(Filter& filt, T eps)
// {
// for (int i = 0; i < 50; ++i) {
// auto value = filt.stepFilter(m_time(i), m_f(i)); // First initialize, some steps
// value = 2.;
// }
// for (int i = 50; i < STEPS; ++i) {
// auto value = filt.stepFilter(m_time(i), m_f(i));
// REQUIRE_SMALL(std::abs(value - m_df(i - filt.center())), eps);
// }
// }
// private:
// vectX_t<T> m_time;
// };
template <int N>
using central_list = std::tuple<CenteredDiffBasicd<N>, CenteredDiffLowNoiseLanczosd<N>, CenteredDiffSuperLowNoiseLanczosd<N>, CenteredDiffNoiseRobust2d<N>, CenteredDiffNoiseRobust4d<N>>; using central_list = std::tuple<CenteredDiffBasicd<N>, CenteredDiffLowNoiseLanczosd<N>, CenteredDiffSuperLowNoiseLanczosd<N>, CenteredDiffNoiseRobust2d<N>, CenteredDiffNoiseRobust4d<N>>;
template <size_t N> // template <size_t N>
TFDiffTester<double, central_list<N>> generateCTester(const vectX_t<double>& f, const vectX_t<double>& df) // TFDiffTester<double, central_list<N>> generateCTester(const vectX_t<double>& f, const vectX_t<double>& df)
{ // {
return { central_list<N>{}, f, df }; // return { central_list<N>{}, f, df };
} // }
template <size_t N> // template <size_t N>
TFDiffTester<double, std::tuple<CenteredDiffSecondOrderd<N>>> generateC2OTester(const vectX_t<double>& f, const vectX_t<double>& df) // TFDiffTester<double, std::tuple<CenteredDiffSecondOrderd<N>>> generateC2OTester(const vectX_t<double>& f, const vectX_t<double>& df)
{ // {
return { std::tuple<CenteredDiffSecondOrderd<N>>{}, f, df }; // return { std::tuple<CenteredDiffSecondOrderd<N>>{}, f, df };
} // }
template <size_t N> template <int N>
using tv_central_list = std::tuple<TVCenteredDiffNoiseRobust2d<N>, TVCenteredDiffNoiseRobust4d<N>>; using tv_central_list = std::tuple<TVCenteredDiffNoiseRobust2d<N>, TVCenteredDiffNoiseRobust4d<N>>;
template <size_t N> // template <size_t N>
TVDiffTester<double, tv_central_list<N>> generateTVCTester(const vectX_t<double>& t, const vectX_t<double>& f, const vectX_t<double>& df) // TVDiffTester<double, tv_central_list<N>> generateTVCTester(const vectX_t<double>& t, const vectX_t<double>& f, const vectX_t<double>& df)
{ // {
return { tv_central_list<N>{}, t, f, df }; // return { tv_central_list<N>{}, t, f, df };
} // }
template <size_t N> // template <size_t N>
TVDiffTester<double, std::tuple<TVCenteredDiffSecondOrderd<N>>> generateTVC2OTester(const vectX_t<double>& t, const vectX_t<double>& f, const vectX_t<double>& df) // TVDiffTester<double, std::tuple<TVCenteredDiffSecondOrderd<N>>> generateTVC2OTester(const vectX_t<double>& t, const vectX_t<double>& f, const vectX_t<double>& df)
{ // {
return { std::tuple<TVCenteredSecondOrderDiff<N>>{}, t, f, df }; // return { std::tuple<TVCenteredSecondOrderDiff<N>>{}, t, f, df };
} // }
} // namespace tester

Wyświetl plik

@ -25,7 +25,6 @@
// of the authors and should not be interpreted as representing official policies, // of the authors and should not be interpreted as representing official policies,
// either expressed or implied, of the FreeBSD Project. // either expressed or implied, of the FreeBSD Project.
#pragma once
#include "catch_helper.h" #include "catch_helper.h"
#include "diffTesters.h" #include "diffTesters.h"
#include "noisy_function_generator.h" #include "noisy_function_generator.h"
@ -38,13 +37,13 @@ constexpr const int SIN_FREQUENCY = 1;
template <typename T> constexpr const std::array<T, 5> POLY_4 = { 2, -3, 3, 2, -5 }; template <typename T> constexpr const std::array<T, 5> POLY_4 = { 2, -3, 3, 2, -5 };
template <typename T> constexpr const std::array<T, 8> POLY_7 = { 10, -12, 5, 6, -9, -3, -2, 4 }; template <typename T> constexpr const std::array<T, 8> POLY_7 = { 10, -12, 5, 6, -9, -3, -2, 4 };
template <size_t N> template <int N>
vectN_t<double, N> generateLNLCoeffs() vectN_t<double, N> generateLNLCoeffs()
{ {
static_assert(N > 2 && N % 2 == 1, "N must be odd"); static_assert(N > 2 && N % 2 == 1, "N must be odd");
vectN_t<double, N> lnl; vectN_t<double, N> lnl;
const size_t M = (N - 1) / 2; const int M = (N - 1) / 2;
for (size_t i = 0; i < M + 1; ++i) { for (int i = 0; i < M + 1; ++i) {
lnl(i) = static_cast<double>(M - i); lnl(i) = static_cast<double>(M - i);
lnl(M + i) = -static_cast<double>(i); lnl(M + i) = -static_cast<double>(i);
} }
@ -52,10 +51,10 @@ vectN_t<double, N> generateLNLCoeffs()
return lnl; return lnl;
} }
template <size_t N> template <int N>
void checkCoeffs(const vectN_t<double, N>& coeffs, const vectN_t<double, N>& goodCoeffs) void checkCoeffs(const vectN_t<double, N>& coeffs, const vectN_t<double, N>& goodCoeffs)
{ {
for (size_t i = 0; i < N; ++i) for (int i = 0; i < N; ++i)
REQUIRE_SMALL(std::abs(coeffs(i) - goodCoeffs(i)), std::numeric_limits<double>::epsilon() * 5); REQUIRE_SMALL(std::abs(coeffs(i) - goodCoeffs(i)), std::numeric_limits<double>::epsilon() * 5);
} }
@ -83,15 +82,17 @@ TEST_CASE("Sinus time-fixed central derivative", "[sin][central][1st]")
{ {
double dt = 0.001; double dt = 0.001;
auto sg = sinGenerator<double>(STEPS, SIN_AMPLITUDE, SIN_FREQUENCY, dt); auto sg = sinGenerator<double>(STEPS, SIN_AMPLITUDE, SIN_FREQUENCY, dt);
auto ct7 = generateCTester<7>(std::get<0>(sg), std::get<1>(sg)); auto ct7 = tester::central_list<7>{};
auto ct9 = generateCTester<9>(std::get<0>(sg), std::get<1>(sg)); auto ct9 = tester::central_list<9>{};
ct7.setFilterTimestep(dt); tester::set_time_steps(ct7, dt);
ct9.setFilterTimestep(dt); tester::set_time_steps(ct9, dt);
std::array<double, 5> eps = { 1e-10, 1e-1, 1e-6, 1e-1, 1e-6 }; // Value checked with MATLAB difi::vectX_t<double> eps{5};
ct7.run(eps); eps << 1e-10, 1e-1, 1e-6, 1e-1, 1e-6; // Value checked with MATLAB
ct9.run(eps);
tester::run_tests(ct7, std::get<0>(sg), std::get<1>(sg), eps);
tester::run_tests(ct9, std::get<0>(sg), std::get<1>(sg), eps);
} }
TEST_CASE("Polynome time-fixed central derivative", "[poly][central][1st]") TEST_CASE("Polynome time-fixed central derivative", "[poly][central][1st]")
@ -99,27 +100,31 @@ TEST_CASE("Polynome time-fixed central derivative", "[poly][central][1st]")
double dt = 0.001; double dt = 0.001;
{ {
auto pg = polyGenerator<double>(STEPS, POLY_4<double>, dt); auto pg = polyGenerator<double>(STEPS, POLY_4<double>, dt);
auto ct7 = generateCTester<7>(std::get<0>(pg), std::get<1>(pg)); auto ct7 = tester::central_list<7>{};
auto ct9 = generateCTester<9>(std::get<0>(pg), std::get<1>(pg)); auto ct9 = tester::central_list<9>{};
ct7.setFilterTimestep(dt); tester::set_time_steps(ct7, dt);
ct9.setFilterTimestep(dt); tester::set_time_steps(ct9, dt);
std::array<double, 5> eps = { 1e-12, 1e-4, 1e-12, 1e-4, 1e-12 }; // Value checked with MATLAB difi::vectX_t<double> eps{5};
ct7.run(eps); eps << 1e-12, 1e-4, 1e-12, 1e-4, 1e-12; // Value checked with MATLAB
ct9.run(eps);
tester::run_tests(ct7, std::get<0>(pg), std::get<1>(pg), eps);
tester::run_tests(ct9, std::get<0>(pg), std::get<1>(pg), eps);
} }
{ {
auto pg = polyGenerator<double>(STEPS, POLY_7<double>, dt); auto pg = polyGenerator<double>(STEPS, POLY_7<double>, dt);
auto ct7 = generateCTester<7>(std::get<0>(pg), std::get<1>(pg)); auto ct7 = tester::central_list<7>{};
auto ct9 = generateCTester<9>(std::get<0>(pg), std::get<1>(pg)); auto ct9 = tester::central_list<9>{};
ct7.setFilterTimestep(dt); tester::set_time_steps(ct7, dt);
ct9.setFilterTimestep(dt); tester::set_time_steps(ct9, dt);
std::array<double, 5> eps = { 1e-11, 1e-3, 1e-9, 1e-4, 1e-9 }; // Value checked with MATLAB difi::vectX_t<double> eps{5};
ct7.run(eps); eps << 1e-11, 1e-3, 1e-9, 1e-4, 1e-9; // Value checked with MATLAB
ct9.run(eps);
tester::run_tests(ct7, std::get<0>(pg), std::get<1>(pg), eps);
tester::run_tests(ct9, std::get<0>(pg), std::get<1>(pg), eps);
} }
} }
@ -127,30 +132,34 @@ TEST_CASE("2nd order sinus time-fixed center derivative", "[sin][center][2nd]")
{ {
double dt = 0.001; double dt = 0.001;
auto sg = sinGenerator<double>(STEPS, SIN_AMPLITUDE, SIN_FREQUENCY, dt); auto sg = sinGenerator<double>(STEPS, SIN_AMPLITUDE, SIN_FREQUENCY, dt);
auto ct7 = generateC2OTester<7>(std::get<0>(sg), std::get<2>(sg)); auto ct7 = std::tuple<CenteredDiffSecondOrderd<7>>{};
auto ct9 = generateC2OTester<9>(std::get<0>(sg), std::get<2>(sg)); auto ct9 = std::tuple<CenteredDiffSecondOrderd<9>>{};
auto ct11 = generateC2OTester<11>(std::get<0>(sg), std::get<2>(sg)); auto ct11 = std::tuple<CenteredDiffSecondOrderd<11>>{};
ct7.setFilterTimestep(dt); tester::set_time_steps(ct7, dt);
ct9.setFilterTimestep(dt); tester::set_time_steps(ct9, dt);
ct11.setFilterTimestep(dt); tester::set_time_steps(ct11, dt);
std::array<double, 1> eps = { 2e-1 }; // Value checked with MATLAB difi::vectX_t<double> eps{1};
ct7.run(eps); eps << 2e-1;
ct9.run(eps);
ct11.run(eps); tester::run_tests(ct7, std::get<0>(sg), std::get<2>(sg), eps);
tester::run_tests(ct9, std::get<0>(sg), std::get<2>(sg), eps);
tester::run_tests(ct11, std::get<0>(sg), std::get<2>(sg), eps);
} }
TEST_CASE("Sinus time-varying central derivative", "[tv][sin][central][1st]") TEST_CASE("Sinus time-varying central derivative", "[tv][sin][central][1st]")
{ {
double dt = 0.001; double dt = 0.001;
auto sg = tvSinGenerator<double>(STEPS, SIN_AMPLITUDE, SIN_FREQUENCY, dt); auto sg = tvSinGenerator<double>(STEPS, SIN_AMPLITUDE, SIN_FREQUENCY, dt);
auto ct7 = generateTVCTester<7>(std::get<0>(sg), std::get<1>(sg), std::get<2>(sg)); auto ct7 = tester::tv_central_list<7>{};
auto ct9 = generateTVCTester<9>(std::get<0>(sg), std::get<1>(sg), std::get<2>(sg)); auto ct9 = tester::tv_central_list<9>{};
std::array<double, 2> eps = { 1., 1. }; difi::vectX_t<double> eps{2};
ct7.run(eps); eps << 1., 1.;
ct9.run(eps);
tester::run_tests(ct7, std::get<0>(sg), std::get<1>(sg), std::get<2>(sg), eps);
tester::run_tests(ct9, std::get<0>(sg), std::get<1>(sg), std::get<2>(sg), eps);
} }
TEST_CASE("Polynome time-varying central derivative", "[tv][poly][central][1st]") TEST_CASE("Polynome time-varying central derivative", "[tv][poly][central][1st]")
@ -158,21 +167,25 @@ TEST_CASE("Polynome time-varying central derivative", "[tv][poly][central][1st]"
double dt = 0.001; double dt = 0.001;
{ {
auto pg = tvPolyGenerator<double>(STEPS, POLY_4<double>, dt); auto pg = tvPolyGenerator<double>(STEPS, POLY_4<double>, dt);
auto ct7 = generateTVCTester<7>(std::get<0>(pg), std::get<1>(pg), std::get<2>(pg)); auto ct7 = tester::tv_central_list<7>{};
auto ct9 = generateTVCTester<9>(std::get<0>(pg), std::get<1>(pg), std::get<2>(pg)); auto ct9 = tester::tv_central_list<9>{};
std::array<double, 2> eps = { 1e-3, 1e-3 }; difi::vectX_t<double> eps{2};
ct7.run(eps); eps << 1e-3, 1e-3;
ct9.run(eps);
tester::run_tests(ct7, std::get<0>(pg), std::get<1>(pg), std::get<2>(pg), eps);
tester::run_tests(ct9, std::get<0>(pg), std::get<1>(pg), std::get<2>(pg), eps);
} }
{ {
auto pg = tvPolyGenerator<double>(STEPS, POLY_4<double>, dt); auto pg = tvPolyGenerator<double>(STEPS, POLY_7<double>, dt);
auto ct7 = generateTVCTester<7>(std::get<0>(pg), std::get<1>(pg), std::get<2>(pg)); auto ct7 = tester::tv_central_list<7>{};
auto ct9 = generateTVCTester<9>(std::get<0>(pg), std::get<1>(pg), std::get<2>(pg)); auto ct9 = tester::tv_central_list<9>{};
std::array<double, 2> eps = { 1e-3, 1e-3 }; difi::vectX_t<double> eps{2};
ct7.run(eps); eps << 1e-2, 1e-2;
ct9.run(eps);
tester::run_tests(ct7, std::get<0>(pg), std::get<1>(pg), std::get<2>(pg), eps);
tester::run_tests(ct9, std::get<0>(pg), std::get<1>(pg), std::get<2>(pg), eps);
} }
} }

Wyświetl plik

@ -76,11 +76,11 @@ FunctionGenerator<T> polyGenerator(int nrSteps, std::array<T, N> coeffs, T dt)
}; };
std::array<T, N - 1> dCoeffs; std::array<T, N - 1> dCoeffs;
for (Eigen::Index i = 1; i < N; ++i) for (size_t i = 1; i < N; ++i)
dCoeffs[i - 1] = i * coeffs[i]; dCoeffs[i - 1] = i * coeffs[i];
std::array<T, N - 2> ddCoeffs; std::array<T, N - 2> ddCoeffs;
for (Eigen::Index i = 1; i < N - 1; ++i) for (size_t i = 1; i < N - 1; ++i)
ddCoeffs[i - 1] = i * dCoeffs[i]; ddCoeffs[i - 1] = i * dCoeffs[i];
vectX_t<T> f(nrSteps); vectX_t<T> f(nrSteps);
@ -159,11 +159,11 @@ TVFunctionGenerator<T> tvPolyGenerator(int nrSteps, std::array<T, N> coeffs, T m
}; };
std::array<T, N - 1> dCoeffs; std::array<T, N - 1> dCoeffs;
for (Eigen::Index i = 1; i < N; ++i) for (size_t i = 1; i < N; ++i)
dCoeffs[i - 1] = i * coeffs[i]; dCoeffs[i - 1] = i * coeffs[i];
std::array<T, N - 2> ddCoeffs; std::array<T, N - 2> ddCoeffs;
for (Eigen::Index i = 1; i < N - 1; ++i) for (size_t i = 1; i < N - 1; ++i)
ddCoeffs[i - 1] = i * dCoeffs[i]; ddCoeffs[i - 1] = i * dCoeffs[i];
vectX_t<T> t(nrSteps); vectX_t<T> t(nrSteps);

Wyświetl plik

@ -27,18 +27,17 @@
#pragma once #pragma once
#ifdef _MSC_VER #if defined(_MSC_VER)
#define DCW_BEGIN \ #define DCW_BEGIN \
__pragma(warning(push)) \ __pragma(warning(push)) \
__pragma(warning(disable : 4305)) __pragma(warning(disable : 4305))
#define DCW_END __pragma(warning(pop)) #define DCW_END __pragma(warning(pop))
#else #elif defined(__GNUC__) || defined(__clang__)
#ifdef __GNUC__ || __clang__
#define DCW_BEGIN \ #define DCW_BEGIN \
_Pragma("GCC warning push") \ _Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wconversion\"") _Pragma("GCC diagnostic ignored \"-Wfloat-conversion\"") \
#define DCW_END _Pragma("GCC warning pop") _Pragma("GCC diagnostic ignored \"-Wconversion\"") // Only needed for clang
#endif #define DCW_END _Pragma("GCC diagnostic pop")
#endif #endif
#ifdef DCW_BEGIN #ifdef DCW_BEGIN