crypto
crypto

Reputation: 953

Creating simple matrices with Eigen?

I'm using the Eigen library to create and manipulate some matrices in C++. Eigen is installed (Ubuntu 16.04) and seems to be working. However, when I declare a matrix as part of a class in an external file and #include the necessary files, it fails. My KalmanFilter.h header file:

#include <Eigen/Dense>
using Eigen::MatrixXd;
class KalmanFilter {
public:
  KalmanFilter(double, double);
  double initialX, initialY;
  MatrixXd m;
};

My KalmanFilter.cpp file:

#include <Eigen/Dense>
#include "KalmanFilter.h"
KalmanFilter::KalmanFilter(double inX, double inY) {
  initialX = inX;
  initialY = inY;
  m(2, 1);
  m << initialX, initialY;
}

And of course my main.cpp:

#include <Eigen/Dense>
#include "Utilities/KalmanFilter.h"
int main() {
  double a, b;
  a = 1.0;
  b = 2.0;
  KalmanFilter KF(a, b);
}

Everything compiles all right, but running it results in an assertion error:

main: /usr/local/include/Eigen/src/Core/DenseCoeffsBase.h:365: Eigen::DenseCoeffsBase<Derived, 1>::Scalar& Eigen::DenseCoeffsBase<Derived, 1>::operator()(Eigen::Index, Eigen::Index) [with Derived = Eigen::Matrix<double, -1, -1>; Eigen::DenseCoeffsBase<Derived, 1>::Scalar = double; Eigen::Index=long int]: Assertion 'row >= 0 && rows() && col >= 0 && col < cols()' failed. Aborted.

If I put MatrixXd m(2, 1); inside my KalmanFiter.cpp file (re-declaring that it's a MatrixXd) the resulting compilation runs, but the m matrix is empty (it exists, but apparently the next line that's supposed to initialize it fails silently). I'm almost positive that Eigen is installed correctly, because declaring and initializing the same MatrixXd matrix inside my main.cpp works just fine.

What am I missing here?

Upvotes: 0

Views: 963

Answers (2)

luk32
luk32

Reputation: 16070

m(2, 1); this doesn't do what you think it does. It doesn't create the object, it's a syntax to get the coefficient at given position (operator()), so your matrix m is empty, and you try to retrieve the element.

The syntax seems the same, but the placement makes a great deal of a difference.

You need to initialize member object in the member initialization list:

KalmanFilter::KalmanFilter(double inX, double inY) : m(2, 1) {
//                                                   ^^^^^^^
  initialX = inX;
  initialY = inY;
  m << initialX, initialY;
}

Upvotes: 4

Avi Ginsburg
Avi Ginsburg

Reputation: 10596

The problem is due to the line in KalmanFilter.cpp:

m(2, 1);

That doesn't resize the matrix as I assume you assume it does. Replace it with m.resize(2, 1); and try again.

Upvotes: 3

Related Questions