private static void TestSystemSolutionFullUpper() { int n = SymmPosDef10by10.Order; var A = Matrix.CreateFromArray(SymmPosDef10by10.Matrix); var b = SymmPosDef10by10.Rhs; var xExpected = SymmPosDef10by10.Lhs; // Factorization CholeskyFactorizations.FactorizeFullUpper2(A.NumColumns, A, pivotTolerance); // Forward substitution var x1Computed = new double[n]; var x2Computed = new double[n]; CholeskyFactorizations.ForwardSubstitutionFullUpper(n, A, b, x1Computed); CholeskyFactorizations.ForwardSubstitutionFullUpper(n, A, b, x2Computed); // Back substitution - column / vector version CholeskyFactorizations.BackSubstitutionFullUpper1(n, A, x1Computed); comparer.AssertEqual(xExpected, x1Computed); // Back substitution - dot version CholeskyFactorizations.BackSubstitutionFullUpper2(n, A, x2Computed); comparer.AssertEqual(xExpected, x2Computed); }
/// <summary> /// Performs the operation: <paramref name="result"/> = generalized_inverse(A) * <paramref name="vector"/> /// </summary> /// <param name="vector">The vector that will be multiplied. Its <see cref="IIndexable1D.Length"/> must be equal to /// <see cref="IIndexable2D.NumRows"/> of the original matrix A. /// </param> /// <param name="result"> /// Output vector that will be overwritten with the solution of the linear system. Its <see cref="IIndexable1D.Length"/> /// must be equal to <see cref="IIndexable2D.NumColumns"/> of the original matrix A. /// </param> /// <exception cref="NonMatchingDimensionsException"> /// Thrown if <paramref name="vector"/> or <paramref name="result"/> violate the described constraints. /// </exception> /// <exception cref="IndefiniteMatrixException"> /// Thrown if the original skyline matrix turns out to not be symmetric positive semi-definite. /// </exception> public void MultiplyGeneralizedInverseMatrixTimesVector(Vector vector, Vector result) { Preconditions.CheckSystemSolutionDimensions(Order, vector.Length); Preconditions.CheckMultiplicationDimensions(Order, result.Length); // TODO: Is this correct? CholeskyFactorizations.ForwardSubstitutionFullUpper(Order, upperFactorized, vector.RawData, result.RawData); CholeskyFactorizations.BackSubstitutionFullUpper1(Order, upperFactorized, result.RawData); }
public IReadOnlyList <double[]> NullSpaceBasis => nullSpaceBasis; //TODO: return IVectorView /// <summary> /// Applies the Cholesky factorization to the independent columns of a symmetric positive semi-definite matrix, /// sets the dependent ones equal to columns of the identity matrix and return the nullspace of the matrix. Requires /// extra memory for the basis vectors of the nullspace. /// </summary> /// <param name="order">The number of rows/ columns of the square matrix.</param> /// <param name="matrix">The matrix to factorize. It will be overwritten with the factorization data.</param> /// <param name="pivotTolerance"> /// If a diagonal entry is <= <paramref name="pivotTolerance"/> it means that the corresponding column is dependent /// on the rest. The Cholesky factorization only applies to independent column, while dependent ones are used to compute /// the nullspace. Therefore it is important to select a tolerance that will identify small pivots that result from /// singularity, but not from ill-conditioning. /// </param> public static SemidefiniteCholeskyFull Factorize(Matrix matrix, double pivotTolerance = PivotTolerance) { Preconditions.CheckSquare(matrix); int order = matrix.NumColumns; (List <int> dependentColumns, List <double[]> nullSpaceBasis) = CholeskyFactorizations.FactorizeSemiDefiniteFullUpper1(order, matrix, pivotTolerance); Debug.Assert(dependentColumns.Count == nullSpaceBasis.Count); return(new SemidefiniteCholeskyFull(order, matrix, dependentColumns, nullSpaceBasis)); }
private static void TestFactorizeFullUpper1() { // positive definite var A1 = Matrix.CreateFromArray(SymmPosDef10by10.Matrix); var expectedU1 = Matrix.CreateFromArray(SymmPosDef10by10.FactorU); CholeskyFactorizations.FactorizeFullUpper1(A1.NumColumns, A1, pivotTolerance); var computedU1 = Matrix.CreateFromArray(Conversions.FullUpperColMajorToArray2D(A1.RawData, false)); comparer.AssertEqual(expectedU1, computedU1); }