/// <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); } }
/// <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); }
/// <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 <= <paramref name="constraints"/>[i] < 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)); }