Running initialization and C ++ and Eigen constructors

I am using the Eigen library in C ++ and I am trying to find the determinant of a matrix. I get different results depending on how I initialize the matrices.

Method I:

MatrixXd a(3, 3);
for (int n = 0; n < 3; n++)
    for (int m = 0; m < 3; m++)
        a(n,m) = (double) (n + m*m + 2.5)/3;

cout << "Matrix a: " << endl;
cout << a << endl;
cout << "Determinat of matrix a is: " << a.determinant() << endl;

      

This piece of code prints

Matrix a:
0.8333333  1.166667  2.166667
1.166667       1.5       2.5
1.5  1.833333  2.833333
Determinat of matrix a is: -7.401487e-17

      

Method II:

MatrixXd b(3, 3);
b << 0.8333333, 1.166667, 2.166667,
    1.166667, 1.5, 2.5,
    1.5, 1.833333, 2.833333;

cout << b;
cout << endl << "Determinant of matrix b is: " << b.determinant();

      

which prints

0.8333333  1.166667  2.166667
1.166667       1.5       2.5
1.5  1.833333  2.833333
Determinant of matrix b is: 2.333331e-07

      

Method i gives the wrong result, while method II gives the correct answer. What happens in the first case? (I am using Visual Studio.) Thanks in advance!

+3


source to share


1 answer


What you are seeing here are rounding errors in your calculations. Let me explain it this way:

For a computer, everything is based on a binary number system, that is, instead of base 10, as we usually use in our daily life, computers calculate with base 2, that is, only the numbers 0 and 1.

This applies not only to integers, but also to real numbers, like 0.83333 ... But just as it is impossible to write down all the digits 0.83333 ..., your computer cannot store every last digit of the binary representation of that number - thus, it has to round up the result somehow.



Depending on how you initialize it (either by calculating (n + m*m + 2.5)/3

or by reading the value from your initialization with a comma), the result may be slightly different in one of the last digits, resulting in different results.

You can try this by comparing 0.8333333 to 2.5 / 3, which will probably return false

. If you print numbers, you get the same result, but the internal representation is slightly different.

However, you should note that the absolute error itself is fairly small (less than 0.000001), so you don't need to worry about that for now. If you want accurate results, it may be helpful to switch to a rational number type that can accurately represent these values.

+5


source







All Articles