Need merge check.

topic/diffentiators
vincent samy 2018-12-14 19:04:41 +09:00
rodzic 0033d2fa72
commit ef7b6dfba1
6 zmienionych plików z 71 dodań i 42 usunięć

Wyświetl plik

@ -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)

Wyświetl plik

@ -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"

Wyświetl plik

@ -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
} // namespace fratio
#include "DigitalFilter.tpp"

Wyświetl plik

@ -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"

Wyświetl plik

@ -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
} // namespace fratio

Wyświetl plik

@ -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
} // namespace fratio