robotsorcerer / Savitzky-Golay

Computes the Savitzky-Golay Filter coefficients.
Apache License 2.0
102 stars 32 forks source link

Wrong matrix dimensions in function savgolfilt #3

Closed markusneg closed 7 years ago

markusneg commented 7 years ago

In my case savgolfilt aborts at line

https://github.com/lakehanne/Savitzky-Golay/blob/099ad9fd268c97443842e06e0624232c21bfe66c/savgol.cpp#L140

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

robotsorcerer commented 7 years ago

I do not understand what you mean by vector of length 1650 and 1030. Did you mean you want a linearly spaced vector between the values [1030, 1650]?

Moreso, you cannot have k as 3 and 5 simultaneously. It must be one of the two. And you would not need to specify Fd explicitly on the command line. That is done internally in the code. Just pass your frame size (F) and polynomial order (k) to the savgol executable like so:

           ./savgol 11 3

If you want to add the lower and upper limits of your vector, you would do:

           ./savgol 11 3 1030 1650

There is a helper function that gets printed in terminal:

./savgol -h
markusneg commented 7 years ago

Sorry for not being clear enough. I didn't use the command line tool from example.cpp but used the C++ function savgolfilt() in my own code directly. I tested multiple parameters consecutively, including data vectors for x containing 1650 and 1030 arbitrary data points, respectively (both optical spectra) and for each, a single k and F value.

Maybe I didn't understand the usage of your library correctly: how can I SG-smooth arbitrary data points and how do I have to input the data? I thought that x is the data vector, x_on is the initialization for the moving window, F is the window size and k is the polynomial order.

robotsorcerer commented 7 years ago

Then pass your data points in lieu of x in the code. You can pick the first F values from x as your x_on value.

markusneg commented 7 years ago

I did try that and got the exception shown in my first post.

robotsorcerer commented 7 years ago

I need to understand what you mean by

x: a vector of length 1650 and 1030
x_on: vector of length F initialized with the first F elements of x

Did you mean x is a vector of [x_1, x_2, ...., x_1650] and [x_1, x_2, ..., x_1030]? If your language is not clear enough, there is little I can do, I'm sorry.

markusneg commented 7 years ago

Yes, I tested arrays with 1650 and 1030 elements in them, respectively, both leading to the exception shown above. What I did basically is:

std::vector<double> x_v(1650); for(double& d : x_v) d = nextValue(); // fill with my own data Eigen::Map<Eigen::VectorXd> x(x_v.data(), 1650); auto result = savgolfilt(x, x.head(11), 3, 11, 11);

journeytosilius commented 3 years ago

I'm getting this just by running the example test data and using savgolfilt() function too, basically doing this, which is the example data :

    F = 5;
    k = 3;
    x_min = 900.0;
    x_max = 980.0;

    // auto s = vander(F); //Compute vandermonde matrix

    // cout << "Frame size: " << F << "; \tPolynomial order: " << k << endl;
    // cout << "\n Vandermonde Matrix: \n"
    //      << s << endl;

    k = 3;

    // auto B = sgdiff(k, F, Fd);

    //To express as a real filtering operation, we shift x around the nth time instant
    auto x = VectorXf::LinSpaced(F, x_min, x_max);

and it fails with that same error