Exemplo n.º 1
0
        private static void TestReordering()
        {
            Skip.IfNot(TestSettings.TestSuiteSparse, TestSettings.MessageWhenSkippingSuiteSparse);

            int order = SparseSymm5by5.Order;

            int[]  rowIndices  = SparseSymm5by5.CscRowIndices;
            int[]  colOffsets  = SparseSymm5by5.CscColOffsets;
            int[]  permutation = new int[order];
            IntPtr common      = SuiteSparsePInvokes.CreateCommon(0, 0);
            int    status      = SuiteSparsePInvokes.ReorderAMDUpper(order, rowIndices.Length, rowIndices, colOffsets, permutation,
                                                                     out int factorNNZ, common);

            Assert.True(status == 1, "SuiteSparse reordering failed. A possible reason is the lack of enough available memory");
            comparer.AssertEqual(SparseSymm5by5.MatlabPermutationAMD, permutation);

            SuiteSparsePInvokes.DestroyCommon(ref common);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Find a fill reducing permutation for the sparsity pattern of a symmetric matrix defined by the parameters.
        /// The returned permutation is new-to-old, namely reordered[i] = original[permutation[i]].
        /// </summary>
        /// <param name="order">The number of rows/columns of the symmetric matrix.</param>
        /// <param name="nonZerosUpper">The number of (structural) non-zero entries in the upper triangle of the symmetric
        ///     matrix.</param>
        /// <param name="cscRowIndices">Row indices of the upper triangle entries of the symmetric matrix, in Compressed Sparse
        ///     Columns format. All row indices of the same column must be sorted.</param>
        /// <param name="cscColOffsets">Column offsets of the upper triangle entries of the symmetric matrix, in Compressed
        ///     Sparse Columns format. All column offsets must be sorted.</param>
        /// <returns>permutation: An array containing the new-to-old fill reducing permutation.
        ///     stats: Measuments taken by SuiteSparse during the execution of AMD.</returns>
        /// <exception cref="SuiteSparseException">Thrown if SuiteSparse dlls cannot be loaded or if AMD fails.</exception>
        public (int[] permutation, ReorderingStatistics stats) FindPermutation(int order, int nonZerosUpper, int[] cscRowIndices,
                                                                               int[] cscColOffsets)
        {
            var    permutation = new int[order];
            IntPtr common      = SuiteSparsePInvokes.CreateCommon(0, 0);

            if (common == IntPtr.Zero)
            {
                throw new SuiteSparseException("Failed to initialize SuiteSparse.");
            }
            int status = SuiteSparsePInvokes.ReorderAMDUpper(order, nonZerosUpper, cscRowIndices, cscColOffsets, permutation,
                                                             out int nnzFactor, common);

            if (status == 0)
            {
                throw new SuiteSparseException("AMD failed. This could be caused by the matrix being so large it"
                                               + " cannot be processed with the available memory.");
            }
            SuiteSparsePInvokes.DestroyCommon(ref common);
            return(permutation, new ReorderingStatistics(nnzFactor, -1));
        }
        /// <summary>
        /// Find a fill reducing permutation for the sparsity pattern of a symmetric matrix defined by the parameters.
        /// The returned permutation is new-to-old, namely reordered[i] = original[permutation[i]].
        /// </summary>
        /// <param name="order">The number of rows/columns of the symmetric matrix.</param>
        /// <param name="cscRowIndices">Row indices of the upper triangle entries of the symmetric matrix, in Compressed Sparse
        ///     Columns format. All row indices of the same column must be sorted.</param>
        /// <param name="cscColOffsets">Column offsets of the upper triangle entries of the symmetric matrix, in Compressed
        ///     Sparse Columns format. All column offsets must be sorted.</param>
        /// <param name="constraints">Array of length = order with ordering constraints. Its values must be
        ///     0 &lt;= <paramref name="constraints"/>[i] &lt; order. If <paramref name="constraints"/> = NULL, no constraints
        ///     will be enforced.
        ///		Example: <paramref name="constraints"/> = { 2, 0, 0, 0, 1 }. This means that indices 1, 2, 3 that have
        ///		<paramref name="constraints"/>[i] = 0, will be ordered before index 4 with <paramref name="constraints"/>[4] = 1,
        ///		which will be ordered before index 0 with <paramref name="constraints"/>[0] = 2. Indeed for a certain pattern,
        ///		permutation = { 3, 2, 1, 4, 0 } (remember permutation is a new-to-old
        ///		mapping).</param>
        /// <returns>permutation: An array containing the new-to-old fill reducing permutation.
        ///     stats: Measuments taken by SuiteSparse during the execution of AMD.</returns>
        /// <exception cref="ArgumentException">If <paramref name="order"/>, <paramref name="cscRowIndices"/> or
        ///     <paramref name="cscColOffsets"/> do not describe a valid symmetric matrix.</exception>
        /// <exception cref="SuiteSparseException">Thrown if SuiteSparse dlls cannot be loaded, or if there is not enough memory
        ///     to allocate during CAMD.</exception>
        public (int[] permutation, ReorderingStatistics stats) FindPermutation(int order, int[] cscRowIndices,
                                                                               int[] cscColOffsets, int[] constraints)
        {
            var permutation = new int[order];
            int status      = SuiteSparsePInvokes.ReorderCAMD(order, cscRowIndices, cscColOffsets, constraints,
                                                              denseThreshold, aggressiveAbsorption ? 1 : 0,
                                                              permutation, out int nnzFactor, out int numMovedDense);

            // Error checking
            //if (status == 1) throw new SuiteSparseException("The matrix had unsorted columns, but was otherwise ok.");
            if (status == 2)
            {
                throw new ArgumentException(
                          "The arrays that describe the non zero pattern of the matrix were invalid or the permutation buffer was NULL.");
            }
            else if (status == 3)
            {
                throw new SuiteSparseException("Not enough memory could be allocated");
            }
            return(permutation, new ReorderingStatistics(nnzFactor, numMovedDense));
        }
Exemplo n.º 4
0
        private static void TestCholeskySolver()
        {
            Skip.IfNot(TestSettings.TestSuiteSparse, TestSettings.MessageWhenSkippingSuiteSparse);

            // Define linear system
            const int n   = 4;
            const int nnz = 7;

            int[] colOffsets = new int[n + 1] {
                0, 1, 2, 5, nnz
            };
            int[] rowIndices = new int[nnz] {
                0, 1, 0, 1, 2, 1, 3
            };
            double[] values = new double[nnz] {
                4.0, 10.0, 2.0, 1.0, 8.0, 3.0, 9.0
            };
            double[] rhs = new double[n] {
                6.0, 14.0, 11.0, 12.0
            };
            double[] solutionExpected = { 1.0, 1.0, 1.0, 1.0 };
            double[] solution         = new double[n];

            // Solve it using SuiteSparse
            IntPtr handle = SuiteSparsePInvokes.CreateCommon(0, 0);
            int    status = SuiteSparsePInvokes.FactorizeCSCUpper(n, nnz, values, rowIndices, colOffsets, out IntPtr factor, handle);

            Assert.True(status == -1);
            int nnzFactor = SuiteSparsePInvokes.GetFactorNonZeros(factor);

            Console.WriteLine($"Before factorization: nnz = {nnz}");
            Console.WriteLine($"After factorization: nnz = {nnzFactor}");

            SuiteSparsePInvokes.Solve(0, n, 1, factor, rhs, solution, handle);
            comparer.AssertEqual(solutionExpected, solution);

            SuiteSparsePInvokes.DestroyFactor(ref factor, handle);
            SuiteSparsePInvokes.DestroyCommon(ref handle);
        }