11 #ifndef EIGEN_INCOMPLETE_LUT_H
12 #define EIGEN_INCOMPLETE_LUT_H
30 template <
typename VectorV,
typename VectorI>
33 typedef typename VectorV::RealScalar RealScalar;
43 if (ncut < first || ncut >
last )
return 0;
47 RealScalar abskey =
abs(
row(mid));
59 if (mid > ncut)
last = mid - 1;
60 else if (mid < ncut )
first = mid + 1;
61 }
while (mid != ncut );
100 template <
typename Scalar_,
typename StorageIndex_ =
int>
126 template<
typename MatrixType>
150 template<
typename MatrixType>
153 template<
typename MatrixType>
161 template<
typename MatrixType>
172 template<
typename Rhs,
typename Dest>
176 x =
m_lu.template triangularView<UnitLower>().solve(
x);
177 x =
m_lu.template triangularView<Upper>().solve(
x);
207 template<
typename Scalar,
typename StorageIndex>
210 this->m_droptol = droptol;
217 template<
typename Scalar,
typename StorageIndex>
220 this->m_fillfactor = fillfactor;
223 template <
typename Scalar,
typename StorageIndex>
224 template<
typename MatrixType_>
238 m_Pinv = m_P.inverse();
239 m_analysisIsOk =
true;
240 m_factorizationIsOk =
false;
241 m_isInitialized =
true;
244 template <
typename Scalar,
typename StorageIndex>
245 template<
typename MatrixType_>
253 eigen_assert((amat.rows() == amat.cols()) &&
"The factorization should be done on a square matrix");
262 eigen_assert(m_analysisIsOk &&
"You must first call analyzePattern()");
264 mat = amat.twistedBy(m_Pinv);
272 Index fill_in = (amat.nonZeros()*m_fillfactor)/
n + 1;
273 if (fill_in >
n) fill_in =
n;
276 Index nnzL = fill_in/2;
278 m_lu.reserve(
n * (nnzL + nnzU + 1));
281 for (
Index ii = 0; ii <
n; ii++)
287 ju(ii) = convert_index<StorageIndex>(ii);
289 jr(ii) = convert_index<StorageIndex>(ii);
292 typename FactorType::InnerIterator j_it(
mat, ii);
295 Index k = j_it.index();
299 ju(sizel) = convert_index<StorageIndex>(k);
300 u(sizel) = j_it.value();
301 jr(k) = convert_index<StorageIndex>(sizel);
306 u(ii) = j_it.value();
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);
327 rownorm =
sqrt(rownorm);
337 Index minrow = ju.segment(jj,sizel-jj).minCoeff(&k);
339 if (minrow != ju(jj))
344 jr(minrow) = convert_index<StorageIndex>(jj);
345 jr(
j) = convert_index<StorageIndex>(k);
352 typename FactorType::InnerIterator ki_it(m_lu, minrow);
353 while (ki_it && ki_it.index() < minrow) ++ki_it;
355 Scalar fact = u(jj) / ki_it.value();
358 if(
abs(fact) <= m_droptol)
366 for (; ki_it; ++ki_it)
368 Scalar prod = fact * ki_it.value();
386 ju(newpos) = convert_index<StorageIndex>(
j);
388 jr(
j) = convert_index<StorageIndex>(newpos);
395 ju(len) = convert_index<StorageIndex>(minrow);
402 for(
Index k = 0; k <sizeu; k++) jr(ju(ii+k)) = -1;
409 typename Vector::SegmentReturnType ul(u.segment(0, sizel));
410 typename VectorI::SegmentReturnType jul(ju.segment(0, sizel));
415 for(
Index k = 0; k < len; k++)
416 m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k);
421 u(ii) =
sqrt(m_droptol) * rownorm;
422 m_lu.insertBackByOuterInnerUnordered(ii, ii) = u(ii);
427 for(
Index k = 1; k < sizeu; k++)
429 if(
abs(u(ii+k)) > m_droptol * rownorm )
432 u(ii + len) = u(ii + k);
433 ju(ii + len) = ju(ii + k);
438 typename Vector::SegmentReturnType uu(u.segment(ii+1, sizeu-1));
439 typename VectorI::SegmentReturnType juu(ju.segment(ii+1, sizeu-1));
443 for(
Index k = ii + 1; k < ii + len; k++)
444 m_lu.insertBackByOuterInnerUnordered(ii,ju(k)) = u(k);
447 m_lu.makeCompressed();
449 m_factorizationIsOk =
true;
const AbsReturnType abs() const
const SqrtReturnType sqrt() const
RowXpr row(Index i)
This is the const version of row(). */.
ColXpr col(Index i)
This is the const version of col().
#define eigen_internal_assert(x)
MatrixXd mat1(size, size)
Matrix< float, 1, Dynamic > MatrixType
Incomplete LU factorization with dual-threshold strategy.
Matrix< StorageIndex, Dynamic, 1 > VectorI
SparseMatrix< Scalar, RowMajor, StorageIndex > FactorType
void analyzePattern(const MatrixType &amat)
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
void setFillfactor(int fillfactor)
void factorize(const MatrixType &amat)
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
NumTraits< Scalar >::Real RealScalar
IncompleteLUT & compute(const MatrixType &amat)
void _solve_impl(const Rhs &b, Dest &x) const
void setDroptol(const RealScalar &droptol)
SparseSolverBase< IncompleteLUT > Base
StorageIndex_ StorageIndex
PermutationMatrix< Dynamic, Dynamic, StorageIndex > m_Pinv
IncompleteLUT(const MatrixType &mat, const RealScalar &droptol=NumTraits< Scalar >::dummy_precision(), int fillfactor=10)
Matrix< Scalar, Dynamic, 1 > Vector
ComputationInfo info() const
Reports whether previous computation was successful.
PermutationMatrix< Dynamic, Dynamic, StorageIndex > m_P
TransposeReturnType transpose()
A base class for sparse solvers.
bfloat16() min(const bfloat16 &a, const bfloat16 &b)
Index QuickSplit(VectorV &row, VectorI &ind, Index ncut)
IndexDest convert_index(const IndexSrc &idx)
EIGEN_CONSTEXPR Index first(const T &x) EIGEN_NOEXCEPT
void swap(scoped_array< T > &a, scoped_array< T > &b)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
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)
bool operator()(const Index &row, const Index &col, const Scalar &) const
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.