1 /* ========================================================================== */
2 /* === Partition/cholmod_csymamd ============================================ */
3 /* ========================================================================== */
4
5 /* -----------------------------------------------------------------------------
6 * CHOLMOD/Partition Module.
7 * Copyright (C) 2005-2013, Univ. of Florida. Author: Timothy A. Davis
8 * -------------------------------------------------------------------------- */
9
10 /* CHOLMOD interface to the CSYMAMD ordering routine. Finds a permutation
11 * p such that the Cholesky factorization of PAP' is sparser than A.
12 * The column etree is found and postordered, and the CSYMAMD
13 * ordering is then combined with its postordering. If A is unsymmetric,
14 * A+A' is ordered (A must be square).
15 *
16 * workspace: Head (nrow+1)
17 *
18 * Supports any xtype (pattern, real, complex, or zomplex).
19 */
20
21 #ifndef NCAMD
22
23 #include "cholmod_internal.h"
24 #include "ccolamd.h"
25 #include "cholmod_camd.h"
26
27 #if (CCOLAMD_VERSION < CCOLAMD_VERSION_CODE (2,5))
28 #error "CCOLAMD v2.0 or later is required"
29 #endif
30
31 /* ========================================================================== */
32 /* === cholmod_csymamd ====================================================== */
33 /* ========================================================================== */
34
CHOLMOD(csymamd)35 int CHOLMOD(csymamd)
36 (
37 /* ---- input ---- */
38 cholmod_sparse *A, /* matrix to order */
39 /* ---- output --- */
40 Int *Cmember, /* size nrow. see cholmod_ccolamd.c for description */
41 Int *Perm, /* size A->nrow, output permutation */
42 /* --------------- */
43 cholmod_common *Common
44 )
45 {
46 double knobs [CCOLAMD_KNOBS] ;
47 Int *perm, *Head ;
48 Int ok, i, nrow, stats [CCOLAMD_STATS] ;
49
50 /* ---------------------------------------------------------------------- */
51 /* check inputs */
52 /* ---------------------------------------------------------------------- */
53
54 RETURN_IF_NULL_COMMON (FALSE) ;
55 RETURN_IF_NULL (A, FALSE) ;
56 RETURN_IF_NULL (Perm, FALSE) ;
57 RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ;
58 Common->status = CHOLMOD_OK ;
59
60 if (A->nrow != A->ncol || !(A->packed))
61 {
62 ERROR (CHOLMOD_INVALID, "matrix must be square and packed") ;
63 return (FALSE) ;
64 }
65
66 /* ---------------------------------------------------------------------- */
67 /* get inputs */
68 /* ---------------------------------------------------------------------- */
69
70 nrow = A->nrow ;
71
72 /* ---------------------------------------------------------------------- */
73 /* allocate workspace */
74 /* ---------------------------------------------------------------------- */
75
76 CHOLMOD(allocate_work) (nrow, 0, 0, Common) ;
77 if (Common->status < CHOLMOD_OK)
78 {
79 return (FALSE) ;
80 }
81
82 /* ---------------------------------------------------------------------- */
83 /* order the matrix (does not affect A->p or A->i) */
84 /* ---------------------------------------------------------------------- */
85
86 perm = Common->Head ; /* size nrow+1 (i/l/l) */
87
88 /* get parameters */
89 #ifdef LONG
90 ccolamd_l_set_defaults (knobs) ;
91 #else
92 ccolamd_set_defaults (knobs) ;
93 #endif
94 if (Common->current >= 0 && Common->current < CHOLMOD_MAXMETHODS)
95 {
96 /* get the knobs from the Common parameters */
97 knobs [CCOLAMD_DENSE_ROW] =Common->method[Common->current].prune_dense ;
98 knobs [CCOLAMD_AGGRESSIVE]=Common->method[Common->current].aggressive ;
99 }
100 {
101 #ifdef LONG
102 csymamd_l (nrow, A->i, A->p, perm, knobs, stats,
103 SuiteSparse_config.calloc_func,
104 SuiteSparse_config.free_func,
105 Cmember, A->stype) ;
106 #else
107 csymamd (nrow, A->i, A->p, perm, knobs, stats,
108 SuiteSparse_config.calloc_func,
109 SuiteSparse_config.free_func,
110 Cmember, A->stype) ;
111 #endif
112 ok = stats [CCOLAMD_STATUS] ;
113 }
114
115 if (ok == CCOLAMD_ERROR_out_of_memory)
116 {
117 ERROR (CHOLMOD_OUT_OF_MEMORY, "out of memory") ;
118 }
119 ok = (ok == CCOLAMD_OK || ok == CCOLAMD_OK_BUT_JUMBLED) ;
120
121 /* ---------------------------------------------------------------------- */
122 /* free the workspace and return result */
123 /* ---------------------------------------------------------------------- */
124
125 /* permutation returned in perm [0..n-1] */
126 for (i = 0 ; i < nrow ; i++)
127 {
128 Perm [i] = perm [i] ;
129 }
130
131 /* clear Head workspace (used for perm, in csymamd): */
132 Head = Common->Head ;
133 for (i = 0 ; i <= nrow ; i++)
134 {
135 Head [i] = EMPTY ;
136 }
137
138 return (ok) ;
139 }
140 #endif
141