1
/* ========================================================================== */
2
/* === colamd mexFunction =================================================== */
3
/* ========================================================================== */
10
[ P, stats ] = colamd (A, knobs) ;
12
see colamd.m for a description.
16
The authors of the code itself are Stefan I. Larimore and Timothy A.
17
Davis (davis at cise.ufl.edu), University of Florida. The algorithm was
18
developed in collaboration with John Gilbert, Xerox PARC, and Esmond
19
Ng, Oak Ridge National Laboratory.
23
This work was supported by the National Science Foundation, under
24
grants DMS-9504974 and DMS-9803599.
28
Copyright (c) 1998-2006, Timothy A. Davis, All Rights Reserved.
30
See http://www.cise.ufl.edu/research/sparse/colamd (the colamd.c
31
file) for the License.
35
The colamd/symamd library is available at
37
http://www.cise.ufl.edu/research/sparse/colamd/
39
This is the http://www.cise.ufl.edu/research/sparse/colamd/colamdmex.c
40
file. It requires the colamd.c and colamd.h files.
44
/* ========================================================================== */
45
/* === Include files ======================================================== */
46
/* ========================================================================== */
54
/* ========================================================================== */
55
/* === colamd mexFunction =================================================== */
56
/* ========================================================================== */
60
/* === Parameters ======================================================= */
62
int nlhs, /* number of left-hand sides */
63
mxArray *plhs [], /* left-hand side matrices */
64
int nrhs, /* number of right--hand sides */
65
const mxArray *prhs [] /* right-hand side matrices */
68
/* === Local variables ================================================== */
70
int *A ; /* colamd's copy of the matrix, and workspace */
71
int *p ; /* colamd's copy of the column pointers */
72
int Alen ; /* size of A */
73
int n_col ; /* number of columns of A */
74
int n_row ; /* number of rows of A */
75
int nnz ; /* number of entries in A */
76
int full ; /* TRUE if input matrix full, FALSE if sparse */
77
double knobs [COLAMD_KNOBS] ; /* colamd user-controllable parameters */
78
double *out_perm ; /* output permutation vector */
79
double *out_stats ; /* output stats vector */
80
double *in_knobs ; /* input knobs vector */
81
int i ; /* loop counter */
82
mxArray *Ainput ; /* input matrix handle */
83
int spumoni ; /* verbosity variable */
84
int stats [COLAMD_STATS] ; /* stats for colamd */
86
colamd_printf = mexPrintf ; /* COLAMD printf routine */
88
/* === Check inputs ===================================================== */
90
if (nrhs < 1 || nrhs > 2 || nlhs < 0 || nlhs > 2)
93
"colamd: incorrect number of input and/or output arguments") ;
96
/* === Get knobs ======================================================== */
98
colamd_set_defaults (knobs) ;
101
/* check for user-passed knobs */
104
in_knobs = mxGetPr (prhs [1]) ;
105
i = mxGetNumberOfElements (prhs [1]) ;
106
if (i > 0) knobs [COLAMD_DENSE_ROW] = in_knobs [0] ;
107
if (i > 1) knobs [COLAMD_DENSE_COL] = in_knobs [1] ;
108
if (i > 2) spumoni = (int) (in_knobs [2] != 0) ;
111
/* print knob settings if spumoni is set */
114
mexPrintf ("\ncolamd version %d.%d, %s:\n",
115
COLAMD_MAIN_VERSION, COLAMD_SUB_VERSION, COLAMD_DATE) ;
116
if (knobs [COLAMD_DENSE_ROW] >= 0)
118
mexPrintf ("knobs(1): %g, rows with > max(16,%g*sqrt(size(A,2)))"
119
" entries removed\n", in_knobs [0], knobs [COLAMD_DENSE_ROW]) ;
123
mexPrintf ("knobs(1): %g, only completely dense rows removed\n",
126
if (knobs [COLAMD_DENSE_COL] >= 0)
128
mexPrintf ("knobs(2): %g, cols with > max(16,%g*sqrt(min(size(A)))"
129
" entries removed\n", in_knobs [1], knobs [COLAMD_DENSE_COL]) ;
133
mexPrintf ("knobs(2): %g, only completely dense columns removed\n",
136
mexPrintf ("knobs(3): %g, statistics and knobs printed\n",
140
/* === If A is full, convert to a sparse matrix ========================= */
142
Ainput = (mxArray *) prhs [0] ;
143
if (mxGetNumberOfDimensions (Ainput) != 2)
145
mexErrMsgTxt ("colamd: input matrix must be 2-dimensional") ;
147
full = !mxIsSparse (Ainput) ;
150
mexCallMATLAB (1, &Ainput, 1, (mxArray **) prhs, "sparse") ;
153
/* === Allocate workspace for colamd ==================================== */
155
/* get size of matrix */
156
n_row = mxGetM (Ainput) ;
157
n_col = mxGetN (Ainput) ;
159
/* get column pointer vector so we can find nnz */
160
p = (int *) mxCalloc (n_col+1, sizeof (int)) ;
161
(void) memcpy (p, mxGetJc (Ainput), (n_col+1)*sizeof (int)) ;
163
Alen = (int) colamd_recommended (nnz, n_row, n_col) ;
166
mexErrMsgTxt ("colamd: problem too large") ;
169
/* === Copy input matrix into workspace ================================= */
171
A = (int *) mxCalloc (Alen, sizeof (int)) ;
172
(void) memcpy (A, mxGetIr (Ainput), nnz*sizeof (int)) ;
176
mxDestroyArray (Ainput) ;
179
/* === Order the columns (destroys A) =================================== */
181
if (!colamd (n_row, n_col, Alen, A, p, knobs, stats))
183
colamd_report (stats) ;
184
mexErrMsgTxt ("colamd error!") ;
188
/* === Return the permutation vector ==================================== */
190
plhs [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ;
191
out_perm = mxGetPr (plhs [0]) ;
192
for (i = 0 ; i < n_col ; i++)
194
/* colamd is 0-based, but MATLAB expects this to be 1-based */
195
out_perm [i] = p [i] + 1 ;
199
/* === Return the stats vector ========================================== */
201
/* print stats if spumoni is set */
204
colamd_report (stats) ;
209
plhs [1] = mxCreateDoubleMatrix (1, COLAMD_STATS, mxREAL) ;
210
out_stats = mxGetPr (plhs [1]) ;
211
for (i = 0 ; i < COLAMD_STATS ; i++)
213
out_stats [i] = stats [i] ;
216
/* fix stats (5) and (6), for 1-based information on jumbled matrix. */
217
/* note that this correction doesn't occur if symamd returns FALSE */
218
out_stats [COLAMD_INFO1] ++ ;
219
out_stats [COLAMD_INFO2] ++ ;