public void SingularValueDecompositionConstructorTest1()
{
// This test catches the bug in SingularValueDecomposition in the line
// for (int j = k + 1; j < nu; j++)
// where it should be
// for (int j = k + 1; j < n; j++)
// Test for m-x-n matrices where m < n. The available SVD
// routine was not meant to be used in this case.
double[,] value = new double[,]
{
{ 1, 2 },
{ 3, 4 },
{ 5, 6 },
{ 7, 8 }
}.Transpose(); // value is 2x4, having less rows than columns.
var target = new SingularValueDecomposition(value, true, true, false);
double[,] actual = target.LeftSingularVectors.Multiply(
target.DiagonalMatrix).Multiply(target.RightSingularVectors.Transpose());
// Checking the decomposition
Assert.IsTrue(Matrix.IsEqual(actual, value, 1e-2));
Assert.IsTrue(Matrix.IsEqual(target.Reverse(), value, 1e-2));
// Checking values
double[,] U =
{
{ -0.641423027995072, -0.767187395072177 },
{ -0.767187395072177, 0.641423027995072 },
};
// U should be equal
Assert.IsTrue(Matrix.IsEqual(target.LeftSingularVectors, U, 0.001));
double[,] V = // economy svd
{
{ -0.152483233310201, 0.822647472225661, },
{ -0.349918371807964, 0.421375287684580, },
{ -0.547353510305727, 0.0201031031435023, },
{ -0.744788648803490, -0.381169081397574, },
};
// V can be different, but for the economy SVD it is often equal
Assert.IsTrue(Matrix.IsEqual(target.RightSingularVectors.Submatrix(0, 3, 0, 1), V, 0.0001));
double[,] S =
{
{ 14.2690954992615, 0.000000000000000 },
{ 0.0000000000000, 0.626828232417543 },
};
// The diagonal values should be equal
Assert.IsTrue(Matrix.IsEqual(target.Diagonal.First(2),
Matrix.Diagonal(S), 0.001));
}