I am using a Teensy 3.1 for a project which involves taking data from various analog pins. The data taken from the pins needs to be organized and multiplied via matrix operations. This can be done (mostly) by using the MatrixMath library (found on arduino playground), though the problem with this library is that is DOES NOT include a matrix determinant routine.
I need to take the determinant of 9x9 matrix. I am familiar with the methods required to do this calculation by hand, and would HATE to have to code it out (as I am rather pressed for time). Does anyone know of existing C code (or something that can be translated to C) that can be used to write a function in the arduino IDE to perform large matrix determinants?
I tried to implement this code as a function in the arduino IDE (aIDE) but received the following errors:
gest.ino: In function 'float Determinant(float**, int)':
gest:396: error: invalid conversion from 'void*' to 'float**' [-fpermissive]
gest:398: error: invalid conversion from 'void*' to 'float*' [-fpermissive]
Show us the code for the function and as small as possible program that uses it and causes the error. It need not be the whole real program but it must be complete and capable of running if it compiled.
The original code uses doubles but you've changed it to use float. What other changes have you made?
There is a forum specifically for Teensys at http://forum.pjrc.com.
el_supremo:
The original code uses doubles but you've changed it to use float. What other changes have you made?
There is a forum specifically for Teensys at http://forum.pjrc.com.
Pete
Hello Pete,
good eye, Sir. Those are the only modifications I made.
You must have made other changes. That function compiles for me on a Teensy3.1 with double or float.
We need to see complete example code which demonstrates the error.
Here is a sketch which attempts to take the determinant of a 9x9 identity matrix. function should return a scalar value (in the case of the identity, the function will return a 1).
Here's the code (the .ino is also attached):
double A[9][9]; // declare 9x9 matrix
double B = 0; // declare and initialize B, B = det(A)
int M = 9; // number of rows in A
int N = 9; // number of columns in A
int m,n; // declare row & column indicies
void setup(){
Serial.begin(9600); // begin serial comm
// initiailize A[][] to the identity matrix -------> det(identity of any square dimensions) = 1
for(m=0;m<=M;m++){
for(n=0;n<N;n++){
if(m == n){ // if m = n, then we're on the diagonal of A
A[m][n] = 1; // set diagonal entries of A to 1
}
else{ // m != n
A[m][n] = 0; // set entry of A to 0
}
}
}
}// end setup
void loop(){
// call determinant function
// B = Determinant(double** A, 9);
}// end loop
//NOT MY CODE: found at "http://paulbourke.net/miscellaneous/determinant/determinant.c"
// Recursive definition of determinate using expansion by minors.
double Determinant(double **a,int n)
{
int i,j,j1,j2;
double det = 0;
double **m = NULL;
if (n < 1) { /* Error */
} else if (n == 1) { /* Shouldn't get used */
det = a[0][0];
} else if (n == 2) {
det = a[0][0] * a[1][1] - a[1][0] * a[0][1];
} else {
det = 0;
for (j1=0;j1<n;j1++) {
m = malloc((n-1)*sizeof(double *));
for (i=0;i<n-1;i++)
m[i] = malloc((n-1)*sizeof(double));
for (i=1;i<n;i++) {
j2 = 0;
for (j=0;j<n;j++) {
if (j == j1)
continue;
m[i-1][j2] = a[i][j];
j2++;
}
}
det += pow(-1.0,1.0+j1+1.0) * a[0][j1] * Determinant(m,n-1);
for (i=0;i<n-1;i++)
free(m[i]);
free(m);
}
}
return(det);
}
The code below produces the following errors. Note that the only change made to this code was the call to the "Determinant" function (as per PaulS's suggestion):
determinant_test.ino: In function 'void loop()':
determinant_test:22: error: cannot convert 'double ()[9]' to 'double**' for argument '1' to 'double Determinant(double**, int)'
determinant_test.ino: In function 'double Determinant(double**, int)':
determinant_test:41: error: invalid conversion from 'void' to 'double**' [-fpermissive]
determinant_test:43: error: invalid conversion from 'void*' to 'double*' [-fpermissive]
double A[9][9]; // declare 9x9 matrix
double B = 0.0; // declare and initialize B, B = det(A)
int M = 9; // number of rows in A
int N = 9; // number of columns in A
int m,n; // declare row & column indicies
void setup(){
Serial.begin(9600); // begin serial comm
for(m=0;m<=M;m++){ // initiailize A[][] to the identity matrix -------> det(identity of any square dimensions) = 1
for(n=0;n<N;n++){
if(m == n){ // if m = n, then we're on the diagonal of A
A[m][n] = 1; // set diagonal entries of A to 1
}
else{ // m != n
A[m][n] = 0; // set entry of A to 0
}
}
}
}// end setup
void loop(){
B = Determinant( A, 9); // call determinant function
}// end loop
double Determinant(double **a,int n)
{
int i,j,j1,j2;
double det = 0;
double **m = NULL;
if (n < 1) { /* Error */
} else if (n == 1) { /* Shouldn't get used */
det = a[0][0];
} else if (n == 2) {
det = a[0][0] * a[1][1] - a[1][0] * a[0][1];
} else {
det = 0;
for (j1=0;j1<n;j1++) {
m = malloc((n-1)*sizeof(double *));
for (i=0;i<n-1;i++)
m[i] = malloc((n-1)*sizeof(double));
for (i=1;i<n;i++) {
j2 = 0;
for (j=0;j<n;j++) {
if (j == j1)
continue;
m[i-1][j2] = a[i][j];
j2++;
}
}
det += pow(-1.0,1.0+j1+1.0) * a[0][j1] * Determinant(m,n-1);
for (i=0;i<n-1;i++)
free(m[i]);
free(m);
}
}
return(det);
}
m = (double **) malloc((n-1)* sizeof(double *)) ;
for (i = 0 ; i < n-1 ; i++)
m[i] = (double *) malloc((n-1)* sizeof(double)) ;
and here's your version:
m = malloc((n-1)*sizeof(double *));
for (i=0;i<n-1;i++)
m[i] = malloc((n-1)*sizeof(double));
Notice any differences?
I had originally assumed that it was the two malloc causing the errors. But the error messages you posted showed the offending lines to be 2 lines apart but in the original code they are 3 lines apart and you said you hadn't made any changes so they couldn't be the problem. But apart from removing the casts you had also removed a blank line which changed the line numbers.
Yes, I notice those differences now. My apologies for not having the clarity of mind to include deleting white space in my list of things that I modified. I re-casted those malloc calls to (double **) and (double *) respectively. I also had to cast the matrix A to (double **) in the call to "Determinant" -errors ensue if I do not do this-. Thank you, gentle-people, for your attention and your helpful suggestions.
umbralTorturer:
I also had to cast the matrix A to (double **) in the call to "Determinant" -errors ensue if I do not do this-.
Of course there are errors if you omit the cast. The compiler is telling you that the type of the argument is different from the type of the function's parameter, and the cast is only telling the compiler to ignore the problem.
A two-dimensional array (such as double [][]) is different from a pointer to pointer (such as double **).
Sorry I have the same problem and I didn't understand how to fix the following errors:
sketch_may10a.ino: In function 'void loop()':
sketch_may10a:23: error: cannot convert 'double ()[9]' to 'double**' for argument '1' to 'double Determinant(double**, int)'
sketch_may10a.ino: In function 'double Determinant(double**, int)':
sketch_may10a:42: error: invalid conversion from 'void' to 'double**'
sketch_may10a:44: error: invalid conversion from 'void*' to 'double*'