public void SquareRandomMatrixQRDecomposition() { for (int d = 1; d <= 100; d += 11) { Console.WriteLine("d={0}", d); SquareMatrix M = CreateSquareRandomMatrix(d); // QR decompose the matrix. SquareQRDecomposition QRD = M.QRDecomposition(); // The dimension should be right. Assert.IsTrue(QRD.Dimension == M.Dimension); // Test that the decomposition works. SquareMatrix Q = QRD.QMatrix; SquareMatrix R = QRD.RMatrix; Assert.IsTrue(TestUtilities.IsNearlyEqual(Q * R, M)); // Check that the inverse works. SquareMatrix MI = QRD.Inverse(); Assert.IsTrue(TestUtilities.IsNearlyEqual(M * MI, UnitMatrix.OfDimension(d))); // Test that a solution works. ColumnVector t = new ColumnVector(d); for (int i = 0; i < d; i++) { t[i] = i; } ColumnVector s = QRD.Solve(t); Assert.IsTrue(TestUtilities.IsNearlyEqual(M * s, t)); } }
public void SquareRandomMatrixLUDecomposition() { for (int d = 1; d <= 256; d += 11) { SquareMatrix M = CreateSquareRandomMatrix(d); // LU decompose the matrix //Stopwatch sw = Stopwatch.StartNew(); LUDecomposition LU = M.LUDecomposition(); //sw.Stop(); //Console.WriteLine(sw.ElapsedMilliseconds); Assert.IsTrue(LU.Dimension == d); // test that the decomposition works SquareMatrix P = LU.PMatrix(); SquareMatrix L = LU.LMatrix(); SquareMatrix U = LU.UMatrix(); Assert.IsTrue(TestUtilities.IsNearlyEqual(P * M, L * U)); // check that the inverse works SquareMatrix MI = LU.Inverse(); Assert.IsTrue(TestUtilities.IsNearlyEqual(M * MI, UnitMatrix.OfDimension(d))); // test that a solution works ColumnVector t = new ColumnVector(d); for (int i = 0; i < d; i++) { t[i] = i; } ColumnVector s = LU.Solve(t); Assert.IsTrue(TestUtilities.IsNearlyEqual(M * s, t)); } }
public void UnitMatrixArithmetic() { SquareMatrix A = new SquareMatrix(new double[, ] { { 1.0, -2.0 }, { -3.0, 4.0 } }); SquareMatrix AI = A * UnitMatrix.OfDimension(A.Dimension); Assert.IsTrue(A == AI); SquareMatrix IA = UnitMatrix.OfDimension(A.Dimension) * A; Assert.IsTrue(IA == A); ColumnVector c = new ColumnVector(1.0, 2.0, 3.0); ColumnVector Ic = UnitMatrix.OfDimension(c.Dimension) * c; Assert.IsTrue(Ic == c); RowVector r = new RowVector(0.0, 1.0); RowVector rI = r * UnitMatrix.OfDimension(r.Dimension); Assert.IsTrue(rI == r); Assert.IsTrue(UnitMatrix.OfDimension(A.Dimension) == UnitMatrix.OfDimension(A.Dimension)); Assert.IsTrue(0.0 * UnitMatrix.OfDimension(3) == UnitMatrix.OfDimension(3) - UnitMatrix.OfDimension(3)); Assert.IsTrue(1.0 * UnitMatrix.OfDimension(3) == UnitMatrix.OfDimension(3)); Assert.IsTrue(2.0 * UnitMatrix.OfDimension(3) == UnitMatrix.OfDimension(3) + UnitMatrix.OfDimension(3)); }
public void SquareUnitMatrixEigensystem() { int d = 3; SquareMatrix I = UnitMatrix.OfDimension(d).ToSquareMatrix(); ComplexEigendecomposition E = I.Eigendecomposition(); Assert.IsTrue(E.Dimension == d); for (int i = 0; i < d; i++) { Complex val = E.Eigenpairs[i].Eigenvalue; Assert.IsTrue(val == 1.0); ComplexColumnVector vec = E.Eigenpairs[i].Eigenvector; for (int j = 0; j < d; j++) { if (i == j) { Assert.IsTrue(vec[j] == 1.0); } else { Assert.IsTrue(vec[j] == 0.0); } } } }
public void SquareVandermondeMatrixInverse() { for (int d = 1; d < 8; d++) { SquareMatrix H = CreateVandermondeMatrix(d); SquareMatrix HI = H.Inverse(); Assert.IsTrue(TestUtilities.IsNearlyEqual(H * HI, UnitMatrix.OfDimension(d))); } }
public void UnitMatrixImmutable() { UnitMatrix I = UnitMatrix.OfDimension(2); try { I[0, 0] += 1.0; Assert.Fail(); } catch (InvalidOperationException) { } }
public void SymmetricRandomMatrixInverse() { for (int d = 1; d <= 100; d = d + 11) { SymmetricMatrix M = TestUtilities.CreateSymmetricRandomMatrix(d, 1); SymmetricMatrix MI = M.Inverse(); Assert.IsTrue(TestUtilities.IsNearlyEqual(MI * M, UnitMatrix.OfDimension(d))); } }
public void SymmetricHilbertMatrixInverse() { for (int d = 1; d < 4; d++) { SymmetricMatrix H = TestUtilities.CreateSymmetricHilbertMatrix(d); SymmetricMatrix HI = H.Inverse(); Assert.IsTrue(TestUtilities.IsNearlyEqual(HI * H, UnitMatrix.OfDimension(d))); } // fails for d >= 4; look into this }
public void UnitMatrixNorms() { UnitMatrix I = UnitMatrix.OfDimension(4); SquareMatrix A = I.ToSquareMatrix(); Assert.IsTrue(I.OneNorm() == A.OneNorm()); Assert.IsTrue(I.InfinityNorm() == A.InfinityNorm()); Assert.IsTrue(I.FrobeniusNorm() == A.FrobeniusNorm()); Assert.IsTrue(I.MaxNorm() == A.MaxNorm()); }
public void SquareUnitMatrixLUDecomposition() { for (int d = 1; d <= 10; d++) { SquareMatrix I = UnitMatrix.OfDimension(d).ToSquareMatrix(); Assert.IsTrue(I.Trace() == d); LUDecomposition LU = I.LUDecomposition(); Assert.IsTrue(LU.Determinant() == 1.0); SquareMatrix II = LU.Inverse(); Assert.IsTrue(TestUtilities.IsNearlyEqual(II, I)); } }
public static void VectorsAndMatrices() { ColumnVector v = new ColumnVector(0.0, 1.0, 2.0); ColumnVector w = new ColumnVector(new double[] { 1.0, -0.5, 1.5 }); SquareMatrix A = new SquareMatrix(new double[, ] { { 1, -2, 3 }, { 2, -5, 12 }, { 0, 2, -10 } }); RowVector u = new RowVector(4); for (int i = 0; i < u.Dimension; i++) { u[i] = i; } Random rng = new Random(1); RectangularMatrix B = new RectangularMatrix(4, 3); for (int r = 0; r < B.RowCount; r++) { for (int c = 0; c < B.ColumnCount; c++) { B[r, c] = rng.NextDouble(); } } SquareMatrix AI = A.Inverse(); PrintMatrix("A * AI", A * AI); PrintMatrix("v + 2.0 * w", v + 2.0 * w); PrintMatrix("Av", A * v); PrintMatrix("B A", B * A); PrintMatrix("v^T", v.Transpose); PrintMatrix("B^T", B.Transpose); Console.WriteLine($"|v| = {v.Norm()}"); Console.WriteLine($"sqrt(v^T v) = {Math.Sqrt(v.Transpose * v)}"); UnitMatrix I = UnitMatrix.OfDimension(3); PrintMatrix("IA", I * A); Console.WriteLine(v == w); Console.WriteLine(I * A == A); }
public void SquareVandermondeMatrixLUDecomposition() { // fails now for d = 8 because determinant slightly off for (int d = 1; d < 8; d++) { // Analytic expression for determinant double[] x = new double[d]; for (int i = 0; i < d; i++) { x[i] = i; } double det = 1.0; for (int i = 0; i < d; i++) { for (int j = 0; j < i; j++) { det = det * (x[i] - x[j]); } } // LU decompose the matrix SquareMatrix V = CreateVandermondeMatrix(d); LUDecomposition LU = V.LUDecomposition(); // Test that the decomposition works SquareMatrix P = LU.PMatrix(); SquareMatrix L = LU.LMatrix(); SquareMatrix U = LU.UMatrix(); Assert.IsTrue(TestUtilities.IsNearlyEqual(P * V, L * U)); // Check that the determinant agrees with the analytic expression Assert.IsTrue(TestUtilities.IsNearlyEqual(LU.Determinant(), det)); // Check that the inverse works SquareMatrix VI = LU.Inverse(); Assert.IsTrue(TestUtilities.IsNearlyEqual(V * VI, UnitMatrix.OfDimension(d))); // Test that a solution works ColumnVector t = new ColumnVector(d); for (int i = 0; i < d; i++) { t[i] = 1.0; } ColumnVector s = LU.Solve(t); Assert.IsTrue(TestUtilities.IsNearlyEqual(V * s, t)); } }
public void RandomRectangularSVD() { for (int c = 1; c < 64; c += 11) { Console.WriteLine(c); RectangularMatrix R = GenerateRandomMatrix(64, c); SingularValueDecomposition SVD = R.SingularValueDecomposition(); Assert.IsTrue(SVD.RowCount == R.RowCount); Assert.IsTrue(SVD.ColumnCount == SVD.ColumnCount); Assert.IsTrue(SVD.Dimension == SVD.ColumnCount); // U has right dimensions and is orthogonal SquareMatrix U = SVD.LeftTransformMatrix; Assert.IsTrue(U.Dimension == R.RowCount); Assert.IsTrue(TestUtilities.IsNearlyEqual(U.Transpose * U, UnitMatrix.OfDimension(U.Dimension))); // V has right dimensions and is orthogonal SquareMatrix V = SVD.RightTransformMatrix; Assert.IsTrue(V.Dimension == R.ColumnCount); Assert.IsTrue(TestUtilities.IsNearlyEqual(V.Transpose * V, UnitMatrix.OfDimension(V.Dimension))); // The transforms decompose the matrix with the claimed singular values RectangularMatrix S = U.Transpose * R * V; for (int i = 0; i < SVD.Contributors.Count; i++) { SingularValueContributor t = SVD.Contributors[i]; Assert.IsTrue(t.SingularValue >= 0.0); Assert.IsTrue(TestUtilities.IsNearlyEqual(S[i, i], t.SingularValue)); Assert.IsTrue(TestUtilities.IsNearlyEqual(R * t.RightSingularVector, t.SingularValue * t.LeftSingularVector)); } // We can reconstruct the original matrix from the claimed singular values RectangularMatrix R2 = new RectangularMatrix(SVD.RowCount, SVD.ColumnCount); foreach (SingularValueContributor t in SVD.Contributors) { R2 += t.SingularValue * t.LeftSingularVector * t.RightSingularVector.Transpose; } Assert.IsTrue(TestUtilities.IsNearlyEqual(R, R2)); } }
public void HilbertMatrixCholeskyDecomposition() { for (int d = 1; d <= 4; d++) { SymmetricMatrix H = TestUtilities.CreateSymmetricHilbertMatrix(d); // Decomposition succeeds CholeskyDecomposition CD = H.CholeskyDecomposition(); Assert.IsTrue(CD != null); Assert.IsTrue(CD.Dimension == d); // Decomposition works SquareMatrix S = CD.SquareRootMatrix(); Assert.IsTrue(TestUtilities.IsNearlyEqual(S * S.Transpose, H)); // Inverse works SymmetricMatrix HI = CD.Inverse(); Assert.IsTrue(TestUtilities.IsNearlyEqual(H * HI, UnitMatrix.OfDimension(d))); } }
public void UnitMatrixConversions() { UnitMatrix I = UnitMatrix.OfDimension(3); SquareMatrix A = I.ToSquareMatrix(); Assert.IsTrue(I == A); A[0, 1] += 2.0; Assert.IsTrue(I != A); SymmetricMatrix B = I.ToSymmetricMatrix(); Assert.IsTrue(I == B); B[0, 1] += 2.0; Assert.IsTrue(I != B); DiagonalMatrix C = I.ToDiagonalMatrix(); Assert.IsTrue(I == C); C[2, 2] -= 1.0; Assert.IsTrue(I != C); }
public void SymmetricRandomMatrixEigenvectors() { for (int d = 1; d <= 100; d = d + 11) { SymmetricMatrix M = CreateSymmetricRandomMatrix(d, 1); RealEigendecomposition E = M.Eigendecomposition(); Assert.IsTrue(E.Dimension == M.Dimension); double[] eigenvalues = new double[E.Dimension]; for (int i = 0; i < E.Dimension; i++) { double e = E.Eigenpairs[i].Eigenvalue; ColumnVector v = E.Eigenpairs[i].Eigenvector; // The eigenvector works Assert.IsTrue(TestUtilities.IsNearlyEigenpair(M, v, e)); // The eigenvalue is the corresponding diagonal value of D Assert.IsTrue(E.DiagonalizedMatrix[i, i] == e); // Remember eigenvalue to take sum in future eigenvalues[i] = e; } // The eigenvectors sum to trace double tr = M.Trace(); Assert.IsTrue(TestUtilities.IsSumNearlyEqual(eigenvalues, tr)); // The decomposition works Assert.IsTrue(TestUtilities.IsNearlyEqual( E.DiagonalizedMatrix, E.TransformMatrix.Transpose * M * E.TransformMatrix )); // Transform matrix is orthogonal Assert.IsTrue(TestUtilities.IsNearlyEqual( E.TransformMatrix.Transpose * E.TransformMatrix, UnitMatrix.OfDimension(d) )); } }
public void RectangularQRDecomposition() { RectangularMatrix M = GenerateRandomMatrix(30, 10); QRDecomposition QRD = M.QRDecomposition(); Assert.IsTrue(QRD.RowCount == M.RowCount); Assert.IsTrue(QRD.ColumnCount == M.ColumnCount); SquareMatrix Q = QRD.QMatrix; Assert.IsTrue(Q.Dimension == M.RowCount); Assert.IsTrue(TestUtilities.IsNearlyEqual(Q * Q.Transpose, UnitMatrix.OfDimension(Q.Dimension))); RectangularMatrix R = QRD.RMatrix; Assert.IsTrue(R.RowCount == M.RowCount); Assert.IsTrue(R.ColumnCount == M.ColumnCount); RectangularMatrix QR = Q * R; Assert.IsTrue(TestUtilities.IsNearlyEqual(QR, M)); }
public void UnitMatrixEntries() { int n = 3; UnitMatrix I = UnitMatrix.OfDimension(n); Assert.IsTrue(I.Dimension == n); Assert.IsTrue(I.RowCount == n); Assert.IsTrue(I.ColumnCount == n); for (int r = 0; r < n; r++) { for (int c = 0; c < n; c++) { if (r == c) { Assert.IsTrue(I[r, c] == 1.0); } else { Assert.IsTrue(I[r, c] == 0.0); } } } }
public void SquareMatrixSVD() { for (int d = 4; d < 64; d += 7) { SquareMatrix A = CreateSquareRandomMatrix(d, d); SingularValueDecomposition SVD = A.SingularValueDecomposition(); Assert.IsTrue(SVD.Dimension == A.Dimension); // U has right dimensions and is orthogonal SquareMatrix U = SVD.LeftTransformMatrix; Assert.IsTrue(U.Dimension == A.Dimension); Assert.IsTrue(TestUtilities.IsNearlyEqual(U.MultiplyTransposeBySelf(), UnitMatrix.OfDimension(U.Dimension))); // V has right dimensions and is orthogonal SquareMatrix V = SVD.RightTransformMatrix; Assert.IsTrue(V.Dimension == A.Dimension); Assert.IsTrue(TestUtilities.IsNearlyEqual(V.MultiplyTransposeBySelf(), UnitMatrix.OfDimension(V.Dimension))); Assert.IsTrue(SVD.Dimension == A.Dimension); // The transforms decompose the matrix with the claimed singular values SquareMatrix S = U.Transpose * A * V; for (int i = 0; i < SVD.Contributors.Count; i++) { SingularValueContributor t = SVD.Contributors[i]; Assert.IsTrue(t.SingularValue >= 0.0); Assert.IsTrue(TestUtilities.IsNearlyEqual(S[i, i], t.SingularValue)); } // We can solve a rhs using the SVD ColumnVector x = new ColumnVector(d); for (int i = 0; i < d; i++) { x[i] = i; } ColumnVector b = A * x; ColumnVector y = SVD.Solve(b); Assert.IsTrue(TestUtilities.IsNearlyEqual(x, y)); } }