Beispiel #1
0
 /// <summary>
 /// Solves the system of equations analytically.
 /// </summary>
 /// <param name="b">The b.</param>
 /// <param name="IsASymmetric">if set to <c>true</c> [a is symmetric].</param>
 /// <param name="potentialDiagonals">The potential diagonals.</param>
 /// <returns>System.Double[].</returns>
 public IList <double> SolveAnalytically(IList <double> b, bool IsASymmetric = false)
 {
     if (IsASymmetric)
     {
         if (ValuesChanged || TopologyChanged)
         {
             MatrixInCCS = convertToCCS(this);
         }
         if (TopologyChanged)
         {
             symbolicFactorizationMat = CSparse.SymbolicAnalysisLDL(MatrixInCCS);
         }
         if (ValuesChanged || TopologyChanged)
         {
             CSparse.FactorizeLDL(MatrixInCCS, symbolicFactorizationMat, out D, out FactorizationMatrix);
         }
         TopologyChanged = ValuesChanged = false;
         return(CSparse.SolveLDL(b, FactorizationMatrix, D, symbolicFactorizationMat.InversePermute));
     }
     else
     {
         var ccs = convertToCCS(this);
         var columnPermutation = ApproximateMinimumDegree.Generate(
             new SymbolicColumnStorage(ccs), NumCols);
         CompressedColumnStorage L, U;
         int[] pinv;
         // Numeric LU factorization
         CSparse.FactorizeLU(ccs, columnPermutation, out L, out U, out pinv);
         var x = CSparse.ApplyInverse(pinv, b, NumCols);              // x = b(p)
         CSparse.SolveLower(L, x);                                    // x = L\x.
         CSparse.SolveUpper(U, x);                                    // x = U\x.
         return(CSparse.ApplyInverse(columnPermutation, x, NumCols)); // b(q) = x
     }
 }
Beispiel #2
0
        /// <summary>
        /// Compute the numeric LDL' factorization of PAP'.
        /// </summary>
        /// <param name="A">The matrix, A.</param>
        /// <param name="S">The symobolic factorization.</param>
        /// <param name="D">The diagonals of LDL.</param>
        /// <param name="L">The lower triangular matrix.</param>
        /// <exception cref="System.Exception">Diagonal element is zero.</exception>
        /// <exception cref="Exception">Diagonal element is zero.</exception>
        internal static void FactorizeLDL(CompressedColumnStorage A, SymbolicFactorization S, out double[] D,
                                          out CompressedColumnStorage L)
        {
            var n = A.ncols;

            var aColPointers = A.ColumnPointers;
            var aRowIndices  = A.RowIndices;
            var aValues      = A.Values;

            var parent = S.ParentIndices;
            var P      = S.PermutationVector;
            var Pinv   = S.InversePermute;

            D = new double[n];
            L = new CompressedColumnStorage(n, n, S.ColumnPointers[n]);

            Array.Copy(S.ColumnPointers, L.ColumnPointers, n + 1);

            var lColPointers = L.ColumnPointers;
            var lRowIndices  = L.RowIndices;
            var lValues      = L.Values;

            // Workspace
            var y       = new double[n];
            var pattern = new int[n];
            var flag    = new int[n];
            var lnz     = new int[n];

            for (var k = 0; k < n; k++)
            {
                // compute nonzero Pattern of kth row of L, in topological order
                y[k] = 0.0;  // Y(0:k) is now all zero
                var top = n;
                flag[k] = k; // mark node k as visited
                lnz[k]  = 0; // count of nonzeros in column k of L
                var kk = P != null ? P[k] : k;
                var p2 = aColPointers[kk + 1];

                for (var p = aColPointers[kk]; p < p2; p++)
                {
                    var i = Pinv != null ? Pinv[aRowIndices[p]] : aRowIndices[p]; // get A(i,k)
                    if (i <= k)
                    {
                        y[i] += aValues[p]; // scatter A(i,k) into Y (sum duplicates)
                        int len;
                        for (len = 0; flag[i] != k; i = parent[i])
                        {
                            pattern[len++] = i; // L(k,i) is nonzero
                            flag[i]        = k; // mark i as visited
                        }
                        while (len > 0)
                        {
                            pattern[--top] = pattern[--len];
                        }
                    }
                }
                // compute numerical values kth row of L (a sparse triangular solve)
                D[k] = y[k]; // get D(k,k) and clear Y(k)
                y[k] = 0.0;
                for (; top < n; top++)
                {
                    var i  = pattern[top]; // Pattern [top:n-1] is pattern of L(:,k)
                    var yi = y[i];
                    y[i] = 0.0;
                    p2   = lColPointers[i] + lnz[i];
                    int p;
                    for (p = lColPointers[i]; p < p2; p++)
                    {
                        y[lRowIndices[p]] -= lValues[p] * yi;
                    }
                    var l_ki = yi / D[i];
                    D[k]          -= l_ki * yi;
                    lRowIndices[p] = k; // store L(k,i) in column form of L
                    lValues[p]     = l_ki;
                    lnz[i]++;           // increment count of nonzeros in col i
                }
                if (D[k] == 0.0)        // failure, D(k,k) is zero
                {
                    throw new Exception("Diagonal element is zero.");
                }
            }
        }