kopia lustrzana https://github.com/vsamy/DiFipp
Need merge check.
rodzic
0033d2fa72
commit
ef7b6dfba1
|
@ -29,8 +29,8 @@ endif()
|
|||
add_compile_options("-D_USE_MATH_DEFINES")
|
||||
|
||||
# Eigen
|
||||
# set(Eigen_REQUIRED "eigen3 >= 3.3")
|
||||
# search_for_eigen()
|
||||
set(Eigen_REQUIRED "eigen3 >= 3.3")
|
||||
search_for_eigen()
|
||||
|
||||
add_subdirectory(include)
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "GenericFilter.h"
|
||||
#include "typedefs.h"
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
|
||||
namespace fratio {
|
||||
|
||||
// https://www.dsprelated.com/showarticle/1119.php
|
||||
template <typename T>
|
||||
class Butterworth : public GenericFilter<T> {
|
||||
class Butterworth : public DigitalFilter<T> {
|
||||
public:
|
||||
T PI = static_cast<T>(M_PI);
|
||||
|
||||
|
@ -39,8 +39,9 @@ private:
|
|||
size_t m_order;
|
||||
T m_fc;
|
||||
T m_fs;
|
||||
Eigen::VectorX<std::complex<T>> m_poles;
|
||||
};
|
||||
|
||||
} // namespace fratio
|
||||
|
||||
#include "Butterworth.inl"
|
||||
#include "Butterworth.tpp"
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "GenericFilter.h"
|
||||
#include "typedefs.h"
|
||||
#include <vector>
|
||||
|
||||
namespace fratio {
|
||||
|
||||
|
@ -9,23 +11,18 @@ class DigitalFilter : public GenericFilter<T> {
|
|||
public:
|
||||
DigitalFilter() = default;
|
||||
DigitalFilter(const std::vector<T>& aCoeff, const std::vector<T>& bCoeff)
|
||||
{
|
||||
setCoeffs(aCoeff, bCoeff);
|
||||
}
|
||||
DigitalFilter(const Eigen::VectorX<T>& aCoeff, const Eigen::VectorX<T>& bCoeff)
|
||||
: GenericFilter<T>(aCoeff, bCoeff)
|
||||
{
|
||||
}
|
||||
|
||||
void setCoeff(const std::vector<double>& aCoeff, const std::vector<double>& bCoeff)
|
||||
{
|
||||
checkCoeff(aCoeff, bCoeff);
|
||||
|
||||
m_aCoeff = aCoeff;
|
||||
m_bCoeff = bCoeff;
|
||||
resetFilter();
|
||||
|
||||
normalize();
|
||||
}
|
||||
|
||||
size_t aOrder() const noexcept { return m_aCoeff.size(); }
|
||||
size_t bOrder() const noexcept { return m_bCoeff.size(); }
|
||||
};
|
||||
|
||||
} // namespace fratio
|
||||
|
||||
#include "DigitalFilter.tpp"
|
|
@ -1,7 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "type_checks.h"
|
||||
#include "typedefs.h"
|
||||
#include <stddef.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fratio {
|
||||
|
@ -11,29 +13,40 @@ class GenericFilter {
|
|||
static_assert(std::is_floating_point<T>::value && !std::is_const<T>::value, "Only accept non-complex floating point types.");
|
||||
|
||||
public:
|
||||
T stepFilter(T data);
|
||||
std::vector<T> filter(const std::vector<T>& data);
|
||||
static std::string filterStatus(FilterStatus status);
|
||||
|
||||
public:
|
||||
// Careful: Only an assert check for the filter status
|
||||
T stepFilter(const T& data);
|
||||
Eigen::VectorX<T> filter(const Eigen::VectorX<T>& data);
|
||||
bool getFilterResults(Eigen::Ref<Eigen::VectorX<T>> results, const Eigen::VectorX<T>& data);
|
||||
void resetFilter();
|
||||
|
||||
void getCoeff(std::vector<T>& aCoeff, std::vector<T>& bCoeff) const noexcept;
|
||||
bool setCoeffs(const std::vector<T>& aCoeff, const std::vector<T>& bCoeff);
|
||||
bool setCoeffs(const Eigen::VectorX<T>& aCoeff, const Eigen::VectorX<T>& bCoeff);
|
||||
void getCoeffs(std::vector<T>& aCoeff, std::vector<T>& bCoeff) const;
|
||||
void getCoeffs(Eigen::Ref<Eigen::VectorX<T>> aCoeff, Eigen::Ref<Eigen::VectorX<T>> bCoeff) const;
|
||||
FilterStatus status() const noexcept { return m_status; }
|
||||
|
||||
protected:
|
||||
GenericFilter() = default;
|
||||
GenericFilter(const std::vector<T>& aCoeff, const std::vector<T>& bCoeff);
|
||||
GenericFilter(const Eigen::VectorX<T>& aCoeff, const Eigen::VectorX<T>& bCoeff);
|
||||
virtual ~GenericFilter() = default;
|
||||
|
||||
void checkCoeff(const std::vector<T>& aCoeff, const std::vector<T>& bCoeff);
|
||||
void normalize();
|
||||
void normalizeCoeffs();
|
||||
template <typename T2>
|
||||
bool checkCoeffs(const T2& aCoeff, const T2& bCoeff);
|
||||
|
||||
protected:
|
||||
std::vector<T> m_aCoeff;
|
||||
std::vector<T> m_bCoeff;
|
||||
FilterStatus m_status;
|
||||
Eigen::VectorX<T> m_aCoeff;
|
||||
Eigen::VectorX<T> m_bCoeff;
|
||||
|
||||
private:
|
||||
std::vector<T> m_filteredData;
|
||||
std::vector<T> m_rawData;
|
||||
Eigen::VectorX<T> m_filteredData;
|
||||
Eigen::VectorX<T> m_rawData;
|
||||
};
|
||||
|
||||
} // namespace fratio
|
||||
|
||||
#include "GenericFilter.inl"
|
||||
#include "GenericFilter.tpp"
|
||||
|
|
|
@ -1,20 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include "GenericFilter.h"
|
||||
#include "DigitalFilter.h"
|
||||
#include "typedefs.h"
|
||||
|
||||
namespace fratio {
|
||||
|
||||
template <typename T>
|
||||
class MovingAverage : public GenericFilter<T> {
|
||||
class MovingAverage : public DigitalFilter<T> {
|
||||
public:
|
||||
MovingAverage() = default;
|
||||
MovingAverage(size_t windowSize)
|
||||
: GenericFilter<T>({ 1 }, std::vector<T>(windowSize, T(1) / windowSize))
|
||||
: DigitalFilter<T>(Eigen::VectorX<T>::Constant(1, T(1)), Eigen::VectorX<T>::Constant(windowSize, T(1) / windowSize)))
|
||||
{
|
||||
}
|
||||
|
||||
void setWindowSize(size_t windowSize) { setCoeff({ 1 }, std::vector<T>(windowSize, 1 / windowSize)); }
|
||||
size_t windowSize() const noexcept { return m_bCoeff.size(); }
|
||||
void setWindowSize(size_t windowSize) { setCoeffs(Eigen::VectorX<T>::Constant(1, T(1)), Eigen::VectorX<T>::Constant(windowSize, T(1) / windowSize)); }
|
||||
size_t windowSize() const noexcept { return bOrder(); }
|
||||
: DigitalFilter<T>(Eigen::VectorX<T>::Constant(1, T(1)), Eigen::VectorX<T>::Constant(windowSize, T(1) / windowSize)))
|
||||
{
|
||||
}
|
||||
|
||||
void setWindowSize(size_t windowSize) { setCoeffs(Eigen::VectorX<T>::Constant(1, T(1)), Eigen::VectorX<T>::Constant(windowSize, T(1) / windowSize)); }
|
||||
size_t windowSize() const noexcept { return bOrder(); }
|
||||
};
|
||||
|
||||
} // namespace fratio
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "type_checks.h"
|
||||
#include "typedefs.h"
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
|
||||
namespace fratio {
|
||||
|
||||
|
@ -11,21 +11,32 @@ struct VietaAlgo {
|
|||
static_assert(std::is_arithmetic<internal::complex_sub_type_t<T>>::value, "This struct can only accept arithmetic types or complex.");
|
||||
|
||||
// Vieta's computation: https://en.wikipedia.org/wiki/Vieta%27s_formulas
|
||||
static std::vector<T> polyCoeffFromRoot(const std::vector<T>& poles);
|
||||
static Eigen::VectorX<T> polyCoeffFromRoot(const Eigen::VectorX<T>& poles);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> VietaAlgo<T>::polyCoeffFromRoot(const std::vector<T>& poles)
|
||||
Eigen::VectorX<T> VietaAlgo<T>::polyCoeffFromRoot(const Eigen::VectorX<T>& poles)
|
||||
{
|
||||
std::vector<T> coeff(poles.size() + 1, 0);
|
||||
coeff[0] = 1;
|
||||
Eigen::VectorX<T> coeffs = Eigen::VectorX<T>::Zero(poles.size() + 1);
|
||||
coeffs(0) = T(1);
|
||||
for (size_t i = 0; i < poles.size(); ++i) {
|
||||
for (size_t k = i + 1; k > 0; --k) {
|
||||
coeff[k] = coeff[k] - poles[i] * coeff[k - 1];
|
||||
coeffs(k) -= poles(i) * coeffs(k - 1);
|
||||
}
|
||||
}
|
||||
// Check for equation c(k) = sum(i=k-1, poles.size() : p(i)) * c(k-1), k>=1
|
||||
// size_t pSize = poles.size();
|
||||
// for (size_t k = 1; k < coeffs.size(); ++k)
|
||||
// coeffs(k) -= poles.tail(pSize - (k - 1)).sum() * coeffs(k - 1);
|
||||
|
||||
return coeff;
|
||||
// Maybe better
|
||||
// T sum = poles.sum();
|
||||
// for (size_t k = 1; k < coeffs.size(); ++k) {
|
||||
// coeffs(k) -= sum * coeffs(k - 1);
|
||||
// sum -= poles(k - 1);
|
||||
// }
|
||||
|
||||
return coeffs;
|
||||
}
|
||||
|
||||
} // namespace fratio
|
Ładowanie…
Reference in New Issue