This forum has been archived. All content is frozen. Please use KDE Discuss instead.

Eigen3 vs MATLAB precision and Norms

Tags: None
(comma "," separated)
drsg
Registered Member
Posts
2
Karma
0
First of all thank you for an amazing work on this library, It's absolutely fantastic!

While learning my way around Eigen3 I was doing some simple test apps and comparing different results of different methods and I got a little surprised with the output of norm() method in Eigen3 vs MATLAB. Results seem to vary rather dramatically and I am not sure I can explain why.

Here is the C++ code:

Code: Select all
Eigen::MatrixXd X(5, 3);
X<< 1.2, 2.2, 3.2,
   1.6, 2.9, 3.4,
   1.1, 2.4, 3.3,
   1.9, 2.7, 3.7,
   1.5, 2.0, 3.5;
std::cout << "X.squaredNorm() = " << X.squaredNorm() << std::endl;
std::cout << "X.norm() = " << X.norm() << std::endl;
std::cout << "X.lpNorm<1>() = " << X.lpNorm<1>() << std::endl;
std::cout << "X.lpNorm<2>() = " << X.lpNorm<2>() << std::endl;
std::cout << "X.lpNorm<Infinity>() = " << X.lpNorm<Eigen::Infinity>() << std::endl;


C++ Eigen3 Results:

X.squaredNorm() = 100
X.norm() = 10
X.lpNorm<1>() = 36.6
X.lpNorm<Infinity>() = 3.7

MATLAB Results:

norm(X,2) = 9.9736 (Eucleadean Norm)
norm(X,'fro') = 10 (Frobenius Norm)
norm(X,1) = 17.1 (L1 Norm)
norm(X,Inf) = 8.3 (L Infinity Norm)

I have checked and MATLAB is using double to represent matrix elements using 64bits, the same as C++ for double.

Using large matrices and comparing Frobeius norm seem to vary rather dramatically.

To be more clear, I use Eigen and compile CMEX file for MATLAB, I use exactly the same underlying code for random SVD calculation using C++ as compiled CMEX in MATLAB. I test using random matrices of 1000, 2500, 5000, 7500, 10 000 rows and 100, 250, 500, 750, 1000 columns, perform SVD (rank = 20) then I compare original matrix with reconstructed U*S*V.transposed. The strange thing is that the results in MATLAB and C++ are very different using the same code and the same Norm.

Would be great if you could shed some light on this.

EDIT:

It appears that MATLAB and Eigen calculate norms differently. Eigen takes in a matrix, turns it in to a vector and then performs norm calculation. MATLAB on the other hand does it without turning input matrix in to a vector.

norm(X,1) is calculated as sum(abs(X)) for a vector and max(sum(abs(X))) for a matrix

More details are here if anyone is interested: https://se.mathworks.com/help/matlab/ref/norm.html?requestedDomain=www.mathworks.com

Thank you
User avatar
ggael
Moderator
Posts
3447
Karma
19
OS
Does your own answer solves all your issues?

See also: http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1071

You can use the more expensive stableNorm() method to avoid under/overflows when computing the Frobenius norm.
drsg
Registered Member
Posts
2
Karma
0
Yes, it does.
In order to be consistent its better to convert MATLAB matrix in to a vector then compute norm.

Thank you for posting the link, it was very useful.


Bookmarks



Who is online

Registered users: bartoloni, Bing [Bot], Evergrowing, Google [Bot], ourcraft