kusano 7d535a
/*
kusano 7d535a
 * -- SuperLU routine (version 3.0) --
kusano 7d535a
 * Univ. of California Berkeley, Xerox Palo Alto Research Center,
kusano 7d535a
 * and Lawrence Berkeley National Lab.
kusano 7d535a
 * October 15, 2003
kusano 7d535a
 *
kusano 7d535a
 */
kusano 7d535a
#include <stdio.h></stdio.h>
kusano 7d535a
#include "mex.h"
kusano 7d535a
#include "slu_ddefs.h"
kusano 7d535a
kusano 7d535a
#ifdef V5
kusano 7d535a
#define  MatlabMatrix mxArray
kusano 7d535a
#else    /* V4 */
kusano 7d535a
#define  MatlabMatrix Matrix
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
kusano 7d535a
/* Aliases for input and output arguments */
kusano 7d535a
#define A_in		prhs[0]
kusano 7d535a
#define b_in    	prhs[1]
kusano 7d535a
#define Pc_in		prhs[2]
kusano 7d535a
#define x_out		plhs[0]
kusano 7d535a
kusano 7d535a
#define verbose (SPUMONI>0)
kusano 7d535a
#define babble  (SPUMONI>1)
kusano 7d535a
#define burble  (SPUMONI>2)
kusano 7d535a
kusano 7d535a
void mexFunction(
kusano 7d535a
    int          nlhs,           /* number of expected outputs */
kusano 7d535a
    MatlabMatrix *plhs[],        /* matrix pointer array returning outputs */
kusano 7d535a
    int          nrhs,           /* number of inputs */
kusano 7d535a
#ifdef V5
kusano 7d535a
    const MatlabMatrix *prhs[]   /* matrix pointer array for inputs. */
kusano 7d535a
#else /* V4 */
kusano 7d535a
    MatlabMatrix *prhs[]         /* matrix pointer array for inputs */
kusano 7d535a
#endif
kusano 7d535a
    )
kusano 7d535a
{
kusano 7d535a
    int SPUMONI;             /* ... as should the sparse monitor flag */
kusano 7d535a
#ifdef V5
kusano 7d535a
    double FlopsInSuperLU;   /* ... as should the flop counter. */
kusano 7d535a
#else /* V4 */
kusano 7d535a
    Real FlopsInSuperLU;     /* ... as should the flop counter */
kusano 7d535a
#endif
kusano 7d535a
    extern flops_t LUFactFlops(SuperLUStat_t*);
kusano 7d535a
    extern flops_t LUSolveFlops(SuperLUStat_t*);
kusano 7d535a
    
kusano 7d535a
    /* Arguments to dgssv(). */
kusano 7d535a
    SuperMatrix A;
kusano 7d535a
    SuperMatrix B;
kusano 7d535a
    SuperMatrix L, U;
kusano 7d535a
    int	   	m, n, nnz;
kusano 7d535a
    int         numrhs;
kusano 7d535a
    double 	*vb, *x;
kusano 7d535a
    double      *val;
kusano 7d535a
    int       	*rowind;
kusano 7d535a
    int		*colptr;
kusano 7d535a
    int    	*perm_r, *perm_c;
kusano 7d535a
    int		info;
kusano 7d535a
    MatlabMatrix *X, *Y;            /* args to calls back to Matlab */
kusano 7d535a
    int         i, mexerr;
kusano 7d535a
    superlu_options_t options;
kusano 7d535a
    SuperLUStat_t stat;
kusano 7d535a
kusano 7d535a
    /* Check number of arguments passed from Matlab. */
kusano 7d535a
    if (nrhs != 3) {
kusano 7d535a
	mexErrMsgTxt("LUSOLVE requires 3 input arguments.");
kusano 7d535a
    } else if (nlhs != 1) {
kusano 7d535a
      	mexErrMsgTxt("LUSOLVE requires 1 output argument.");
kusano 7d535a
    }   
kusano 7d535a
kusano 7d535a
    /* Read the Sparse Monitor Flag */
kusano 7d535a
    X = mxCreateString("spumoni");
kusano 7d535a
    mexerr = mexCallMATLAB(1, &Y, 1, &X, "sparsfun");
kusano 7d535a
    SPUMONI = mxGetScalar(Y);
kusano 7d535a
#ifdef V5
kusano 7d535a
    mxDestroyArray(Y);
kusano 7d535a
    mxDestroyArray(X);
kusano 7d535a
#else
kusano 7d535a
    mxFreeMatrix(Y);
kusano 7d535a
    mxFreeMatrix(X);
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
    m = mxGetM(A_in);
kusano 7d535a
    n = mxGetN(A_in);
kusano 7d535a
    numrhs = mxGetN(b_in);
kusano 7d535a
    if ( babble ) printf("m=%d, n=%d, numrhs=%d\n", m, n, numrhs);
kusano 7d535a
    vb = mxGetPr(b_in);
kusano 7d535a
#ifdef V5
kusano 7d535a
    x_out = mxCreateDoubleMatrix(m, numrhs, mxREAL);
kusano 7d535a
#else
kusano 7d535a
    x_out = mxCreateFull(m, numrhs, REAL);
kusano 7d535a
#endif
kusano 7d535a
    x = mxGetPr(x_out);
kusano 7d535a
    perm_r = (int *) mxCalloc(m, sizeof(int));
kusano 7d535a
    perm_c = mxGetIr(Pc_in); 
kusano 7d535a
kusano 7d535a
    val = mxGetPr(A_in);
kusano 7d535a
    rowind = mxGetIr(A_in);
kusano 7d535a
    colptr = mxGetJc(A_in);
kusano 7d535a
    nnz = colptr[n];
kusano 7d535a
    dCreate_CompCol_Matrix(&A, m, n, nnz, val, rowind, colptr,
kusano 7d535a
			   SLU_NC, SLU_D, SLU_GE);
kusano 7d535a
    dCopy_Dense_Matrix(m, numrhs, vb, m, x, m);
kusano 7d535a
    dCreate_Dense_Matrix(&B, m, numrhs, x, m, SLU_DN, SLU_D, SLU_GE);
kusano 7d535a
kusano 7d535a
    FlopsInSuperLU = 0;
kusano 7d535a
kusano 7d535a
    set_default_options(&options);
kusano 7d535a
    options.ColPerm = MY_PERMC;
kusano 7d535a
    StatInit(&stat);
kusano 7d535a
kusano 7d535a
    /* Call simple driver */
kusano 7d535a
    if ( verbose )
kusano 7d535a
      mexPrintf("Call LUSOLVE, use SUPERLU to factor first ...\n");
kusano 7d535a
    dgssv(&options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info);
kusano 7d535a
kusano 7d535a
#if 0 /* FLOPS is not available in the new Matlab. */
kusano 7d535a
    /* Tell Matlab how many flops we did. */
kusano 7d535a
    FlopsInSuperLU += LUFactFlops(&stat) + LUSolveFlops(&stat);
kusano 7d535a
    if ( verbose ) mexPrintf("LUSOLVE flops: %.f\n", FlopsInSuperLU);
kusano 7d535a
    mexerr = mexCallMATLAB(1, &X, 0, NULL, "flops");
kusano 7d535a
    *(mxGetPr(X)) += FlopsInSuperLU;
kusano 7d535a
    mexerr = mexCallMATLAB(1, &Y, 1, &X, "flops");
kusano 7d535a
#ifdef V5
kusano 7d535a
    mxDestroyArray(Y);
kusano 7d535a
    mxDestroyArray(X);
kusano 7d535a
#else
kusano 7d535a
    mxFreeMatrix(Y);
kusano 7d535a
    mxFreeMatrix(X);
kusano 7d535a
#endif
kusano 7d535a
#endif
kusano 7d535a
kusano 7d535a
    /* Construct Matlab solution matrix. */
kusano 7d535a
    if ( !info ) {
kusano 7d535a
        Destroy_SuperNode_Matrix(&L);
kusano 7d535a
        Destroy_CompCol_Matrix(&U);
kusano 7d535a
        if ( babble ) printf("Destroy L & U from SuperLU...\n");
kusano 7d535a
    } else {
kusano 7d535a
	mexErrMsgTxt("Error returned from C dgssv().");
kusano 7d535a
    }
kusano 7d535a
kusano 7d535a
    mxFree(perm_r);
kusano 7d535a
    StatFree(&stat);
kusano 7d535a
kusano 7d535a
    return;
kusano 7d535a
 
kusano 7d535a
}