When trying to initialize a Vector using the result of some operation in Eigen, the result seems to be different depending on what syntax is used, i.e., on my machine, the assertion at the end of the following code fails:
const unsigned int n = 25;
Eigen::MatrixXd R = Eigen::MatrixXd::Random(n,n);
Eigen::VectorXd b = Eigen::VectorXd::Random(n);
Eigen::VectorXd x = Eigen::VectorXd::Zero(n);
Eigen::VectorXd y = Eigen::VectorXd::Zero(n);
y = R.triangularView<Eigen::Upper>().solve(b);
x << R.triangularView<Eigen::Upper>().solve(b);
assert((x-y).norm() < std::numeric_limits<double>::epsilon()*10E6);
I am aware of potential rounding errors, but in my understanding, the two evaluations of
R.triangularView<Eigen::Upper>().solve(b)
should have the exact same precision errors, and therefore the same result. This also only happens when initializing one variable with <<
and the other withoperator=
, but not if both variables are assigned to the same way.
When not using only backwards substitution on the upper triangular part but evaluating R.lu().solve(b)
on both and comparing the result, the difference is far smaller, but still exists. Why are the two vectors different if assigned in nearly the same, deterministic way?
I tried this code on Arch Linux and Debian with a x86-64 architecture, using Eigen Version 3.4.0, with C++11, C++17, C++20, compiled with both clang and gcc.
#include <eigen3/Eigen/Dense> #include <cassert>
, I use Eigen 3.4.0. – Dishx
andy
are on the order of e-14. The norm is around 2e-12 and the assert passes because eps*10e6 is 2e-9. Changing versions of c++ didn't affect the results. Also, doingx << y
produce a difference of0.0
as expected. Doingx = R.triangular...
also produced0.0
so I can confirm the insertion with solve does cause a difference. – Tadepsilon
could potentially be defined differently on different implementations – Peso