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