Svd recomposition with Mathnet numerics library seems wrong

折月煮酒 提交于 2019-12-24 03:08:28

问题


I'm looking for non regression between Mathnet.Iridium and Mathnet.Numerics. Here is my code, using Mathnet.Numerics :

double[][] symJaggedArray = new double[5][];
symJaggedArray[0] = new double[] { 3, 0, 0, 0, 0 };
symJaggedArray[1] = new double[] { 0, 2, 4, 0, 0 };
symJaggedArray[2] = new double[] { 0, 4, 5, -4, 5 };
symJaggedArray[3] = new double[] { 0, 0, -4, -8, 12 };
symJaggedArray[4] = new double[] { 0, 0, 5, 12, -5 };
symDenseMatrix = DenseMatrix.OfArray(new Matrix(symJaggedArray).CopyToArray());// not optimal but it's not the point

Svd svd = new UserSvd(symDenseMatrix , true);
Matrix<double> recompo = svd.U().Multiply(svd.W()).Multiply(svd.VT());

When i compare recompo and the initial matrix, they are different. I found this difference when comparing each decomposition matrix with the previous implementation :

  • U and singularValueDecomposition.LeftSingularVectors are equal
  • W and singularValueDecomposition.S are equal
  • VT and Matrix.Transpose(singulaValueDecomposition.RightSingularVectors) are different

Finally, recomposition with older API is correct.

MathNet.Numerics version used : Math.NET Numerics v2.5.0

So my question is : Where is my mistake when rebuilding initial matrix with the new API ?

RecompoMatrix =

  • 3 0 0 0 0
  • 0 -1.216846655456 2.83903817786199 1.4472680220698 2.89215520227421
  • 0 -2.46695399700557 8.657344064164 0.92863757484644 -0.31963101527516
  • 0 0.349540484418384 8.20515629935223 -2.26741625715781 -12.3049605878983
  • 0 -0.402667067831389 -6.32914150795323 9.13315298351198 8.3884053064068

回答1:


I quickly tried to reproduce this, but I failed. I've used Math.NET Numerics v2.6 (NuGet package), but there was no change around the SVD decomposition in this release. This is my code:

var m = DenseMatrix.OfArray(new double[,] {
   { 3, 0, 0, 0, 0 },
   { 0, 2, 4, 0, 0 },
   { 0, 4, 5, -4, 5 },
   { 0, 0, -4, -8, 12},
   { 0, 0, 5, 12, -5 }});

var svd = m.Svd(true);
//var svd = new UserSvd(m, true);

svd.U() * svd.W() * svd.VT()

Where the last line evaluates to:

DenseMatrix 5x5-Double
           3            0            0            0            0
           0            2            4 -1.23512E-15   -3.747E-16
           0            4            5           -4            5
           0  3.26128E-16           -4           -8           12
           0 -1.15186E-15            5           12           -5

VT in this case is:

DenseMatrix 5x5-Double
           0   -0.0449147     0.249507     0.718099    -0.648123
           0     0.466822     0.823535    0.0324572     0.320646
           0     0.208479     0.176729    -0.670706    -0.689534
          -1            0            0            0            0
           0     0.858252    -0.477811     0.182848   -0.0408292

I wonder why you get a completely different result? Can you try again with the same code I posted above?




回答2:


Have you considered centering the matrices before SVD? It might have been centered before computation of Eigen vectors.



来源:https://stackoverflow.com/questions/18100873/svd-recomposition-with-mathnet-numerics-library-seems-wrong

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!