/* ========================================================================== */
/* === CHOLMOD/MATLAB/etree2 mexFunction ==================================== */
/* ========================================================================== */
/* -----------------------------------------------------------------------------
* CHOLMOD/MATLAB Module. Copyright (C) 2005-2006, Timothy A. Davis
* The CHOLMOD/MATLAB Module is licensed under Version 2.0 of the GNU
* General Public License. See gpl.txt for a text of the license.
* CHOLMOD is also available under other licenses; contact authors for details.
* http://www.cise.ufl.edu/research/sparse
* MATLAB(tm) is a Trademark of The MathWorks, Inc.
* -------------------------------------------------------------------------- */
/* Usage:
*
* parent = etree2 (A) returns etree of A, uses triu(A)
* parent = etree2 (A, 'col') returns etree of A'*A
* parent = etree2 (A, 'sym') same as etree2 (A)
* parent = etree2 (A, 'row') same as etree2 (A', 'col')
* parent = etree2 (A, 'lo') returns etree of A, uses tril(A)
*
* [parent post] = etree2(...) also returns a postorder of the tree
*
* etree2 (A, 'col') does not form A'*A and is thus faster than etree2 (A'*A)
* and takes less memory. Likewise, etree (A, 'row') does not
* form A*A', and is thus faster than etree2 (A*A') and takes less memory.
*/
#include "cholmod_matlab.h"
void mexFunction
(
int nargout,
mxArray *pargout [ ],
int nargin,
const mxArray *pargin [ ]
)
{
double dummy = 0 ;
int *Parent ;
cholmod_sparse *A, Amatrix, *S ;
cholmod_common Common, *cm ;
int n, coletree, c ;
char buf [LEN] ;
/* ---------------------------------------------------------------------- */
/* start CHOLMOD and set defaults */
/* ---------------------------------------------------------------------- */
cm = &Common ;
cholmod_start (cm) ;
sputil_config (SPUMONI, cm) ;
/* ---------------------------------------------------------------------- */
/* get inputs */
/* ---------------------------------------------------------------------- */
if (nargout > 2 || nargin < 1 || nargin > 2)
{
mexErrMsgTxt ("Usage: [parent post] = etree2 (A, mode)") ;
}
/* ---------------------------------------------------------------------- */
/* get input matrix A */
/* ---------------------------------------------------------------------- */
A = sputil_get_sparse_pattern (pargin [0], &Amatrix, &dummy, cm) ;
S = (A == &Amatrix) ? NULL : A ;
/* ---------------------------------------------------------------------- */
/* get A->stype, default is to use triu(A) */
/* ---------------------------------------------------------------------- */
A->stype = 1 ;
n = A->nrow ;
coletree = FALSE ;
if (nargin > 1)
{
buf [0] = '\0' ;
if (mxIsChar (pargin [1]))
{
mxGetString (pargin [1], buf, LEN) ;
}
c = buf [0] ;
if (tolower (c) == 'r')
{
/* unsymmetric case (A*A') if string starts with 'r' */
A->stype = 0 ;
}
else if (tolower (c) == 'c')
{
/* unsymmetric case (A'*A) if string starts with 'c' */
n = A->ncol ;
coletree = TRUE ;
A->stype = 0 ;
}
else if (tolower (c) == 's')
{
/* symmetric upper case (A) if string starts with 's' */
A->stype = 1 ;
}
else if (tolower (c) == 'l')
{
/* symmetric lower case (A) if string starts with 'l' */
A->stype = -1 ;
}
else
{
mexErrMsgTxt ("etree2: unrecognized mode") ;
}
}
if (A->stype && A->nrow != A->ncol)
{
mexErrMsgTxt ("etree2: A must be square") ;
}
/* ---------------------------------------------------------------------- */
/* compute the etree */
/* ---------------------------------------------------------------------- */
Parent = cholmod_malloc (n, sizeof (int), cm) ;
if (A->stype == 1 || coletree)
{
/* symmetric case: find etree of A, using triu(A) */
/* column case: find column etree of A, which is etree of A'*A */
cholmod_etree (A, Parent, cm) ;
}
else
{
/* symmetric case: find etree of A, using tril(A) */
/* row case: find row etree of A, which is etree of A*A' */
/* R = A' */
cholmod_sparse *R ;
R = cholmod_transpose (A, 0, cm) ;
cholmod_etree (R, Parent, cm) ;
cholmod_free_sparse (&R, cm) ;
}
if (cm->status < CHOLMOD_OK)
{
/* out of memory or matrix invalid */
mexErrMsgTxt ("etree2 failed: matrix corrupted!") ;
}
/* ---------------------------------------------------------------------- */
/* return Parent to MATLAB */
/* ---------------------------------------------------------------------- */
pargout [0] = sputil_put_int (Parent, n, 1) ;
/* ---------------------------------------------------------------------- */
/* postorder the tree and return results to MATLAB */
/* ---------------------------------------------------------------------- */
if (nargout > 1)
{
int *Post ;
Post = cholmod_malloc (n, sizeof (int), cm) ;
if (cholmod_postorder (Parent, n, NULL, Post, cm) != n)
{
/* out of memory or Parent invalid */
mexErrMsgTxt ("etree2 postorder failed!") ;
}
pargout [1] = sputil_put_int (Post, n, 1) ;
cholmod_free (n, sizeof (int), Post, cm) ;
}
/* ---------------------------------------------------------------------- */
/* free workspace */
/* ---------------------------------------------------------------------- */
cholmod_free (n, sizeof (int), Parent, cm) ;
cholmod_free_sparse (&S, cm) ;
cholmod_finish (cm) ;
cholmod_print_common (" ", cm) ;
/* if (cm->malloc_count != 0) mexErrMsgTxt ("!") ; */
}
syntax highlighted by Code2HTML, v. 0.9.1