Mercurial > octave-nkf
diff liboctave/UMFPACK/UMFPACK/Source/umf_extend_front.c @ 5164:57077d0ddc8e
[project @ 2005-02-25 19:55:24 by jwe]
author | jwe |
---|---|
date | Fri, 25 Feb 2005 19:55:28 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/UMFPACK/UMFPACK/Source/umf_extend_front.c Fri Feb 25 19:55:28 2005 +0000 @@ -0,0 +1,392 @@ +/* ========================================================================== */ +/* === UMF_extend_front ===================================================== */ +/* ========================================================================== */ + +/* -------------------------------------------------------------------------- */ +/* UMFPACK Version 4.4, 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 ivdep + for (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 ivdep + for (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 ivdep + for (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 ivdep + for (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 NDEBUG + DEBUG2 (("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) ; +#endif + + if (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 NDEBUG + DEBUG2 (("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)) ; +#endif + + Fl = 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 NDEBUG + row = 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 NDEBUG + DEBUG2 ((" "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) ; +#endif + pos = 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 NDEBUG + DEBUG6 (("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")) ; +#endif + + if (Work->pivrow_in_front) + { + if (Work->pivcol_in_front) + { + ASSERT (Fcols == Work->Wrow) ; + for (j = fncols ; j < rrdeg ; j++) + { +#ifndef NDEBUG + col = 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) ; +#endif + Fcpos [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 NDEBUG + ASSERT (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) ; + +}