source: tol/tol/bmath/csparse/cs_chol.c @ 6d7779d

1941-docker-image-to-testdevel
Last change on this file since 6d7779d was 6d7779d, checked in by Jorge Pérez <josp.jorge@…>, 18 years ago

initial import

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@1 be4846ae-f051-483a-831f-b64e7d08527f

  • Property mode set to 100644
File size: 2.6 KB
Line 
1#include "cs.h"
2/* compute nonzero pattern of L(k,:) */
3static
4int cs_ereach (cs *A, int j, int k, int *parent, int *s, int *w, double *x,
5    int top)
6{
7    int i, p, len, *Ap = A->p, *Ai = A->i ;
8    double *Ax = A->x ;
9    for (p = Ap [j] ; p < Ap [j+1] ; p++)       /* get pattern of L(k,:) */
10    {
11        i = Ai [p] ;                /* A(i,k) is nonzero */
12        if (i > k) continue ;       /* only use upper triangular part of A */
13        x [i] = Ax [p] ;            /* x(i) = A(i,k) */
14        for (len = 0 ; w [i] != k ; i = parent [i]) /* traverse up etree */
15        {
16            s [len++] = i ;         /* L(k,i) is nonzero */
17            w [i] = k ;             /* mark i as visited */
18        }
19        while (len > 0) s [--top] = s [--len] ; /* push path onto stack */
20    }
21    return (top) ;                  /* s [top..n-1] contains pattern of L(k,:)*/
22}
23
24/* L = chol (A, [Pinv parent cp]), Pinv is optional */
25csn *cs_chol (cs *A, css *S)
26{
27    double d, lki, *Lx, *x ;
28    int top, i, p, k, n, *Li, *Lp, *cp, *Pinv, *w, *s, *c, *parent ;
29    cs *L, *C, *E ;
30    csn *N ;
31    if (!A || !S || !S->cp || !S->parent) return (NULL) ;   /* check inputs */
32    n = A->n ;
33    N = cs_calloc (1, sizeof (csn)) ;
34    w = cs_malloc (3*n, sizeof (int)) ; s = w + n, c = w + 2*n ;
35    x = cs_malloc (n, sizeof (double)) ;
36    cp = S->cp ; Pinv = S->Pinv ; parent = S->parent ;
37    C = Pinv ? cs_symperm (A, Pinv, 1) : A ;
38    E = Pinv ? C : NULL ;
39    if (!N || !w || !x || !C) return (cs_ndone (N, E, w, x, 0)) ;
40    N->L = L = cs_spalloc (n, n, cp [n], 1, 0) ;
41    if (!L) return (cs_ndone (N, E, w, x, 0)) ;
42    Lp = L->p ; Li = L->i ; Lx = L->x ;
43    for (k = 0 ; k < n ; k++)
44    {
45        Lp [k] = c [k] = cp [k] ;   /* column k of L starts here */
46        x [k] = 0 ;                 /* x (0:k) is now zero */
47        w [k] = k ;                 /* mark node k as visited */
48        top = cs_ereach (C, k, k, parent, s, w, x, n) ;   /* find row k of L*/
49        d = x [k] ;                 /* d = C(k,k) */
50        x [k] = 0 ;                 /* clear workspace for k+1st iteration */
51        for ( ; top < n ; top++)    /* solve L(0:k-1,0:k-1) * x = C(:,k) */
52        {
53            i = s [top] ;           /* s [top..n-1] is pattern of L(k,:) */
54            lki = x [i] / Lx [Lp [i]] ; /* L(k,i) = x (i) / L(i,i) */
55            x [i] = 0 ;             /* clear workspace for k+1st iteration */
56            for (p = Lp [i] + 1 ; p < c [i] ; p++)
57            {
58                x [Li [p]] -= Lx [p] * lki ;
59            }
60            d -= lki*lki ;          /* d = d - L(k,i)*L(k,i) */
61            p = c [i]++ ;
62            Li [p] = k ;            /* store L(k,i) in column i */
63            Lx [p] = lki ;
64        }
65        if (d <= 0) return (cs_ndone (N, E, w, x, 0)) ; /* not pos def */
66        p = c [k]++ ;
67        Li [p] = k ;                /* store L(k,k) = sqrt (d) in column k */
68        Lx [p] = sqrt (d) ;
69    }
70    Lp [n] = cp [n] ;               /* finalize L */
71    return (cs_ndone (N, E, w, x, 1)) ; /* success: free E,w,x; return N */
72}
Note: See TracBrowser for help on using the repository browser.