Beispiel #1
0
        /// <summary>
        /// Initializes a new instance of <see cref="SparsityPatternSymmetric"/> for an existing matrix
        /// provided as <paramref name="dense"/>.
        /// Initialy, only the entries of <paramref name="dense"/> that satisfy: Math.Abs(<paramref name="dense"/>[i, j]) &gt;
        /// <paramref name="tolerance"/> will be considered as non-zero.
        /// </summary>
        /// <param name="dense">A matrix whose sparsity pattern will be extracted. It must be square and symmetric. Only its
        ///     upper triangle entries will be processed, thus its symmetry will not be checked explicitly.</param>
        /// <param name="tolerance">The tolerance under which an entry of <paramref name="dense"/> is considered as 0.</param>
        /// <exception cref="Exceptions.NonMatchingDimensionsException">Thrown if <paramref name="dense"/> is not
        ///     square.</exception>
        public static SparsityPatternSymmetric CreateFromDense(Matrix dense, double tolerance = 0.0)
        {
            Preconditions.CheckSquare(dense);
            SparsityPatternSymmetric pattern = CreateEmpty(dense.NumColumns);

            if (tolerance == 0.0)
            {
                for (int j = 0; j < dense.NumColumns; ++j)
                {
                    for (int i = 0; i <= j; ++i)
                    {
                        if (dense[i, j] != 0)
                        {
                            pattern.columns[j].Add(i);
                        }
                    }
                }
            }
            else
            {
                for (int j = 0; j < dense.NumColumns; ++j)
                {
                    for (int i = 0; i <= j; ++i)
                    {
                        if (Math.Abs(dense[i, j]) > tolerance)
                        {
                            pattern.columns[j].Add(i);
                        }
                    }
                }
            }
            return(pattern);
        }
Beispiel #2
0
        /// <summary>
        /// See <see cref="IReorderingAlgorithm.FindPermutation(SparsityPatternSymmetric)"/>
        /// </summary>
        /// <remarks>The returned permutation is new-to-old.</remarks>
        public (int[] permutation, bool oldToNew) FindPermutation(SparsityPatternSymmetric pattern)
        {
            int order = pattern.Order;

            (int[] cscRowIndices, int[] cscColOffsets) = pattern.BuildSymmetricCSCArrays(true); //TODO: perhaps sorting is not needed here.
            var dummyCscValues = new double[cscRowIndices.Length];                              //TODO: too expensive
            var matrixCSparse  = new SparseMatrix(order, order, dummyCscValues, cscRowIndices, cscColOffsets);

            int[] permutation = AMD.Generate <double>(matrixCSparse, ColumnOrdering.MinimumDegreeAtPlusA);

            // It is possible that CSparse.NET AMD algorithm returns more entries than the matrix order (so far I have found 1
            // extra). In that case, make sure the first ones are valid and return only them.
            if (permutation.Length > order)
            {
                for (int i = order; i < permutation.Length; ++i)
                {
                    if (permutation[i] < pattern.Order)
                    {
                        throw new Exception(
                                  "Something went wrong during AMD. The permutation vector has more entries than the matrix order.");
                    }
                }
                var permutationCorrected = new int[order];
                Array.Copy(permutation, permutationCorrected, order);
                return(permutationCorrected, false);
            }
            else
            {
                return(permutation, false);
            }
        }
Beispiel #3
0
 /// <summary>
 /// See <see cref="IReorderingAlgorithm.FindPermutation(SparsityPatternSymmetric)"/>.
 /// </summary>
 /// <remarks>The returned permutation is new-to-old.</remarks>
 /// <exception cref="SuiteSparseException">Thrown if SuiteSparse dlls cannot be loaded or if AMD fails.</exception>
 public (int[] permutation, bool oldToNew) FindPermutation(SparsityPatternSymmetric pattern)
 {
     (int[] rowIndices, int[] colOffsets)            = pattern.BuildSymmetricCSCArrays(true);
     (int[] permutation, ReorderingStatistics stats) =
         FindPermutation(pattern.Order, rowIndices.Length, rowIndices, colOffsets);
     return(permutation, false);
 }
Beispiel #4
0
 /// <summary>
 /// Find a fill reducing permutation for the sparsity pattern of a symmetric matrix.
 /// The returned permutation is new-to-old, namely reordered[i] = original[permutation[i]].
 /// </summary>
 /// <param name="pattern">The indices of the non-zero entries of a symmetric matrix.</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(SparsityPatternSymmetric pattern,
                                                                        int[] constraints)
 {
     (int[] rowIndices, int[] colOffsets) = pattern.BuildSymmetricCSCArrays(true);
     return(FindPermutation(pattern.Order, rowIndices, colOffsets, constraints));
 }