예제 #1
0
        /// <summary>
        /// Calculates the Schur complement of M/C = S = A - B^T * inv(C) * B, where M = [A B; B^T C].
        /// This method constructs inv(C) * B one column at a time and uses that column to calculate the superdiagonal
        /// entries of the corresponding column of B^T * inv(C) * B.
        /// </summary>
        public static SymmetricMatrix CalcSchurComplementSymmetric(SymmetricMatrix A, CscMatrix B, ITriangulation inverseC)
        { //TODO: Unfortunately this cannot take advantage of MKL for CSC^T * vector.
            double[] valuesB     = B.RawValues;
            int[]    rowIndicesB = B.RawRowIndices;
            int[]    colOffsetsB = B.RawColOffsets;
            var      S           = SymmetricMatrix.CreateZero(A.Order);

            for (int j = 0; j < B.NumColumns; ++j)
            {
                // column j of (inv(C) * B) = inv(C) * column j of B
                Vector   colB     = B.GetColumn(j);
                double[] colInvCB = inverseC.SolveLinearSystem(colB).RawData;

                // column j of (B^T * inv(C) * B) = B^T * column j of (inv(C) * B)
                // However we only need the superdiagonal part of this column.
                // Thus we only multiply the rows i of B^T (stored as columns i of B) with i <= j.
                for (int i = 0; i <= j; ++i)
                {
                    double dot      = 0.0;
                    int    colStart = colOffsetsB[i];     //inclusive
                    int    colEnd   = colOffsetsB[i + 1]; //exclusive
                    for (int k = colStart; k < colEnd; ++k)
                    {
                        dot += valuesB[k] * colInvCB[rowIndicesB[k]];
                    }

                    // Perform the subtraction S = A - (B^T * inv(C) * B) for the current (i, j)
                    int indexS = S.Find1DIndex(i, j);
                    S.RawData[indexS] = A.RawData[indexS] - dot;
                }
            }

            return(S);
        }
예제 #2
0
        /// <summary>
        /// Solves the linear system A * x = b, where A is the original matrix (before the factorization),
        /// b = <paramref name="rhsVector"/> and x is the solution vector, which will be returned.
        /// </summary>
        /// <param name="rhsVector">
        /// The right hand side vector. Its <see cref="IIndexable1D.Length"/> must be equal to
        /// <see cref="Matrices.IIndexable2D.NumRows"/> of the original matrix A.
        /// </param>
        /// Thrown if the length of <paramref name="rhsVector"/> is different than <see cref="Matrices.IIndexable2D.NumRows"/>
        /// of the original matrix A.
        /// </exception>
        public static Vector SolveLinearSystem(this ITriangulation triangulation, Vector rhsVector)
        {
            var solution = Vector.CreateZero(triangulation.Order);

            triangulation.SolveLinearSystem(rhsVector, solution);
            return(solution);
        }