Reputation: 613
I am new to Eigen3. I am trying to write a simple neural network using it as a practice. Since I want to play around with the precision of the model, I used auto to declare my variables. Here is an example,
auto inp = MatrixXf::Random(4,10);
This is the line that I used to initialise the input of my neural network. But this line of code caused me quite a lot of troubles. It caused me an whole afternoon to realise that this is not correct. The values inside the matrix changes every time I called it!!!!!!!!!!!!
Here is a small code example to see the situation.
#include <iostream>
#include <Eigen/Dense>
using Eigen::MatrixXf;
using Eigen::VectorXf;
using Eigen::ArrayXXf;
int main()
{
auto inp = MatrixXf::Random(4,10);
auto exp_oup = MatrixXf::Random(4,5);
std::cout<<inp<<std::endl<<std::endl;
std::cout<<exp_oup<<std::endl<<std::endl;
std::cout<<"Wait!!!!"<<std::endl<<std::endl;
std::cout<<inp<<std::endl<<std::endl;
std::cout<<exp_oup<<std::endl<<std::endl;
return 0;
}
My output is as follow
[JDIP@localhost Eigen]$ ./eigen
0.680375 0.823295 -0.444451 -0.270431 0.271423 -0.967399 -0.686642 0.997849 0.22528 -0.012834
-0.211234 -0.604897 0.10794 0.0268018 0.434594 -0.514226 -0.198111 -0.563486 -0.407937 0.94555
0.566198 -0.329554 -0.0452059 0.904459 -0.716795 -0.725537 -0.740419 0.0258648 0.275105 -0.414966
0.59688 0.536459 0.257742 0.83239 0.213938 0.608353 -0.782382 0.678224 0.0485743 0.542715
0.0534899 -0.433371 -0.860489 -0.615572 -0.871657
0.539828 -0.295083 0.898654 0.326454 -0.959954
-0.199543 0.615449 0.0519907 0.780465 -0.0845965
0.783059 0.838053 -0.827888 -0.302214 -0.873808
Wait!!!!
-0.52344 -0.466668 0.0250708 -0.124725 -0.431413 0.375723 0.658402 -0.29928 0.314608 -0.203127
0.941268 0.0795207 0.335448 0.86367 0.477069 -0.668052 -0.339326 0.37334 0.717353 0.629534
0.804416 -0.249586 0.0632129 0.86162 0.279958 -0.119791 -0.542064 0.912936 -0.12088 0.368437
0.70184 0.520497 -0.921439 0.441905 -0.291903 0.76015 0.786745 0.17728 0.84794 0.821944
-0.0350187 -0.70468 0.239193 -0.105933 0.112888
-0.56835 0.762124 -0.437881 -0.547787 -0.166997
0.900505 0.282161 0.572004 -0.624934 -0.660786
0.840256 -0.136093 -0.385084 -0.447531 0.813608
Can anyone explain this to me? Is this a bug? Or it is intended? What is the actual type of data returned by the instructor if I used the auto?
Upvotes: 1
Views: 229
Reputation: 7905
According to Eigen's documentation:
Executive summary: Eigen has intelligent compile-time mechanisms to enable lazy evaluation and removing temporaries where appropriate. It will handle aliasing automatically in most cases, for example with matrix products. The automatic behavior can be overridden manually by using the MatrixBase::eval() and MatrixBase::noalias() methods.
Eigen:docs:lazy eval & aliasing
Simply put; Eigen has intelligent mechanisms that will know when to use lazy evaluation and when not to in most cases.
Examples:
// In this example:
matrix1 = matrix2 + matrix3;
// Eigen chooses lazy evaluation over immediate evaluation(producing a temporary)
// In this example:
matrix1 = matrix2 * matrix3;
// Since the order of operation of the matrix operands are important due
// to how matrix multiplication works; Eigen will evaluate immediately and
// store the results into a temporary then copy it back into the variable
// assignment.
Since Eigen is an Expression-templates-based library the use of using the keyword auto
is advised against which can be seen here:
C++11 and the auto keyword
In short: do not use the auto keywords with Eigen's expressions, unless you are 100% sure about what you are doing. In particular, do not use the auto keyword as a replacement for a Matrix<> type.
For examples and explanations about the auto key word Eigen:docs:common pitfalls.
Instead try doing this:
MatrixXf inp = MatrixXf::Random(4,10);
MatrixXf exp_oup = MatrixXf::Random(4,5);
The Random(...)
method depending on the context in which it is used can return either a random matrix expression
, random vector expression
or fixed sized random matrix or vector expression
. Random()
Upvotes: 2
Reputation: 10596
As mentioned in the documentation:
Returns
a random matrix expression
An expression is not a matrix, but a "placeholder" that can be evaluated later. This is used for lazy evaluation. See common pitfalls for using auto with Eigen.
Upvotes: 3