EVSL  1.1.0 EigenValues Slicing Library
cs_lu.c
Go to the documentation of this file.
1 #include "cs.h"
2 /* [L,U,pinv]=lu(A, [q lnz unz]). lnz and unz can be guess */
3 csn *cs_lu (const cs *A, const css *S, double tol)
4 {
5  cs *L, *U ;
6  csn *N ;
7  CS_ENTRY pivot, *Lx, *Ux, *x ;
8  double a, t ;
9  CS_INT *Lp, *Li, *Up, *Ui, *pinv, *xi, *q, n, ipiv, k, top, p, i, col, lnz,unz;
10  if (!CS_CSC (A) || !S) return (NULL) ; /* check inputs */
11  n = A->n ;
12  q = S->q ; lnz = S->lnz ; unz = S->unz ;
13  x = cs_malloc (n, sizeof (CS_ENTRY)) ; /* get CS_ENTRY workspace */
14  xi = cs_malloc (2*n, sizeof (CS_INT)) ; /* get CS_INT workspace */
15  N = cs_calloc (1, sizeof (csn)) ; /* allocate result */
16  if (!x || !xi || !N) return (cs_ndone (N, NULL, xi, x, 0)) ;
17  N->L = L = cs_spalloc (n, n, lnz, 1, 0) ; /* allocate result L */
18  N->U = U = cs_spalloc (n, n, unz, 1, 0) ; /* allocate result U */
19  N->pinv = pinv = cs_malloc (n, sizeof (CS_INT)) ; /* allocate result pinv */
20  if (!L || !U || !pinv) return (cs_ndone (N, NULL, xi, x, 0)) ;
21  Lp = L->p ; Up = U->p ;
22  for (i = 0 ; i < n ; i++) x [i] = 0 ; /* clear workspace */
23  for (i = 0 ; i < n ; i++) pinv [i] = -1 ; /* no rows pivotal yet */
24  for (k = 0 ; k <= n ; k++) Lp [k] = 0 ; /* no cols of L yet */
25  lnz = unz = 0 ;
26  for (k = 0 ; k < n ; k++) /* compute L(:,k) and U(:,k) */
27  {
28  /* --- Triangular solve --------------------------------------------- */
29  Lp [k] = lnz ; /* L(:,k) starts here */
30  Up [k] = unz ; /* U(:,k) starts here */
31  if ((lnz + n > L->nzmax && !cs_sprealloc (L, 2*L->nzmax + n)) ||
32  (unz + n > U->nzmax && !cs_sprealloc (U, 2*U->nzmax + n)))
33  {
34  return (cs_ndone (N, NULL, xi, x, 0)) ;
35  }
36  Li = L->i ; Lx = L->x ; Ui = U->i ; Ux = U->x ;
37  col = q ? (q [k]) : k ;
38  top = cs_spsolve (L, A, col, xi, x, pinv, 1) ; /* x = L\A(:,col) */
39  /* --- Find pivot --------------------------------------------------- */
40  ipiv = -1 ;
41  a = -1 ;
42  for (p = top ; p < n ; p++)
43  {
44  i = xi [p] ; /* x(i) is nonzero */
45  if (pinv [i] < 0) /* row i is not yet pivotal */
46  {
47  if ((t = CS_ABS (x [i])) > a)
48  {
49  a = t ; /* largest pivot candidate so far */
50  ipiv = i ;
51  }
52  }
53  else /* x(i) is the entry U(pinv[i],k) */
54  {
55  Ui [unz] = pinv [i] ;
56  Ux [unz++] = x [i] ;
57  }
58  }
59  if (ipiv == -1 || a <= 0) return (cs_ndone (N, NULL, xi, x, 0)) ;
60  if (pinv [col] < 0 && CS_ABS (x [col]) >= a*tol) ipiv = col ;
61  /* --- Divide by pivot ---------------------------------------------- */
62  pivot = x [ipiv] ; /* the chosen pivot */
63  Ui [unz] = k ; /* last entry in U(:,k) is U(k,k) */
64  Ux [unz++] = pivot ;
65  pinv [ipiv] = k ; /* ipiv is the kth pivot row */
66  Li [lnz] = ipiv ; /* first entry in L(:,k) is L(k,k) = 1 */
67  Lx [lnz++] = 1 ;
68  for (p = top ; p < n ; p++) /* L(k+1:n,k) = x / pivot */
69  {
70  i = xi [p] ;
71  if (pinv [i] < 0) /* x(i) is an entry in L(:,k) */
72  {
73  Li [lnz] = i ; /* save unpermuted row in L */
74  Lx [lnz++] = x [i] / pivot ; /* scale pivot column */
75  }
76  x [i] = 0 ; /* x [0..n-1] = 0 for next k */
77  }
78  }
79  /* --- Finalize L and U ------------------------------------------------- */
80  Lp [n] = lnz ;
81  Up [n] = unz ;
82  Li = L->i ; /* fix row indices of L for final pinv */
83  for (p = 0 ; p < lnz ; p++) Li [p] = pinv [Li [p]] ;
84  cs_sprealloc (L, 0) ; /* remove extra space from L and U */
85  cs_sprealloc (U, 0) ;
86  return (cs_ndone (N, NULL, xi, x, 1)) ; /* success */
87 }
csn * cs_ndone(csn *N, cs *C, void *w, void *x, CS_INT ok)
Definition: cs_util.c:106
#define cs
Definition: cs.h:637
#define css
Definition: cs.h:688
#define CS_ENTRY
Definition: cs.h:635
cs * cs_spalloc(CS_INT m, CS_INT n, CS_INT nzmax, CS_INT values, CS_INT triplet)
Definition: cs_util.c:3
#define CS_ABS(x)
Definition: cs.h:650
#define csn
Definition: cs.h:689
#define CS_CSC(A)
Definition: cs.h:659
void * cs_calloc(CS_INT n, size_t size)
Definition: cs_malloc.c:16
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)
Definition: cs_spsolve.c:3
#define CS_INT
Definition: cs.h:627
CS_INT cs_sprealloc(cs *A, CS_INT nzmax)
Definition: cs_util.c:18
void * cs_malloc(CS_INT n, size_t size)
Definition: cs_malloc.c:10
csn * cs_lu(const cs *A, const css *S, double tol)
Definition: cs_lu.c:3