예제 #1
0
        /// <summary>
        /// Do symbolic factorization for current type.
        /// </summary>
        protected virtual int DoSymbolic()
        {
            int n    = matrix.ColumnCount;
            int nrhs = 1;

            int error = 0;
            var iparm = options.iparm;

            var h = new List <GCHandle>();

            try
            {
                var a  = InteropHelper.Pin(matrix.Values, h);
                var ia = InteropHelper.Pin(matrix.ColumnPointers, h);
                var ja = InteropHelper.Pin(matrix.RowIndices, h);

                // Reordering and Symbolic Factorization. This step also allocates
                // all memory that is necessary for the factorization.
                int phase = 11;

                NativeMethods.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase,
                                      ref n, a, ia, ja, perm, ref nrhs, iparm, ref msglvl,
                                      IntPtr.Zero, IntPtr.Zero, out error);
            }
            finally
            {
                InteropHelper.Free(h);
            }

            return(error);
        }
예제 #2
0
        /// <summary>
        /// Solves a system of linear equations, Ax = b.
        /// </summary>
        /// <param name="input">Right hand side vector b.</param>
        /// <param name="result">Solution vector x.</param>
        public void Solve(T[] input, T[] result)
        {
            if (!factorized)
            {
                Factorize();
            }

            var handles = new List <GCHandle>();

            try
            {
                var h_b = InteropHelper.Pin(input, handles);
                var h_x = InteropHelper.Pin(result, handles);

                int rows    = input.Length;
                int columns = result.Length;

                Cuda.CopyToDevice(d_b, h_b, sizeT * rows);

                // Solve A*x = b.
                Check(Solve(rows, columns));

                Cuda.CopyToHost(h_x, d_x, sizeT * columns);
            }
            finally
            {
                InteropHelper.Free(handles);
            }
        }
예제 #3
0
        protected void Dispose(bool disposing)
        {
            if (pt != null && pt.Any(p => p != IntPtr.Zero))
            {
                int n    = matrix.ColumnCount;
                int nrhs = 1;

                int error = 0;
                var iparm = options.iparm;

                var h = new List <GCHandle>();

                try
                {
                    var ia = InteropHelper.Pin(matrix.ColumnPointers, h);
                    var ja = InteropHelper.Pin(matrix.RowIndices, h);

                    // Release internal memory.
                    int phase = -1;

                    NativeMethods.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase,
                                          ref n, IntPtr.Zero, ia, ja, null, ref nrhs, iparm, ref msglvl,
                                          IntPtr.Zero, IntPtr.Zero, out error);
                }
                finally
                {
                    InteropHelper.Free(h);
                }

                pt = null;
            }
        }
예제 #4
0
        protected virtual int DoNumeric()
        {
            if (qr == IntPtr.Zero)
            {
                throw new Exception("A call to DoNumeric() must be preceeded by DoSymbolic().");
            }

            var h = new List <GCHandle>();

            try
            {
                var A = CreateSparse(matrix, h);

                double tol = Constants.SPQR_DEFAULT_TOL;

                int status = NativeMethods.SuiteSparseQR_C_numeric(tol, ref A, qr, ref common);

                if (common.status != Constants.CHOLMOD_OK)
                {
                    throw new CholmodException(common.status);
                }

                return(status);
            }
            finally
            {
                InteropHelper.Free(h);
            }
        }
예제 #5
0
        /// <summary>
        /// Solve multiple systems of linear equations.
        /// </summary>
        /// <param name="sys">The system to solve.</param>
        /// <param name="input">Right hand side B</param>
        /// <param name="result">Solution matrix X.</param>
        protected virtual int DoSolve(CholmodSolve sys, DenseColumnMajorStorage <T> input, DenseColumnMajorStorage <T> result)
        {
            var h = new List <GCHandle>();

            try
            {
                var B = CreateDense(input, h);

                var ptr = NativeMethods.cholmod_solve((int)sys, ref L, ref B, ref common);

                if (common.status != Constants.CHOLMOD_OK)
                {
                    throw new CholmodException(common.status);
                }

                var X = (CholmodDense)Marshal.PtrToStructure(ptr, typeof(CholmodDense));

                CopyDense(X, result);

                NativeMethods.cholmod_free_dense(ref ptr, ref common);

                return(1);
            }
            finally
            {
                InteropHelper.Free(h);
            }
        }
예제 #6
0
        /// <summary>
        /// Solve the standard eigenvalue problem in shift-invert mode.
        /// </summary>
        public override IEigenSolverResult SolveStandard(int k, Complex sigma, Spectrum job = Spectrum.LargestMagnitude)
        {
            if (!CheckSquare(A))
            {
                throw new InvalidOperationException("Cannot solve eigenvalue problem with non-square matrix.");
            }

            if (!Job.Validate(symmetric, job))
            {
                throw new ArgumentException("Invalid job for given eigenvalue problem.", "job");
            }

            var result = new ArpackResult(k, size, ComputeEigenVectors);

            var handles = new List <GCHandle>();

            var a = GetMatrix(A, handles);
            var e = result.GetEigenvalueStorage(handles);

            int conv = NativeMethods.ar_zi_ns_shift(GetJob(job), k, ArnoldiCount, Iterations,
                                                    Tolerance, sigma, ref a, ref e);

            result.IterationsTaken      = e.iterations;
            result.ArnoldiCount         = e.ncv;
            result.ConvergedEigenValues = conv;
            result.ErrorCode            = e.info;

            InteropHelper.Free(handles);

            return(result);
        }
예제 #7
0
        /// <summary>
        /// Do symbolic and numeric factorization for current type.
        /// </summary>
        protected virtual int DoFactorize()
        {
            int n    = matrix.ColumnCount;
            int nrhs = 1;

            int error = 0;
            var iparm = options.iparm;

            var h = new List <GCHandle>();

            try
            {
                var a  = InteropHelper.Pin(matrix.Values, h);
                var ia = InteropHelper.Pin(matrix.ColumnPointers, h);
                var ja = InteropHelper.Pin(matrix.RowIndices, h);

                // Analysis and numerical factorization.
                int phase = 12;

                NativeMethods.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase,
                                      ref n, a, ia, ja, perm, ref nrhs, iparm, ref msglvl,
                                      IntPtr.Zero, IntPtr.Zero, out error);
            }
            finally
            {
                InteropHelper.Free(h);
            }

            return(error);
        }
예제 #8
0
        /// <summary>
        /// Solve the generalized eigenvalue problem in user-defined shift-invert mode.
        /// </summary>
        public IEigenSolverResult SolveGeneralized(int k, double sigma, ShiftMode mode, Spectrum job = Spectrum.LargestMagnitude)
        {
            if (!symmetric && !(mode == ShiftMode.None || mode == ShiftMode.Regular))
            {
                throw new InvalidOperationException("This mode is only available for symmetric eigenvalue problems.");
            }

            if (!CheckSquare(A))
            {
                throw new InvalidOperationException("Cannot solve eigenvalue problem with non-square matrix.");
            }

            if (!Job.Validate(symmetric, job))
            {
                throw new ArgumentException("Invalid job for symmetric eigenvalue problem.", "job");
            }

            var result = new ArpackResult(k, size, ComputeEigenVectors, symmetric);

            var handles = new List <GCHandle>();

            var a = GetMatrix(A, handles);
            var b = GetMatrix(B, handles);
            var e = result.GetEigenvalueStorage(handles);

            int conv = 0;

            if (symmetric)
            {
                char m = 'S';

                if (mode == ShiftMode.Buckling)
                {
                    m = 'B';
                }
                else if (mode == ShiftMode.Cayley)
                {
                    m = 'C';
                }

                conv = NativeMethods.ar_di_sg_shift(GetJob(job), m, k, ArnoldiCount, Iterations,
                                                    Tolerance, sigma, ref a, ref b, ref e);
            }
            else
            {
                conv = NativeMethods.ar_di_ng_shift(GetJob(job), k, ArnoldiCount, Iterations,
                                                    Tolerance, sigma, ref a, ref b, ref e);
            }

            result.IterationsTaken      = e.iterations;
            result.ArnoldiCount         = e.ncv;
            result.ConvergedEigenValues = conv;
            result.ErrorCode            = e.info;

            InteropHelper.Free(handles);

            return(result);
        }
예제 #9
0
        private MetisStatus Partition(int nparts, int[] part, MetisOptions options, bool kway)
        {
            int objval = 0;

            if (part == null || part.Length < this.nvtxs)
            {
                return(MetisStatus.ERROR_INPUT);
            }

            var handles = new List <GCHandle>();

            // Pin array data.
            var p_part   = InteropHelper.Pin(part, handles);
            var p_xadj   = InteropHelper.Pin(xadj, handles);
            var p_adjncy = InteropHelper.Pin(adjncy, handles);
            var p_vwgt   = InteropHelper.Pin(vwgt, handles);
            var p_ewgt   = InteropHelper.Pin(adjwgt, handles);
            var p_vsize  = InteropHelper.Pin(vsize, handles);

            var p_opts = options == null ? IntPtr.Zero : InteropHelper.Pin(options.raw, handles);

            int l_nv = nvtxs;
            int l_nw = ncon;

            int status = 0;

            try
            {
                if (kway)
                {
                    status = NativeMethods.PartGraphKway(ref l_nv, ref l_nw, p_xadj, p_adjncy,
                                                         p_vwgt, p_vsize, p_ewgt, ref nparts, IntPtr.Zero, IntPtr.Zero,
                                                         p_opts, ref objval, p_part);
                }
                else
                {
                    status = NativeMethods.PartGraphRecursive(ref l_nv, ref l_nw, p_xadj, p_adjncy,
                                                              p_vwgt, p_vsize, p_ewgt, ref nparts, IntPtr.Zero, IntPtr.Zero,
                                                              p_opts, ref objval, p_part);
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                InteropHelper.Free(handles);
            }

            return((MetisStatus)status);
        }
예제 #10
0
        /// <inheritdoc />
        public override FeastResult <double> SolveGeneralized(int m0, double emin, double emax, DenseColumnMajorStorage <double> subspace)
        {
            // TODO: check subspace matrix dimensions.

            char uplo = 'F'; // Full matrix.
            int  n    = A.RowCount;

            double epsout; // Relative error on the trace.
            int    loop;   // Number of refinement loops.
            int    m = m0; // Total number of eigenvalues found in the interval.
            int    info;

            var E = new double[m0];  // Eigenvalues
            var R = new double[m0];  // Residual
            var X = subspace.Values; // Eigenvectors

            var fpm = this.Options.fpm;

            var h = new List <GCHandle>();

            try
            {
                Increment(A);
                Increment(B);

                var a  = InteropHelper.Pin(A.Values, h);
                var ia = InteropHelper.Pin(A.ColumnPointers, h);
                var ja = InteropHelper.Pin(A.RowIndices, h);

                var b  = InteropHelper.Pin(B.Values, h);
                var ib = InteropHelper.Pin(B.ColumnPointers, h);
                var jb = InteropHelper.Pin(B.RowIndices, h);

                var pe = InteropHelper.Pin(E, h);
                var px = InteropHelper.Pin(X, h);
                var pr = InteropHelper.Pin(R, h);

                NativeMethods.dfeast_scsrgv(ref uplo, ref n, a, ia, ja, b, ib, jb, fpm, out epsout, out loop, ref emin, ref emax, ref m0, pe, px, out m, pr, out info);

                Decrement(A);
                Decrement(B);

                return(new FeastResult(info, m0, n, loop, epsout, m, E, subspace, R));
            }
            finally
            {
                InteropHelper.Free(h);
            }
        }
예제 #11
0
        /// <summary>
        /// Special case solving the standard real generalized eigenvalue problem with complex shift.
        /// </summary>
        /// <param name="k">The number of eigenvalues to compute.</param>
        /// <param name="sigma_r">The real part of the complex shift.</param>
        /// <param name="sigma_i">The imaginary part of the complex shift.</param>
        /// <param name="part">Part to apply ('R' for real, 'I' for imaginary).</param>
        /// <param name="job">The part of the spectrum to compute.</param>
        /// <returns>The number of converged eigenvalues.</returns>
        public IEigenSolverResult SolveGeneralized(int k, double sigma_r, double sigma_i, char part, Spectrum job = Spectrum.LargestMagnitude)
        {
            if (symmetric)
            {
                throw new InvalidOperationException("Complex shift doesn't apply to real symmetric eigenvalue problems.");
            }

            if (!CheckSquare(A))
            {
                throw new InvalidOperationException("Cannot solve eigenvalue problem with non-square matrix.");
            }

            if (!Job.ValidateGeneral(job))
            {
                throw new ArgumentException("Invalid job for non-symmetric eigenvalue problem.", "job");
            }

            part = char.ToUpperInvariant(part);

            if (part != 'R' && part != 'I')
            {
                throw new ArgumentException("Invalid part specified for complex shift.", "part");
            }

            var result = new ArpackResult(k, size, ComputeEigenVectors, symmetric);

            var handles = new List <GCHandle>();

            var a = GetMatrix(A, handles);
            var b = GetMatrix(B, handles);
            var e = result.GetEigenvalueStorage(handles);

            int conv = 0;

            conv = NativeMethods.ar_di_ng_shift_cx(GetJob(job),
                                                   k, ArnoldiCount, Iterations, Tolerance,
                                                   part, sigma_r, sigma_i, ref a, ref b, ref e);


            result.IterationsTaken      = e.iterations;
            result.ArnoldiCount         = e.ncv;
            result.ConvergedEigenValues = conv;
            result.ErrorCode            = e.info;

            InteropHelper.Free(handles);

            return(result);
        }
예제 #12
0
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                InteropHelper.Free(handles);
            }

            if (Lp != IntPtr.Zero)
            {
                NativeMethods.cholmod_free_factor(ref Lp, ref common);

                NativeMethods.cholmod_finish(ref common);

                L = default(CholmodFactor);
            }
        }
예제 #13
0
        public override void Solve(double[] input, double[] result)
        {
            if (!factorized && DoFactorize() != 0)
            {
                throw new Exception(); // TODO: exception
            }

            var n = matrix.RowCount;

            var h = new List <GCHandle>();

            var b = InteropHelper.Pin(input, h);
            var x = InteropHelper.Pin(result, h);
            var t = InteropHelper.Pin(w, h);

            try
            {
                // x = b(p)
                if (NativeMethods.cs_di_ipvec(N.pinv, b, t, n) == 0)
                {
                    return;
                }

                // x = L\x
                if (NativeMethods.cs_di_lsolve(N.L, t) == 0)
                {
                    return;
                }

                // x = U\x
                if (NativeMethods.cs_di_usolve(N.U, t) == 0)
                {
                    return;
                }

                // b(q) = x
                if (NativeMethods.cs_di_pvec(S.q, t, x, n) == 0)
                {
                    return;
                }
            }
            finally
            {
                InteropHelper.Free(h);
            }
        }
예제 #14
0
        /// <summary>
        /// Compute singular values and the partial singular value decomposition.
        /// </summary>
        /// <param name="k">The number of singular values to compute.</param>
        /// <param name="normal">Use normal equation to compute (squared) singular values.</param>
        /// <param name="job">The part of the spectrum to compute.</param>
        /// <returns>The number of converged singular values.</returns>
        /// <remarks>
        /// If <paramref name="normal"/> is true, the normal equation <c>(A'*A)*v = sigma*v</c>
        /// is considered, where A is an m-by-n real matrix. This formulation is appropriate
        /// when m >= n. The roles of A and A' must be reversed in the case that m &lt; n.
        ///
        /// The eigenvalues returned are the squared singular values of A. If requested, the
        /// returned eigenvectors correspond to the right singular vectors, if <c>A = U*S*V'</c>.
        /// The left singular vectors can be computed from the equation <c>A*v - sigma*u = 0</c>.
        ///
        /// If <paramref name="normal"/> is false, the symmetric system <c>[0  A; A' 0]</c> is
        /// considered (size m + n), where A is an m-by-n real matrix.
        ///
        /// This problem can be used to obtain the decomposition <c>A = U*S*V'</c>. The positive
        /// eigenvalues of this problem are the singular values of A (the eigenvalues come in
        /// pairs, the negative eigenvalues have the same magnitude of the positive ones and
        /// can be discarded). The columns of U can be extracted from the first m components
        /// of the eigenvectors y, while the columns of V can be extracted from the remaining
        /// n components.
        /// </remarks>
        public IEigenSolverResult SingularValues(int k, bool normal, Spectrum job = Spectrum.LargestMagnitude)
        {
            if (!Job.ValidateSymmetric(job))
            {
                throw new ArgumentException("Invalid job for singular value decomposition.", "job");
            }

            int m = A.RowCount;
            int n = A.ColumnCount;

            if (normal && m < n)
            {
                throw new InvalidOperationException("Number of columns must not be smaller than number of rows (use transposed matrix).");
            }

            int size = normal ? n : m + n;

            var result = new ArpackResult(k, size, ComputeEigenVectors, true);

            var handles = new List <GCHandle>();

            var a = GetMatrix(A, handles);
            var e = result.GetEigenvalueStorage(handles);

            int conv = 0;

            if (normal)
            {
                conv = NativeMethods.ar_di_svd_nrm(GetJob(job),
                                                   k, ArnoldiCount, Iterations, Tolerance, ref a, ref e);
            }
            else
            {
                conv = NativeMethods.ar_di_svd(GetJob(job),
                                               k, ArnoldiCount, Iterations, Tolerance, ref a, ref e);
            }

            result.IterationsTaken      = e.iterations;
            result.ArnoldiCount         = e.ncv;
            result.ConvergedEigenValues = conv;
            result.ErrorCode            = e.info;

            InteropHelper.Free(handles);

            return(result);
        }
예제 #15
0
        public override void Solve(Complex[] input, Complex[] result)
        {
            if (!factorized && DoFactorize() != 0)
            {
                throw new Exception(); // TODO: exception
            }

            var n = matrix.RowCount;

            var h = new List <GCHandle>();

            var b = InteropHelper.Pin(input, h);
            var x = InteropHelper.Pin(result, h);
            var t = InteropHelper.Pin(w, h);

            try
            {
                // x = P*b
                if (NativeMethods.cs_ci_ipvec(S.pinv, b, t, n) == 0)
                {
                    return;
                }

                // x = L\x
                if (NativeMethods.cs_ci_lsolve(N.L, t) == 0)
                {
                    return;
                }

                // x = L'\x
                if (NativeMethods.cs_ci_ltsolve(N.L, t) == 0)
                {
                    return;
                }

                // b = P'*x
                if (NativeMethods.cs_ci_pvec(S.pinv, t, x, n) == 0)
                {
                    return;
                }
            }
            finally
            {
                InteropHelper.Free(h);
            }
        }
예제 #16
0
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                InteropHelper.Free(handles);
            }

            if (L.Store != IntPtr.Zero)
            {
                NativeMethods.Destroy_SuperNode_Matrix(ref L);
                L.Store = IntPtr.Zero;
            }

            if (U.Store != IntPtr.Zero)
            {
                NativeMethods.Destroy_CompCol_Matrix(ref U);
                U.Store = IntPtr.Zero;
            }
        }
예제 #17
0
        protected virtual int DoSolve(int sys, int method, DenseColumnMajorStorage <T> input, DenseColumnMajorStorage <T> result)
        {
            if (!factorized)
            {
                DoFactorize();
            }

            var h = new List <GCHandle>();

            try
            {
                var B = CreateDense(input, h);

                // Y = Q'*B
                var Yp = NativeMethods.SuiteSparseQR_C_qmult(method, qr, ref B, ref common);

                if (Yp == IntPtr.Zero)
                {
                    return(-1000);
                }

                // X = R\(E*Y)
                var Xp = NativeMethods.SuiteSparseQR_C_solve(sys, qr, Yp, ref common);

                if (Xp == IntPtr.Zero)
                {
                    return(-1000);
                }

                var X = (CholmodDense)Marshal.PtrToStructure(Xp, typeof(CholmodDense));

                CopyDense(X, result);

                Cholmod.NativeMethods.cholmod_free_dense(ref Yp, ref common);
                Cholmod.NativeMethods.cholmod_free_dense(ref Xp, ref common);

                return(1);
            }
            finally
            {
                InteropHelper.Free(h);
            }
        }
예제 #18
0
        /// <summary>
        /// Solve system of linear equations.
        /// </summary>
        /// <param name="sys">The system to solve.</param>
        /// <param name="input">Right-hand side b.</param>
        /// <param name="result">The solution x.</param>
        /// <returns></returns>
        /// <remarks>
        /// Parameter sys corresponds to iparm[11]:
        ///    sys = 0: non-transposed
        ///    sys = 1: conjugate transposed
        ///    sys = 2: transposed
        /// </remarks>
        protected virtual int DoSolve(int sys, DenseColumnMajorStorage <T> input, DenseColumnMajorStorage <T> result)
        {
            int n = matrix.ColumnCount;

            // The number of right-hand sides.
            int nrhs = input.ColumnCount;

            if (nrhs != result.ColumnCount)
            {
                throw new ArgumentException("result");
            }

            int error = 0;
            var iparm = options.iparm;

            var h = new List <GCHandle>();

            try
            {
                var a  = InteropHelper.Pin(matrix.Values, h);
                var ia = InteropHelper.Pin(matrix.ColumnPointers, h);
                var ja = InteropHelper.Pin(matrix.RowIndices, h);

                var b = InteropHelper.Pin(input.Values, h);
                var x = InteropHelper.Pin(result.Values, h);

                iparm[11] = sys;

                // Solve system.
                int phase = 33;

                NativeMethods.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase,
                                      ref n, a, ia, ja, perm, ref nrhs, iparm, ref msglvl,
                                      b, x, out error);
            }
            finally
            {
                InteropHelper.Free(h);
            }

            return(error);
        }
예제 #19
0
        /// <summary>
        /// Solve the generalized eigenvalue problem.
        /// </summary>
        public override IEigenSolverResult SolveGeneralized(int k, Spectrum job = Spectrum.LargestMagnitude)
        {
            if (!Job.Validate(symmetric, job))
            {
                throw new ArgumentException("Invalid job for given eigenvalue problem.", "job");
            }

            if (ArnoldiCount < k)
            {
                ArnoldiCount = Math.Min(3 * k, A.RowCount);
            }

            var result = new SpectraResult(k, size, ComputeEigenVectors, symmetric);

            var handles = new List <GCHandle>();

            var a = GetMatrix(A, handles);
            var b = GetMatrix(B, handles);
            var e = result.GetEigenvalueStorage(handles);

            int conv = 0;

            if (symmetric)
            {
                conv = NativeMethods.spectra_di_sg(GetJob(job), k, ArnoldiCount,
                                                   Iterations, Tolerance, ref a, ref b, ref e);
            }
            else
            {
                throw new NotImplementedException();
                //conv = NativeMethods.spectra_di_ng(GetJob(job), k, ArnoldiCount,
                //    Iterations, Tolerance, ref a, ref b, ref e);
            }

            result.IterationsTaken      = e.iterations;
            result.ConvergedEigenValues = conv;
            result.ErrorCode            = e.info;

            InteropHelper.Free(handles);

            return(result);
        }
예제 #20
0
        /// <inheritdoc />
        public override ExtendedEigensolverResult <double> SolveStandard(int k0, Job job, DenseColumnMajorStorage <double> eigenvectors)
        {
            // TODO: check eigenvectors matrix dimensions.

            string which = job == Job.Smallest ? "S" : "L";

            int n = A.RowCount;

            int k = 0;                   // Total number of eigenvalues found in the interval.

            var E = new double[k0];      // Eigenvalues
            var R = new double[k0];      // Residual
            var X = eigenvectors.Values; // Eigenvectors

            var h = new List <GCHandle>();

            try
            {
                var pe = InteropHelper.Pin(E, h);
                var px = InteropHelper.Pin(X, h);
                var pr = InteropHelper.Pin(R, h);

                var h_A  = CreateMatrixHandle(A, h);
                var desc = CreateMatrixDecriptor();

                var info = NativeMethods.mkl_sparse_d_ev(new StringBuilder(which), pm, h_A, desc, k0, ref k, pe, px, pr);

                //if (info != sparse_status.SUCCESS)
                //{
                //    throw new Exception(info.ToString());
                //}

                return(new ExtendedEigensolverResult(info, n, k, E, eigenvectors, R));
            }
            finally
            {
                InteropHelper.Free(h);
            }
        }
예제 #21
0
        /// <summary>
        /// Computes fill reducing orderings of sparse matrices using the multilevel nested dissection algorithm.
        /// </summary>
        /// <param name="perm">Target array storing the fill-reducing permutaion (size nvtxs).</param>
        /// <param name="iperm">Target array storing the fill-reducing inverse permutaion (size nvtxs).</param>
        /// <param name="options">Partitioning options.</param>
        /// <returns></returns>
        public MetisStatus NestedDissection(int[] perm, int[] iperm, MetisOptions options = null)
        {
            if (perm.Length != nvtxs || iperm.Length != nvtxs)
            {
                return(MetisStatus.ERROR_INPUT);
            }

            var handles = new List <GCHandle>();

            // Pin array data.
            var p_xadj   = InteropHelper.Pin(xadj, handles);
            var p_adjncy = InteropHelper.Pin(adjncy, handles);
            var p_vwgt   = InteropHelper.Pin(vwgt, handles);

            var p_opts = options == null ? IntPtr.Zero : InteropHelper.Pin(options.raw, handles);

            var p_perm  = InteropHelper.Pin(perm, handles);
            var p_iperm = InteropHelper.Pin(iperm, handles);

            int l_nv = nvtxs;

            int status = 0;

            try
            {
                status = NativeMethods.NodeND(ref l_nv, p_xadj, p_adjncy, p_vwgt, p_opts, p_perm, p_iperm);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                InteropHelper.Free(handles);
            }

            return((MetisStatus)status);
        }
예제 #22
0
        protected override int DoFactorize()
        {
            int info = 0;

            var mem_usage = new mem_usage();
            var stat      = new SuperLUStat();

            int m = A.nrow;
            int n = A.ncol;

            var h = new List <GCHandle>();

            // Create matrix with ncol = 0 to indicate not to solve the system.
            var B = CreateEmptyDense(Dtype.SLU_D, m, h);
            var X = CreateEmptyDense(Dtype.SLU_D, n, h);

            try
            {
                var o = options.Raw;

                NativeMethods.StatInit(ref stat);

                NativeMethods.dgssvx(ref o, ref A, perm_c, perm_r, etree, equed,
                                     (double[])R, (double[])C, ref L, ref U,
                                     IntPtr.Zero, 0, ref B, ref X, out rpg, out rcond, null, null,
                                     ref glu, ref mem_usage, ref stat, out info);

                NativeMethods.StatFree(ref stat);

                options.Raw.Fact = Constants.FACTORED;
            }
            finally
            {
                InteropHelper.Free(h);
            }

            return(info);
        }
예제 #23
0
        protected virtual void DoFactorize()
        {
            var h = new List <GCHandle>();

            try
            {
                var A = CreateSparse(matrix, h);

                int    ordering = (int)SpqrOrdering.Default;
                double tol      = Constants.SPQR_DEFAULT_TOL;

                qr = NativeMethods.SuiteSparseQR_C_factorize(ordering, tol, ref A, ref common);

                if (common.status != Constants.CHOLMOD_OK)
                {
                    throw new CholmodException(common.status);
                }
            }
            finally
            {
                InteropHelper.Free(h);
            }
        }
예제 #24
0
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                InteropHelper.Free(handles);
            }

            // NOTE: cs_di_*free and cs_ci_*free both do the same, so there's
            //       no need to move this method to the derived classes.

            if (N.L != IntPtr.Zero)
            {
                cs_nfree(ref N);
                N.L = IntPtr.Zero;
            }

            if (S.pinv != IntPtr.Zero || S.q != IntPtr.Zero)
            {
                cs_sfree(ref S);
                S.pinv = IntPtr.Zero;
                S.q = IntPtr.Zero;
            }
        }
예제 #25
0
        protected virtual void DoSymbolic()
        {
            var h = new List <GCHandle>();

            try
            {
                var A = CreateSparse(matrix, h);

                int ordering  = (int)SpqrOrdering.Default;
                int allow_tol = 1;

                qr = NativeMethods.SuiteSparseQR_C_symbolic(ordering, allow_tol, ref A, ref common);

                if (common.status != Constants.CHOLMOD_OK)
                {
                    throw new CholmodException(common.status);
                }
            }
            finally
            {
                InteropHelper.Free(h);
            }
        }
예제 #26
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CuSparseContext{T}"/> class.
        /// </summary>
        /// <param name="stream">The <see cref="CudaStream"/>.</param>
        /// <param name="A">The sparse matrix.</param>
        /// <param name="type">The matrix type.</param>
        /// <param name="transpose">A value indicating, whether the storage should be transposed.</param>
        public CuSparseContext(CudaStream stream, CompressedColumnStorage <T> A, MatrixType type, bool transpose)
        {
            Check(NativeMethods.cusparseCreate(ref _p));
            Check(NativeMethods.cusparseSetStream(_p, stream.Pointer));
            Check(NativeMethods.cusparseCreateMatDescr(ref _matDescr));
            Check(NativeMethods.cusparseSetMatType(_matDescr, type));
            Check(NativeMethods.cusparseSetMatIndexBase(_matDescr, IndexBase.Zero));

            var sizeT = Marshal.SizeOf(typeof(T));

            int rows = A.RowCount;
            int nnz  = A.NonZerosCount;

            Cuda.Malloc(ref d_ap, sizeof(int) * (rows + 1));
            Cuda.Malloc(ref d_ai, sizeof(int) * nnz);
            Cuda.Malloc(ref d_ax, sizeT * nnz);

            var handles = new List <GCHandle>();

            try
            {
                // Convert storage to CSR format.
                var C = transpose ? A.Transpose(true) : A;

                var h_ap = InteropHelper.Pin(C.ColumnPointers, handles);
                var h_ai = InteropHelper.Pin(C.RowIndices, handles);
                var h_ax = InteropHelper.Pin(C.Values, handles);

                Cuda.CopyToDevice(d_ap, h_ap, sizeof(int) * (rows + 1));
                Cuda.CopyToDevice(d_ai, h_ai, sizeof(int) * nnz);
                Cuda.CopyToDevice(d_ax, h_ax, sizeT * nnz);
            }
            finally
            {
                InteropHelper.Free(handles);
            }
        }
예제 #27
0
        protected override int DoSolve(DenseColumnMajorStorage <double> input, DenseColumnMajorStorage <double> result)
        {
            int info = 0;

            var mem_usage = new mem_usage();
            var stat      = new SuperLUStat();

            int nrhs = input.ColumnCount;

            var ferr = new double[nrhs];
            var berr = new double[nrhs];

            var h = new List <GCHandle>();

            var B = CreateDense(Dtype.SLU_D, input, h);
            var X = CreateDense(Dtype.SLU_D, result, h);

            try
            {
                var o = options.Raw;

                NativeMethods.StatInit(ref stat);

                NativeMethods.dgssvx(ref o, ref A, perm_c, perm_r, etree, equed,
                                     (double[])R, (double[])C, ref L, ref U,
                                     IntPtr.Zero, 0, ref B, ref X, out rpg, out rcond, ferr, berr,
                                     ref glu, ref mem_usage, ref stat, out info);

                NativeMethods.StatFree(ref stat);
            }
            finally
            {
                InteropHelper.Free(h);
            }

            return(info);
        }
예제 #28
0
        protected override int DoFactorize()
        {
            var h = new List <GCHandle>();
            var A = CreateSparse(matrix, h);

            try
            {
                int order = (int)ordering;

                // ordering and symbolic analysis
                var pS = NativeMethods.cs_di_sqr(order, ref A, 0);

                if (pS == IntPtr.Zero)
                {
                    return(-1);
                }

                S = Marshal.PtrToStructure <css>(pS);

                // numeric LU factorization
                var pN = NativeMethods.cs_di_lu(ref A, ref S, tol);

                if (pN == IntPtr.Zero)
                {
                    return(-1);
                }

                N = Marshal.PtrToStructure <csn>(pN);
            }
            finally
            {
                InteropHelper.Free(h);
            }

            return(0);
        }
예제 #29
0
        protected override int DoFactorize()
        {
            var h = new List <GCHandle>();
            var A = CreateSparse(matrix, h);

            int m = matrix.RowCount;
            int n = matrix.ColumnCount;

            try
            {
                int order = (int)ordering;

                if (m >= n)
                {
                    // ordering and symbolic analysis
                    var pS = NativeMethods.cs_di_sqr(order, ref A, 1);

                    if (pS == IntPtr.Zero)
                    {
                        return(-1);
                    }

                    S = Marshal.PtrToStructure <css>(pS);

                    // numeric QR factorization
                    var pN = NativeMethods.cs_di_qr(ref A, ref S);

                    if (pN == IntPtr.Zero)
                    {
                        return(-1);
                    }

                    N = Marshal.PtrToStructure <csn>(pN);

                    beta = new double[n];

                    // Copy beta values for later access.
                    Marshal.Copy(N.B, beta, 0, n);
                }
                else
                {
                    // Ax=b is underdetermined
                    var pAT = NativeMethods.cs_di_transpose(ref A, 1);

                    AT = Marshal.PtrToStructure <cs>(pAT);

                    // ordering and symbolic analysis
                    var pS = NativeMethods.cs_di_sqr(order, ref AT, 1);

                    if (pS == IntPtr.Zero)
                    {
                        return(-1);
                    }

                    S = Marshal.PtrToStructure <css>(pS);

                    // numeric QR factorization of A'
                    var pN = NativeMethods.cs_di_qr(ref AT, ref S);

                    if (pN == IntPtr.Zero)
                    {
                        return(-1);
                    }

                    N = Marshal.PtrToStructure <csn>(pN);

                    beta = new double[m];

                    // Copy beta values for later access.
                    Marshal.Copy(N.B, beta, 0, m);
                }

                if (w.Length < S.m2)
                {
                    // Fix workspace length, if neccessary.
                    w = new double[S.m2];
                }
            }
            finally
            {
                InteropHelper.Free(h);
            }

            return(0);
        }
예제 #30
0
        public override void Solve(double[] input, double[] result)
        {
            if (!factorized && DoFactorize() != 0)
            {
                throw new Exception(); // TODO: exception
            }

            var m = matrix.RowCount;
            var n = matrix.ColumnCount;

            var h = new List <GCHandle>();

            var b = InteropHelper.Pin(input, h);
            var x = InteropHelper.Pin(result, h);
            var t = InteropHelper.Pin(w, h);

            try
            {
                // x = b(p)
                if (NativeMethods.cs_di_ipvec(N.pinv, b, t, n) == 0)
                {
                    return;
                }

                // x = L\x
                if (NativeMethods.cs_di_lsolve(N.L, t) == 0)
                {
                    return;
                }

                // x = U\x
                if (NativeMethods.cs_di_ltsolve(N.U, t) == 0)
                {
                    return;
                }

                // b(q) = x
                if (NativeMethods.cs_di_pvec(S.q, t, x, n) == 0)
                {
                    return;
                }
            }
            finally
            {
                InteropHelper.Free(h);
            }


            if (m >= n)
            {
                // x(0:m-1) = b(p(0:m-1)
                NativeMethods.cs_di_ipvec(S.pinv, b, x, m);

                // apply Householder refl. to x
                for (int k = 0; k < n; k++)
                {
                    NativeMethods.cs_di_happly(N.L, k, beta[k], x);
                }
                // x = R\x
                NativeMethods.cs_di_usolve(N.U, x);

                // b(q(0:n-1)) = x(0:n-1)
                NativeMethods.cs_di_ipvec(S.q, x, b, n);
            }
            else
            {
                // x(q(0:m-1)) = b(0:m-1)
                NativeMethods.cs_di_pvec(S.q, b, x, m);

                // x = R'\x
                NativeMethods.cs_di_utsolve(N.U, x);

                // apply Householder refl. to x
                for (int k = m - 1; k >= 0; k--)
                {
                    NativeMethods.cs_di_happly(N.L, k, beta[k], x);
                }

                // b(0:n-1) = x(p(0:n-1))
                NativeMethods.cs_di_pvec(S.pinv, x, b, n);
            }
        }