Skip to content

Factorization members

wo80 edited this page Jun 18, 2020 · 2 revisions

The actual members of the factorizations available in CSparse.NET are private. If you need to access those member, for example the L and U factors of SparseLU, you can do this using reflection. The following code defines some extension mehtods for the CSparse.Double.Factorization namespace. The same could be done for the complex valued factorizations.

namespace CSparse.Double.Factorization
{
    using CSparse.Double;
    using CSparse.Factorization;
    using System;
    using System.Linq;
    using System.Reflection;

    public static class ExtensionMethods
    {
        const BindingFlags PRIVATE = BindingFlags.Instance | BindingFlags.NonPublic;

        /// <summary>
        /// Gets the internal Cholesky factorization data.
        /// </summary>
        /// <param name="chol">The sparse Cholesky factorization.</param>
        /// <param name="L">The L matrix.</param>
        /// <param name="pinv">Column and row permutation.</param>
        public static void GetFactors(this SparseCholesky chol, out SparseMatrix L, out int[] pinv)
        {
            var type = chol.GetType();

            L = (SparseMatrix)type.GetField("L", PRIVATE).GetValue(chol);

            var S = (SymbolicFactorization)type.GetField("S", PRIVATE).GetValue(chol);

            pinv = S.pinv;

            // Fix array size.

            if (pinv.Length != L.ColumnCount)
            {
                pinv = pinv.Take(L.ColumnCount).ToArray();
            }
        }

        /// <summary>
        /// Gets the internal LU factorization data.
        /// </summary>
        /// <param name="lu">The sparse LU factorization.</param>
        /// <param name="L">The L matrix.</param>
        /// <param name="U">The U matrix.</param>
        /// <param name="q">Fill-reducing column permutation.</param>
        /// <param name="pinv">Inverse row permutation (partial pivoting).</param>
        public static void GetFactors(this SparseLU lu, out SparseMatrix L, out SparseMatrix U,
            out int[] q, out int[] pinv)
        {
            var type = lu.GetType();

            L = (SparseMatrix)type.GetField("L", PRIVATE).GetValue(lu);
            U = (SparseMatrix)type.GetField("U", PRIVATE).GetValue(lu);
            pinv = (int[])type.GetField("pinv", PRIVATE).GetValue(lu);

            var S = (SymbolicFactorization)type.GetField("S", PRIVATE).GetValue(lu);

            q = S.q;

            // Fix array size.

            if (q.Length != L.ColumnCount)
            {
                q = q.Take(L.ColumnCount).ToArray();
            }
        }

        /// <summary>
        /// Gets the internal QR factorization data.
        /// </summary>
        /// <param name="qr">The sparse QR factorization.</param>
        /// <param name="H">The matrix containing the Householder vectors.</param>
        /// <param name="R">The R matrix.</param>
        /// <param name="beta">Scaling factors for Householder vectors.</param>
        /// <param name="q">Fill-reducing column permutation.</param>
        /// <param name="pinv">Inverse row permutation.</param>
        public static void GetFactors(this SparseQR qr, out SparseMatrix H, out SparseMatrix R,
            out double[] beta, out int[] q, out int[] pinv)
        {
            var type = qr.GetType();

            R = (SparseMatrix)type.GetField("R", PRIVATE).GetValue(qr);
            H = (SparseMatrix)type.GetField("Q", PRIVATE).GetValue(qr);
            beta = (double[])type.GetField("beta", PRIVATE).GetValue(qr);

            var S = (SymbolicFactorization)type.GetField("S", PRIVATE).GetValue(qr);

            q = S.q;
            pinv = S.pinv;

            // Fix array sizes.

            if (q.Length != H.ColumnCount)
            {
                q = q.Take(H.ColumnCount).ToArray();
            }

            if (pinv.Length != H.RowCount)
            {
                pinv = pinv.Take(H.RowCount).ToArray();
            }
        }
    }
}