int cs_spsolve (cs *G, const cs *B, int k, int *xi, double *x, const int *pinv, int lo) { int j, J, p, q, px, top, n, *Gp, *Gi, *Bp, *Bi ; double *Gx, *Bx ; if (!CS_CSC (G) || !CS_CSC (B) || !xi || !x) return (-1) ; Gp = G->p ; Gi = G->i ; Gx = G->x ; n = G->n ; Bp = B->p ; Bi = B->i ; Bx = B->x ; top = cs_reach (G, B, k, xi, pinv) ; /* xi[top..n-1]=Reach(B(:,k)) */ for (p = top ; p < n ; p++) x [xi [p]] = 0 ; /* clear x */ for (p = Bp [k] ; p < Bp [k+1] ; p++) x [Bi [p]] = Bx [p] ; /* scatter B */ for (px = top ; px < n ; px++) { j = xi [px] ; /* x(j) is nonzero */ J = pinv ? (pinv [j]) : j ; /* j maps to col J of G */ if (J < 0) continue ; /* column J is empty */ x [j] /= Gx [lo ? (Gp [J]) : (Gp [J+1]-1)] ;/* x(j) /= G(j,j) */ p = lo ? (Gp [J]+1) : (Gp [J]) ; /* lo: L(j,j) 1st entry */ q = lo ? (Gp [J+1]) : (Gp [J+1]-1) ; /* up: U(j,j) last entry */ for ( ; p < q ; p++) { x [Gi [p]] -= Gx [p] * x [j] ; /* x(i) -= G(i,j) * x(j) */ } } return (top) ; /* return top of stack */ }
void mexFunction ( int nargout, mxArray *pargout [ ], int nargin, const mxArray *pargin [ ] ) { cs Lmatrix, Bmatrix, *L, *B ; double *x ; int k, i, j, top, *xi, *perm ; if (nargout > 1 || nargin != 2) { mexErrMsgTxt ("Usage: x = cs_reach(L,b)") ; } /* get inputs */ L = cs_mex_get_sparse (&Lmatrix, 1, 1, pargin [0]) ; B = cs_mex_get_sparse (&Bmatrix, 0, 1, pargin [1]) ; cs_mex_check (0, L->n, 1, 0, 1, 1, pargin [1]) ; perm = cs_malloc (L->n, sizeof (int)) ; for (k = 0 ; k < L->n ; k++) perm [k] = k ; xi = cs_calloc (3*L->n, sizeof (int)) ; top = cs_reach (L, B, 0, xi, perm) ; pargout [0] = mxCreateDoubleMatrix (L->n - top, 1, mxREAL) ; x = mxGetPr (pargout [0]) ; for (j = 0, i = top ; i < L->n ; i++, j++) x [j] = xi [i] ; cs_free (xi) ; cs_free (perm) ; }