Beispiel #1
0
/************************************
  Given the factorization LB = U for some B, solve the problem
  Bx = vec for x
  Solve using LUMOD functions.
************************************/
void LU_Solve0(PT_Matrix pL, PT_Matrix pU, double *vec, double *x)
{
	int mode;
	ptrdiff_t n;

	n = Matrix_Rows(pL);

	/* solve using lumod */
	/* solve for Bx = vec */
	mode = 1;

	/* due to 1-based indexing in Lprod, Usolve we need to shift vectors backwards */
	/* Computes x = L*vec */
	Lprod(mode, pL->rows_alloc, n, pL->A-1, vec-1, x-1);

	/* Computes x_new s.t. U x_new = x */
	Usolve(mode, pU->rows_alloc, n, pU->A-1, x-1);
	
	/* Vector_Print_raw(x,n); */
}
void LUmod ( int mode, ptrdiff_t maxmod, ptrdiff_t n, ptrdiff_t krow, ptrdiff_t kcol,
             double *L, double *U, double *y, double *z, double *w)
{
  ptrdiff_t    first, last, n1, i, j, lastu, lastl, ls, ll, lu, incu;
  double zero = 0.0;
  double one  = 1.0;
  double eps  = MACHINEPREC;   /* The machine precision -- A value slightly too large is OK. */


  n1 = n - 1;

  if (mode == 1) {
/*   ---------------------------------------------------------------
     mode = 1.  Add a row y and a column z.
     The LU factors will expand in dimension from n-1 to n.
     The new diagonal element of C is in y[n].
     --------------------------------------------------------------- */
     lastu    = n1*maxmod + (3 - n)*n/2;
     lastl    = n1*maxmod + n;
     ls       = n1*maxmod + 1;
     L[lastl] = one;
     if (n == 1) {
        U[lastu] = y[n];
        return;
     }

/*   Compute L*z and temporarily store it in w;
     (changed to w from last row of L by KE). */

     Lprod ( 1, maxmod, n1, L, z, w );

/*       Copy L*z into the new last column of U.
         Border L with zeros. */

     ll     = ls;
     lu     = n;
     incu   = maxmod - 1;
     for (j = 1; j<=n1; j++) {
        U[lu] = w[j];
        L[ll] = zero;
        ll++;
        lu   += incu;
        incu--;
     }

     ll     = n;
     for (i = 1; i<=n1; i++) {
        L[ll] = zero;
        ll   += maxmod;
     }

/*   Add row y to the factorization
     using a forward sweep of eliminations. */

     last   = n;
     LUforw ( 1, last, n, n, maxmod, eps, L, U, y );

  }
  else if (mode == 2) {
/*   ---------------------------------------------------------------
     mode=2.  Replace the kcol-th column of C by the vector z.
     ---------------------------------------------------------------*/

/*   Compute w = L*z. */

     Lprod ( 1, maxmod, n, L, z, w );

/*   Copy the top of w into column kcol of U. */

     lu     = kcol;
     incu   = maxmod - 1;
     for (i = 1; i<=kcol; i++) {
        U[lu] = w[i];
        lu   += incu;
        incu--;
     }

     if (kcol < n) {

/*      Find w[last], the last nonzero in the bottom part of w.
        Eliminate elements last-1, last-2, ... kcol+1 of w[*]
        using a partial backward sweep of eliminations. */

        first  = kcol + 1;
        last   = n;
        LUback( first, &last, n, n, maxmod, eps, L, U, y, w );
        y[kcol] = w[last];

/*      Eliminate elements kcol, kcol+1, ... last-1 of y[*]
        using a partial forward sweep of eliminations. */

        LUforw ( kcol, last, n, n, maxmod, eps, L, U, y );
     }

  }
  else if (mode == 3) {
/*   ---------------------------------------------------------------
     mode=3.  Replace the krow-th row of C by the vector y.
     --------------------------------------------------------------- */
     if (n == 1) {
        L[1] = one;
        U[1] = y[1];
        return;
     }

/*   Copy the krow-th column of L into w, and zero the column. */

     ll     = krow;
     for (i = 1; i<=n; i++) {
        w[i]  = L[ll];
        L[ll] = zero;
        ll   += maxmod;
     }

/*   Reduce the krow-th column of L to the unit vector e(last).
     where 'last' is determined by LUback.
     This is done by eliminating elements last-1, last-2, ..., 1
     using a backward sweep of eliminations.
     On exit, row 'last' of U is a spike stored in z, whose first
     nonzero entry is in z[first].  However, z will be discarded. */

     first  = 1;
     last   = n;
     LUback ( first, &last, n, n, maxmod, eps, L, U, z, w );

/*   Replace the 'last' row of L by the krow-th unit vector. */

     ll     = (last - 1)*maxmod;
     for (j = 1; j<=n; j++)
        L[ll + j] = zero;
     L[ll + krow] = one;

/*   Eliminate the elements of the new row y,
     using a forward sweep of eliminations. */

     LUforw ( 1, last, n, n, maxmod, eps, L, U, y );

  }

  else if (mode == 4) {
/*   ---------------------------------------------------------------
     mode=4.  Delete the krow-th row and the kcol-th column of C.
              Replace them by the last row and column respectively.
     --------------------------------------------------------------- */

/*   First, move the last column into position kcol. */

     if (kcol < n) {

/*      Set w = last column of U. */

        lu     = n;
        incu   = maxmod - 1;
        for (i = 1; i<=n; i++) {
           w[i] = U[lu];
           lu  += incu;
           incu--;
        }

/*      Copy the top of w into column kcol of U. */

        lu     = kcol;
        incu   = maxmod - 1;
        for (i = 1; i<=kcol; i++) {
           U[lu] = w[i];
           lu   += incu;
           incu--;
        }

/*      U now has only n-1 columns.
        Find w[last], the last nonzero in the bottom part of w.
        Eliminate elements last-1, last-2, ... kcol+1 of w[*]
        using a partial backward sweep of eliminations. */

        first  = kcol + 1;
        last   = n;
        LUback ( first, &last, n, n1, maxmod, eps, L, U, y, w );
        y[kcol] = w[last];

/*      Eliminate elements kcol, kcol+1, ... last-1 of y[*]
        using a partial forward sweep of eliminations. */

        LUforw ( kcol, last, n, n1, maxmod, eps, L, U, y );
     }

/*   Now, move the last row into position krow. */

/*   Swap columns krow and n of L, using w = krow-th column of L. */

     LUdcopy ( n, &L[subvec(krow)], maxmod, w, 1 );
     if (krow < n)
        LUdcopy ( n, &L[subvec(n)], maxmod, &L[subvec(krow)], maxmod );

/*   Reduce the last column of L (in w) to the unit vector e(n).
     This is done by eliminating elements n-1, n-2, ..., 1
     using a backward sweep of eliminations. */

     last   = - n;
     LUback ( 1, &last, n, n1, maxmod, eps, L, U, z, w );
     /* printvec(n, w, 0); */
     /* printmatUT(maxmod, n, U, 0); */
     /* printmatSQ(maxmod, n, L, 0); */
  }

/*     End of LUmod  */
}