refactor: move iir_filter to separate compilation unit
This commit is contained in:
@@ -11,6 +11,10 @@ include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR} libnpy/inclu
|
|||||||
add_executable(Google_Tests_run test1.cpp)
|
add_executable(Google_Tests_run test1.cpp)
|
||||||
|
|
||||||
file(COPY test1/data1.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test1)
|
file(COPY test1/data1.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test1)
|
||||||
|
file(COPY test1/iir_t1_a.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test1)
|
||||||
|
file(COPY test1/iir_t1_b.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test1)
|
||||||
|
file(COPY test1/iir_t1_x.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test1)
|
||||||
|
file(COPY test1/iir_t1_y.npy DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/test1)
|
||||||
|
|
||||||
target_link_libraries(Google_Tests_run pasada)
|
target_link_libraries(Google_Tests_run pasada)
|
||||||
#target_include_directories(Google_Tests_run PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/pasada-lib/include")
|
#target_include_directories(Google_Tests_run PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/pasada-lib/include")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
//
|
//
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include "library.h"
|
#include "library.h"
|
||||||
|
#include "iir_filter.h"
|
||||||
#include "npy.hpp"
|
#include "npy.hpp"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -51,76 +52,6 @@ TEST(HelloTest, Save_npy_matrix) {
|
|||||||
npy::write_npy(path, d);
|
npy::write_npy(path, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Shift register implemented as a circular buffer. */
|
|
||||||
class Buf {
|
|
||||||
protected:
|
|
||||||
std::vector<double> data;
|
|
||||||
size_t size;
|
|
||||||
size_t n;
|
|
||||||
public:
|
|
||||||
Buf(size_t N): size(N), n(0) {
|
|
||||||
data.resize(N);
|
|
||||||
data.assign(N, 0.0);
|
|
||||||
}
|
|
||||||
void push(double val) {
|
|
||||||
data[n] = val;
|
|
||||||
n = (n+1) % size;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Running filter base. */
|
|
||||||
class Filt : Buf {
|
|
||||||
protected:
|
|
||||||
std::vector<double> taps;
|
|
||||||
size_t shift;
|
|
||||||
size_t offset;
|
|
||||||
public:
|
|
||||||
Filt(size_t N, size_t shift, size_t offset, std::vector<double> taps): Buf(N), shift(shift), offset(offset), taps(taps) {
|
|
||||||
if (taps.size() != N) throw std::invalid_argument("taps.size() != N");
|
|
||||||
}
|
|
||||||
double filter(double val) {
|
|
||||||
this->push(val);
|
|
||||||
return this->peek();
|
|
||||||
}
|
|
||||||
double peek() {
|
|
||||||
double sum = 0;
|
|
||||||
for (size_t i = offset; i < this->size; i++) {
|
|
||||||
//size_t n = (this->n - i + shift - 1) % this->size; // unsigned % size ... bad if u is negative
|
|
||||||
size_t n = (this->size + this->n - i + shift - 1) % this->size;
|
|
||||||
//std::cout << " t[" << i << "] * v[" << n << "]" << std::endl;
|
|
||||||
sum += this->data[n] * this->taps[i];
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
void push(double val) {
|
|
||||||
Buf::push(val);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class IirFilter {
|
|
||||||
protected:
|
|
||||||
Filt y;
|
|
||||||
Filt x;
|
|
||||||
public:
|
|
||||||
IirFilter(std::vector<double> b, std::vector<double> a) : x(b.size(), 0, 0, b), y(a.size(), 1, 1, a) {
|
|
||||||
if (b.size() != a.size()) throw std::invalid_argument("b.size() != a.size()");
|
|
||||||
}
|
|
||||||
double filter(double val) {
|
|
||||||
//std::cout << "x.filter(" << val << ")" << std::endl;
|
|
||||||
double xv = x.filter(val);
|
|
||||||
//std::cout << "xv=" << xv << std::endl;
|
|
||||||
//std::cout << "y.peek()" << std::endl;
|
|
||||||
double yv = y.peek();
|
|
||||||
//std::cout << "yv=" << yv << std::endl;
|
|
||||||
//std::cout << "---" << std::endl;
|
|
||||||
double yo = xv - yv;
|
|
||||||
y.push(yo);
|
|
||||||
return yo;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: copy npy files from CMake output folder
|
|
||||||
// TODO: add npy files to CMakeLists.txt so they are copied into output folder
|
|
||||||
TEST(HelloTest, Test_IIR_1_Apply_IIR) {
|
TEST(HelloTest, Test_IIR_1_Apply_IIR) {
|
||||||
npy::npy_data x = npy::read_npy<double>("test1/iir_t1_x.npy");
|
npy::npy_data x = npy::read_npy<double>("test1/iir_t1_x.npy");
|
||||||
npy::npy_data y_e = npy::read_npy<double>("test1/iir_t1_y.npy");
|
npy::npy_data y_e = npy::read_npy<double>("test1/iir_t1_y.npy");
|
||||||
|
|||||||
BIN
google-tests/test1/iir_t1_a.npy
Normal file
BIN
google-tests/test1/iir_t1_a.npy
Normal file
Binary file not shown.
BIN
google-tests/test1/iir_t1_b.npy
Normal file
BIN
google-tests/test1/iir_t1_b.npy
Normal file
Binary file not shown.
BIN
google-tests/test1/iir_t1_x.npy
Normal file
BIN
google-tests/test1/iir_t1_x.npy
Normal file
Binary file not shown.
BIN
google-tests/test1/iir_t1_y.npy
Normal file
BIN
google-tests/test1/iir_t1_y.npy
Normal file
Binary file not shown.
@@ -2,6 +2,7 @@ project(Pasada_Lib)
|
|||||||
|
|
||||||
SET(PASADA_SRC
|
SET(PASADA_SRC
|
||||||
library.cpp
|
library.cpp
|
||||||
|
iir_filter.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(PASADA_BUILD_TESTS)
|
if(PASADA_BUILD_TESTS)
|
||||||
|
|||||||
51
pasada-lib/iir_filter.cpp
Normal file
51
pasada-lib/iir_filter.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
//
|
||||||
|
// Created by david on 02.03.2026.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "iir_filter.h"
|
||||||
|
|
||||||
|
Buf::Buf(size_t N): size(N), n(0) {
|
||||||
|
data.resize(N);
|
||||||
|
data.assign(N, 0.0);
|
||||||
|
}
|
||||||
|
void Buf::push(double val) {
|
||||||
|
data[n] = val;
|
||||||
|
n = (n+1) % size;
|
||||||
|
}
|
||||||
|
|
||||||
|
Filt::Filt(size_t N, size_t shift, size_t offset, std::vector<double> taps): Buf(N), shift(shift), offset(offset), taps(taps) {
|
||||||
|
if (taps.size() != N) throw std::invalid_argument("taps.size() != N");
|
||||||
|
}
|
||||||
|
double Filt::filter(double val) {
|
||||||
|
this->push(val);
|
||||||
|
return this->peek();
|
||||||
|
}
|
||||||
|
double Filt::peek() {
|
||||||
|
double sum = 0;
|
||||||
|
for (size_t i = offset; i < this->size; i++) {
|
||||||
|
//size_t n = (this->n - i + shift - 1) % this->size; // unsigned % size ... bad if u is negative
|
||||||
|
size_t n = (this->size + this->n - i + shift - 1) % this->size;
|
||||||
|
//std::cout << " t[" << i << "] * v[" << n << "]" << std::endl;
|
||||||
|
sum += this->data[n] * this->taps[i];
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
void Filt::push(double val) {
|
||||||
|
Buf::push(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
IirFilter::IirFilter(std::vector<double> b, std::vector<double> a) : x(b.size(), 0, 0, b), y(a.size(), 1, 1, a) {
|
||||||
|
if (b.size() != a.size()) throw std::invalid_argument("b.size() != a.size()");
|
||||||
|
}
|
||||||
|
double IirFilter::filter(double val) {
|
||||||
|
//std::cout << "x.filter(" << val << ")" << std::endl;
|
||||||
|
double xv = x.filter(val);
|
||||||
|
//std::cout << "xv=" << xv << std::endl;
|
||||||
|
//std::cout << "y.peek()" << std::endl;
|
||||||
|
double yv = y.peek();
|
||||||
|
//std::cout << "yv=" << yv << std::endl;
|
||||||
|
//std::cout << "---" << std::endl;
|
||||||
|
double yo = xv - yv;
|
||||||
|
y.push(yo);
|
||||||
|
return yo;
|
||||||
|
}
|
||||||
46
pasada-lib/include/iir_filter.h
Normal file
46
pasada-lib/include/iir_filter.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// Created by david on 02.03.2026.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef PASADASUPERPROJECT_IIR_FILTER_H
|
||||||
|
#define PASADASUPERPROJECT_IIR_FILTER_H
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
/** Shift register implemented as a circular buffer. */
|
||||||
|
class Buf {
|
||||||
|
protected:
|
||||||
|
std::vector<double> data;
|
||||||
|
size_t size;
|
||||||
|
size_t n;
|
||||||
|
public:
|
||||||
|
Buf(size_t N);
|
||||||
|
void push(double val);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Running filter base. */
|
||||||
|
class Filt : Buf {
|
||||||
|
protected:
|
||||||
|
std::vector<double> taps;
|
||||||
|
size_t shift;
|
||||||
|
size_t offset;
|
||||||
|
public:
|
||||||
|
Filt(size_t N, size_t shift, size_t offset, std::vector<double> taps);
|
||||||
|
double filter(double val);
|
||||||
|
double peek();
|
||||||
|
void push(double val);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Running IIR filter. */
|
||||||
|
class IirFilter {
|
||||||
|
protected:
|
||||||
|
Filt y;
|
||||||
|
Filt x;
|
||||||
|
public:
|
||||||
|
IirFilter(std::vector<double> b, std::vector<double> a);
|
||||||
|
double filter(double val);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //PASADASUPERPROJECT_IIR_FILTER_H
|
||||||
Reference in New Issue
Block a user