/* ========================================================================== */
/* === klus mexFunction ===================================================== */
/* ========================================================================== */
/* Solve Ax=b using KLU, with ordering provided by CHOLMOD
*
* [x, Info] = klus (A, b) order A+A' for each block
* [x, Info] = klus (A, b, 0) order A'A for each block
*
* b may be n-by-m with m > 1. It must be dense.
*/
/* ========================================================================== */
#include "klu.h"
#include "klu_cholmod.h"
#include "mex.h"
void mexFunction
(
int nargout,
mxArray *pargout [ ],
int nargin,
const mxArray *pargin [ ]
)
{
double condest ;
double *Ax, *Info, *B, *X ;
int n, *Ap, *Ai, k, nrhs, result, symmetric ;
klu_symbolic *Symbolic ;
klu_numeric *Numeric ;
klu_common Common ;
/* ---------------------------------------------------------------------- */
/* get inputs */
/* ---------------------------------------------------------------------- */
if (nargin < 2 || nargin > 3 || nargout > 2)
{
mexErrMsgTxt ("Usage: [x, Info] = klus (A, b, options)") ;
}
/* get sparse matrix A */
n = mxGetN (pargin [0]) ;
if (!mxIsSparse (pargin [0]) || n != mxGetM (pargin [0]) ||
mxIsComplex (pargin [0]) || n == 0)
{
mexErrMsgTxt ("klus: A must be sparse, square, real, and non-empty") ;
}
Ap = mxGetJc (pargin [0]) ;
Ai = mxGetIr (pargin [0]) ;
Ax = mxGetPr (pargin [0]) ;
/* get dense vector B */
B = mxGetPr (pargin [1]) ;
nrhs = mxGetN (pargin [1]) ;
if (mxIsSparse (pargin [1]) || n != mxGetM (pargin [1]) ||
mxIsComplex (pargin [1]) || nrhs == 0)
{
mexErrMsgTxt (
"klus: B must be dense, real, non-empty, and correct dimensions") ;
}
/* get options */
symmetric = (nargin == 2) || (mxGetScalar (pargin [2])) ;
/* get control parameters */
klu_defaults (&Common) ;
Common.ordering = 3 ;
Common.user_order = klu_cholmod ;
Common.user_data = &symmetric ;
/* hack
Common.btf = 0 ; printf ("btf off\n") ;
*/
/* allocate Info output */
pargout [1] = mxCreateDoubleMatrix (1, 3, mxREAL) ;
Info = mxGetPr (pargout [1]) ;
for (k = 0 ; k < 3 ; k++) Info [k] = -1 ;
/* ---------------------------------------------------------------------- */
/* analyze */
/* ---------------------------------------------------------------------- */
Symbolic = klu_analyze (n, Ap, Ai, &Common) ;
if (Symbolic == (klu_symbolic *) NULL)
{
mexErrMsgTxt ("klu_analyze failed") ;
}
Info [0] = Symbolic->nblocks ;
Info [1] = Symbolic->maxblock ;
/* ---------------------------------------------------------------------- */
/* factorize */
/* ---------------------------------------------------------------------- */
Numeric = klu_factor (Ap, Ai, Ax, Symbolic, &Common) ;
if (Common.status == KLU_SINGULAR)
{
printf("# singular column : %d\n", Common.singular_col) ;
}
if (Common.status != KLU_OK)
{
mexErrMsgTxt ("klu_factor failed") ;
}
/* nz in L, U, and off-diagonal blocks */
Info [2] = Numeric->lnz + Numeric->unz + n + Common.noffdiag ;
klu_condest (Ap, Ax, Symbolic, Numeric, &condest, &Common) ;
printf ("cond est %g\n", condest) ;
/* ---------------------------------------------------------------------- */
/* allocate outputs and set X=B */
/* ---------------------------------------------------------------------- */
pargout [0] = mxCreateDoubleMatrix (n, nrhs, mxREAL) ;
X = mxGetPr (pargout [0]) ;
for (k = 0 ; k < n*nrhs ; k++) X [k] = B [k] ;
/* ---------------------------------------------------------------------- */
/* solve (overwrites right-hand-side with solution) */
/* ---------------------------------------------------------------------- */
result = klu_solve (Symbolic, Numeric, n, nrhs, X, &Common) ;
/* ---------------------------------------------------------------------- */
/* free Symbolic and Numeric objects, and free workspace */
/* ---------------------------------------------------------------------- */
result = klu_free_symbolic (&Symbolic, &Common) ;
result = klu_free_numeric (&Numeric, &Common) ;
}
syntax highlighted by Code2HTML, v. 0.9.1