topic/diffentiators
Vincent Samy 2018-10-26 10:31:14 +09:00
rodzic 7f350bdf53
commit a6105fa9ff
8 zmienionych plików z 62 dodań i 42 usunięć

Wyświetl plik

@ -48,17 +48,17 @@ void Butterworth<T>::computeDigitalRep()
T pi = static_cast<T>(M_PI);
// Continuous pre-warped frequency
T fpw = (m_fs / pi) * std::tan(pi * m_fc / m_fs);
T scaleFactor = T(2) * pi * fpw;
T scaleFactor = 2 * pi * fpw;
auto thetaK = [pi, order = m_order](size_t k) -> T {
return (T(2) * k - T(1)) * pi / (T(2) * order);
return (2 * k - 1) * pi / (2 * order);
};
// Compute poles
std::complex<T> scalePole;
for (size_t k = 1; k <= m_order; ++k) {
scalePole = scaleFactor * std::complex<T>(-std::sin(thetaK(k)), std::cos(thetaK(k)));
scalePole /= T(2) * m_fs;
scalePole /= 2 * m_fs;
m_poles[k - 1] = (T(1) + scalePole) / (T(1) - scalePole);
}

Wyświetl plik

@ -70,7 +70,7 @@ void GenericFilter<T>::normalize()
if (std::abs(a0) < 1e-8) // Divide by zero
throw std::invalid_argument("By filtering value for coefficient a0. Should be superior to 1e-8");
if (std::abs(a0 - T(1)) < 1e-8)
if (std::abs(a0 - 1) < 1e-8)
return;
for (T& a : m_aCoeff)

Wyświetl plik

@ -9,11 +9,11 @@ class MovingAverage : public GenericFilter<T> {
public:
MovingAverage() = default;
MovingAverage(size_t windowSize)
: GenericFilter<T>({ T(1) }, std::vector<T>(windowSize, T(1) / windowSize))
: GenericFilter<T>({ 1 }, std::vector<T>(windowSize, T(1) / windowSize))
{
}
void setWindowSize(size_t windowSize) { setCoeff({ T(1) }, std::vector<T>(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(); }
};

Wyświetl plik

@ -18,8 +18,8 @@ struct VietaAlgo<T> {
template <typename T>
std::vector<T> VietaAlgo<T>::polyCoeffFromRoot(const std::vector<T>& poles)
{
std::vector<T> coeff(poles.size() + 1, T(0));
coeff[0] = T(1);
std::vector<T> coeff(poles.size() + 1, 0);
coeff[0] = 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];

Wyświetl plik

@ -21,10 +21,10 @@ DISABLE_CONVERSION_WARNING_END
BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_FILTER_FLOAT, System<float>)
{
auto gf = fratio::Butterworthf(order, fc, fs);
auto bf = fratio::Butterworthf(order, fc, fs);
std::vector<float> aCoeff, bCoeff, filteredData;
gf.getCoeff(aCoeff, bCoeff);
bf.getCoeff(aCoeff, bCoeff);
BOOST_REQUIRE_EQUAL(aCoeff.size(), aCoeffRes.size());
BOOST_REQUIRE_EQUAL(bCoeff.size(), bCoeffRes.size());
@ -36,23 +36,33 @@ BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_FILTER_FLOAT, System<float>)
}
for (float d : data)
filteredData.push_back(gf.stepFilter(d));
filteredData.push_back(bf.stepFilter(d));
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-4f);
gf.resetFilter();
filteredData = gf.filter(data);
bf.resetFilter();
filteredData = bf.filter(data);
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-4f);
auto bf2 = fratio::Butterworthf();
bf2.setFilterParameters(order, fc, fs);
filteredData.resize(0);
for (float d : data)
filteredData.push_back(bf2.stepFilter(d));
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-4f);
}
BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_FILTER_DOUBLE, System<double>)
{
auto gf = fratio::Butterworthd(order, fc, fs);
auto bf = fratio::Butterworthd(order, fc, fs);
std::vector<double> aCoeff, bCoeff, filteredData;
gf.getCoeff(aCoeff, bCoeff);
bf.getCoeff(aCoeff, bCoeff);
BOOST_REQUIRE_EQUAL(aCoeff.size(), aCoeffRes.size());
BOOST_REQUIRE_EQUAL(bCoeff.size(), bCoeffRes.size());
@ -64,13 +74,23 @@ BOOST_FIXTURE_TEST_CASE(BUTTERWORTH_FILTER_DOUBLE, System<double>)
}
for (double d : data)
filteredData.push_back(gf.stepFilter(d));
filteredData.push_back(bf.stepFilter(d));
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-14);
gf.resetFilter();
filteredData = gf.filter(data);
bf.resetFilter();
filteredData = bf.filter(data);
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-14);
auto bf2 = fratio::Butterworthd();
bf2.setFilterParameters(order, fc, fs);
filteredData.resize(0);
for (float d : data)
filteredData.push_back(bf2.stepFilter(d));
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-14);
}

Wyświetl plik

@ -18,40 +18,40 @@ DISABLE_CONVERSION_WARNING_END
BOOST_FIXTURE_TEST_CASE(DIGITAL_FILTER_FLOAT, System<float>)
{
auto gf = fratio::DigitalFilterf(aCoeff, bCoeff);
BOOST_REQUIRE_EQUAL(aCoeff.size(), gf.aOrder());
BOOST_REQUIRE_EQUAL(bCoeff.size(), gf.bOrder());
auto df = fratio::DigitalFilterf(aCoeff, bCoeff);
BOOST_REQUIRE_EQUAL(aCoeff.size(), df.aOrder());
BOOST_REQUIRE_EQUAL(bCoeff.size(), df.bOrder());
std::vector<float> filteredData;
for (float d : data)
filteredData.push_back(gf.stepFilter(d));
filteredData.push_back(df.stepFilter(d));
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-6f);
gf.resetFilter();
filteredData = gf.filter(data);
df.resetFilter();
filteredData = df.filter(data);
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-6f);
}
BOOST_FIXTURE_TEST_CASE(DIGITAL_FILTER_DOUBLE, System<double>)
{
auto gf = fratio::DigitalFilterd(aCoeff, bCoeff);
BOOST_REQUIRE_EQUAL(aCoeff.size(), gf.aOrder());
BOOST_REQUIRE_EQUAL(bCoeff.size(), gf.bOrder());
auto df = fratio::DigitalFilterd(aCoeff, bCoeff);
BOOST_REQUIRE_EQUAL(aCoeff.size(), df.aOrder());
BOOST_REQUIRE_EQUAL(bCoeff.size(), df.bOrder());
std::vector<double> filteredData;
for (double d : data)
filteredData.push_back(gf.stepFilter(d));
filteredData.push_back(df.stepFilter(d));
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-14);
gf.resetFilter();
filteredData = gf.filter(data);
df.resetFilter();
filteredData = df.filter(data);
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-14);
}

Wyświetl plik

@ -9,8 +9,8 @@ BOOST_AUTO_TEST_CASE(FilterThrows)
BOOST_REQUIRE_THROW(fratio::DigitalFilterd({ 1., 2. }, {}), std::runtime_error);
BOOST_REQUIRE_THROW(fratio::DigitalFilterd({ 0. }, { 1. }), std::invalid_argument);
auto gf = fratio::DigitalFilterd();
BOOST_REQUIRE_THROW(gf.setCoeff({}, { 1., 2. }), std::runtime_error);
BOOST_REQUIRE_THROW(gf.setCoeff({ 1., 2. }, {}), std::runtime_error);
BOOST_REQUIRE_THROW(gf.setCoeff({ 0. }, { 1. }), std::invalid_argument);
auto df = fratio::DigitalFilterd();
BOOST_REQUIRE_THROW(df.setCoeff({}, { 1., 2. }), std::runtime_error);
BOOST_REQUIRE_THROW(df.setCoeff({ 1., 2. }, {}), std::runtime_error);
BOOST_REQUIRE_THROW(df.setCoeff({ 0. }, { 1. }), std::invalid_argument);
}

Wyświetl plik

@ -12,32 +12,32 @@ struct System {
BOOST_FIXTURE_TEST_CASE(MOVING_AVERAGE_FLOAT, System<float>)
{
auto ma = fratio::MovingAveragef(windowSize);
auto maf = fratio::MovingAveragef(windowSize);
std::vector<float> filteredData;
for (float d : data)
filteredData.push_back(ma.stepFilter(d));
filteredData.push_back(maf.stepFilter(d));
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-6f);
ma.resetFilter();
filteredData = ma.filter(data);
maf.resetFilter();
filteredData = maf.filter(data);
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-6f);
}
BOOST_FIXTURE_TEST_CASE(MOVING_AVERAGE_DOUBLE, System<double>)
{
auto ma = fratio::MovingAveraged(windowSize);
auto maf = fratio::MovingAveraged(windowSize);
std::vector<double> filteredData;
for (double d : data)
filteredData.push_back(ma.stepFilter(d));
filteredData.push_back(maf.stepFilter(d));
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-14);
ma.resetFilter();
filteredData = ma.filter(data);
maf.resetFilter();
filteredData = maf.filter(data);
for (size_t i = 0; i < filteredData.size(); ++i)
BOOST_CHECK_SMALL(std::abs(filteredData[i] - results[i]), 1e-14);
}