Eigen::IncompleteLUT< Scalar_, StorageIndex_ > Class Template Reference

Incomplete LU factorization with dual-threshold strategy. More...

+ Inheritance diagram for Eigen::IncompleteLUT< Scalar_, StorageIndex_ >:

Classes

struct  keep_diag
 

Public Types

enum  {
  ColsAtCompileTime ,
  MaxColsAtCompileTime
}
 
typedef SparseMatrix< Scalar, RowMajor, StorageIndexFactorType
 
typedef NumTraits< Scalar >::Real RealScalar
 
typedef Scalar_ Scalar
 
typedef StorageIndex_ StorageIndex
 
typedef Matrix< Scalar, Dynamic, 1 > Vector
 
typedef Matrix< StorageIndex, Dynamic, 1 > VectorI
 

Public Member Functions

template<typename Rhs , typename Dest >
void _solve_impl (const Rhs &b, Dest &x) const
 
template<typename MatrixType >
void analyzePattern (const MatrixType &amat)
 
template<typename MatrixType_ >
void analyzePattern (const MatrixType_ &amat)
 
EIGEN_CONSTEXPR Index cols () const EIGEN_NOEXCEPT
 
template<typename MatrixType >
IncompleteLUTcompute (const MatrixType &amat)
 
template<typename MatrixType >
void factorize (const MatrixType &amat)
 
template<typename MatrixType_ >
void factorize (const MatrixType_ &amat)
 
 IncompleteLUT ()
 
template<typename MatrixType >
 IncompleteLUT (const MatrixType &mat, const RealScalar &droptol=NumTraits< Scalar >::dummy_precision(), int fillfactor=10)
 
ComputationInfo info () const
 Reports whether previous computation was successful. More...
 
EIGEN_CONSTEXPR Index rows () const EIGEN_NOEXCEPT
 
void setDroptol (const RealScalar &droptol)
 
void setFillfactor (int fillfactor)
 
- Public Member Functions inherited from Eigen::SparseSolverBase< IncompleteLUT< Scalar_, int > >
IncompleteLUT< Scalar_, int > & derived ()
 
const IncompleteLUT< Scalar_, int > & derived () const
 
const Solve< IncompleteLUT< Scalar_, int >, Rhs > solve (const MatrixBase< Rhs > &b) const
 
const Solve< IncompleteLUT< Scalar_, int >, Rhs > solve (const SparseMatrixBase< Rhs > &b) const
 
 SparseSolverBase ()
 
 SparseSolverBase (SparseSolverBase &&other)
 
 ~SparseSolverBase ()
 

Protected Types

typedef SparseSolverBase< IncompleteLUTBase
 

Protected Attributes

bool m_analysisIsOk
 
RealScalar m_droptol
 
bool m_factorizationIsOk
 
int m_fillfactor
 
ComputationInfo m_info
 
bool m_isInitialized
 
FactorType m_lu
 
PermutationMatrix< Dynamic, Dynamic, StorageIndexm_P
 
PermutationMatrix< Dynamic, Dynamic, StorageIndexm_Pinv
 
- Protected Attributes inherited from Eigen::SparseSolverBase< IncompleteLUT< Scalar_, int > >
bool m_isInitialized
 

Detailed Description

template<typename Scalar_, typename StorageIndex_ = int>
class Eigen::IncompleteLUT< Scalar_, StorageIndex_ >

Incomplete LU factorization with dual-threshold strategy.

This class follows the sparse solver concept .

During the numerical factorization, two dropping rules are used : 1) any element whose magnitude is less than some tolerance is dropped. This tolerance is obtained by multiplying the input tolerance droptol by the average magnitude of all the original elements in the current row. 2) After the elimination of the row, only the fill largest elements in the L part and the fill largest elements in the U part are kept (in addition to the diagonal element ). Note that fill is computed from the input parameter fillfactor which is used the ratio to control the fill_in relatively to the initial number of nonzero elements.

The two extreme cases are when droptol=0 (to keep all the fill*2 largest elements) and when fill=n/2 with droptol being different to zero.

References : Yousef Saad, ILUT: A dual threshold incomplete LU factorization, Numerical Linear Algebra with Applications, 1(4), pp 387-402, 1994.

NOTE : The following implementation is derived from the ILUT implementation in the SPARSKIT package, Copyright (C) 2005, the Regents of the University of Minnesota released under the terms of the GNU LGPL: http://www-users.cs.umn.edu/~saad/software/SPARSKIT/README However, Yousef Saad gave us permission to relicense his ILUT code to MPL2. See the Eigen mailing list archive, thread: ILUT, date: July 8, 2012: http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2012/07/msg00064.html alternatively, on GMANE: http://comments.gmane.org/gmane.comp.lib.eigen/3302

Definition at line 101 of file IncompleteLUT.h.

Member Typedef Documentation

◆ Base

template<typename Scalar_ , typename StorageIndex_ = int>
typedef SparseSolverBase<IncompleteLUT> Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::Base
protected

Definition at line 104 of file IncompleteLUT.h.

◆ FactorType

template<typename Scalar_ , typename StorageIndex_ = int>
typedef SparseMatrix<Scalar,RowMajor,StorageIndex> Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::FactorType

Definition at line 112 of file IncompleteLUT.h.

◆ RealScalar

template<typename Scalar_ , typename StorageIndex_ = int>
typedef NumTraits<Scalar>::Real Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::RealScalar

Definition at line 109 of file IncompleteLUT.h.

◆ Scalar

template<typename Scalar_ , typename StorageIndex_ = int>
typedef Scalar_ Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::Scalar

Definition at line 107 of file IncompleteLUT.h.

◆ StorageIndex

template<typename Scalar_ , typename StorageIndex_ = int>
typedef StorageIndex_ Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::StorageIndex

Definition at line 108 of file IncompleteLUT.h.

◆ Vector

template<typename Scalar_ , typename StorageIndex_ = int>
typedef Matrix<Scalar,Dynamic,1> Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::Vector

Definition at line 110 of file IncompleteLUT.h.

◆ VectorI

template<typename Scalar_ , typename StorageIndex_ = int>
typedef Matrix<StorageIndex,Dynamic,1> Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::VectorI

Definition at line 111 of file IncompleteLUT.h.

Member Enumeration Documentation

◆ anonymous enum

template<typename Scalar_ , typename StorageIndex_ = int>
anonymous enum
Enumerator
ColsAtCompileTime 
MaxColsAtCompileTime 

Definition at line 114 of file IncompleteLUT.h.

114  {
117  };
const int Dynamic
Definition: Constants.h:24

Constructor & Destructor Documentation

◆ IncompleteLUT() [1/2]

template<typename Scalar_ , typename StorageIndex_ = int>
Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::IncompleteLUT ( )
inline

Definition at line 121 of file IncompleteLUT.h.

122  : m_droptol(NumTraits<Scalar>::dummy_precision()), m_fillfactor(10),
123  m_analysisIsOk(false), m_factorizationIsOk(false)
124  {}

◆ IncompleteLUT() [2/2]

template<typename Scalar_ , typename StorageIndex_ = int>
template<typename MatrixType >
Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::IncompleteLUT ( const MatrixType mat,
const RealScalar droptol = NumTraits<Scalar>::dummy_precision(),
int  fillfactor = 10 
)
inlineexplicit

Definition at line 127 of file IncompleteLUT.h.

128  : m_droptol(droptol),m_fillfactor(fillfactor),
129  m_analysisIsOk(false),m_factorizationIsOk(false)
130  {
131  eigen_assert(fillfactor != 0);
132  compute(mat);
133  }
#define eigen_assert(x)
Definition: Macros.h:902
IncompleteLUT & compute(const MatrixType &amat)

Member Function Documentation

◆ _solve_impl()

template<typename Scalar_ , typename StorageIndex_ = int>
template<typename Rhs , typename Dest >
void Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::_solve_impl ( const Rhs &  b,
Dest &  x 
) const
inline

Definition at line 173 of file IncompleteLUT.h.

174  {
175  x = m_Pinv * b;
176  x = m_lu.template triangularView<UnitLower>().solve(x);
177  x = m_lu.template triangularView<Upper>().solve(x);
178  x = m_P * x;
179  }
Array< int, 3, 1 > b
PermutationMatrix< Dynamic, Dynamic, StorageIndex > m_Pinv
PermutationMatrix< Dynamic, Dynamic, StorageIndex > m_P

◆ analyzePattern() [1/2]

template<typename Scalar_ , typename StorageIndex_ = int>
template<typename MatrixType >
void Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::analyzePattern ( const MatrixType amat)

◆ analyzePattern() [2/2]

template<typename Scalar_ , typename StorageIndex_ = int>
template<typename MatrixType_ >
void Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::analyzePattern ( const MatrixType_ &  amat)

Definition at line 225 of file IncompleteLUT.h.

226 {
227  // Compute the Fill-reducing permutation
228  // Since ILUT does not perform any numerical pivoting,
229  // it is highly preferable to keep the diagonal through symmetric permutations.
230  // To this end, let's symmetrize the pattern and perform AMD on it.
231  SparseMatrix<Scalar,ColMajor, StorageIndex> mat1 = amat;
232  SparseMatrix<Scalar,ColMajor, StorageIndex> mat2 = amat.transpose();
233  // FIXME for a matrix with nearly symmetric pattern, mat2+mat1 is the appropriate choice.
234  // on the other hand for a really non-symmetric pattern, mat2*mat1 should be preferred...
235  SparseMatrix<Scalar,ColMajor, StorageIndex> AtA = mat2 + mat1;
236  AMDOrdering<StorageIndex> ordering;
237  ordering(AtA,m_P);
238  m_Pinv = m_P.inverse(); // cache the inverse permutation
239  m_analysisIsOk = true;
240  m_factorizationIsOk = false;
241  m_isInitialized = true;
242 }
MatrixXd mat1(size, size)
InverseReturnType inverse() const

◆ cols()

template<typename Scalar_ , typename StorageIndex_ = int>
EIGEN_CONSTEXPR Index Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::cols ( void  ) const
inline

Definition at line 137 of file IncompleteLUT.h.

137 { return m_lu.cols(); }
Index cols() const
Definition: SparseMatrix.h:167

◆ compute()

template<typename Scalar_ , typename StorageIndex_ = int>
template<typename MatrixType >
IncompleteLUT& Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::compute ( const MatrixType amat)
inline

Compute an incomplete LU factorization with dual threshold on the matrix mat No pivoting is done in this version

Definition at line 162 of file IncompleteLUT.h.

163  {
164  analyzePattern(amat);
165  factorize(amat);
166  return *this;
167  }
void analyzePattern(const MatrixType &amat)
void factorize(const MatrixType &amat)

◆ factorize() [1/2]

template<typename Scalar_ , typename StorageIndex_ = int>
template<typename MatrixType >
void Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::factorize ( const MatrixType amat)

◆ factorize() [2/2]

template<typename Scalar_ , typename StorageIndex_ = int>
template<typename MatrixType_ >
void Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::factorize ( const MatrixType_ &  amat)

Definition at line 246 of file IncompleteLUT.h.

247 {
248  using std::sqrt;
249  using std::swap;
250  using std::abs;
252 
253  eigen_assert((amat.rows() == amat.cols()) && "The factorization should be done on a square matrix");
254  Index n = amat.cols(); // Size of the matrix
255  m_lu.resize(n,n);
256  // Declare Working vectors and variables
257  Vector u(n) ; // real values of the row -- maximum size is n --
258  VectorI ju(n); // column position of the values in u -- maximum size is n
259  VectorI jr(n); // Indicate the position of the nonzero elements in the vector u -- A zero location is indicated by -1
260 
261  // Apply the fill-reducing permutation
262  eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
263  SparseMatrix<Scalar,RowMajor, StorageIndex> mat;
264  mat = amat.twistedBy(m_Pinv);
265 
266  // Initialization
267  jr.fill(-1);
268  ju.fill(0);
269  u.fill(0);
270 
271  // number of largest elements to keep in each row:
272  Index fill_in = (amat.nonZeros()*m_fillfactor)/n + 1;
273  if (fill_in > n) fill_in = n;
274 
275  // number of largest nonzero elements to keep in the L and the U part of the current row:
276  Index nnzL = fill_in/2;
277  Index nnzU = nnzL;
278  m_lu.reserve(n * (nnzL + nnzU + 1));
279 
280  // global loop over the rows of the sparse matrix
281  for (Index ii = 0; ii < n; ii++)
282  {
283  // 1 - copy the lower and the upper part of the row i of mat in the working vector u
284 
285  Index sizeu = 1; // number of nonzero elements in the upper part of the current row
286  Index sizel = 0; // number of nonzero elements in the lower part of the current row
287  ju(ii) = convert_index<StorageIndex>(ii);
288  u(ii) = 0;
289  jr(ii) = convert_index<StorageIndex>(ii);
290  RealScalar rownorm = 0;
291 
292  typename FactorType::InnerIterator j_it(mat, ii); // Iterate through the current row ii
293  for (; j_it; ++j_it)
294  {
295  Index k = j_it.index();
296  if (k < ii)
297  {
298  // copy the lower part
299  ju(sizel) = convert_index<StorageIndex>(k);
300  u(sizel) = j_it.value();
301  jr(k) = convert_index<StorageIndex>(sizel);
302  ++sizel;
303  }
304  else if (k == ii)
305  {
306  u(ii) = j_it.value();
307  }
308  else
309  {
310  // copy the upper part
311  Index jpos = ii + sizeu;
312  ju(jpos) = convert_index<StorageIndex>(k);
313  u(jpos) = j_it.value();
314  jr(k) = convert_index<StorageIndex>(jpos);
315  ++sizeu;
316  }
317  rownorm += numext::abs2(j_it.value());
318  }
319 
320  // 2 - detect possible zero row
321  if(rownorm==0)
322  {
324  return;
325  }
326  // Take the 2-norm of the current row as a relative tolerance
327  rownorm = sqrt(rownorm);
328 
329  // 3 - eliminate the previous nonzero rows
330  Index jj = 0;
331  Index len = 0;
332  while (jj < sizel)
333  {
334  // In order to eliminate in the correct order,
335  // we must select first the smallest column index among ju(jj:sizel)
336  Index k;
337  Index minrow = ju.segment(jj,sizel-jj).minCoeff(&k); // k is relative to the segment
338  k += jj;
339  if (minrow != ju(jj))
340  {
341  // swap the two locations
342  Index j = ju(jj);
343  swap(ju(jj), ju(k));
344  jr(minrow) = convert_index<StorageIndex>(jj);
345  jr(j) = convert_index<StorageIndex>(k);
346  swap(u(jj), u(k));
347  }
348  // Reset this location
349  jr(minrow) = -1;
350 
351  // Start elimination
352  typename FactorType::InnerIterator ki_it(m_lu, minrow);
353  while (ki_it && ki_it.index() < minrow) ++ki_it;
354  eigen_internal_assert(ki_it && ki_it.col()==minrow);
355  Scalar fact = u(jj) / ki_it.value();
356 
357  // drop too small elements
358  if(abs(fact) <= m_droptol)
359  {
360  jj++;
361  continue;
362  }
363 
364  // linear combination of the current row ii and the row minrow
365  ++ki_it;
366  for (; ki_it; ++ki_it)
367  {
368  Scalar prod = fact * ki_it.value();
369  Index j = ki_it.index();
370  Index jpos = jr(j);
371  if (jpos == -1) // fill-in element
372  {
373  Index newpos;
374  if (j >= ii) // dealing with the upper part
375  {
376  newpos = ii + sizeu;
377  sizeu++;
378  eigen_internal_assert(sizeu<=n);
379  }
380  else // dealing with the lower part
381  {
382  newpos = sizel;
383  sizel++;
384  eigen_internal_assert(sizel<=ii);
385  }
386  ju(newpos) = convert_index<StorageIndex>(j);
387  u(newpos) = -prod;
388  jr(j) = convert_index<StorageIndex>(newpos);
389  }
390  else
391  u(jpos) -= prod;
392  }
393  // store the pivot element
394  u(len) = fact;
395  ju(len) = convert_index<StorageIndex>(minrow);
396  ++len;
397 
398  jj++;
399  } // end of the elimination on the row ii
400 
401  // reset the upper part of the pointer jr to zero
402  for(Index k = 0; k <sizeu; k++) jr(ju(ii+k)) = -1;
403 
404  // 4 - partially sort and insert the elements in the m_lu matrix
405 
406  // sort the L-part of the row
407  sizel = len;
408  len = (std::min)(sizel, nnzL);
409  typename Vector::SegmentReturnType ul(u.segment(0, sizel));
410  typename VectorI::SegmentReturnType jul(ju.segment(0, sizel));
411  internal::QuickSplit(ul, jul, len);
412 
413  // store the largest m_fill elements of the L part
414  m_lu.startVec(ii);
415  for(Index k = 0; k < len; k++)
416  m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k);
417 
418  // store the diagonal element
419  // apply a shifting rule to avoid zero pivots (we are doing an incomplete factorization)
420  if (u(ii) == Scalar(0))
421  u(ii) = sqrt(m_droptol) * rownorm;
422  m_lu.insertBackByOuterInnerUnordered(ii, ii) = u(ii);
423 
424  // sort the U-part of the row
425  // apply the dropping rule first
426  len = 0;
427  for(Index k = 1; k < sizeu; k++)
428  {
429  if(abs(u(ii+k)) > m_droptol * rownorm )
430  {
431  ++len;
432  u(ii + len) = u(ii + k);
433  ju(ii + len) = ju(ii + k);
434  }
435  }
436  sizeu = len + 1; // +1 to take into account the diagonal element
437  len = (std::min)(sizeu, nnzU);
438  typename Vector::SegmentReturnType uu(u.segment(ii+1, sizeu-1));
439  typename VectorI::SegmentReturnType juu(ju.segment(ii+1, sizeu-1));
440  internal::QuickSplit(uu, juu, len);
441 
442  // store the largest elements of the U part
443  for(Index k = ii + 1; k < ii + len; k++)
444  m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k);
445  }
446  m_lu.finalize();
448 
449  m_factorizationIsOk = true;
450  m_info = Success;
451 }
const AbsReturnType abs() const
const SqrtReturnType sqrt() const
int n
#define eigen_internal_assert(x)
Definition: Macros.h:908
Matrix< StorageIndex, Dynamic, 1 > VectorI
ComputationInfo m_info
NumTraits< Scalar >::Real RealScalar
Matrix< Scalar, Dynamic, 1 > Vector
void startVec(Index outer)
Definition: SparseMatrix.h:447
void resize(Index rows, Index cols)
Definition: SparseMatrix.h:739
void reserve(Index reserveSize)
Definition: SparseMatrix.h:300
Scalar & insertBackByOuterInnerUnordered(Index outer, Index inner)
Definition: SparseMatrix.h:437
@ NumericalIssue
Definition: Constants.h:448
@ Success
Definition: Constants.h:446
bfloat16() min(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:684
Index QuickSplit(VectorV &row, VectorI &ind, Index ncut)
Definition: IncompleteLUT.h:31
IndexDest convert_index(const IndexSrc &idx)
Definition: XprHelper.h:64
void swap(scoped_array< T > &a, scoped_array< T > &b)
Definition: Memory.h:788
bool abs2(bool x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
std::ptrdiff_t j

◆ info()

template<typename Scalar_ , typename StorageIndex_ = int>
ComputationInfo Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::info ( ) const
inline

Reports whether previous computation was successful.

Returns
Success if computation was successful, NumericalIssue if the matrix.appears to be negative.

Definition at line 144 of file IncompleteLUT.h.

145  {
146  eigen_assert(m_isInitialized && "IncompleteLUT is not initialized.");
147  return m_info;
148  }

◆ rows()

template<typename Scalar_ , typename StorageIndex_ = int>
EIGEN_CONSTEXPR Index Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::rows ( void  ) const
inline

Definition at line 135 of file IncompleteLUT.h.

135 { return m_lu.rows(); }
Index rows() const
Definition: SparseMatrix.h:165

◆ setDroptol()

template<typename Scalar , typename StorageIndex >
void Eigen::IncompleteLUT< Scalar, StorageIndex >::setDroptol ( const RealScalar droptol)

Set control parameter droptol

Parameters
droptolDrop any element whose magnitude is less than this tolerance

Definition at line 208 of file IncompleteLUT.h.

209 {
210  this->m_droptol = droptol;
211 }

◆ setFillfactor()

template<typename Scalar , typename StorageIndex >
void Eigen::IncompleteLUT< Scalar, StorageIndex >::setFillfactor ( int  fillfactor)

Set control parameter fillfactor

Parameters
fillfactorThis is used to compute the number fill_in of largest elements to keep on each row.

Definition at line 218 of file IncompleteLUT.h.

219 {
220  this->m_fillfactor = fillfactor;
221 }

Member Data Documentation

◆ m_analysisIsOk

template<typename Scalar_ , typename StorageIndex_ = int>
bool Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::m_analysisIsOk
protected

Definition at line 196 of file IncompleteLUT.h.

◆ m_droptol

template<typename Scalar_ , typename StorageIndex_ = int>
RealScalar Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::m_droptol
protected

Definition at line 194 of file IncompleteLUT.h.

◆ m_factorizationIsOk

template<typename Scalar_ , typename StorageIndex_ = int>
bool Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::m_factorizationIsOk
protected

Definition at line 197 of file IncompleteLUT.h.

◆ m_fillfactor

template<typename Scalar_ , typename StorageIndex_ = int>
int Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::m_fillfactor
protected

Definition at line 195 of file IncompleteLUT.h.

◆ m_info

template<typename Scalar_ , typename StorageIndex_ = int>
ComputationInfo Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::m_info
protected

Definition at line 198 of file IncompleteLUT.h.

◆ m_isInitialized

template<typename Scalar_ , typename StorageIndex_ = int>
bool Eigen::SparseSolverBase< Derived >::m_isInitialized
mutableprotected

Definition at line 123 of file SparseSolverBase.h.

◆ m_lu

template<typename Scalar_ , typename StorageIndex_ = int>
FactorType Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::m_lu
protected

Definition at line 193 of file IncompleteLUT.h.

◆ m_P

template<typename Scalar_ , typename StorageIndex_ = int>
PermutationMatrix<Dynamic,Dynamic,StorageIndex> Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::m_P
protected

Definition at line 199 of file IncompleteLUT.h.

◆ m_Pinv

template<typename Scalar_ , typename StorageIndex_ = int>
PermutationMatrix<Dynamic,Dynamic,StorageIndex> Eigen::IncompleteLUT< Scalar_, StorageIndex_ >::m_Pinv
protected

Definition at line 200 of file IncompleteLUT.h.


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