## Fixed Sized Matrices and Code Performance

Registered Member
Posts
4
Karma
0

### Fixed Sized Matrices and Code Performance

Thu Oct 19, 2017 5:26 pm
Hello!

I could not think of an apt title but I will go right into it. I am working on an embedded project and I need linear algebra library
so I chose Eigen. It has been very good so far, I tested my code on Visual Studio with optimizations on and it reports that
the code compiled in 0.008 seconds, but my console window doesn't open up that fast. It takes about 30 seconds for it to open
up (I build in release mode by the way).

I have 3 things I want to get some assistance on. Firstly, I have opted for fixed sized matrices of type float because the microcontroller
I am to upload my code to doesn't work well with dynamic sized matrices of type double. I do know that by doing
Code: Select all
`Matrix <float, 10, 10> A `

I am declaring Matrix A as a fixed size. My question, at what size does using a fixed sized matrix become a performance issue? In my
work the biggest matrix size I have is a
Code: Select all
` 48 by 12 Matrix `
.

The section of code below will be used to ask my next two questions:

Code: Select all
` MatrixXf P_output(MatrixXf *A, MatrixXf *C, int *ny){   MatrixXf prod;   prod = *C * *A;   int row_size = prod.rows();   int column_size = prod.cols();   // P   MatrixXf P(row_size**ny, column_size); // Declaring P as an empty matrix   int t = 0; // Px row index            // A matrix power loop   for (int i = 1; i < *ny + 1; i++) {      MatrixXf CAprod = *C * (*A).pow(i); // C times A                                     // Columns      for (int l = 0; l < column_size; l++)      {          // Rows         for (int k = 0; k < row_size; k++)         {            P(k + (row_size*t), l) = CAprod(k, l);         }      } t++;   }   return P;}`

So this is a function that takes in the arguments by reference (I did it this way to speed things up, to avoid making copies each time the function
was called). Now the thing is, I know the sizes of matrices A and B, hence I can declare them as fixed matrix types. So how would you think i could
declare the type of the matrix P (I am assuming that you cannot mix dynamic and fixed matrix types)?

Lastly, in this line in the for loop,

Code: Select all
`MatrixXf CAprod = *C * (*A).pow(i); // C times A`

I am multiplying C with A raised to a power. Is there another way to compute this that is faster? There was a method I tried:

Code: Select all
`  MatrixXf CAprod = (*C).array()*(*A).array().pow(i); `

it is faster but outputs the wrong answer.

I made some tweaks yesterday by changing the dynamically sized matrices ( I could change) to fixed sized ones and it improved my performance but I am
afraid that my STM32F4 microcontroller still isn't as fast. My last option might be to hardcode some of the variables to be
Code: Select all
`const static`

I tremendously appreciate any input I can get from you. Please ask me for any clarifications. Thank you!
Registered Member
Posts
4
Karma
0

### Re: Fixed Sized Matrices and Code Performance

Thu Oct 19, 2017 5:31 pm
PS

The console window reporting speed of 0.008 s gets to me especially since it takes 30 seconds
for the window to open. Is this the right way to clock the computation:

Code: Select all
`high_resolution_clock::time_point t1 = high_resolution_clock::now();// Code in between...high_resolution_clock::time_point t2 = high_resolution_clock::now();duration<double> time_span = t2 - t1;std::cout << "It took me " << time_span.count() << " seconds.";`

Thanks again
ggael
Moderator
Posts
3447
Karma
19
OS

### Re: Fixed Sized Matrices and Code Performance

Thu Oct 19, 2017 8:16 pm
Why do you use pointers ? References, and even const references would be more appropriate:

MatrixXf P_output(const MatrixTypeA &A, const MatrixTypeC &C, int ny)

and this will make your code more readable. You can mix fixed and dynamic sized objects, you can even fix only one dimension, but unless ny is known at compile-time, there is no way to avoid a dynamic size for P.

Regarding A.pow(i), better compute it incrementally during the for loop, and then make use of Eigen's API to avoid stupid for loops and temporaries:

Code: Select all
`const int Rows = MatrixTypeC::RowsAtCompileTime;const int Cols = MatrixTypeA::ColsAtCompileTime;Matrix<float,Dynamic,Cols> P;MatrixTypeA pow_A_i = A;for (int i = 0; i < ny ; i++) {  P.middleRows<Rows>(i*Rows).noalias() = C * pow_A_i;  if(i+1<ny) pow_A_i = pow_A_i * A;}return P;`

for your embedded platform you might want to enforce a simpler product implementation using lazyProduct:

Code: Select all
`  P.middleRows<Rows>(i*Rows).noalias() = C.lazyProduct(pow_A_i);  if(i+1<ny) pow_A_i = pow_A_i.lazyProduct(A);`
Registered Member
Posts
4
Karma
0

### Re: Fixed Sized Matrices and Code Performance

Fri Oct 20, 2017 11:58 am
Hello,

I took your advice and decided to have a test run where matrices C and A are dynamically fixed:

Code: Select all
`   MatrixXf A;   A << 0.9f, -0.5f,      0.0f, 0.8f;   MatrixXf C;   C << 2.0f, 0.5f,      -1.0f, 1.0f;   int ny = 4;   const int Rows = MatrixXf::RowsAtCompileTime;   const int Cols = MatrixXf::ColsAtCompileTime;   Matrix<float, Dynamic, Cols> P;      MatrixXf pow_A_i = A;   for (int i = 0; i < ny; i++)   {      P.middleRows<Rows>(i*Rows).noalias() = C * pow_A_i;      if (i + 1<ny) pow_A_i = pow_A_i * A;   }   cout << P << endl;`

But doing this results in a program crash and this is the only section of code running.

Likewise, if I define the matrices A and C as fixed, it also crashes

Code: Select all
`   Matrix2f A;   A << 0.9f, -0.5f,      0.0f, 0.8f;   Matrix2f C;   C << 2.0f, 0.5f,      -1.0f, 1.0f;   int ny = 4;   const int Rows = Matrix2f::RowsAtCompileTime;   const int Cols = Matrix2f::ColsAtCompileTime;   Matrix<float, Dynamic, Cols> P;   Matrix2f pow_A_i = A;   for (int i = 0; i < ny; i++)   {      P.middleRows<Rows>(i*Rows).noalias() = C * pow_A_i;      if (i + 1<ny) pow_A_i = pow_A_i * A;   }   cout << P << endl;`

I am expecting P to output this:

Code: Select all
`1.8 -0.6-0.9 1.31.62 -1.38-0.81 1.49-1.458 -1.914-0.729 1.5971.3122 -2.2602-0.6561 1.6421`

Please let me know what I am doing wrong. Thank you Ggael

## Who is online

Registered users: Baidu [Spider], Barade, Bing [Bot], chockie, Exabot [Bot], gmazzola, Google [Bot], scottpetrovic, Sogou [Bot]