public int[] getFillPermutation()
 {
     return(applyReduce.getArrayP());
 }
Beispiel #2
0
        private bool performLU(DMatrixSparseCSC A)
        {
            int m = A.numRows;
            int n = A.numCols;

            int[] q = applyReduce.getArrayP();

            // main loop for computing L and U
            for (int k = 0; k < n; k++)
            {
                //--------- Triangular Solve
                L.col_idx[k] = L.nz_length; // start of column k
                U.col_idx[k] = U.nz_length;

                // grow storage in L and U if needed
                if (L.nz_length + n > L.nz_values.Length)
                {
                    L.growMaxLength(2 * L.nz_values.Length + n, true);
                }
                if (U.nz_length + n > U.nz_values.Length)
                {
                    U.growMaxLength(2 * U.nz_values.Length + n, true);
                }

                int   col = q != null ? q[k] : k;
                int   top = TriangularSolver_DSCC.solve(L, true, A, col, x, pinv, gxi, gw);
                int[] xi  = gxi.data;

                //--------- Find the Next Pivot. That will be the row with the largest value
                //
                int    ipiv = -1;
                double a    = -double.MaxValue;
                for (int p = top; p < n; p++)
                {
                    int i = xi[p]; // x(i) is nonzero
                    if (pinv[i] < 0)
                    {
                        double t;
                        if ((t = Math.Abs(x[i])) > a)
                        {
                            a    = t;
                            ipiv = i;
                        }
                    }
                    else
                    {
                        U.nz_rows[U.nz_length]     = pinv[i];
                        U.nz_values[U.nz_length++] = x[i];
                    }
                }
                if (ipiv == -1 || a <= 0)
                {
                    singular = true;
                    return(false);
                }

                // NOTE: The line is commented out below. It can cause a poor pivot to be selected. Instead of the largest
                //       row it will pick whatever is in this column. it does try to make sure it's not zero, but I'm not
                //       sure what it's purpose is.
//            if( pinv[col] < 0 && Math.Abs(x[col]) >= a*tol ) {
//                ipiv = col;
//            }

                //---------- Divide by the pivot
                double pivot = x[ipiv];
                U.nz_rows[U.nz_length]     = k;
                U.nz_values[U.nz_length++] = pivot; // last entry in U(:k) us U(k,k)
                pinv[ipiv]                 = k;
                L.nz_rows[L.nz_length]     = ipiv;  // First entry L(:,k) is L(k,k) = 1
                L.nz_values[L.nz_length++] = 1;

                for (int p = top; p < n; p++)
                {
                    int i = xi[p];
                    if (pinv[i] < 0)
                    {
                        // x(i) is entry in L(:,k)
                        L.nz_rows[L.nz_length]     = i;
                        L.nz_values[L.nz_length++] = x[i] / pivot;
                    }
                    x[i] = 0;
                }
            }
            //----------- Finalize L and U
            L.col_idx[n] = L.nz_length;
            U.col_idx[n] = U.nz_length;
            for (int p = 0; p < L.nz_length; p++)
            {
                L.nz_rows[p] = pinv[L.nz_rows[p]];
            }

//        Console.WriteLine("  reduce "+(reduceFill!=null));
//        System.out.print("  pinv[ ");
//        for (int i = 0; i < A.numCols; i++) {
//            System.out.printf("%2d ",pinv[i]);
//        }
//        Console.WriteLine(" ]");

            return(true);
        }