Macaulay2 Engine
Loading...
Searching...
No Matches

◆ computeLU() [5/5]

template<class RingType>
void DMatLUinPlace< RingType >::computeLU ( )
private

Definition at line 230 of file dmat-lu-inplace.hpp.

231{
232 if (mIsDone) return;
233
234 // std::cout << "computing LU decomposition generic version" << std::endl;
235 typename RingType::Element tmp(mLU.ring());
236
237 size_t col = 0; // current column we are working on
238 size_t row = 0; // current row we are working on
239 size_t nrows = mLU.numRows();
240 size_t ncols = mLU.numColumns();
241
242 while (col < ncols && row < nrows)
243 {
244 // printf("*** in naive row,col = (%ld, %ld) ***\n", row, col);
245 // debug_out();
246
247 // Step 1: Set the 'upper' values: (row,col)..(nrows-1,col)
248 for (size_t r = row; r < nrows; r++)
249 {
250 for (size_t i = 0; i < row; i++)
251 {
252 mLU.ring().mult(tmp, mLU.entry(r, i), mLU.entry(i, col));
253 mLU.ring().subtract(mLU.entry(r, col), mLU.entry(r, col), tmp);
254 }
255 }
256
257 // printf("after step 1\n");
258 // debug_out();
259
260 // Step 2: Find a pivot among the elements in step 1.
261 // If one: swap rows if needed
262 // If none, increment 'col', and continue at start of loop
263 size_t k = findPivot(row, col);
264 if (k == static_cast<size_t>(-1))
265 {
266 col = col + 1;
267 continue;
268 }
269 // printf("pivot is in row %ld\n", k);
271 if (k != row)
272 {
274 mSign = !mSign;
275 }
276 mPivotColumns.push_back(col);
277 const ElementType& pivot = mLU.entry(row, col);
278
279 // printf("after step 2:\n");
280 // debug_out();
281
282 // Step 3A: Set the 'upper' elements in (row,col+1), ..., (row,ncols-1).
283 for (size_t c = col + 1; c < ncols; c++)
284 {
285 for (size_t i = 0; i < row; i++)
286 {
287 mLU.ring().mult(tmp, mLU.entry(row, i), mLU.entry(i, c));
288 mLU.ring().subtract(mLU.entry(row, c), mLU.entry(row, c), tmp);
289 }
290 }
291 // printf("after step 3A:\n");
292 // debug_out();
293
294 // Step 3B: Set the 'lower' elements in (row+1,row), ..., (nrows-1,row)
295 // from (row+1,col), ..., (nrows-1,col)
296 // This just means dividing then by the pivot
297 // except, if we have skipped columns for pivots, we must set these
298 // elements
299 // in column 'row', not 'col'...
300 // Step 3C: if row != col, then set these elements to 0:
301 // (row+1,col), ..., (nrows-1,col)
302 for (size_t r = row + 1; r < nrows; r++)
303 {
304 mLU.ring().divide(mLU.entry(r, row), mLU.entry(r, col), pivot);
305 if (row < col) ring().set_zero(mLU.entry(r, col));
306 }
307
308 // printf("after step 3B:\n");
309 // debug_out();
310
311 row++;
312 col++;
313 }
314
315 mIsDone = true;
316}
const RingType & ring() const
RingType::ElementType ElementType
std::vector< size_t > mPivotColumns
std::vector< size_t > mPerm
size_t findPivot(size_t row, size_t col)
void swap(mpfr::mpreal &x, mpfr::mpreal &y)
Definition mpreal.h:3244

References findPivot(), mIsDone, mLU, mPerm, mPivotColumns, mSign, ring(), and std::swap().

Referenced by LUinPlace().