/* ========================================================================== */
/* === klu_cholmod ========================================================== */
/* ========================================================================== */
/* klu_cholmod: user-defined ordering function to interface KLU to CHOLMOD.
*
* This routine is an example of a user-provided ordering function for KLU.
* Its return value is klu_cholmod's estimate of max (nnz(L),nnz(U)):
* 0 if error,
* -1 if OK, but estimate of max (nnz(L),nnz(U)) not computed
* > 0 if OK and estimate computed.
*
* This function can be assigned to KLU's Common->user_order function pointer.
*/
#include "klu_cholmod.h"
#include "cholmod.h"
#define TRUE 1
#define FALSE 0
int klu_cholmod
(
/* inputs */
int n, /* A is n-by-n */
int Ap [ ], /* column pointers */
int Ai [ ], /* row indices */
/* outputs */
int Perm [ ], /* fill-reducing permutation */
/* user-defined */
void *user_datap /* this is KLU's Common->user_data, unchanged.
* You may use this to pass additional parameters
* to your ordering routine. KLU does not access
* Common->user_data, except to pass it here. */
)
{
double one [2] = {1,0}, zero [2] = {0,0} ;
cholmod_sparse *A, *AT, *S ;
cholmod_factor *L ;
cholmod_common *cm, Common ;
int *P, *user_data ;
int k, symmetric ;
/* start CHOLMOD */
cm = &Common ;
cholmod_start (cm) ;
cm->supernodal = CHOLMOD_SIMPLICIAL ;
/* cm->print = 5 ; */
/* construct a CHOLMOD version of the input matrix A */
A = cholmod_malloc (1, sizeof (cholmod_sparse), cm) ;
if (A == NULL)
{
/* out of memory */
return (0) ;
}
A->nrow = n ; /* A is n-by-n */
A->ncol = n ;
A->nzmax = Ap [n] ; /* with nzmax entries */
A->packed = TRUE ; /* there is no A->nz array */
A->stype = 0 ; /* A is unsymmetric */
A->itype = CHOLMOD_INT ;
A->xtype = CHOLMOD_PATTERN ;
A->dtype = CHOLMOD_DOUBLE ;
A->nz = NULL ;
A->p = Ap ; /* column pointers */
A->i = Ai ; /* row indices */
A->x = NULL ; /* no numerical values */
A->z = NULL ;
A->sorted = FALSE ; /* columns of A are not sorted */
/* cholmod_print_sparse (A, "A for user order", cm) ; */
/* get the user_data */
user_data = user_datap ;
symmetric = (user_data == NULL) ? TRUE : (user_data [0] != 0) ;
/* AT = pattern of A' */
AT = cholmod_transpose (A, 0, cm) ;
if (symmetric)
{
/* S = the symmetric pattern of A+A' */
S = cholmod_add (A, AT, one, zero, FALSE, FALSE, cm) ;
cholmod_free_sparse (&AT, cm) ;
}
else
{
/* S = A'. CHOLMOD will order S*S', which is A'*A */
S = AT ;
}
/* free the header for A, but not Ap and Ai */
A->p = NULL ;
A->i = NULL ;
cholmod_free_sparse (&A, cm) ;
if (S == NULL)
{
/* out of memory */
return (0) ;
}
if (symmetric)
{
S->stype = 1 ;
}
/* cholmod_print_sparse (S, "S", cm) ; */
cm->nmethods = 10 ;
/*
cm->nmethods = 1 ;
cm->method [0].ordering = CHOLMOD_AMD ;
cm->method [0].ordering = CHOLMOD_METIS ;
cm->method [0].ordering = CHOLMOD_NESDIS ;
*/
/* order and analyze S or S*S' */
L = cholmod_analyze (S, cm) ;
if (L == NULL)
{
return (0) ;
}
/*
printf ("L->ordering %d\n", L->ordering) ;
*/
/* cholmod_print_factor (L, "L, symbolic analysis only", cm) ; */
/* copy the permutation from L to the output */
P = L->Perm ;
for (k = 0 ; k < n ; k++)
{
Perm [k] = P [k] ;
}
/* cholmod_print_perm (Perm, n, n, "Final permutation", cm) ; */
cholmod_free_sparse (&S, cm) ;
cholmod_free_factor (&L, cm) ;
cholmod_finish (cm) ;
/*
if (n > 100) cholmod_print_common ("Final statistics", cm) ;
if (cm->malloc_count != 0) printf ("CHOLMOD memory leak!") ;
*/
return ((int) (cm->lnz)) ;
}
syntax highlighted by Code2HTML, v. 0.9.1