Rev 4428 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/* ========================================================================== *//* === 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 == 1NUMERIC (WDIM,1) (update, j, e, a, W1, L, Common) ;#elseswitch (Path [path].rank){case 1:NUMERIC (WDIM,1) (update, j, e, a, W1, L, Common) ;break ;#if WDIM >= 2case 2:NUMERIC (WDIM,2) (update, j, e, a, W1, L, Common) ;break ;#endif#if WDIM >= 4case 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 == 8case 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