haskell-igraph-0.8.0: igraph/src/cs_spsolve.c
/*
* CXSPARSE: a Concise Sparse Matrix package - Extended.
* Copyright (c) 2006-2009, Timothy A. Davis.
* http://www.cise.ufl.edu/research/sparse/CXSparse
*
* CXSparse is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* CXSparse is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this Module; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "cs.h"
/* solve Gx=b(:,k), where G is either upper (lo=0) or lower (lo=1) triangular */
CS_INT cs_spsolve (cs *G, const cs *B, CS_INT k, CS_INT *xi, CS_ENTRY *x, const CS_INT *pinv,
CS_INT lo)
{
CS_INT j, J, p, q, px, top, n, *Gp, *Gi, *Bp, *Bi ;
CS_ENTRY *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 */
}