1 #include "cs.h"
2 /* solve Gx=b(:,k), where G is either upper (lo=0) or lower (lo=1) triangular */
cs_spsolve(cs * G,const cs * B,CS_INT k,CS_INT * xi,CS_ENTRY * x,const CS_INT * pinv,CS_INT lo)3 CS_INT cs_spsolve (cs *G, const cs *B, CS_INT k, CS_INT *xi, CS_ENTRY *x, const CS_INT *pinv,
4     CS_INT lo)
5 {
6     CS_INT j, J, p, q, px, top, n, *Gp, *Gi, *Bp, *Bi ;
7     CS_ENTRY *Gx, *Bx ;
8     if (!CS_CSC (G) || !CS_CSC (B) || !xi || !x) return (-1) ;
9     Gp = G->p ; Gi = G->i ; Gx = G->x ; n = G->n ;
10     Bp = B->p ; Bi = B->i ; Bx = B->x ;
11     top = cs_reach (G, B, k, xi, pinv) ;        /* xi[top..n-1]=Reach(B(:,k)) */
12     for (p = top ; p < n ; p++) x [xi [p]] = 0 ;    /* clear x */
13     for (p = Bp [k] ; p < Bp [k+1] ; p++) x [Bi [p]] = Bx [p] ; /* scatter B */
14     for (px = top ; px < n ; px++)
15     {
16         j = xi [px] ;                               /* x(j) is nonzero */
17         J = pinv ? (pinv [j]) : j ;                 /* j maps to col J of G */
18         if (J < 0) continue ;                       /* column J is empty */
19         x [j] /= Gx [lo ? (Gp [J]) : (Gp [J+1]-1)] ;/* x(j) /= G(j,j) */
20         p = lo ? (Gp [J]+1) : (Gp [J]) ;            /* lo: L(j,j) 1st entry */
21         q = lo ? (Gp [J+1]) : (Gp [J+1]-1) ;        /* up: U(j,j) last entry */
22         for ( ; p < q ; p++)
23         {
24             x [Gi [p]] -= Gx [p] * x [j] ;          /* x(i) -= G(i,j) * x(j) */
25         }
26     }
27     return (top) ;                                  /* return top of stack */
28 }
29