public void TestRandomA() { RandomHelper.Random = new Random(1); for (int i = 0; i < 100; i++) { // Create A. MatrixF a = new MatrixF(3, 3); RandomHelper.Random.NextMatrixF(a, 0, 1); LUDecompositionF d = new LUDecompositionF(a); if (d.IsNumericallySingular == false) { // Check solving of linear equations. MatrixF b = new MatrixF(3, 2); RandomHelper.Random.NextMatrixF(b, 0, 1); MatrixF x = d.SolveLinearEquations(b); MatrixF b2 = a * x; Assert.IsTrue(MatrixF.AreNumericallyEqual(b, b2, 0.01f)); MatrixF aPermuted = d.L * d.U; Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 2))); } } }
public void TestRandomRegularA() { RandomHelper.Random = new Random(1); for (int i = 0; i < 100; i++) { VectorF column1 = new VectorF(3); RandomHelper.Random.NextVectorF(column1, 1, 2); VectorF column2 = new VectorF(3); RandomHelper.Random.NextVectorF(column2, 1, 2); // Make linearly independent. if (column1 / column1[0] == column2 / column2[0]) { column2[0]++; } // Create linearly independent third column. VectorF column3 = column1 + column2; column3[1]++; // Create A. MatrixF a = new MatrixF(3, 3); a.SetColumn(0, column1); a.SetColumn(1, column2); a.SetColumn(2, column3); LUDecompositionF d = new LUDecompositionF(a); MatrixF aPermuted = d.L * d.U; Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 2))); aPermuted = d.L * d.U; // Repeat with to test cached values. Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 2))); Assert.AreEqual(false, d.IsNumericallySingular); // Check solving of linear equations. MatrixF b = new MatrixF(3, 2); RandomHelper.Random.NextMatrixF(b, 0, 1); MatrixF x = d.SolveLinearEquations(b); MatrixF b2 = a * x; Assert.IsTrue(MatrixF.AreNumericallyEqual(b, b2, 0.01f)); } }
public void Determinant() { MatrixF a = new MatrixF(new float[,] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 0, 1, 2, 0 }, { 1, 0, 1, 0 } }); LUDecompositionF d = new LUDecompositionF(a); Assert.AreEqual(false, d.IsNumericallySingular); Assert.IsTrue(Numeric.AreEqual(-24, d.Determinant)); MatrixF aPermuted = d.L * d.U; Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 3))); }
/// <summary> /// Returns the least squares solution for the equation <c>A * X = B</c>. /// </summary> /// <param name="matrixB">The matrix B with as many rows as A and any number of columns.</param> /// <returns>X with the least squares solution.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="matrixB"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// The number of rows does not match. /// </exception> /// <exception cref="MathematicsException"> /// The matrix A does not have full rank. /// </exception> public MatrixF SolveLinearEquations(MatrixF matrixB) { if (matrixB == null) { throw new ArgumentNullException("matrixB"); } if (matrixB.NumberOfRows != _m) { throw new ArgumentException("The number of rows does not match.", "matrixB"); } if (HasNumericallyFullRank == false) { throw new MathematicsException("The matrix does not have full rank."); } // Copy right hand side MatrixF x = matrixB.Clone(); // Compute Y = transpose(Q)*B for (int k = 0; k < _n; k++) { for (int j = 0; j < matrixB.NumberOfColumns; j++) { float s = 0; for (int i = k; i < _m; i++) { s += _qr[i, k] * x[i, j]; } s = -s / _qr[k, k]; for (int i = k; i < _m; i++) { x[i, j] += s * _qr[i, k]; } } } // Solve R*X = Y. for (int k = _n - 1; k >= 0; k--) { for (int j = 0; j < matrixB.NumberOfColumns; j++) { x[k, j] /= _rDiagonal[k]; } for (int i = 0; i < k; i++) { for (int j = 0; j < matrixB.NumberOfColumns; j++) { x[i, j] -= x[k, j] * _qr[i, k]; } } } return(x.GetSubmatrix(0, _n - 1, 0, matrixB.NumberOfColumns - 1)); }
public void Determinant() { MatrixF a = new MatrixF(new float[, ] { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 0, 1, 2, 0 }, { 1, 0, 1, 0 } }); LUDecompositionF d = new LUDecompositionF(a); Assert.AreEqual(false, d.IsNumericallySingular); Assert.IsTrue(Numeric.AreEqual(-24, d.Determinant())); MatrixF aPermuted = d.L * d.U; Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 3))); }
//-------------------------------------------------------------- #region Methods //-------------------------------------------------------------- /// <summary> /// Solves the equation <c>A * X = B</c>. /// </summary> /// <param name="matrixB">The matrix B with as many rows as A and any number of columns.</param> /// <returns>X, so that <c>A * X = B</c>.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="matrixB"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// The number of rows does not match. /// </exception> /// <exception cref="MathematicsException"> /// The matrix A is numerically singular. /// </exception> public MatrixF SolveLinearEquations(MatrixF matrixB) { if (matrixB == null) { throw new ArgumentNullException("matrixB"); } if (matrixB.NumberOfRows != _m) { throw new ArgumentException("The number of rows does not match.", "matrixB"); } if (IsNumericallySingular) { throw new MathematicsException("The original matrix A is numerically singular."); } // Copy right hand side with pivoting MatrixF x = matrixB.GetSubmatrix(_pivotVector, 0, matrixB.NumberOfColumns - 1); // Solve L*Y = B(piv,:) for (int k = 0; k < _n; k++) { for (int i = k + 1; i < _n; i++) { for (int j = 0; j < matrixB.NumberOfColumns; j++) { x[i, j] -= x[k, j] * _lu[i, k]; } } } // Solve U*X = Y; for (int k = _n - 1; k >= 0; k--) { for (int j = 0; j < matrixB.NumberOfColumns; j++) { x[k, j] /= _lu[k, k]; } for (int i = 0; i < k; i++) { for (int j = 0; j < matrixB.NumberOfColumns; j++) { x[i, j] -= x[k, j] * _lu[i, k]; } } } return(x); }
public void GetSubmatrixException9() { MatrixF m = new MatrixF(4, 3, rowMajor, MatrixOrder.RowMajor); m.GetSubmatrix(0, 4, new int[]{1}); }
public void GetSubmatrixException8() { MatrixF m = new MatrixF(4, 3, rowMajor, MatrixOrder.RowMajor); m.GetSubmatrix(0, 1, 0, -1); }
public void GetSubmatrixException4() { MatrixF m = new MatrixF(4, 3, rowMajor, MatrixOrder.RowMajor); m.GetSubmatrix(new int[] { 1 }, 1, 0); }
public void GetSubmatrixException14() { MatrixF m = new MatrixF(4, 3, rowMajor, MatrixOrder.RowMajor); m.GetSubmatrix(new int[] { 2 }, new int[] { 4 }); }
public void GetSubmatrix() { MatrixF m = new MatrixF(3, 4, rowMajor, MatrixOrder.RowMajor); Assert.AreEqual(m, m.GetSubmatrix(0, 2, 0, 3)); Assert.AreEqual(new MatrixF(1, 1, 1), m.GetSubmatrix(0, 0, 0, 0)); Assert.AreEqual(new MatrixF(1, 1, 12), m.GetSubmatrix(2, 2, 3, 3)); Assert.AreEqual(new MatrixF(1, 1, 12), m.GetSubmatrix(2, 2, new int[] { 3 })); Assert.AreEqual(new MatrixF(1, 1, 4), m.GetSubmatrix(new int[] {0}, 3, 3)); Assert.AreEqual(new MatrixF(1, 1, 10), m.GetSubmatrix(new int[] { 2 }, new int[] { 1 })); Assert.AreEqual(new MatrixF(new float[,] { { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }), m.GetSubmatrix(1, 2, 0, 3)); Assert.AreEqual(new MatrixF(new float[,] { { 8, 6, 7 }, { 12, 10, 11 } }), m.GetSubmatrix(1, 2, new int[] { 3, 1, 2})); Assert.AreEqual(new MatrixF(new float[,] { { 11, 12 }, { 7, 8 }, { 3, 4 } }), m.GetSubmatrix(new int[] { 2, 1, 0 }, 2, 3)); Assert.AreEqual(new MatrixF(new float[,] { { 8, 7, 5, 6 }, { 12, 11, 9, 10 }, { 4, 3, 1, 2 } }), m.GetSubmatrix(new int[] { 1, 2, 0 }, new int[] {3, 2, 0, 1})); Assert.AreEqual(null, m.GetSubmatrix(null, 0, 2)); Assert.AreEqual(null, m.GetSubmatrix(0, 2, null)); Assert.AreEqual(null, m.GetSubmatrix(null, new int[] { 1 })); Assert.AreEqual(null, m.GetSubmatrix(new int[] { 1 }, null)); Assert.AreEqual(null, m.GetSubmatrix(null, null)); }
public void TestRandomRegularA() { RandomHelper.Random = new Random(1); for (int i = 0; i < 100; i++) { VectorF column1 = new VectorF(3); RandomHelper.Random.NextVectorF(column1, 1, 2); VectorF column2 = new VectorF(3); RandomHelper.Random.NextVectorF(column2, 1, 2); // Make linearly independent. if (column1 / column1[0] == column2 / column2[0]) column2[0]++; // Create linearly independent third column. VectorF column3 = column1 + column2; column3[1]++; // Create A. MatrixF a = new MatrixF(3, 3); a.SetColumn(0, column1); a.SetColumn(1, column2); a.SetColumn(2, column3); LUDecompositionF d = new LUDecompositionF(a); MatrixF aPermuted = d.L * d.U; Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 2))); aPermuted = d.L * d.U; // Repeat with to test cached values. Assert.IsTrue(MatrixF.AreNumericallyEqual(aPermuted, a.GetSubmatrix(d.PivotPermutationVector, 0, 2))); Assert.AreEqual(false, d.IsNumericallySingular); // Check solving of linear equations. MatrixF b = new MatrixF(3, 2); RandomHelper.Random.NextMatrixF(b, 0, 1); MatrixF x = d.SolveLinearEquations(b); MatrixF b2 = a * x; Assert.IsTrue(MatrixF.AreNumericallyEqual(b, b2, 0.01f)); } }
//-------------------------------------------------------------- /// <summary> /// Solves the equation <c>A * X = B</c>. /// </summary> /// <param name="matrixB">The matrix B with as many rows as A and any number of columns.</param> /// <returns>X, so that <c>A * X = B</c>.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="matrixB"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// The number of rows does not match. /// </exception> /// <exception cref="MathematicsException"> /// The matrix A is numerically singular. /// </exception> public MatrixF SolveLinearEquations(MatrixF matrixB) { if (matrixB == null) throw new ArgumentNullException("matrixB"); if (matrixB.NumberOfRows != _m) throw new ArgumentException("The number of rows does not match.", "matrixB"); if (IsNumericallySingular) throw new MathematicsException("The original matrix A is numerically singular."); // Copy right hand side with pivoting MatrixF x = matrixB.GetSubmatrix(_pivotVector, 0, matrixB.NumberOfColumns-1); // Solve L*Y = B(piv,:) for (int k = 0; k < _n; k++) for (int i = k + 1; i < _n; i++) for (int j = 0; j < matrixB.NumberOfColumns; j++) x[i, j] -= x[k, j] * _lu[i, k]; // Solve U*X = Y; for (int k = _n - 1; k >= 0; k--) { for (int j = 0; j < matrixB.NumberOfColumns; j++) x[k, j] /= _lu[k, k]; for (int i = 0; i < k; i++) for (int j = 0; j < matrixB.NumberOfColumns; j++) x[i, j] -= x[k, j] * _lu[i, k]; } return x; }