Function Invert() in BasicLinearAlgebra library

Hello
I have a problem with the function Invert in the NotSoBasicLinearAlgebra.h header file.
This is its definition:

template <int dim, class MemT>
bool Invert(const Matrix<dim, dim, MemT> &A, Matrix<dim, dim, MemT> &out)

The function has to return a boolean value:
"true" if the matrix is not singular (i.e. it is reversible) or "false" if it is singular (not reversible).
My problem is that the function always return "true" although it is singular.

Here is a example code:

loop
{
  Matrix<4, 4, Array<4, 4, int>> Matr;		//matrix of 4x4
  Matrix<4, 4, Array<4, 4, int>> InvMatr;		//invert matrix of 4x4
  int arr2[4][4] = { {1,0,0,0},{0,1,0,0},{1,1,0,0},{0,0,0,1} };	//example of singular matrix
  Matr = arr2;								//init. Matr
  bool b = Invert(Matr, InvMatr);			//call to invert func. must return false
  Serial.println("Matr:");					
  Check<Matr.Rows, Matr.Cols>(Matr);		//display Matr
  Serial.print("b = ");
  Serial.println(b);							//print Invert() return
  Serial.println("InvMatr:");
  Check<InvMatr.Rows, InvMatr.Cols>(InvMatr);    //display inverted matrix
}

With Check function defined to print the matrix

template <int R, int C, class T = Array<R, C, float>>
void Check(Matrix<R, C, Array<R, C, T>> m)
{
	for (int i = 0; i < R; i++)
	{
		for (int j = 0; j < C; j++)
		{
			Serial.print(m(i, j));
			Serial.print(" ");
		}
		Serial.println("");
	}
	Serial.println("");
}

The result is:

Matr:
1 0 0 0 
0 1 0 0 
1 1 0 0 
0 0 0 1 

b = 1
InvMatr:
0 0 0 0 
0 0 0 0 
0 0 0 0 
0 0 0 0

Sorry, I wanted to preview my message and sent it before conclusion.
So as I said the function returns true instead of false and also calculate the inverse matrix.
It is strange!
Is there something to do to solve this issue.
Thank you very much
Daniel

Please post in a meaningful forum for your question ➜ moved

Sorry where did you move it to?

Hello

That library looks wrong :

  • I'm far from an expert with matrices, but it doesn't look like the correct way to check if it's singular..
  • This loop for (int j = 0; j <= dim; ++j) will read outside of the array, it should be <

I saw that too and filed a bug.

This seems also to detect a singular matrix only if all the elements are null, but the determinant is never checked

Even fixing the <= bug does not solve the issue.

here is a quick code to demonstrate the problem:

#include <BasicLinearAlgebra.h>
using namespace BLA;

void printMatrix(Matrix<4, 4, Array<4, 4, int>>& m) {
  for (size_t i = 0; i < m.Rows; i++) {
    for (size_t j = 0; j < m.Cols; j++) {
      Serial.print(m(i, j));
      Serial.write('\t');
    }
    Serial.println();
  }
  Serial.println();
}

void setup() {
  Serial.begin(115200); Serial.println();

  Matrix<4, 4, Array<4, 4, int>> baseMatrix;
  Matrix<4, 4, Array<4, 4, int>> inverseMatrix;
  Matrix<4, 4, Array<4, 4, int>> verif;

  baseMatrix = {1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1};

  Serial.println("attempting to inverse");
  printMatrix(baseMatrix);

  int d  = Determinant(baseMatrix);
  Serial.print("Determinant = ");  Serial.println(d);

  if (Invert(baseMatrix, inverseMatrix)) {
    Serial.println("Matrix could be inveresed");
    printMatrix(inverseMatrix);

    verif = baseMatrix * inverseMatrix;
    Serial.println("Multiplying the matrix gives");
    printMatrix(inverseMatrix);
  } else {
    Serial.println("Matrix could not be inveresed");
  }
}

void loop() {}

it says

attempting to inverse
1	0	0	0	
0	1	0	0	
1	1	0	0	
0	0	0	1	

Determinant = 0
Matrix could be inveresed
1	0	0	0	
-1	0	1	0	
-1	-1	1	-1	
-1	-1	1	-1	

Multiplying the matrix gives
1	0	0	0	
-1	0	1	0	
-1	-1	1	-1	
-1	-1	1	-1	

so it correctly sees the determinant but the Invert process does not catch that and produces an incorrect result.

short term ➜ calculate the determinant first and check if it's null before attempting to invert.

PS/

I moved it for you

Ok, I can check determinant and then calculate inverse matrix if it was not zero.
It is a good enough solution.

Thank you

With that many fatal errors, a much better idea would be to use a linear algebra library that has actually been tested, and that works. There are many that have been around for decades.

the bug for this function has been addressed, threre is an updated library (that will be more efficient than computing the determinant of the original matrix)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.