/* ========================================================================== */
/* === Modify/t_cholmod_updown ============================================== */
/* ========================================================================== */
/* -----------------------------------------------------------------------------
* CHOLMOD/Modify Module. Copyright (C) 2005-2006,
* Timothy A. Davis and William W. Hager.
* The CHOLMOD/Modify Module is licensed under Version 2.0 of the GNU
* General Public License. See gpl.txt for a text of the license.
* CHOLMOD is also available under other licenses; contact authors for details.
* http://www.cise.ufl.edu/research/sparse
* -------------------------------------------------------------------------- */
/* Updates/downdates the LDL' factorization, by computing a new factorization of
*
* Lnew * Dnew * Lnew' = Lold * Dold * Lold' +/- C*C'
*
* This file is not compiled separately. It is included into
* cholmod_updown.c. There are no user-callable routines in this file.
*
* The next include statements, below, create the numerical update/downdate
* kernels from t_cholmod_updown_numkr.c. There are 4 compiled versions of this
* file, one for each value of WDIM in the set 1, 2, 4, and 8. Each calls
* multiple versions of t_cholmod_updown_numkr; the number of versions of each
* is equal to WDIM. Each t_cholmod_updown_numkr version is included as a
* static function within its t_cholmod_updown.c caller routine. Thus:
*
* t*_updown.c creates these versions of t_cholmod_updown_numkr.c:
* --------- ---------------------------------------------------
*
* updown_1_r updown_1_1
*
* updown_2_r updown_2_1 updown_2_2
*
* updown_4_r updown_4_1 updown_4_2 updown_4_3 updown_4_4
*
* updown_8_r updown_8_1 updown_8_2 updown_8_3 updown_8_4
* updown_8_5 updown_8_6 updown_8_7 updown_8_8
*
* workspace: Xwork (nrow*wdim)
*/
/* ========================================================================== */
/* === routines for numeric update/downdate along one path ================== */
/* ========================================================================== */
#undef FORM_NAME
#undef NUMERIC
#define FORM_NAME(k,rank) updown_ ## k ## _ ## rank
#define NUMERIC(k,rank) FORM_NAME(k,rank)
#define RANK 1
#include "t_cholmod_updown_numkr.c"
#if WDIM >= 2
#define RANK 2
#include "t_cholmod_updown_numkr.c"
#endif
#if WDIM >= 4
#define RANK 3
#include "t_cholmod_updown_numkr.c"
#define RANK 4
#include "t_cholmod_updown_numkr.c"
#endif
#if WDIM == 8
#define RANK 5
#include "t_cholmod_updown_numkr.c"
#define RANK 6
#include "t_cholmod_updown_numkr.c"
#define RANK 7
#include "t_cholmod_updown_numkr.c"
#define RANK 8
#include "t_cholmod_updown_numkr.c"
#endif
/* ========================================================================== */
/* === numeric update/downdate for all paths ================================ */
/* ========================================================================== */
static void NUMERIC (WDIM, r)
(
int update, /* TRUE for update, FALSE for downdate */
cholmod_sparse *C, /* in packed or unpacked, and sorted form */
/* no empty columns */
Int rank, /* rank of the update/downdate */
cholmod_factor *L, /* with unit diagonal (diagonal not stored) */
/* temporary workspaces: */
double W [ ], /* n-by-WDIM dense matrix, initially zero */
Path_type Path [ ],
Int npaths,
Int mask [ ], /* size n */
cholmod_common *Common
)
{
double Alpha [8] ;
double *Cx, *Wpath, *W1, *a ;
Int i, j, p, ccol, pend, wfirst, e, path, packed ;
Int *Ci, *Cp, *Cnz ;
/* ---------------------------------------------------------------------- */
/* get inputs */
/* ---------------------------------------------------------------------- */
Ci = C->i ;
Cx = C->x ;
Cp = C->p ;
Cnz = C->nz ;
packed = C->packed ;
ASSERT (IMPLIES (!packed, Cnz != NULL)) ;
ASSERT (L->n == C->nrow) ;
DEBUG (CHOLMOD(dump_real) ("num_d: in W:", W, WDIM, L->n, FALSE, 1,Common));
/* ---------------------------------------------------------------------- */
/* scatter C into W */
/* ---------------------------------------------------------------------- */
for (path = 0 ; path < rank ; path++)
{
/* W (:, path) = C (:, Path [path].col) */
ccol = Path [path].ccol ;
Wpath = W + path ;
PRINT1 (("Ordered Columns [path = "ID"] = "ID"\n", path, ccol)) ;
p = Cp [ccol] ;
pend = (packed) ? (Cp [ccol+1]) : (p + Cnz [ccol]) ;
/* column C can be empty */
for ( ; p < pend ; p++)
{
i = Ci [p] ;
ASSERT (i >= 0 && i < (Int) (C->nrow)) ;
if (mask == NULL || mask [i] < 0)
{
Wpath [WDIM * i] = Cx [p] ;
}
PRINT1 ((" row "ID" : %g mask "ID"\n", i, Cx [p],
(mask) ? mask [i] : 0)) ;
}
Alpha [path] = 1.0 ;
}
DEBUG (CHOLMOD(dump_real) ("num_d: W:", W, WDIM, L->n, FALSE, 1,Common)) ;
/* ---------------------------------------------------------------------- */
/* numeric update/downdate of the paths */
/* ---------------------------------------------------------------------- */
/* for each disjoint subpath in Tbar in DFS order do */
for (path = rank ; path < npaths ; path++)
{
/* determine which columns of W to use */
wfirst = Path [path].wfirst ;
e = Path [path].end ;
j = Path [path].start ;
ASSERT (e >= 0 && e < (Int) (L->n)) ;
ASSERT (j >= 0 && j < (Int) (L->n)) ;
W1 = W + wfirst ; /* pointer to row 0, column wfirst of W */
a = Alpha + wfirst ; /* pointer to Alpha [wfirst] */
PRINT1 (("Numerical update/downdate of path "ID"\n", path)) ;
PRINT1 (("start "ID" end "ID" wfirst "ID" rank "ID" ccol "ID"\n", j, e,
wfirst, Path [path].rank, Path [path].ccol)) ;
#if WDIM == 1
NUMERIC (WDIM,1) (update, j, e, a, W1, L, Common) ;
#else
switch (Path [path].rank)
{
case 1:
NUMERIC (WDIM,1) (update, j, e, a, W1, L, Common) ;
break ;
#if WDIM >= 2
case 2:
NUMERIC (WDIM,2) (update, j, e, a, W1, L, Common) ;
break ;
#endif
#if WDIM >= 4
case 3:
NUMERIC (WDIM,3) (update, j, e, a, W1, L, Common) ;
break ;
case 4:
NUMERIC (WDIM,4) (update, j, e, a, W1, L, Common) ;
break ;
#endif
#if WDIM == 8
case 5:
NUMERIC (WDIM,5) (update, j, e, a, W1, L, Common) ;
break ;
case 6:
NUMERIC (WDIM,6) (update, j, e, a, W1, L, Common) ;
break ;
case 7:
NUMERIC (WDIM,7) (update, j, e, a, W1, L, Common) ;
break ;
case 8:
NUMERIC (WDIM,8) (update, j, e, a, W1, L, Common) ;
break ;
#endif
}
#endif
}
}
/* prepare for the next inclusion of this file in cholmod_updown.c */
#undef WDIM
syntax highlighted by Code2HTML, v. 0.9.1