Eigen Matrix Math Library

I need a matrix class with the following functions:

  • Multiply, divide, subtract and add a combination of:
  • Matrices
  • Vectors
  • Scalars
  • Transpose
  • Inverse
  • Assign

Is there a class or importable library available that can already do all this?

If not would it be worthwhile to port the Arduino Eigen implementation found here?

Is there any reason why a port would not work, I would prefer not to waste my time if there is.

Are there any other options?

While that library might ā€œjust workā€ since it seems pretty vanilla, it has a ton of code you might not really need for things like chol, QR, eigenvalues etc. depending on exactly what kind of inverse you want to compute.

The other choice might be the GNU Scientific Library (gsl) which I think you will find might be too large for your needs.

And then there has been some interest in the ARM-specific CMSIS-DSP which looks closer to what you need.

I donā€™t know of anyone who has these working on Particle devices, but they are all possible depending on your time and energy.

There may be other ways to do what you want:

Can you say how large are your matrices? There is a big difference between 3x3 or 4x4 and 10x10!

What are you trying to do with the matrix inverse? Do you know anything special about the matrix (symmetry, condition number, etc.)?

Hi,

Thanks for taking the time to reply :slight_smile:

At the moment iā€™m using a slightly modified version of the matrix class found here https://www.quantstart.com/articles/Matrix-Classes-in-C-The-Source-File

This does everything I need apart from generating the (multiplicative) inverse of a matrix. Itā€™s this function in python I need to transfer over to C++ http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.inv.html

The matrices Iā€™m working with are 4 x 4.

Thanks

So I asked because there are analytic solutions to the matrix inverse for 2x2, 3x3 and 4x4 using various methods. Wikipedia has a brief bit on it here:

So using that you can just write out the expression for each position of the inverse. This page has the formula:

http://www.cg.info.hiroshima-cu.ac.jp/~miyazaki/knowledge/teche23.html

It helps to know if you really need the determinant scaling (multiply by 1/det(A)) since not every application does. If you do need it, that is just another algebraic expression but it roughly doubles the amount of arithmetic you have to do.

The library you are using looks very straight-forward and simple. I would just stay away from dynamic allocation (calling new or constructing matrices on the stack) to avoid memory problems.

And @msolters I am not sure I get the ski instructor from Southparkā€“am I missing a ā€œbad timeā€ joke or something?

1 Like

Itā€™s just a snarky way of conveying that if you are trying to do matrix inversion in an embedded environment, in general, ā€œyou are going to have a bad time.ā€ I certainly wasnā€™t trying to call ā€œrank.ā€ (heh)

As you said ā€“ it would be better to find some mechanism that would allow these systems to be reduced to a smaller set of sub-calculations rather than bust out the big guns!

OK thanks. I will give it a go - looks super simple.

Iā€™m not totally sure if I need determinant scaling to be honest, Iā€™m following a Kalman filter example here http://greg.czerniak.info/guides/kalman1/

On a different note is there an easy modification I can make to the library so that the overloaded operators will work with different types? I get the error below when I try, I tried googling but I donā€™t think I know the correct terms to search forā€¦

error: no match for 'operator-' (operand types are 'QSMatrix<int>' and 'QSMatrix<double>')

Hi @joe4465

I think you have two matrices defined, one that has floating point numbers (1.0 3.14 etc.) and one that has only integers (1, 2, 3, etc.). You probably have something written as 1, 2, 3 and you should change it to 1.0, 2.0, 3.0 to be sure to get floating point numbers (either float or double in C/C++).

I want to subtract a matrix of doubles from a matrix of ints to give me a matrix of doubles, is this possible with a template class? or do I have to define all my matrices as doubles?

Example below.

QSMatrix<double> observation(4, 4, 0.0);
QSMatrix<int> identity(4, 4, 0);

//Initialise observation
observation(0, 0) = 1.0;
observation(1, 1) = 1.0;
observation(2, 2) = 1.0;
observation(3, 3) = 1.0;

//Initialise identity
identity(0, 0) = 1;
identity(1, 1) = 1;
identity(2, 2) = 1;
identity(3, 3) = 1;

QSMatrix<double> test = identity - observation;

Throws the error

KalmanFilter.cpp:68:39: error: no match for 'operator-' (operand types are 'QSMatrix<int>' and 'QSMatrix<double>')
     QSMatrix<double> test = _identity - _observation;

How do I find out whether I need determinant scaling?

Thanks

Hi @joe4465

The actual math will be done in doubles so there is not really much to be gained by using an int matrix.

Change this to:

QSMatrix<double> identity(4, 4, 0);
...
//Initialise identity
identity(0, 0) = 1.0;
identity(1, 1) = 1.0;
identity(2, 2) = 1.0;
identity(3, 3) = 1.0;

I took the CMSIS math library and I am using it to do FFT on audio. While you can do f32 which on the Photon will be done in software. You can also choose to use one of the Qx.y formats.

I am using Q15 for my project and it is much fast then f32. as it uses normal integer math. I have not use the Matrix functions in the math lib, They do have them and they will probably compile for the M3.

I had to put all the files in my project including the .h which are in the build somewhere but no the correct version for the library I found. I also had to put this at the top of arm_math.h to solve some compile issues

#define ARM_MATH_CM3

#undef A0
#undef A1
#undef A2

Actually it would be nice to include these in the actual build libraries. (hint any Particle employees)

1 Like