#include "sparseinv.h" /* Z = sparseinv_mex (L, d, UT, Zpattern) Given (L+I)*D*(UT+I)' = A, and the symbolic Cholesky factorization of A+A', compute the sparse inverse subset, Z. UT is stored by column, so U = UT' is implicitly stored by row, and is implicitly unit-diagonal. The diagonal is not present. L is stored by column, and is also unit-diagonal. The diagonal is not present in L, either. d is a full vector of size n. This mexFunction is only meant to be called from the sparsinv m-file. An optional 2nd output argument returns the flop count. Copyright 2011, Timothy A. Davis, http://www.suitesparse.com */ void mexFunction ( int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin [ ] ) { Int *Zp, *Zi, *Lp, *Li, *Up, *Uj, *Zpatp, *Zpati, n, *Zdiagp, *Lmunch, znz, j, p, flops ; double *Zx, *Lx, *Ux, *z, *d ; /* check inputs */ if (nargin != 4 || nargout > 2) { mexErrMsgTxt ("Usage: [Z flops] = sparseinv_mex (L, d, UT, Zpattern)") ; } n = mxGetN (pargin [0]) ; for (j = 0 ; j < 4 ; j++) { if (j == 1) continue ; if (!mxIsSparse (pargin [j]) || mxIsComplex (pargin [j]) || (mxGetM (pargin [j]) != n) || (mxGetN (pargin [j]) != n)) { mexErrMsgTxt ("Matrices must be sparse, real, square, & same size"); } } if (mxIsSparse (pargin [1]) || mxIsComplex (pargin [1]) || (mxGetM (pargin [1]) != n) || (mxGetN (pargin [1]) != 1)) { mexErrMsgTxt ("Input d must be a real dense vector of right size") ; } /* get inputs */ Lp = (Int *) mxGetJc (pargin [0]) ; Li = (Int *) mxGetIr (pargin [0]) ; Lx = mxGetPr (pargin [0]) ; d = mxGetPr (pargin [1]) ; Up = (Int *) mxGetJc (pargin [2]) ; Uj = (Int *) mxGetIr (pargin [2]) ; Ux = mxGetPr (pargin [2]) ; Zpatp = (Int *) mxGetJc (pargin [3]) ; Zpati = (Int *) mxGetIr (pargin [3]) ; znz = Zpatp [n] ; /* create output */ pargout [0] = mxCreateSparse (n, n, znz, mxREAL) ; Zx = mxGetPr (pargout [0]) ; /* get workspace */ z = mxCalloc (n, sizeof (double)) ; Zdiagp = mxMalloc (n * sizeof (Int)) ; Lmunch = mxMalloc (n * sizeof (Int)) ; /* do the work */ flops = sparseinv (n, Lp, Li, Lx, d, Up, Uj, Ux, Zpatp, Zpati, Zx, z, Zdiagp, Lmunch) ; /* free workspace */ mxFree (z) ; mxFree (Zdiagp) ; mxFree (Lmunch) ; /* return results to MATLAB */ Zp = (Int *) mxGetJc (pargout [0]) ; Zi = (Int *) mxGetIr (pargout [0]) ; for (j = 0 ; j <= n ; j++) { Zp [j] = Zpatp [j] ; } for (p = 0 ; p < znz ; p++) { Zi [p] = Zpati [p] ; } /* drop explicit zeros from the output Z matrix */ znz = 0 ; for (j = 0 ; j < n ; j++) { p = Zp [j] ; /* get current location of col j */ Zp [j] = znz ; /* record new location of col j */ for ( ; p < Zp [j+1] ; p++) { if (Zx [p] != 0) { Zx [znz] = Zx [p] ; /* keep Z(i,j) */ Zi [znz++] = Zi [p] ; } } } Zp [n] = znz ; /* finalize Z */ if (nargout > 1) { pargout [1] = mxCreateDoubleScalar ((double) flops) ; } }