Rev 1820 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/* ========================================================================== *//* === UMF_extend_front ===================================================== *//* ========================================================================== *//* -------------------------------------------------------------------------- *//* UMFPACK Version 4.5, Copyright (c) 2005 by Timothy A. Davis. CISE Dept, *//* Univ. of Florida. All Rights Reserved. See ../Doc/License for License. *//* web: http://www.cise.ufl.edu/research/sparse/umfpack *//* -------------------------------------------------------------------------- *//* Called by kernel. */#include "umf_internal.h"#include "umf_grow_front.h"/* ========================================================================== *//* === zero_front =========================================================== *//* ========================================================================== */PRIVATE void zero_front (Entry *Flblock, Entry *Fublock, Entry *Fcblock,Int fnrows, Int fncols, Int fnr_curr, Int fnc_curr,Int fnpiv, Int fnrows_extended, Int fncols_extended){Int j, i ;Entry *F, *Fj, *Fi ;Fj = Fcblock + fnrows ;for (j = 0 ; j < fncols ; j++){/* zero the new rows in the contribution block: */F = Fj ;Fj += fnr_curr ;#pragma ivdepfor (i = fnrows ; i < fnrows_extended ; i++){/* CLEAR (Fcblock [i + j*fnr_curr]) ; */CLEAR_AND_INCREMENT (F) ;}}Fj -= fnrows ;for (j = fncols ; j < fncols_extended ; j++){/* zero the new columns in the contribution block: */F = Fj ;Fj += fnr_curr ;#pragma ivdepfor (i = 0 ; i < fnrows_extended ; i++){/* CLEAR (Fcblock [i + j*fnr_curr]) ; */CLEAR_AND_INCREMENT (F) ;}}Fj = Flblock + fnrows ;for (j = 0 ; j < fnpiv ; j++){/* zero the new rows in L block: */F = Fj ;Fj += fnr_curr ;#pragma ivdepfor (i = fnrows ; i < fnrows_extended ; i++){/* CLEAR (Flblock [i + j*fnr_curr]) ; */CLEAR_AND_INCREMENT (F) ;}}Fi = Fublock + fncols ;for (i = 0 ; i < fnpiv ; i++){/* zero the new columns in U block: */F = Fi ;Fi += fnc_curr ;#pragma ivdepfor (j = fncols ; j < fncols_extended ; j++){/* CLEAR (Fublock [i*fnc_curr + j]) ; */CLEAR_AND_INCREMENT (F) ;}}}/* ========================================================================== *//* === UMF_extend_front ===================================================== *//* ========================================================================== */GLOBAL Int UMF_extend_front(NumericType *Numeric,WorkType *Work){/* ---------------------------------------------------------------------- *//* local variables *//* ---------------------------------------------------------------------- */Int j, i, *Frows, row, col, *Wrow, fnr2, fnc2, *Frpos, *Fcpos, *Fcols,fnrows_extended, rrdeg, ccdeg, fncols_extended, fnr_curr, fnc_curr,fnrows, fncols, pos, fnpiv, *Wm ;Entry *Wx, *Wy, *Fu, *Fl ;/* ---------------------------------------------------------------------- *//* get current frontal matrix and check for frontal growth *//* ---------------------------------------------------------------------- */fnpiv = Work->fnpiv ;#ifndef NDEBUGDEBUG2 (("EXTEND FRONT\n")) ;DEBUG2 (("Work->fnpiv "ID"\n", fnpiv)) ;ASSERT (Work->Flblock == Work->Flublock + Work->nb*Work->nb) ;ASSERT (Work->Fublock == Work->Flblock + Work->fnr_curr*Work->nb) ;ASSERT (Work->Fcblock == Work->Fublock + Work->nb*Work->fnc_curr) ;DEBUG7 (("C block: ")) ;UMF_dump_dense (Work->Fcblock, Work->fnr_curr, Work->fnrows, Work->fncols) ;DEBUG7 (("L block: ")) ;UMF_dump_dense (Work->Flblock, Work->fnr_curr, Work->fnrows, fnpiv);DEBUG7 (("U' block: ")) ;UMF_dump_dense (Work->Fublock, Work->fnc_curr, Work->fncols, fnpiv) ;DEBUG7 (("LU block: ")) ;UMF_dump_dense (Work->Flublock, Work->nb, fnpiv, fnpiv) ;#endifif (Work->do_grow){fnr2 = UMF_FRONTAL_GROWTH * Work->fnrows_new + 2 ;fnc2 = UMF_FRONTAL_GROWTH * Work->fncols_new + 2 ;if (!UMF_grow_front (Numeric, fnr2, fnc2, Work, 1)){DEBUGm4 (("out of memory: extend front\n")) ;return (FALSE) ;}}fnr_curr = Work->fnr_curr ;fnc_curr = Work->fnc_curr ;ASSERT (Work->fnrows_new + 1 <= fnr_curr) ;ASSERT (Work->fncols_new + 1 <= fnc_curr) ;ASSERT (fnr_curr >= 0 && fnr_curr % 2 == 1) ;/* ---------------------------------------------------------------------- *//* get parameters *//* ---------------------------------------------------------------------- */Frows = Work->Frows ;Frpos = Work->Frpos ;Fcols = Work->Fcols ;Fcpos = Work->Fcpos ;fnrows = Work->fnrows ;fncols = Work->fncols ;rrdeg = Work->rrdeg ;ccdeg = Work->ccdeg ;/* scan starts at the first new column in Fcols *//* also scan the pivot column if it was not in the front */Work->fscan_col = fncols ;Work->NewCols = Fcols ;/* scan1 starts at the first new row in Frows *//* also scan the pivot row if it was not in the front */Work->fscan_row = fnrows ;Work->NewRows = Frows ;/* ---------------------------------------------------------------------- *//* extend row pattern of the front with the new pivot column *//* ---------------------------------------------------------------------- */fnrows_extended = fnrows ;fncols_extended = fncols ;#ifndef NDEBUGDEBUG2 (("Pivot col, before extension: "ID"\n", fnrows)) ;for (i = 0 ; i < fnrows ; i++){DEBUG2 ((" "ID": row "ID"\n", i, Frows [i])) ;ASSERT (Frpos [Frows [i]] == i) ;}DEBUG2 (("Extending pivot column: pivcol_in_front: "ID"\n",Work->pivcol_in_front)) ;#endifFl = Work->Flblock + fnpiv * fnr_curr ;if (Work->pivcol_in_front){/* extended pattern and position already in Frows, Frpos. Values above* the diagonal are already in LU block. Values on and below the* diagonal are in Wy [0 .. fnrows_extended-1]. Copy into the L* block. */fnrows_extended += ccdeg ;Wy = Work->Wy ;for (i = 0 ; i < fnrows_extended ; i++){Fl [i] = Wy [i] ;#ifndef NDEBUGrow = Frows [i] ;DEBUG2 ((" "ID": row "ID" ", i, row)) ;EDEBUG2 (Fl [i]) ;if (row == Work->pivrow) DEBUG2 ((" <- pivrow")) ;DEBUG2 (("\n")) ;if (i == fnrows - 1) DEBUG2 ((" :::::::\n")) ;ASSERT (row >= 0 && row < Work->n_row) ;ASSERT (Frpos [row] == i) ;#endif}}else{/* extended pattern,values is in (Wm,Wx), not yet in the front */Entry *F ;Fu = Work->Flublock + fnpiv * Work->nb ;Wm = Work->Wm ;Wx = Work->Wx ;F = Fu ;for (i = 0 ; i < fnpiv ; i++){CLEAR_AND_INCREMENT (F) ;}F = Fl ;for (i = 0 ; i < fnrows ; i++){CLEAR_AND_INCREMENT (F) ;}for (i = 0 ; i < ccdeg ; i++){row = Wm [i] ;#ifndef NDEBUGDEBUG2 ((" "ID": row "ID" (ext) ", fnrows_extended, row)) ;EDEBUG2 (Wx [i]) ;if (row == Work->pivrow) DEBUG2 ((" <- pivrow")) ;DEBUG2 (("\n")) ;ASSERT (row >= 0 && row < Work->n_row) ;#endifpos = Frpos [row] ;if (pos < 0){pos = fnrows_extended++ ;Frows [pos] = row ;Frpos [row] = pos ;}Fl [pos] = Wx [i] ;}}ASSERT (fnrows_extended <= fnr_curr) ;/* ---------------------------------------------------------------------- *//* extend the column pattern of the front with the new pivot row *//* ---------------------------------------------------------------------- */#ifndef NDEBUGDEBUG6 (("Pivot row, before extension: "ID"\n", fncols)) ;for (j = 0 ; j < fncols ; j++){DEBUG7 ((" "ID": col "ID"\n", j, Fcols [j])) ;ASSERT (Fcpos [Fcols [j]] == j * fnr_curr) ;}DEBUG6 (("Extending pivot row:\n")) ;#endifif (Work->pivrow_in_front){if (Work->pivcol_in_front){ASSERT (Fcols == Work->Wrow) ;for (j = fncols ; j < rrdeg ; j++){#ifndef NDEBUGcol = Fcols [j] ;DEBUG2 ((" "ID": col "ID" (ext)\n", j, col)) ;ASSERT (col != Work->pivcol) ;ASSERT (col >= 0 && col < Work->n_col) ;ASSERT (Fcpos [col] < 0) ;#endifFcpos [Fcols [j]] = j * fnr_curr ;}}else{/* OUT-IN option: pivcol not in front, but pivrow is in front */Wrow = Work->Wrow ;ASSERT (IMPLIES (Work->pivcol_in_front, Wrow == Fcols)) ;if (Wrow == Fcols){/* Wrow and Fcols are equivalenced */for (j = fncols ; j < rrdeg ; j++){col = Wrow [j] ;DEBUG2 ((" "ID": col "ID" (ext)\n", j, col)) ;ASSERT (Fcpos [col] < 0) ;/* Fcols [j] = col ; not needed */Fcpos [col] = j * fnr_curr ;}}else{for (j = fncols ; j < rrdeg ; j++){col = Wrow [j] ;DEBUG2 ((" "ID": col "ID" (ext)\n", j, col)) ;ASSERT (Fcpos [col] < 0) ;Fcols [j] = col ;Fcpos [col] = j * fnr_curr ;}}}fncols_extended = rrdeg ;}else{ASSERT (Fcols != Work->Wrow) ;Wrow = Work->Wrow ;for (j = 0 ; j < rrdeg ; j++){col = Wrow [j] ;ASSERT (col >= 0 && col < Work->n_col) ;if (Fcpos [col] < 0){DEBUG2 ((" col:: "ID" (ext)\n", col)) ;Fcols [fncols_extended] = col ;Fcpos [col] = fncols_extended * fnr_curr ;fncols_extended++ ;}}}/* ---------------------------------------------------------------------- *//* pivot row and column have been extended *//* ---------------------------------------------------------------------- */#ifndef NDEBUGASSERT (fncols_extended <= fnc_curr) ;ASSERT (fnrows_extended <= fnr_curr) ;DEBUG6 (("Pivot col, after ext: "ID" "ID"\n", fnrows,fnrows_extended)) ;for (i = 0 ; i < fnrows_extended ; i++){row = Frows [i] ;DEBUG7 ((" "ID": row "ID" pos "ID" old: %d", i, row, Frpos [row],i < fnrows)) ;if (row == Work->pivrow ) DEBUG7 ((" <-- pivrow")) ;DEBUG7 (("\n")) ;ASSERT (Frpos [Frows [i]] == i) ;}DEBUG6 (("Pivot row position: "ID"\n", Frpos [Work->pivrow])) ;ASSERT (Frpos [Work->pivrow] >= 0) ;ASSERT (Frpos [Work->pivrow] < fnrows_extended) ;DEBUG6 (("Pivot row, after ext: "ID" "ID"\n", fncols,fncols_extended)) ;for (j = 0 ; j < fncols_extended ; j++){col = Fcols [j] ;DEBUG7 ((" "ID": col "ID" pos "ID" old: %d", j, col, Fcpos [col],j < fncols)) ;if (col == Work->pivcol ) DEBUG7 ((" <-- pivcol")) ;DEBUG7 (("\n")) ;ASSERT (Fcpos [Fcols [j]] == j * fnr_curr) ;}DEBUG6 (("Pivot col position: "ID"\n", Fcpos [Work->pivcol])) ;ASSERT (Fcpos [Work->pivcol] >= 0) ;ASSERT (Fcpos [Work->pivcol] < fncols_extended * fnr_curr) ;#endif/* ---------------------------------------------------------------------- *//* Zero the newly extended frontal matrix *//* ---------------------------------------------------------------------- */zero_front (Work->Flblock, Work->Fublock, Work->Fcblock,fnrows, fncols, fnr_curr, fnc_curr,fnpiv, fnrows_extended, fncols_extended) ;/* ---------------------------------------------------------------------- *//* finalize extended row and column pattern of the frontal matrix *//* ---------------------------------------------------------------------- */Work->fnrows = fnrows_extended ;Work->fncols = fncols_extended ;ASSERT (fnrows_extended == Work->fnrows_new + 1) ;ASSERT (fncols_extended == Work->fncols_new + 1) ;return (TRUE) ;}