|
|
robotsorcerer / savitzky-golay Goto Github PK
View Code? Open in Web Editor NEWComputes the Savitzky-Golay Filter coefficients.
License: Apache License 2.0
Computes the Savitzky-Golay Filter coefficients.
License: Apache License 2.0
|
|
Hi.
I downloaded your code and did some test runs. However, I encountered some issues.
I need to use the code within the bigger project. I have a .dll library where I need to apply s-g filtering. Although the main file is .cu, I don't use any Cuda code now. This library is then called from MFC application to run some operations on data.
I am working with Visual Studio 2019, Eigen 3.3, on Windows 10.
This code is pretty much copied from example.cpp. I run the function "savgolfilt" with a given set of values 30 times and sometimes, I get different result from "Filter". I use F, x, x values from example.
My code:
// initialize values
int F = 9;
int k = 5;
float x_min = 100, x_max = 1000;
// create vector of x values
auto x = VectorXf::LinSpaced(F, x_min, x_max);
// calculate the same Filter 30 times
for (int i = 0; i < 30; i++)
{
auto Filter = savgolfilt(x, k, F);
log_file << "Filter = " << Filter << "\n"; // save to a log_file, which is later saved as .txt
}
Results are as follows: middle value is different sometimes.
Filter = 662.501 775 887.5 1000 550 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 550 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 957289 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 957289 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 550 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 550 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 957289 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 957289 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 957289 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 957289 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 957289 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 550 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 957289 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 550 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 550 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 550 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 550 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 550 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 1.96313e+06 99.9998 212.5 325 437.5
Filter = 662.501 775 887.5 1000 957289 99.9998 212.5 325 437.5
I run a couple of tests to see where the error happens. It seems that the line
y << y_off.transpose().eval(), y_ss, y_on.transpose().eval();
in savgolfilt function is problematic - the vectors before concatenating into y seem just fine. Do you know what could be a problem?
I apply savgolfilt on my data. Typically, F = 129, k = 6, x is signal of length 400 (in other applications the length can be up to 1600) with float values in range for example (-0.0038, 0.0266). Here, I show example for F = 9 and k = 5 (in order not to show so many values).
// initialize values
int F = 9;
int k = 5;
// create vector of x values
auto x = my_data;
// calculate
for (int i = 0; i < 10; i++)
{
auto Filter = savgolfilt(x, k, F);
log_file << "Filter = " << Filter << "\n";
}
Result
Filter = 0.0066643 0.00634263 0.00642954 0.00900544 -nan 0.00869701 0.00574144 0.00707652 0.00823701
Filter = 0.0066643 0.00634263 0.00642954 0.00900544 -nan 0.00869701 0.00574144 0.00707652 0.00823701
Filter = 0.0066643 0.00634263 0.00642954 0.00900544 -nan 0.00869701 0.00574144 0.00707652 0.00823701
Filter = 0.0066643 0.00634263 0.00642954 0.00900544 -nan 0.00869701 0.00574144 0.00707652 0.00823701
Filter = 0.0066643 0.00634263 0.00642954 0.00900544 -nan 0.00869701 0.00574144 0.00707652 0.00823701
Filter = 0.0066643 0.00634263 0.00642954 0.00900544 -nan 0.00869701 0.00574144 0.00707652 0.00823701
Filter = 0.0066643 0.00634263 0.00642954 0.00900544 -nan 0.00869701 0.00574144 0.00707652 0.00823701
Filter = 0.0066643 0.00634263 0.00642954 0.00900544 -nan 0.00869701 0.00574144 0.00707652 0.00823701
Filter = 0.0066643 0.00634263 0.00642954 0.00900544 -nan 0.00869701 0.00574144 0.00707652 0.00823701
Filter = 0.0066643 0.00634263 0.00642954 0.00900544 -nan 0.00869701 0.00574144 0.00707652 0.00823701
There is nan in the middle. Is there any condition for data? Like they should be positive, in some range, or?
Or, is there just problem with << operator, which displays values of Eigen variables?
I am sorry, but I got confused, even more after reading other issues here. How exactly should I use the code to get smoothed signal? I expect the smoothed signal will have the same length as input signal x, but it is not the case of savgolfilt. In Readme.md there is "savgolfilt(x, x_on, k, F);", but I don't see the four-argument input of this function nor in savgol.cpp, nor in its header.
Thank you for your answers. I am sorry if I ask something trivial, but I didn't find answer anywhere.
db@zweistein:/array_data01> git clone https://github.com/lakehanne/Savitzky-Golay.git
Klone nach 'Savitzky-Golay' ...
remote: Enumerating objects: 220, done.
remote: Total 220 (delta 0), reused 0 (delta 0), pack-reused 220
Empfange Objekte: 100% (220/220), 329.79 KiB | 0 bytes/s, Fertig.
Löse Unterschiede auf: 100% (123/123), Fertig.
db@zweistein:/array_data01> cd Savitzky-Golay
db@zweistein:/array_data01/Savitzky-Golay> mkdir build
db@zweistein:/array_data01/Savitzky-Golay> cd build/
db@zweistein:/array_data01/Savitzky-Golay/build> cmake ../
-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.28")
-- Checking for module 'eigen3'
-- Found eigen3, version 3.2.9
-- Performing Test COMPILER_SUPPORTS_CXX11
-- Performing Test COMPILER_SUPPORTS_CXX11 - Success
-- Performing Test COMPILER_SUPPORTS_CXX0X
-- Performing Test COMPILER_SUPPORTS_CXX0X - Success
-- savgol include path:
eigen3 include path: /usr/include/eigen3
-- Configuring done
-- Generating done
-- Build files have been written to: /array_data01/Savitzky-Golay/build
db@zweistein:/array_data01/Savitzky-Golay/build> make
Scanning dependencies of target savgol
[ 33%] Building CXX object CMakeFiles/savgol.dir/savgol.cpp.o
[ 66%] Building CXX object CMakeFiles/savgol.dir/example.cpp.o
[100%] Linking CXX executable savgol
[100%] Built target savgol
db@zweistein:/array_data01/Savitzky-Golay/build> ./savgol
Frame size: 5; Polynomial order: 3
Vandermonde Matrix:
1 -2 4 -8 16
1 -1 1 -1 1
1 0 0 0 0
1 1 1 1 1
1 2 4 8 16
Filtered values in the range
900 920 940 960 980
are:
960 980 940 900 920
USAGE:
./savgol [<frame_size> [<polynomial_order> [<x_low> <x_high>] ] ]
<frame_size>: odd int and ideally greater than
<polynomial_order>: an integer
<x_low>, <x_high>: min and max limits of
linspaced vector to be filtered.
===================================================
Example: ./savgol 9 5
USAGE:
./savgol [<frame_size> [<polynomial_order> [<x_low> <x_high>] ] ]
<frame_size>: odd int and ideally greater than
<polynomial_order>: an integer
<x_low>, <x_high>: min and max limits of
linspaced vector to be filtered.
===================================================
Example: ./savgol 9 5
x: a vector of length 990
I mean x is a vector of [x_1, x_2, ...., x_990]
FILE *fp_y;
fp_y=fopen("niosy_data.txt","r");
std::vector x_v(990);
if (fp_y == NULL)
cout<<"\n\nSpecified file is not found\n\n"<<endl;
int i = 0; float Y_data = 0;
result_out :: 0 0 0 0 0 -nan 0 0 0 0 0
Could you help on same
Dear Lekan,
I was trying to smooth a signal of size 1000 samples with order 3.
But when I execute I get output array size as polynomial order size.But output array should be the same size as the input array.
Could you help on same?
Thanks,
Amaresh P Kandagal
I transfer it to Windows Enviroment, I get a Error about Eigen Lib.
lhs.cols() == rhs.rows() && "invalid matrix product" && "if you wanted a coeff-wise or a dot product use the respective explicit functions", file E:\SavitzkyGolay\SavitzkyGolay\eigen\Eigen\src\Core\Product.h, line 98
How to solve it???
please help me...
Hi ! I dowloaded your implementation of SG filter and did not succeed to run it as is. The assertion comes at the line MatrixXf G = Sd * Rinv * RinvT;
in the function sgdiff
. With F=5
and k=3
, it seems that the dimensions of Sd
is 5x4 but the dimensions of Rinv
and RinvT
is 1x1. Hence, the multiplication Sd * Rinv * RinvT
cause the program to abord. I did not edited anything, just downloaded the library, created a blank project in VS 2015, imported those plus the Eigen library. Any idea ?
In my case savgolfilt aborts at line
with:
/usr/include/eigen3/Eigen/src/Core/CwiseBinaryOp.h:131: Eigen::CwiseBinaryOp<BinaryOp, Lhs, Rhs>::CwiseBinaryOp(const Lhs&, const Rhs&, const BinaryOp&) [with BinaryOp = Eigen::internal::scalar_product_op<double, double>; Lhs = const Eigen::Transpose<const Eigen::Matrix<double, 1, -1> >; Rhs = const Eigen::Matrix<double, -1, 1>]: assertion »aLhs.rows() == aRhs.rows() && aLhs.cols() == aRhs.cols() failed
My tested arguments for savgolfilt:
x: a vector of length 1650 and 1030
x_on: vector of length F initialized with the first F elements of x
k: 3 and 5
F: 11
Fd: 11
My version of Eigen: 3.2.0
OS: Ubuntu 14.04
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.