csymamdmex.c
Go to the documentation of this file.
1 /* ========================================================================== */
2 /* === csymamd mexFunction ================================================== */
3 /* ========================================================================== */
4 
5 /* ----------------------------------------------------------------------------
6  * CCOLAMD, Copyright (C), Univ. of Florida. Authors: Timothy A. Davis,
7  * Sivasankaran Rajamanickam, and Stefan Larimore
8  * -------------------------------------------------------------------------- */
9 
10 /*
11  * Usage:
12  * p = csymamd (A) ;
13  * [p stats] = csymamd (A, knobs, cmember) ;
14  *
15  * See csymamd.m for a description.
16  */
17 
18 /* ========================================================================== */
19 /* === Include files ======================================================== */
20 /* ========================================================================== */
21 
22 #include "ccolamd.h"
23 #include "mex.h"
24 #include "matrix.h"
25 #include <stdlib.h>
26 #define Long SuiteSparse_long
27 
28 /* ========================================================================== */
29 /* === csymamd mexFunction ================================================== */
30 /* ========================================================================== */
31 
32 void mexFunction
33 (
34  /* === Parameters ======================================================= */
35 
36  int nargout,
37  mxArray *pargout [ ],
38  int nargin,
39  const mxArray *pargin [ ]
40 )
41 {
42  /* === Local variables ================================================== */
43 
44  Long *A ; /* row indices of input matrix A */
45  Long *perm ; /* column ordering of M and ordering of A */
46  Long *cmember ; /* csymamd's copy of the constraint set */
47  double *in_cmember ; /* input constraint set */
48  Long *p ; /* column pointers of input matrix A */
49  Long cslen ; /* size of constraint set */
50  Long n_col ; /* number of columns of A */
51  Long n_row ; /* number of rows of A */
52  Long full ; /* TRUE if input matrix full, FALSE if sparse */
53  double knobs [CCOLAMD_KNOBS] ; /* csymamd user-controllable parameters */
54  double *out_perm ; /* output permutation vector */
55  double *out_stats ; /* output stats vector */
56  double *in_knobs ; /* input knobs vector */
57  Long i ; /* loop counter */
58  mxArray *Ainput ; /* input matrix handle */
59  Long spumoni ; /* verbosity variable */
60  Long stats [CCOLAMD_STATS] ;/* stats for symamd */
61 
62  /* === Check inputs ===================================================== */
63 
64  if (nargin < 1 || nargin > 3 || nargout < 0 || nargout > 2)
65  {
66  mexErrMsgTxt ("Usage: [p stats] = csymamd (S, knobs, cmember)") ;
67  }
68 
69  /* === Get cmember ====================================================== */
70 
71  cmember = NULL ;
72  cslen = 0 ;
73  if (nargin > 2)
74  {
75  in_cmember = mxGetPr (pargin [2]) ;
76  cslen = mxGetNumberOfElements (pargin [2]) ;
77  if (cslen != 0)
78  {
79  cmember = (Long *) mxCalloc (cslen, sizeof (Long)) ;
80  for (i = 0 ; i < cslen ; i++)
81  {
82  /* convert cmember from 1-based to 0-based */
83  cmember[i] = ((Long) in_cmember [i] - 1) ;
84  }
85  }
86  }
87 
88  /* === Get knobs ======================================================== */
89 
90  ccolamd_l_set_defaults (knobs) ;
91  spumoni = 0 ;
92 
93  /* check for user-passed knobs */
94  i = 0 ;
95  if (nargin > 1)
96  {
97  in_knobs = mxGetPr (pargin [1]) ;
98  i = mxGetNumberOfElements (pargin [1]) ;
99  if (i > 0) knobs [CCOLAMD_DENSE_ROW] = in_knobs [0] ;
100  if (i > 1) knobs [CCOLAMD_AGGRESSIVE] = in_knobs [1] ;
101  if (i > 2) spumoni = (in_knobs [2] != 0) ;
102  }
103 
104  /* print knob settings if spumoni is set */
105  if (spumoni)
106  {
107  mexPrintf ("\ncsymamd version %d.%d, %s:\n",
109  if (knobs [CCOLAMD_DENSE_ROW] >= 0)
110  {
111  mexPrintf ("knobs(1): %g, rows/cols with > "
112  "max(16,%g*sqrt(size(A,2))) entries removed\n",
113  in_knobs [0], knobs [CCOLAMD_DENSE_ROW]) ;
114  }
115  else
116  {
117  mexPrintf ("knobs(1): %g, no dense rows removed\n",
118  in_knobs [0]) ;
119  }
120  mexPrintf ("knobs(2): %g, aggressive absorption: %s\n",
121  in_knobs [1], (knobs [CCOLAMD_AGGRESSIVE] != 0) ? "yes" : "no") ;
122  mexPrintf ("knobs(3): %g, statistics and knobs printed\n",
123  in_knobs [2]) ;
124  }
125 
126  /* === If A is full, convert to a sparse matrix ========================= */
127 
128  Ainput = (mxArray *) pargin [0] ;
129  if (mxGetNumberOfDimensions (Ainput) != 2)
130  {
131  mexErrMsgTxt ("csymamd: input matrix must be 2-dimensional.") ;
132  }
133  full = !mxIsSparse (Ainput) ;
134  if (full)
135  {
136  mexCallMATLAB (1, &Ainput, 1, (mxArray **) pargin, "sparse") ;
137  }
138 
139  /* === Allocate workspace for csymamd =================================== */
140 
141  /* get size of matrix */
142  n_row = mxGetM (Ainput) ;
143  n_col = mxGetN (Ainput) ;
144  if (n_col != n_row)
145  {
146  mexErrMsgTxt ("csymamd: matrix must be square.") ;
147  }
148 
149  if (cmember != NULL && cslen != n_col)
150  {
151  mexErrMsgTxt ("csymamd: cmember must be of length equal to #cols of A");
152  }
153 
154  A = (Long *) mxGetIr (Ainput) ;
155  p = (Long *) mxGetJc (Ainput) ;
156  perm = (Long *) mxCalloc (n_col+1, sizeof (Long)) ;
157 
158  /* === Order the rows and columns of A (does not destroy A) ============= */
159 
160  if (!csymamd_l (n_col, A, p, perm, knobs, stats, &mxCalloc, &mxFree,
161  cmember, -1))
162  {
163  csymamd_l_report (stats) ;
164  mexErrMsgTxt ("csymamd error!") ;
165  }
166 
167  if (full)
168  {
169  mxDestroyArray (Ainput) ;
170  }
171 
172  /* === Return the permutation vector ==================================== */
173 
174  pargout [0] = mxCreateDoubleMatrix (1, n_col, mxREAL) ;
175  out_perm = mxGetPr (pargout [0]) ;
176  for (i = 0 ; i < n_col ; i++)
177  {
178  /* symamd is 0-based, but MATLAB expects this to be 1-based */
179  out_perm [i] = perm [i] + 1 ;
180  }
181  mxFree (perm) ;
182  mxFree (cmember) ;
183 
184  /* === Return the stats vector ========================================== */
185 
186  /* print stats if spumoni is set */
187  if (spumoni)
188  {
189  csymamd_l_report (stats) ;
190  }
191 
192  if (nargout == 2)
193  {
194  pargout [1] = mxCreateDoubleMatrix (1, CCOLAMD_STATS, mxREAL) ;
195  out_stats = mxGetPr (pargout [1]) ;
196  for (i = 0 ; i < CCOLAMD_STATS ; i++)
197  {
198  out_stats [i] = stats [i] ;
199  }
200 
201  /* fix stats (5) and (6), for 1-based information on jumbled matrix. */
202  /* note that this correction doesn't occur if symamd returns FALSE */
203  out_stats [CCOLAMD_INFO1] ++ ;
204  out_stats [CCOLAMD_INFO2] ++ ;
205  }
206 }
#define CCOLAMD_SUB_VERSION
Definition: ccolamd.h:47
void ccolamd_l_set_defaults(double knobs [CCOLAMD_KNOBS])
#define CCOLAMD_INFO2
Definition: ccolamd.h:82
#define CCOLAMD_DENSE_ROW
Definition: ccolamd.h:63
#define CCOLAMD_MAIN_VERSION
Definition: ccolamd.h:46
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:48
bool stats
void mexFunction(int nargout, mxArray *pargout [], int nargin, const mxArray *pargin [])
Definition: csymamdmex.c:33
void csymamd_l_report(SuiteSparse_long stats [CCOLAMD_STATS])
#define Long
Definition: csymamdmex.c:26
#define CCOLAMD_DATE
Definition: ccolamd.h:44
idx_t idx_t idx_t idx_t idx_t * perm
#define NULL
Definition: ccolamd.c:609
#define CCOLAMD_AGGRESSIVE
Definition: ccolamd.h:69
SuiteSparse_long csymamd_l(SuiteSparse_long n, SuiteSparse_long A [], SuiteSparse_long p [], SuiteSparse_long perm [], double knobs [CCOLAMD_KNOBS], SuiteSparse_long stats [CCOLAMD_STATS], void *(*allocate)(size_t, size_t), void(*release)(void *), SuiteSparse_long cmember [], SuiteSparse_long stype)
float * p
#define CCOLAMD_KNOBS
Definition: ccolamd.h:57
#define CCOLAMD_STATS
Definition: ccolamd.h:60
#define CCOLAMD_INFO1
Definition: ccolamd.h:81


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:06