10 #ifndef EIGEN_ITERATIVE_SOLVER_BASE_H
11 #define EIGEN_ITERATIVE_SOLVER_BASE_H
17 template<
typename MatrixType>
21 template <
typename T0>
24 template <
typename T> any_conversion(
const volatile T&);
25 template <
typename T> any_conversion(T&);
27 struct yes {
int a[1];};
28 struct no {
int a[2];};
33 static no test(any_conversion<T>, ...);
36 static MatrixType ms_from;
37 enum { value =
sizeof(test<MatrixType>(ms_from, 0))==
sizeof(yes) };
40 template<
typename MatrixType>
46 template<typename MatrixType, bool MatrixFree = !internal::is_ref_compatible<MatrixType>::value>
50 template<
typename MatrixType>
55 template<
int UpLo>
struct ConstSelfAdjointViewReturnType {
56 typedef typename ActualMatrixType::template ConstSelfAdjointViewReturnType<UpLo>::Type Type;
64 : m_dummy(0,0), m_matrix(m_dummy)
67 template<
typename InputType>
68 generic_matrix_wrapper(
const InputType &mat)
72 const ActualMatrixType& matrix()
const
77 template<
typename MatrixDerived>
78 void grab(
const EigenBase<MatrixDerived> &mat)
80 m_matrix.~Ref<
const MatrixType>();
81 ::new (&m_matrix) Ref<const MatrixType>(mat.derived());
84 void grab(
const Ref<const MatrixType> &mat)
86 if(&(mat.derived()) != &m_matrix)
88 m_matrix.~Ref<
const MatrixType>();
89 ::new (&m_matrix) Ref<const MatrixType>(mat);
95 ActualMatrixType m_matrix;
99 template<
typename MatrixType>
103 typedef MatrixType ActualMatrixType;
104 template<
int UpLo>
struct ConstSelfAdjointViewReturnType
106 typedef ActualMatrixType Type;
117 generic_matrix_wrapper(
const MatrixType &mat)
121 const ActualMatrixType& matrix()
const
126 void grab(
const MatrixType &mat)
132 const ActualMatrixType *mp_matrix;
142 template<
typename Derived>
147 using Base::m_isInitialized;
152 typedef typename MatrixType::Scalar Scalar;
153 typedef typename MatrixType::StorageIndex StorageIndex;
154 typedef typename MatrixType::RealScalar RealScalar;
157 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
158 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
181 template<
typename MatrixDerived>
183 : m_matrixWrapper(A.derived())
196 template<
typename MatrixDerived>
200 m_preconditioner.analyzePattern(matrix());
201 m_isInitialized =
true;
202 m_analysisIsOk =
true;
203 m_info = m_preconditioner.info();
216 template<
typename MatrixDerived>
219 eigen_assert(m_analysisIsOk &&
"You must first call analyzePattern()");
221 m_preconditioner.factorize(matrix());
222 m_factorizationIsOk =
true;
223 m_info = m_preconditioner.info();
237 template<
typename MatrixDerived>
241 m_preconditioner.compute(matrix());
242 m_isInitialized =
true;
243 m_analysisIsOk =
true;
244 m_factorizationIsOk =
true;
245 m_info = m_preconditioner.info();
250 Index rows()
const {
return matrix().rows(); }
253 Index cols()
const {
return matrix().cols(); }
283 return (m_maxIterations<0) ? 2*matrix().cols() : m_maxIterations;
291 m_maxIterations = maxIters;
298 eigen_assert(m_isInitialized &&
"ConjugateGradient is not initialized.");
307 eigen_assert(m_isInitialized &&
"ConjugateGradient is not initialized.");
316 template<
typename Rhs,
typename Guess>
320 eigen_assert(m_isInitialized &&
"Solver is not initialized.");
321 eigen_assert(derived().rows()==b.rows() &&
"solve(): invalid number of rows of the right hand side matrix b");
328 eigen_assert(m_isInitialized &&
"IterativeSolverBase is not initialized.");
333 template<
typename Rhs,
typename DestDerived>
336 eigen_assert(rows()==b.rows());
338 Index rhsCols = b.cols();
339 Index size = b.rows();
340 DestDerived& dest(aDest.derived());
341 typedef typename DestDerived::Scalar DestScalar;
346 typename DestDerived::PlainObject tmp(cols(),rhsCols);
348 for(
Index k=0; k<rhsCols; ++k)
352 derived()._solve_vector_with_guess_impl(tb,tx);
353 tmp.col(k) = tx.sparseView(0);
362 m_info = global_info;
366 template<
typename Rhs,
typename DestDerived>
367 typename internal::enable_if<Rhs::ColsAtCompileTime!=1 && DestDerived::ColsAtCompileTime!=1>::type
368 _solve_with_guess_impl(
const Rhs& b, MatrixBase<DestDerived> &aDest)
const
370 eigen_assert(rows()==b.rows());
372 Index rhsCols = b.cols();
373 DestDerived& dest(aDest.derived());
375 for(
Index k=0; k<rhsCols; ++k)
377 typename DestDerived::ColXpr xk(dest,k);
378 typename Rhs::ConstColXpr bk(b,k);
379 derived()._solve_vector_with_guess_impl(bk,xk);
388 m_info = global_info;
391 template<
typename Rhs,
typename DestDerived>
392 typename internal::enable_if<Rhs::ColsAtCompileTime==1 || DestDerived::ColsAtCompileTime==1>::type
393 _solve_with_guess_impl(
const Rhs& b, MatrixBase<DestDerived> &dest)
const
395 derived()._solve_vector_with_guess_impl(b,dest.derived());
399 template<
typename Rhs,
typename Dest>
400 void _solve_impl(
const Rhs& b, Dest& x)
const
403 derived()._solve_with_guess_impl(b,x);
409 m_isInitialized =
false;
410 m_analysisIsOk =
false;
411 m_factorizationIsOk =
false;
412 m_maxIterations = -1;
413 m_tolerance = NumTraits<Scalar>::epsilon();
416 typedef internal::generic_matrix_wrapper<MatrixType> MatrixWrapper;
417 typedef typename MatrixWrapper::ActualMatrixType ActualMatrixType;
419 const ActualMatrixType& matrix()
const
421 return m_matrixWrapper.matrix();
424 template<
typename InputType>
425 void grab(
const InputType &A)
427 m_matrixWrapper.grab(A);
430 MatrixWrapper m_matrixWrapper;
431 Preconditioner m_preconditioner;
433 Index m_maxIterations;
434 RealScalar m_tolerance;
436 mutable RealScalar m_error;
437 mutable Index m_iterations;
439 mutable bool m_analysisIsOk, m_factorizationIsOk;
444 #endif // EIGEN_ITERATIVE_SOLVER_BASE_H