Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime > Struct Template Reference

#include <PartialPivLU.h>

Public Types

typedef Matrix< Scalar, ActualSizeAtCompileTime, ActualSizeAtCompileTime, StorageOrder > MatrixType
 
typedef Ref< MatrixTypeMatrixTypeRef
 
typedef Ref< Matrix< Scalar, Dynamic, Dynamic, StorageOrder > > BlockType
 
typedef MatrixType::RealScalar RealScalar
 

Static Public Member Functions

static Index unblocked_lu (MatrixTypeRef &lu, PivIndex *row_transpositions, PivIndex &nb_transpositions)
 
static Index blocked_lu (Index rows, Index cols, Scalar *lu_data, Index luStride, PivIndex *row_transpositions, PivIndex &nb_transpositions, Index maxBlockSize=256)
 

Static Public Attributes

static constexpr int UnBlockedBound = 16
 
static constexpr bool UnBlockedAtCompileTime = SizeAtCompileTime != Dynamic && SizeAtCompileTime <= UnBlockedBound
 
static constexpr int ActualSizeAtCompileTime = UnBlockedAtCompileTime ? SizeAtCompileTime : Dynamic
 
static constexpr int RRows = SizeAtCompileTime == 2 ? 1 : Dynamic
 
static constexpr int RCols = SizeAtCompileTime == 2 ? 1 : Dynamic
 

Detailed Description

template<typename Scalar, int StorageOrder, typename PivIndex, int SizeAtCompileTime = Dynamic>
struct Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >

This is the blocked version of fullpivlu_unblocked()

Member Typedef Documentation

◆ BlockType

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
typedef Ref<Matrix<Scalar, Dynamic, Dynamic, StorageOrder> > Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::BlockType

◆ MatrixType

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
typedef Matrix<Scalar, ActualSizeAtCompileTime, ActualSizeAtCompileTime, StorageOrder> Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::MatrixType

◆ MatrixTypeRef

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
typedef Ref<MatrixType> Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::MatrixTypeRef

◆ RealScalar

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
typedef MatrixType::RealScalar Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::RealScalar

Member Function Documentation

◆ blocked_lu()

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
static Index Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::blocked_lu ( Index  rows,
Index  cols,
Scalar lu_data,
Index  luStride,
PivIndex *  row_transpositions,
PivIndex &  nb_transpositions,
Index  maxBlockSize = 256 
)
inlinestatic

performs the LU decomposition in-place of the matrix represented by the variables rows, cols, lu_data, and lu_stride using a recursive, blocked algorithm.

In addition, this function returns the row transpositions in the vector row_transpositions which must have a size equal to the number of columns of the matrix lu, and an integer nb_transpositions which returns the actual number of transpositions.

Returns
The index of the first pivot which is exactly zero if any, or a negative number otherwise.
Note
This very low level interface using pointers, etc. is to: 1 - reduce the number of instantiations to the strict minimum 2 - avoid infinite recursion of the instantiations with Block<Block<Block<...> > >
392  {
393  MatrixTypeRef lu = MatrixType::Map(lu_data, rows, cols, OuterStride<>(luStride));
394 
395  const Index size = (std::min)(rows, cols);
396 
397  // if the matrix is too small, no blocking:
399  return unblocked_lu(lu, row_transpositions, nb_transpositions);
400  }
401 
402  // automatically adjust the number of subdivisions to the size
403  // of the matrix so that there is enough sub blocks:
404  Index blockSize;
405  {
406  blockSize = size / 8;
407  blockSize = (blockSize / 16) * 16;
408  blockSize = (std::min)((std::max)(blockSize, Index(8)), maxBlockSize);
409  }
410 
411  nb_transpositions = 0;
412  Index first_zero_pivot = -1;
413  for (Index k = 0; k < size; k += blockSize) {
414  Index bs = (std::min)(size - k, blockSize); // actual size of the block
415  Index trows = rows - k - bs; // trailing rows
416  Index tsize = size - k - bs; // trailing size
417 
418  // partition the matrix:
419  // A00 | A01 | A02
420  // lu = A_0 | A_1 | A_2 = A10 | A11 | A12
421  // A20 | A21 | A22
422  BlockType A_0 = lu.block(0, 0, rows, k);
423  BlockType A_2 = lu.block(0, k + bs, rows, tsize);
424  BlockType A11 = lu.block(k, k, bs, bs);
425  BlockType A12 = lu.block(k, k + bs, bs, tsize);
426  BlockType A21 = lu.block(k + bs, k, trows, bs);
427  BlockType A22 = lu.block(k + bs, k + bs, trows, tsize);
428 
429  PivIndex nb_transpositions_in_panel;
430  // recursively call the blocked LU algorithm on [A11^T A21^T]^T
431  // with a very small blocking size:
432  Index ret = blocked_lu(trows + bs, bs, &lu.coeffRef(k, k), luStride, row_transpositions + k,
433  nb_transpositions_in_panel, 16);
434  if (ret >= 0 && first_zero_pivot == -1) first_zero_pivot = k + ret;
435 
436  nb_transpositions += nb_transpositions_in_panel;
437  // update permutations and apply them to A_0
438  for (Index i = k; i < k + bs; ++i) {
439  Index piv = (row_transpositions[i] += internal::convert_index<PivIndex>(k));
440  A_0.row(i).swap(A_0.row(piv));
441  }
442 
443  if (trows) {
444  // apply permutations to A_2
445  for (Index i = k; i < k + bs; ++i) A_2.row(i).swap(A_2.row(row_transpositions[i]));
446 
447  // A12 = A11^-1 A12
448  A11.template triangularView<UnitLower>().solveInPlace(A12);
449 
450  A22.noalias() -= A21 * A12;
451  }
452  }
453  return first_zero_pivot;
454  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
static ConstMapType Map(const Scalar *data)
Definition: PlainObjectBase.h:595
cout<< "Here is the matrix m:"<< endl<< m<< endl;Eigen::FullPivLU< Matrix5x3 > lu(m)
#define min(a, b)
Definition: datatypes.h:22
#define max(a, b)
Definition: datatypes.h:23
Eigen::DenseIndex ret
Definition: level1_cplx_impl.h:43
char char char int int * k
Definition: level2_impl.h:374
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
static Index blocked_lu(Index rows, Index cols, Scalar *lu_data, Index luStride, PivIndex *row_transpositions, PivIndex &nb_transpositions, Index maxBlockSize=256)
Definition: PartialPivLU.h:391
static constexpr int UnBlockedBound
Definition: PartialPivLU.h:306
Ref< Matrix< Scalar, Dynamic, Dynamic, StorageOrder > > BlockType
Definition: PartialPivLU.h:314
Ref< MatrixType > MatrixTypeRef
Definition: PartialPivLU.h:313
static constexpr bool UnBlockedAtCompileTime
Definition: PartialPivLU.h:307
static Index unblocked_lu(MatrixTypeRef &lu, PivIndex *row_transpositions, PivIndex &nb_transpositions)
Definition: PartialPivLU.h:327

References cols, i, k, lu(), Eigen::PlainObjectBase< Matrix< Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_ > >::Map(), max, min, ret, rows, size, Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::unblocked_lu(), Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::UnBlockedAtCompileTime, and Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::UnBlockedBound.

◆ unblocked_lu()

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
static Index Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::unblocked_lu ( MatrixTypeRef lu,
PivIndex *  row_transpositions,
PivIndex &  nb_transpositions 
)
inlinestatic

performs the LU decomposition in-place of the matrix lu using an unblocked algorithm.

In addition, this function returns the row transpositions in the vector row_transpositions which must have a size equal to the number of columns of the matrix lu, and an integer nb_transpositions which returns the actual number of transpositions.

Returns
The index of the first pivot which is exactly zero if any, or a negative number otherwise.
327  {
328  typedef scalar_score_coeff_op<Scalar> Scoring;
329  typedef typename Scoring::result_type Score;
330  const Index rows = lu.rows();
331  const Index cols = lu.cols();
332  const Index size = (std::min)(rows, cols);
333  // For small compile-time matrices it is worth processing the last row separately:
334  // speedup: +100% for 2x2, +10% for others.
335  const Index endk = UnBlockedAtCompileTime ? size - 1 : size;
336  nb_transpositions = 0;
337  Index first_zero_pivot = -1;
338  for (Index k = 0; k < endk; ++k) {
339  int rrows = internal::convert_index<int>(rows - k - 1);
340  int rcols = internal::convert_index<int>(cols - k - 1);
341 
342  Index row_of_biggest_in_col;
343  Score biggest_in_corner = lu.col(k).tail(rows - k).unaryExpr(Scoring()).maxCoeff(&row_of_biggest_in_col);
344  row_of_biggest_in_col += k;
345 
346  row_transpositions[k] = PivIndex(row_of_biggest_in_col);
347 
348  if (!numext::is_exactly_zero(biggest_in_corner)) {
349  if (k != row_of_biggest_in_col) {
350  lu.row(k).swap(lu.row(row_of_biggest_in_col));
351  ++nb_transpositions;
352  }
353 
354  lu.col(k).tail(fix<RRows>(rrows)) /= lu.coeff(k, k);
355  } else if (first_zero_pivot == -1) {
356  // the pivot is exactly zero, we record the index of the first pivot which is exactly 0,
357  // and continue the factorization such we still have A = PLU
358  first_zero_pivot = k;
359  }
360 
361  if (k < rows - 1)
362  lu.bottomRightCorner(fix<RRows>(rrows), fix<RCols>(rcols)).noalias() -=
363  lu.col(k).tail(fix<RRows>(rrows)) * lu.row(k).tail(fix<RCols>(rcols));
364  }
365 
366  // special handling of the last entry
368  Index k = endk;
369  row_transpositions[k] = PivIndex(k);
370  if (numext::is_exactly_zero(Scoring()(lu(k, k))) && first_zero_pivot == -1) first_zero_pivot = k;
371  }
372 
373  return first_zero_pivot;
374  }
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X &x)
Definition: Meta.h:592

References cols, Eigen::numext::is_exactly_zero(), k, lu(), min, rows, size, and Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::UnBlockedAtCompileTime.

Referenced by Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::blocked_lu().

Member Data Documentation

◆ ActualSizeAtCompileTime

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
constexpr int Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::ActualSizeAtCompileTime = UnBlockedAtCompileTime ? SizeAtCompileTime : Dynamic
staticconstexpr

◆ RCols

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
constexpr int Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::RCols = SizeAtCompileTime == 2 ? 1 : Dynamic
staticconstexpr

◆ RRows

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
constexpr int Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::RRows = SizeAtCompileTime == 2 ? 1 : Dynamic
staticconstexpr

◆ UnBlockedAtCompileTime

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
constexpr bool Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::UnBlockedAtCompileTime = SizeAtCompileTime != Dynamic && SizeAtCompileTime <= UnBlockedBound
staticconstexpr

◆ UnBlockedBound

template<typename Scalar , int StorageOrder, typename PivIndex , int SizeAtCompileTime = Dynamic>
constexpr int Eigen::internal::partial_lu_impl< Scalar, StorageOrder, PivIndex, SizeAtCompileTime >::UnBlockedBound = 16
staticconstexpr

The documentation for this struct was generated from the following file: