2013-08-07 4 views
2

Mathnet.Iridium과 Mathnet.Numerics 간의 비 회귀 성을 찾고 있습니다. 다음은 Mathnet을 사용하는 코드입니다. 숫자 :Mathnet 숫자 라이브러리가있는 Svd 재구성이 잘못되었습니다.

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()); 

내가 recompo와 초기 매트릭스를 비교할 때, 그들은 다릅니다.

  • U 및 singularValueDecomposition.LeftSingularVectors는
  • W 동일하고 singularValueDecomposition.S는
  • VT와 Matrix.Transpose (singulaValueDecomposition.RightSingularVectors 같다 : 이전 구현 각 분해 매트릭스를 비교할 때 I는이 차이를 발견)가 다릅니다.

마지막으로 이전 API로 재구성하는 것이 정확합니다. 사용

MathNet.Numerics 버전 : Math.NET 메릭스의 v2.5.0

그래서 내 질문은 : 새로운 API와 초기 행렬을 재건 할 때 어디에 내 실수는?

RecompoMatrix =

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

답변

1

신속하게 재현하려고했지만 실패했습니다. Math.NET Numerics v2.6 (NuGet 패키지)을 사용했지만이 릴리스에서는 SVD 분해와 관련된 변경 사항이 없습니다. 당신은 완전히 다른 결과를 얻을 이유

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 

가 궁금해 : 마지막 줄로 평가

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() 

:이 경우

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는이 내 코드? 내가 위에 올린 동일한 코드로 다시 시도 할 수 있습니까?

+0

재미있는 점이 있습니다 : m.Svd (true) 메서드로 올바른 결과를 얻었지만 대체하면 올바르지 않습니다. // var svd = m.Svd (true); var svd = 새 UserSvd (m, true); – FabricePA

+0

어쨌든, 회귀를 저장했기 때문에 대답을 표시합니다. 이것에 대해 고마워. Matrix.Svd()를 사용하겠습니다. 그럼에도 불구하고, 나는 정말로 UserSvd와 DenseSvd에 문제가 있거나 그것이 어떻게 사용되어야하는지 이해하지 못했다고 생각합니다. – FabricePA

+0

감사합니다. 두 메서드 (LINQPad)를 모두 시험해 보면 DenseSvd와 UserSvd에서 실제로 똑같은 결과가 나타납니다. 그래서 나는 어딘가에 숨겨진 버그가 없는지 확인하기 위해 문제가 무엇인지 알아내는 데 여전히 관심이 있습니다. –

0

SVD 이전에 매트릭스를 중심에 두는 것이 좋습니까? Eigen 벡터를 계산하기 전에 중심에 놓 였을 수도 있습니다.