/************************************ 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 */ }