Writing a function implementing a Jacobi Matrix for Newton's method I have noticed a really nasty error.
Calling the function
auto DF = [T](VectorXd y){
return PhiAndW(y(0),y(1),T).second - MatrixXd::Identity(2,2);
};
only returns the value of PhiAndW(y(0),y(1),T).second
and omits the subtraction of MatrixXd::Identity(2,2)
. But if I change the code to
auto DF = [T](VectorXd y){
MatrixXd mat = PhiAndW(y(0),y(1),T).second - MatrixXd::Identity(2,2);
return mat;
};
everything works seamlessly.
I have tried to reproduce it and this is not the exact same behavior but it also doesn't behave as wanted:
Consider the following code:
MatrixXd FF(MatrixXd y){
return y;
}
int other(){
auto DF = [](MatrixXd y){
MatrixXd test = FF(y) - MatrixXd::Identity(2,2);
return test;
};
std::cout << DF(MatrixXd::Ones(2,2)) <<std::endl;
std::cout << std::endl;
std::cout << (MatrixXd::Ones(2,2) - MatrixXd::Identity(2,2))<< std::endl;
}
It will print
> 1 0
> 0 1
>
> 1 0
> 0 1
to the console.
However if I change to function DF
to
auto DF = [](MatrixXd y){
return FF(y) - MatrixXd::Identity(2,2);
};
The console will print
> 2.22045e-15 1.63042e-322
> 2.37152e-322 -0.999998
for the second matrix. (Which is just some uninitialized junk from memory).
Could someone explain what is happening with my code and my example problem. I have truly no idea what is going on here. I am especially interested why saving the result of the calculation in a temporary variable fixes the problem.
auto
on this page: eigen.tuxfamily.org/dox-devel/TopicPitfalls.html – Outrunauto
is implicitly the return type of the lambda) – Commemorativeauto DF = []() -> MatrixXd {...}
? This should force the evaluation of return value. – Sileauto
might not be that cool like everyone else (except me) seems to believe. ;-) I assume an explicit cast would fix the first sample as well:auto DF = [](MatrixXd y){ return MatrixXd(FF(y) - MatrixXd::Identity(2,2)); };
– Butylene