1
/* ========================================================================== */
2
/* === csymamd mexFunction ================================================== */
3
/* ========================================================================== */
5
/* ----------------------------------------------------------------------------
6
* CCOLAMD, Copyright (C), Univ. of Florida. Authors: Timothy A. Davis,
7
* Sivasankaran Rajamanickam, and Stefan Larimore
8
* See License.txt for the Version 2.1 of the GNU Lesser General Public License
9
* http://www.cise.ufl.edu/research/sparse
10
* -------------------------------------------------------------------------- */
15
* [p stats] = csymamd (A, knobs, cmember) ;
17
* See csymamd.m for a description.
20
/* ========================================================================== */
21
/* === Include files ======================================================== */
22
/* ========================================================================== */
30
/* ========================================================================== */
31
/* === csymamd mexFunction ================================================== */
32
/* ========================================================================== */
36
/* === Parameters ======================================================= */
41
const mxArray *pargin [ ]
44
/* === Local variables ================================================== */
46
UF_long *A ; /* row indices of input matrix A */
47
UF_long *perm ; /* column ordering of M and ordering of A */
48
UF_long *cmember ; /* csymamd's copy of the constraint set */
49
double *in_cmember ; /* input constraint set */
50
UF_long *p ; /* column pointers of input matrix A */
51
UF_long cslen ; /* size of constraint set */
52
UF_long n_col ; /* number of columns of A */
53
UF_long n_row ; /* number of rows of A */
54
UF_long full ; /* TRUE if input matrix full, FALSE if sparse */
55
double knobs [CCOLAMD_KNOBS] ; /* csymamd user-controllable parameters */
56
double *out_perm ; /* output permutation vector */
57
double *out_stats ; /* output stats vector */
58
double *in_knobs ; /* input knobs vector */
59
UF_long i ; /* loop counter */
60
mxArray *Ainput ; /* input matrix handle */
61
UF_long spumoni ; /* verbosity variable */
62
UF_long stats [CCOLAMD_STATS] ; /* stats for symamd */
64
/* === Check inputs ===================================================== */
66
if (nargin < 1 || nargin > 3 || nargout < 0 || nargout > 2)
68
mexErrMsgTxt ("Usage: [p stats] = csymamd (S, knobs, cmember)") ;
71
/* === Get cmember ====================================================== */
77
in_cmember = mxGetPr (pargin [2]) ;
78
cslen = mxGetNumberOfElements (pargin [2]) ;
81
cmember = (UF_long *) mxCalloc (cslen, sizeof (UF_long)) ;
82
for (i = 0 ; i < cslen ; i++)
84
/* convert cmember from 1-based to 0-based */
85
cmember[i] = ((UF_long) in_cmember [i] - 1) ;
90
/* === Get knobs ======================================================== */
92
ccolamd_l_set_defaults (knobs) ;
95
/* check for user-passed knobs */
99
in_knobs = mxGetPr (pargin [1]) ;
100
i = mxGetNumberOfElements (pargin [1]) ;
101
if (i > 0) knobs [CCOLAMD_DENSE_ROW] = in_knobs [0] ;
102
if (i > 1) knobs [CCOLAMD_AGGRESSIVE] = in_knobs [1] ;
103
if (i > 2) spumoni = (in_knobs [2] != 0) ;
106
/* print knob settings if spumoni is set */
109
mexPrintf ("\ncsymamd version %d.%d, %s:\n",
110
CCOLAMD_MAIN_VERSION, CCOLAMD_SUB_VERSION, CCOLAMD_DATE) ;
111
if (knobs [CCOLAMD_DENSE_ROW] >= 0)
113
mexPrintf ("knobs(1): %g, rows/cols with > "
114
"max(16,%g*sqrt(size(A,2))) entries removed\n",
115
in_knobs [0], knobs [CCOLAMD_DENSE_ROW]) ;
119
mexPrintf ("knobs(1): %g, no dense rows removed\n",
122
mexPrintf ("knobs(2): %g, aggressive absorption: %s\n",
123
in_knobs [1], (knobs [CCOLAMD_AGGRESSIVE] != 0) ? "yes" : "no") ;
124
mexPrintf ("knobs(3): %g, statistics and knobs printed\n",
128
/* === If A is full, convert to a sparse matrix ========================= */
130
Ainput = (mxArray *) pargin [0] ;
131
if (mxGetNumberOfDimensions (Ainput) != 2)
133
mexErrMsgTxt ("csymamd: input matrix must be 2-dimensional.") ;
135
full = !mxIsSparse (Ainput) ;
138
mexCallMATLAB (1, &Ainput, 1, (mxArray **) pargin, "sparse") ;
141
/* === Allocate workspace for csymamd =================================== */
143
/* get size of matrix */
144
n_row = mxGetM (Ainput) ;
145
n_col = mxGetN (Ainput) ;
148
mexErrMsgTxt ("csymamd: matrix must be square.") ;
151
if (cmember != NULL && cslen != n_col)
153
mexErrMsgTxt ("csymamd: cmember must be of length equal to #cols of A");
156
A = (UF_long *) mxGetIr (Ainput) ;
157
p = (UF_long *) mxGetJc (Ainput) ;
158
perm = (UF_long *) mxCalloc (n_col+1, sizeof (UF_long)) ;
160
/* === Order the rows and columns of A (does not destroy A) ============= */
162
if (!csymamd_l (n_col, A, p, perm, knobs, stats, &mxCalloc, &mxFree,
165
csymamd_l_report (stats) ;
166
mexErrMsgTxt ("csymamd error!") ;
171
mxDestroyArray (Ainput) ;
174
/* === Return the permutation vector ==================================== */
176
pargout [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ;
177
out_perm = mxGetPr (pargout [0]) ;
178
for (i = 0 ; i < n_col ; i++)
180
/* symamd is 0-based, but MATLAB expects this to be 1-based */
181
out_perm [i] = perm [i] + 1 ;
186
/* === Return the stats vector ========================================== */
188
/* print stats if spumoni is set */
191
csymamd_l_report (stats) ;
196
pargout [1] = mxCreateDoubleMatrix (1, CCOLAMD_STATS, mxREAL) ;
197
out_stats = mxGetPr (pargout [1]) ;
198
for (i = 0 ; i < CCOLAMD_STATS ; i++)
200
out_stats [i] = stats [i] ;
203
/* fix stats (5) and (6), for 1-based information on jumbled matrix. */
204
/* note that this correction doesn't occur if symamd returns FALSE */
205
out_stats [CCOLAMD_INFO1] ++ ;
206
out_stats [CCOLAMD_INFO2] ++ ;