1 /* ========================================================================= */ 2 /* === AMD: approximate minimum degree ordering =========================== */ 3 /* ========================================================================= */ 4 5 /* ------------------------------------------------------------------------- */ 6 /* AMD Version 2.4, Copyright (c) 1996-2013 by Timothy A. Davis, */ 7 /* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ 8 /* email: DrTimothyAldenDavis@gmail.com */ 9 /* ------------------------------------------------------------------------- */ 10 11 /* AMD finds a symmetric ordering P of a matrix A so that the Cholesky 12 * factorization of P*A*P' has fewer nonzeros and takes less work than the 13 * Cholesky factorization of A. If A is not symmetric, then it performs its 14 * ordering on the matrix A+A'. Two sets of user-callable routines are 15 * provided, one for int integers and the other for SuiteSparse_long integers. 16 * 17 * The method is based on the approximate minimum degree algorithm, discussed 18 * in Amestoy, Davis, and Duff, "An approximate degree ordering algorithm", 19 * SIAM Journal of Matrix Analysis and Applications, vol. 17, no. 4, pp. 20 * 886-905, 1996. This package can perform both the AMD ordering (with 21 * aggressive absorption), and the AMDBAR ordering (without aggressive 22 * absorption) discussed in the above paper. This package differs from the 23 * Fortran codes discussed in the paper: 24 * 25 * (1) it can ignore "dense" rows and columns, leading to faster run times 26 * (2) it computes the ordering of A+A' if A is not symmetric 27 * (3) it is followed by a depth-first post-ordering of the assembly tree 28 * (or supernodal elimination tree) 29 * 30 * For historical reasons, the Fortran versions, amd.f and amdbar.f, have 31 * been left (nearly) unchanged. They compute the identical ordering as 32 * described in the above paper. 33 */ 34 35 #ifndef AMD_H 36 #define AMD_H 37 38 /* make it easy for C++ programs to include AMD */ 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /* get the definition of size_t: */ 44 #include <stddef.h> 45 46 #include "SuiteSparse_config.h" 47 48 int amd_order /* returns AMD_OK, AMD_OK_BUT_JUMBLED, 49 * AMD_INVALID, or AMD_OUT_OF_MEMORY */ 50 ( 51 int n, /* A is n-by-n. n must be >= 0. */ 52 const int Ap [ ], /* column pointers for A, of size n+1 */ 53 const int Ai [ ], /* row indices of A, of size nz = Ap [n] */ 54 int P [ ], /* output permutation, of size n */ 55 double Control [ ], /* input Control settings, of size AMD_CONTROL */ 56 double Info [ ] /* output Info statistics, of size AMD_INFO */ 57 ) ; 58 59 SuiteSparse_long amd_l_order /* see above for description of arguments */ 60 ( 61 SuiteSparse_long n, 62 const SuiteSparse_long Ap [ ], 63 const SuiteSparse_long Ai [ ], 64 SuiteSparse_long P [ ], 65 double Control [ ], 66 double Info [ ] 67 ) ; 68 69 /* Input arguments (not modified): 70 * 71 * n: the matrix A is n-by-n. 72 * Ap: an int/SuiteSparse_long array of size n+1, containing column 73 * pointers of A. 74 * Ai: an int/SuiteSparse_long array of size nz, containing the row 75 * indices of A, where nz = Ap [n]. 76 * Control: a double array of size AMD_CONTROL, containing control 77 * parameters. Defaults are used if Control is NULL. 78 * 79 * Output arguments (not defined on input): 80 * 81 * P: an int/SuiteSparse_long array of size n, containing the output 82 * permutation. If row i is the kth pivot row, then P [k] = i. In 83 * MATLAB notation, the reordered matrix is A (P,P). 84 * Info: a double array of size AMD_INFO, containing statistical 85 * information. Ignored if Info is NULL. 86 * 87 * On input, the matrix A is stored in column-oriented form. The row indices 88 * of nonzero entries in column j are stored in Ai [Ap [j] ... Ap [j+1]-1]. 89 * 90 * If the row indices appear in ascending order in each column, and there 91 * are no duplicate entries, then amd_order is slightly more efficient in 92 * terms of time and memory usage. If this condition does not hold, a copy 93 * of the matrix is created (where these conditions do hold), and the copy is 94 * ordered. This feature is new to v2.0 (v1.2 and earlier required this 95 * condition to hold for the input matrix). 96 * 97 * Row indices must be in the range 0 to 98 * n-1. Ap [0] must be zero, and thus nz = Ap [n] is the number of nonzeros 99 * in A. The array Ap is of size n+1, and the array Ai is of size nz = Ap [n]. 100 * The matrix does not need to be symmetric, and the diagonal does not need to 101 * be present (if diagonal entries are present, they are ignored except for 102 * the output statistic Info [AMD_NZDIAG]). The arrays Ai and Ap are not 103 * modified. This form of the Ap and Ai arrays to represent the nonzero 104 * pattern of the matrix A is the same as that used internally by MATLAB. 105 * If you wish to use a more flexible input structure, please see the 106 * umfpack_*_triplet_to_col routines in the UMFPACK package, at 107 * http://www.suitesparse.com. 108 * 109 * Restrictions: n >= 0. Ap [0] = 0. Ap [j] <= Ap [j+1] for all j in the 110 * range 0 to n-1. nz = Ap [n] >= 0. Ai [0..nz-1] must be in the range 0 111 * to n-1. Finally, Ai, Ap, and P must not be NULL. If any of these 112 * restrictions are not met, AMD returns AMD_INVALID. 113 * 114 * AMD returns: 115 * 116 * AMD_OK if the matrix is valid and sufficient memory can be allocated to 117 * perform the ordering. 118 * 119 * AMD_OUT_OF_MEMORY if not enough memory can be allocated. 120 * 121 * AMD_INVALID if the input arguments n, Ap, Ai are invalid, or if P is 122 * NULL. 123 * 124 * AMD_OK_BUT_JUMBLED if the matrix had unsorted columns, and/or duplicate 125 * entries, but was otherwise valid. 126 * 127 * The AMD routine first forms the pattern of the matrix A+A', and then 128 * computes a fill-reducing ordering, P. If P [k] = i, then row/column i of 129 * the original is the kth pivotal row. In MATLAB notation, the permuted 130 * matrix is A (P,P), except that 0-based indexing is used instead of the 131 * 1-based indexing in MATLAB. 132 * 133 * The Control array is used to set various parameters for AMD. If a NULL 134 * pointer is passed, default values are used. The Control array is not 135 * modified. 136 * 137 * Control [AMD_DENSE]: controls the threshold for "dense" rows/columns. 138 * A dense row/column in A+A' can cause AMD to spend a lot of time in 139 * ordering the matrix. If Control [AMD_DENSE] >= 0, rows/columns 140 * with more than Control [AMD_DENSE] * sqrt (n) entries are ignored 141 * during the ordering, and placed last in the output order. The 142 * default value of Control [AMD_DENSE] is 10. If negative, no 143 * rows/columns are treated as "dense". Rows/columns with 16 or 144 * fewer off-diagonal entries are never considered "dense". 145 * 146 * Control [AMD_AGGRESSIVE]: controls whether or not to use aggressive 147 * absorption, in which a prior element is absorbed into the current 148 * element if is a subset of the current element, even if it is not 149 * adjacent to the current pivot element (refer to Amestoy, Davis, 150 * & Duff, 1996, for more details). The default value is nonzero, 151 * which means to perform aggressive absorption. This nearly always 152 * leads to a better ordering (because the approximate degrees are 153 * more accurate) and a lower execution time. There are cases where 154 * it can lead to a slightly worse ordering, however. To turn it off, 155 * set Control [AMD_AGGRESSIVE] to 0. 156 * 157 * Control [2..4] are not used in the current version, but may be used in 158 * future versions. 159 * 160 * The Info array provides statistics about the ordering on output. If it is 161 * not present, the statistics are not returned. This is not an error 162 * condition. 163 * 164 * Info [AMD_STATUS]: the return value of AMD, either AMD_OK, 165 * AMD_OK_BUT_JUMBLED, AMD_OUT_OF_MEMORY, or AMD_INVALID. 166 * 167 * Info [AMD_N]: n, the size of the input matrix 168 * 169 * Info [AMD_NZ]: the number of nonzeros in A, nz = Ap [n] 170 * 171 * Info [AMD_SYMMETRY]: the symmetry of the matrix A. It is the number 172 * of "matched" off-diagonal entries divided by the total number of 173 * off-diagonal entries. An entry A(i,j) is matched if A(j,i) is also 174 * an entry, for any pair (i,j) for which i != j. In MATLAB notation, 175 * S = spones (A) ; 176 * B = tril (S, -1) + triu (S, 1) ; 177 * symmetry = nnz (B & B') / nnz (B) ; 178 * 179 * Info [AMD_NZDIAG]: the number of entries on the diagonal of A. 180 * 181 * Info [AMD_NZ_A_PLUS_AT]: the number of nonzeros in A+A', excluding the 182 * diagonal. If A is perfectly symmetric (Info [AMD_SYMMETRY] = 1) 183 * with a fully nonzero diagonal, then Info [AMD_NZ_A_PLUS_AT] = nz-n 184 * (the smallest possible value). If A is perfectly unsymmetric 185 * (Info [AMD_SYMMETRY] = 0, for an upper triangular matrix, for 186 * example) with no diagonal, then Info [AMD_NZ_A_PLUS_AT] = 2*nz 187 * (the largest possible value). 188 * 189 * Info [AMD_NDENSE]: the number of "dense" rows/columns of A+A' that were 190 * removed from A prior to ordering. These are placed last in the 191 * output order P. 192 * 193 * Info [AMD_MEMORY]: the amount of memory used by AMD, in bytes. In the 194 * current version, this is 1.2 * Info [AMD_NZ_A_PLUS_AT] + 9*n 195 * times the size of an integer. This is at most 2.4nz + 9n. This 196 * excludes the size of the input arguments Ai, Ap, and P, which have 197 * a total size of nz + 2*n + 1 integers. 198 * 199 * Info [AMD_NCMPA]: the number of garbage collections performed. 200 * 201 * Info [AMD_LNZ]: the number of nonzeros in L (excluding the diagonal). 202 * This is a slight upper bound because mass elimination is combined 203 * with the approximate degree update. It is a rough upper bound if 204 * there are many "dense" rows/columns. The rest of the statistics, 205 * below, are also slight or rough upper bounds, for the same reasons. 206 * The post-ordering of the assembly tree might also not exactly 207 * correspond to a true elimination tree postordering. 208 * 209 * Info [AMD_NDIV]: the number of divide operations for a subsequent LDL' 210 * or LU factorization of the permuted matrix A (P,P). 211 * 212 * Info [AMD_NMULTSUBS_LDL]: the number of multiply-subtract pairs for a 213 * subsequent LDL' factorization of A (P,P). 214 * 215 * Info [AMD_NMULTSUBS_LU]: the number of multiply-subtract pairs for a 216 * subsequent LU factorization of A (P,P), assuming that no numerical 217 * pivoting is required. 218 * 219 * Info [AMD_DMAX]: the maximum number of nonzeros in any column of L, 220 * including the diagonal. 221 * 222 * Info [14..19] are not used in the current version, but may be used in 223 * future versions. 224 */ 225 226 /* ------------------------------------------------------------------------- */ 227 /* direct interface to AMD */ 228 /* ------------------------------------------------------------------------- */ 229 230 /* amd_2 is the primary AMD ordering routine. It is not meant to be 231 * user-callable because of its restrictive inputs and because it destroys 232 * the user's input matrix. It does not check its inputs for errors, either. 233 * However, if you can work with these restrictions it can be faster than 234 * amd_order and use less memory (assuming that you can create your own copy 235 * of the matrix for AMD to destroy). Refer to AMD/Source/amd_2.c for a 236 * description of each parameter. */ 237 238 void amd_2 239 ( 240 int n, 241 int Pe [ ], 242 int Iw [ ], 243 int Len [ ], 244 int iwlen, 245 int pfree, 246 int Nv [ ], 247 int Next [ ], 248 int Last [ ], 249 int Head [ ], 250 int Elen [ ], 251 int Degree [ ], 252 int W [ ], 253 double Control [ ], 254 double Info [ ] 255 ) ; 256 257 void amd_l2 258 ( 259 SuiteSparse_long n, 260 SuiteSparse_long Pe [ ], 261 SuiteSparse_long Iw [ ], 262 SuiteSparse_long Len [ ], 263 SuiteSparse_long iwlen, 264 SuiteSparse_long pfree, 265 SuiteSparse_long Nv [ ], 266 SuiteSparse_long Next [ ], 267 SuiteSparse_long Last [ ], 268 SuiteSparse_long Head [ ], 269 SuiteSparse_long Elen [ ], 270 SuiteSparse_long Degree [ ], 271 SuiteSparse_long W [ ], 272 double Control [ ], 273 double Info [ ] 274 ) ; 275 276 /* ------------------------------------------------------------------------- */ 277 /* amd_valid */ 278 /* ------------------------------------------------------------------------- */ 279 280 /* Returns AMD_OK or AMD_OK_BUT_JUMBLED if the matrix is valid as input to 281 * amd_order; the latter is returned if the matrix has unsorted and/or 282 * duplicate row indices in one or more columns. Returns AMD_INVALID if the 283 * matrix cannot be passed to amd_order. For amd_order, the matrix must also 284 * be square. The first two arguments are the number of rows and the number 285 * of columns of the matrix. For its use in AMD, these must both equal n. 286 * 287 * NOTE: this routine returned TRUE/FALSE in v1.2 and earlier. 288 */ 289 290 int amd_valid 291 ( 292 int n_row, /* # of rows */ 293 int n_col, /* # of columns */ 294 const int Ap [ ], /* column pointers, of size n_col+1 */ 295 const int Ai [ ] /* row indices, of size Ap [n_col] */ 296 ) ; 297 298 SuiteSparse_long amd_l_valid 299 ( 300 SuiteSparse_long n_row, 301 SuiteSparse_long n_col, 302 const SuiteSparse_long Ap [ ], 303 const SuiteSparse_long Ai [ ] 304 ) ; 305 306 /* ------------------------------------------------------------------------- */ 307 /* AMD memory manager and printf routines */ 308 /* ------------------------------------------------------------------------- */ 309 310 /* moved to SuiteSparse_config.c */ 311 312 /* ------------------------------------------------------------------------- */ 313 /* AMD Control and Info arrays */ 314 /* ------------------------------------------------------------------------- */ 315 316 /* amd_defaults: sets the default control settings */ 317 void amd_defaults (double Control [ ]) ; 318 void amd_l_defaults (double Control [ ]) ; 319 320 /* amd_control: prints the control settings */ 321 void amd_control (double Control [ ]) ; 322 void amd_l_control (double Control [ ]) ; 323 324 /* amd_info: prints the statistics */ 325 void amd_info (double Info [ ]) ; 326 void amd_l_info (double Info [ ]) ; 327 328 #define AMD_CONTROL 5 /* size of Control array */ 329 #define AMD_INFO 20 /* size of Info array */ 330 331 /* contents of Control */ 332 #define AMD_DENSE 0 /* "dense" if degree > Control [0] * sqrt (n) */ 333 #define AMD_AGGRESSIVE 1 /* do aggressive absorption if Control [1] != 0 */ 334 335 /* default Control settings */ 336 #define AMD_DEFAULT_DENSE 10.0 /* default "dense" degree 10*sqrt(n) */ 337 #define AMD_DEFAULT_AGGRESSIVE 1 /* do aggressive absorption by default */ 338 339 /* contents of Info */ 340 #define AMD_STATUS 0 /* return value of amd_order and amd_l_order */ 341 #define AMD_N 1 /* A is n-by-n */ 342 #define AMD_NZ 2 /* number of nonzeros in A */ 343 #define AMD_SYMMETRY 3 /* symmetry of pattern (1 is sym., 0 is unsym.) */ 344 #define AMD_NZDIAG 4 /* # of entries on diagonal */ 345 #define AMD_NZ_A_PLUS_AT 5 /* nz in A+A' */ 346 #define AMD_NDENSE 6 /* number of "dense" rows/columns in A */ 347 #define AMD_MEMORY 7 /* amount of memory used by AMD */ 348 #define AMD_NCMPA 8 /* number of garbage collections in AMD */ 349 #define AMD_LNZ 9 /* approx. nz in L, excluding the diagonal */ 350 #define AMD_NDIV 10 /* number of fl. point divides for LU and LDL' */ 351 #define AMD_NMULTSUBS_LDL 11 /* number of fl. point (*,-) pairs for LDL' */ 352 #define AMD_NMULTSUBS_LU 12 /* number of fl. point (*,-) pairs for LU */ 353 #define AMD_DMAX 13 /* max nz. in any column of L, incl. diagonal */ 354 355 /* ------------------------------------------------------------------------- */ 356 /* return values of AMD */ 357 /* ------------------------------------------------------------------------- */ 358 359 #define AMD_OK 0 /* success */ 360 #define AMD_OUT_OF_MEMORY -1 /* malloc failed, or problem too large */ 361 #define AMD_INVALID -2 /* input arguments are not valid */ 362 #define AMD_OK_BUT_JUMBLED 1 /* input matrix is OK for amd_order, but 363 * columns were not sorted, and/or duplicate entries were present. AMD had 364 * to do extra work before ordering the matrix. This is a warning, not an 365 * error. */ 366 367 /* ========================================================================== */ 368 /* === AMD version ========================================================== */ 369 /* ========================================================================== */ 370 371 /* AMD Version 1.2 and later include the following definitions. 372 * As an example, to test if the version you are using is 1.2 or later: 373 * 374 * #ifdef AMD_VERSION 375 * if (AMD_VERSION >= AMD_VERSION_CODE (1,2)) ... 376 * #endif 377 * 378 * This also works during compile-time: 379 * 380 * #if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE (1,2)) 381 * printf ("This is version 1.2 or later\n") ; 382 * #else 383 * printf ("This is an early version\n") ; 384 * #endif 385 * 386 * Versions 1.1 and earlier of AMD do not include a #define'd version number. 387 */ 388 389 #define AMD_DATE "May 4, 2016" 390 #define AMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) 391 #define AMD_MAIN_VERSION 2 392 #define AMD_SUB_VERSION 4 393 #define AMD_SUBSUB_VERSION 6 394 #define AMD_VERSION AMD_VERSION_CODE(AMD_MAIN_VERSION,AMD_SUB_VERSION) 395 396 #ifdef __cplusplus 397 } 398 #endif 399 400 #endif 401