1 /* ========================================================================== */
2 /* === CHOLMOD/MATLAB/analyze mexFunction =================================== */
3 /* ========================================================================== */
4
5 /* -----------------------------------------------------------------------------
6 * CHOLMOD/MATLAB Module. Copyright (C) 2005-2006, Timothy A. Davis
7 * http://www.suitesparse.com
8 * MATLAB(tm) is a Trademark of The MathWorks, Inc.
9 * -------------------------------------------------------------------------- */
10
11 /* Order a matrix and then analyze it, using CHOLMOD's best-effort ordering.
12 * Returns the count of the number of nonzeros in each column of L for the
13 * permuted matrix A.
14 *
15 * Usage:
16 *
17 * [p count] = analyze (A) orders A, using just tril(A)
18 * [p count] = analyze (A,'sym') orders A, using just tril(A)
19 * [p count] = analyze (A,'row') orders A*A'
20 * [p count] = analyze (A,'col') orders A'*A
21 *
22 * with an optional 3rd parameter:
23 *
24 * [p count] = analyze (A,'sym',k) orders A, using just tril(A)
25 * [p count] = analyze (A,'row',k) orders A*A'
26 * [p count] = analyze (A,'col',k) orders A'*A
27 *
28 * k=0 is the default. k != 0 selects the ordering strategy.
29 *
30 * See analyze.m for more details.
31 */
32
33 #include "cholmod_matlab.h"
34
mexFunction(int nargout,mxArray * pargout[],int nargin,const mxArray * pargin[])35 void mexFunction
36 (
37 int nargout,
38 mxArray *pargout [ ],
39 int nargin,
40 const mxArray *pargin [ ]
41 )
42 {
43 double dummy = 0 ;
44 cholmod_factor *L ;
45 cholmod_sparse *A, Amatrix, *C, *S ;
46 cholmod_common Common, *cm ;
47 Long n, transpose, c ;
48 char buf [LEN] ;
49
50 /* ---------------------------------------------------------------------- */
51 /* start CHOLMOD and set defaults */
52 /* ---------------------------------------------------------------------- */
53
54 cm = &Common ;
55 cholmod_l_start (cm) ;
56 sputil_config (SPUMONI, cm) ;
57
58 /* only do the simplicial analysis (L->Perm and L->ColCount) */
59 cm->supernodal = CHOLMOD_SIMPLICIAL ;
60
61 /* ---------------------------------------------------------------------- */
62 /* get inputs */
63 /* ---------------------------------------------------------------------- */
64
65 if (nargout > 2 || nargin < 1 || nargin > 3)
66 {
67 mexErrMsgTxt ("Usage: [p count] = analyze (A, mode)") ;
68 }
69 if (nargin == 3)
70 {
71 cm->nmethods = mxGetScalar (pargin [2]) ;
72 if (cm->nmethods == -1)
73 {
74 /* use AMD only */
75 cm->nmethods = 1 ;
76 cm->method [0].ordering = CHOLMOD_AMD ;
77 cm->postorder = TRUE ;
78 }
79 else if (cm->nmethods == -2)
80 {
81 /* use METIS only */
82 cm->nmethods = 1 ;
83 cm->method [0].ordering = CHOLMOD_METIS ;
84 cm->postorder = TRUE ;
85 }
86 else if (cm->nmethods == -3)
87 {
88 /* use NESDIS only */
89 cm->nmethods = 1 ;
90 cm->method [0].ordering = CHOLMOD_NESDIS ;
91 cm->postorder = TRUE ;
92 }
93 }
94
95 /* ---------------------------------------------------------------------- */
96 /* get input matrix A */
97 /* ---------------------------------------------------------------------- */
98
99 A = sputil_get_sparse_pattern (pargin [0], &Amatrix, &dummy, cm) ;
100 S = (A == &Amatrix) ? NULL : A ;
101
102 /* ---------------------------------------------------------------------- */
103 /* get A->stype, default is to use tril(A) */
104 /* ---------------------------------------------------------------------- */
105
106 A->stype = -1 ;
107 transpose = FALSE ;
108
109 if (nargin > 1)
110 {
111 buf [0] = '\0' ;
112 if (mxIsChar (pargin [1]))
113 {
114 mxGetString (pargin [1], buf, LEN) ;
115 }
116 c = buf [0] ;
117 if (tolower (c) == 'r')
118 {
119 /* unsymmetric case (A*A') if string starts with 'r' */
120 transpose = FALSE ;
121 A->stype = 0 ;
122 }
123 else if (tolower (c) == 'c')
124 {
125 /* unsymmetric case (A'*A) if string starts with 'c' */
126 transpose = TRUE ;
127 A->stype = 0 ;
128 }
129 else if (tolower (c) == 's')
130 {
131 /* symmetric case (A) if string starts with 's' */
132 transpose = FALSE ;
133 A->stype = -1 ;
134 }
135 else
136 {
137 mexErrMsgTxt ("analyze: unrecognized mode") ;
138 }
139 }
140
141 if (A->stype && A->nrow != A->ncol)
142 {
143 mexErrMsgTxt ("analyze: A must be square") ;
144 }
145
146 C = NULL ;
147 if (transpose)
148 {
149 /* C = A', and then order C*C' */
150 C = cholmod_l_transpose (A, 0, cm) ;
151 if (C == NULL)
152 {
153 mexErrMsgTxt ("analyze failed") ;
154 }
155 A = C ;
156 }
157
158 n = A->nrow ;
159
160 /* ---------------------------------------------------------------------- */
161 /* analyze and order the matrix */
162 /* ---------------------------------------------------------------------- */
163
164 L = cholmod_l_analyze (A, cm) ;
165
166 /* ---------------------------------------------------------------------- */
167 /* return Perm */
168 /* ---------------------------------------------------------------------- */
169
170 pargout [0] = sputil_put_int (L->Perm, n, 1) ;
171 if (nargout > 1)
172 {
173 pargout [1] = sputil_put_int (L->ColCount, n, 0) ;
174 }
175
176 /* ---------------------------------------------------------------------- */
177 /* free workspace */
178 /* ---------------------------------------------------------------------- */
179
180 cholmod_l_free_factor (&L, cm) ;
181 cholmod_l_free_sparse (&C, cm) ;
182 cholmod_l_free_sparse (&S, cm) ;
183 cholmod_l_finish (cm) ;
184 cholmod_l_print_common (" ", cm) ;
185 /* if (cm->malloc_count != 0) mexErrMsgTxt ("!") ; */
186 }
187