WPILibC++ 2023.4.3-108-ge5452e3
IterativeSolverBase.h
Go to the documentation of this file.
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2011-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#ifndef EIGEN_ITERATIVE_SOLVER_BASE_H
11#define EIGEN_ITERATIVE_SOLVER_BASE_H
12
13namespace Eigen {
14
15namespace internal {
16
17template<typename MatrixType>
19{
20private:
21 template <typename T0>
22 struct any_conversion
23 {
24 template <typename T> any_conversion(const volatile T&);
25 template <typename T> any_conversion(T&);
26 };
27 struct yes {int a[1];};
28 struct no {int a[2];};
29
30 template<typename T>
31 static yes test(const Ref<const T>&, int);
32 template<typename T>
33 static no test(any_conversion<T>, ...);
34
35public:
36 static MatrixType ms_from;
37 enum { value = sizeof(test<MatrixType>(ms_from, 0))==sizeof(yes) };
38};
39
40template<typename MatrixType>
42{
44};
45
46template<typename MatrixType, bool MatrixFree = !internal::is_ref_compatible<MatrixType>::value>
48
49// We have an explicit matrix at hand, compatible with Ref<>
50template<typename MatrixType>
51class generic_matrix_wrapper<MatrixType,false>
52{
53public:
55 template<int UpLo> struct ConstSelfAdjointViewReturnType {
56 typedef typename ActualMatrixType::template ConstSelfAdjointViewReturnType<UpLo>::Type Type;
57 };
58
59 enum {
60 MatrixFree = false
61 };
62
64 : m_dummy(0,0), m_matrix(m_dummy)
65 {}
66
67 template<typename InputType>
68 generic_matrix_wrapper(const InputType &mat)
69 : m_matrix(mat)
70 {}
71
72 const ActualMatrixType& matrix() const
73 {
74 return m_matrix;
75 }
76
77 template<typename MatrixDerived>
79 {
80 m_matrix.~Ref<const MatrixType>();
81 ::new (&m_matrix) Ref<const MatrixType>(mat.derived());
82 }
83
84 void grab(const Ref<const MatrixType> &mat)
85 {
86 if(&(mat.derived()) != &m_matrix)
87 {
88 m_matrix.~Ref<const MatrixType>();
89 ::new (&m_matrix) Ref<const MatrixType>(mat);
90 }
91 }
92
93protected:
94 MatrixType m_dummy; // used to default initialize the Ref<> object
96};
97
98// MatrixType is not compatible with Ref<> -> matrix-free wrapper
99template<typename MatrixType>
100class generic_matrix_wrapper<MatrixType,true>
101{
102public:
103 typedef MatrixType ActualMatrixType;
104 template<int UpLo> struct ConstSelfAdjointViewReturnType
105 {
107 };
108
109 enum {
110 MatrixFree = true
111 };
112
114 : mp_matrix(0)
115 {}
116
117 generic_matrix_wrapper(const MatrixType &mat)
118 : mp_matrix(&mat)
119 {}
120
122 {
123 return *mp_matrix;
124 }
125
126 void grab(const MatrixType &mat)
127 {
128 mp_matrix = &mat;
129 }
130
131protected:
133};
134
135}
136
137/** \ingroup IterativeLinearSolvers_Module
138 * \brief Base class for linear iterative solvers
139 *
140 * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner
141 */
142template< typename Derived>
144{
145protected:
148
149public:
152 typedef typename MatrixType::Scalar Scalar;
153 typedef typename MatrixType::StorageIndex StorageIndex;
154 typedef typename MatrixType::RealScalar RealScalar;
155
156 enum {
157 ColsAtCompileTime = MatrixType::ColsAtCompileTime,
158 MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
159 };
160
161public:
162
163 using Base::derived;
164
165 /** Default constructor. */
167 {
168 init();
169 }
170
171 /** Initialize the solver with matrix \a A for further \c Ax=b solving.
172 *
173 * This constructor is a shortcut for the default constructor followed
174 * by a call to compute().
175 *
176 * \warning this class stores a reference to the matrix A as well as some
177 * precomputed values that depend on it. Therefore, if \a A is changed
178 * this class becomes invalid. Call compute() to update it with the new
179 * matrix A, or modify a copy of A.
180 */
181 template<typename MatrixDerived>
184 {
185 init();
186 compute(matrix());
187 }
188
190
191 /** Initializes the iterative solver for the sparsity pattern of the matrix \a A for further solving \c Ax=b problems.
192 *
193 * Currently, this function mostly calls analyzePattern on the preconditioner. In the future
194 * we might, for instance, implement column reordering for faster matrix vector products.
195 */
196 template<typename MatrixDerived>
198 {
199 grab(A.derived());
200 m_preconditioner.analyzePattern(matrix());
201 m_isInitialized = true;
202 m_analysisIsOk = true;
203 m_info = m_preconditioner.info();
204 return derived();
205 }
206
207 /** Initializes the iterative solver with the numerical values of the matrix \a A for further solving \c Ax=b problems.
208 *
209 * Currently, this function mostly calls factorize on the preconditioner.
210 *
211 * \warning this class stores a reference to the matrix A as well as some
212 * precomputed values that depend on it. Therefore, if \a A is changed
213 * this class becomes invalid. Call compute() to update it with the new
214 * matrix A, or modify a copy of A.
215 */
216 template<typename MatrixDerived>
218 {
219 eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
220 grab(A.derived());
221 m_preconditioner.factorize(matrix());
222 m_factorizationIsOk = true;
223 m_info = m_preconditioner.info();
224 return derived();
225 }
226
227 /** Initializes the iterative solver with the matrix \a A for further solving \c Ax=b problems.
228 *
229 * Currently, this function mostly initializes/computes the preconditioner. In the future
230 * we might, for instance, implement column reordering for faster matrix vector products.
231 *
232 * \warning this class stores a reference to the matrix A as well as some
233 * precomputed values that depend on it. Therefore, if \a A is changed
234 * this class becomes invalid. Call compute() to update it with the new
235 * matrix A, or modify a copy of A.
236 */
237 template<typename MatrixDerived>
239 {
240 grab(A.derived());
241 m_preconditioner.compute(matrix());
242 m_isInitialized = true;
243 m_analysisIsOk = true;
244 m_factorizationIsOk = true;
245 m_info = m_preconditioner.info();
246 return derived();
247 }
248
249 /** \internal */
250 EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return matrix().rows(); }
251
252 /** \internal */
253 EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return matrix().cols(); }
254
255 /** \returns the tolerance threshold used by the stopping criteria.
256 * \sa setTolerance()
257 */
258 RealScalar tolerance() const { return m_tolerance; }
259
260 /** Sets the tolerance threshold used by the stopping criteria.
261 *
262 * This value is used as an upper bound to the relative residual error: |Ax-b|/|b|.
263 * The default value is the machine precision given by NumTraits<Scalar>::epsilon()
264 */
266 {
268 return derived();
269 }
270
271 /** \returns a read-write reference to the preconditioner for custom configuration. */
273
274 /** \returns a read-only reference to the preconditioner. */
276
277 /** \returns the max number of iterations.
278 * It is either the value set by setMaxIterations or, by default,
279 * twice the number of columns of the matrix.
280 */
282 {
283 return (m_maxIterations<0) ? 2*matrix().cols() : m_maxIterations;
284 }
285
286 /** Sets the max number of iterations.
287 * Default is twice the number of columns of the matrix.
288 */
289 Derived& setMaxIterations(Index maxIters)
290 {
291 m_maxIterations = maxIters;
292 return derived();
293 }
294
295 /** \returns the number of iterations performed during the last solve */
297 {
298 eigen_assert(m_isInitialized && "ConjugateGradient is not initialized.");
299 return m_iterations;
300 }
301
302 /** \returns the tolerance error reached during the last solve.
303 * It is a close approximation of the true relative residual error |Ax-b|/|b|.
304 */
306 {
307 eigen_assert(m_isInitialized && "ConjugateGradient is not initialized.");
308 return m_error;
309 }
310
311 /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A
312 * and \a x0 as an initial solution.
313 *
314 * \sa solve(), compute()
315 */
316 template<typename Rhs,typename Guess>
318 solveWithGuess(const MatrixBase<Rhs>& b, const Guess& x0) const
319 {
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");
322 return SolveWithGuess<Derived, Rhs, Guess>(derived(), b.derived(), x0);
323 }
324
325 /** \returns Success if the iterations converged, and NoConvergence otherwise. */
327 {
328 eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized.");
329 return m_info;
330 }
331
332 /** \internal */
333 template<typename Rhs, typename DestDerived>
335 {
336 eigen_assert(rows()==b.rows());
337
338 Index rhsCols = b.cols();
339 Index size = b.rows();
340 DestDerived& dest(aDest.derived());
341 typedef typename DestDerived::Scalar DestScalar;
344 // We do not directly fill dest because sparse expressions have to be free of aliasing issue.
345 // For non square least-square problems, b and dest might not have the same size whereas they might alias each-other.
346 typename DestDerived::PlainObject tmp(cols(),rhsCols);
347 ComputationInfo global_info = Success;
348 for(Index k=0; k<rhsCols; ++k)
349 {
350 tb = b.col(k);
351 tx = dest.col(k);
352 derived()._solve_vector_with_guess_impl(tb,tx);
353 tmp.col(k) = tx.sparseView(0);
354
355 // The call to _solve_vector_with_guess_impl updates m_info, so if it failed for a previous column
356 // we need to restore it to the worst value.
358 global_info = NumericalIssue;
359 else if(m_info==NoConvergence)
360 global_info = NoConvergence;
361 }
362 m_info = global_info;
363 dest.swap(tmp);
364 }
365
366 template<typename Rhs, typename DestDerived>
369 {
370 eigen_assert(rows()==b.rows());
371
372 Index rhsCols = b.cols();
373 DestDerived& dest(aDest.derived());
374 ComputationInfo global_info = Success;
375 for(Index k=0; k<rhsCols; ++k)
376 {
377 typename DestDerived::ColXpr xk(dest,k);
378 typename Rhs::ConstColXpr bk(b,k);
379 derived()._solve_vector_with_guess_impl(bk,xk);
380
381 // The call to _solve_vector_with_guess updates m_info, so if it failed for a previous column
382 // we need to restore it to the worst value.
384 global_info = NumericalIssue;
385 else if(m_info==NoConvergence)
386 global_info = NoConvergence;
387 }
388 m_info = global_info;
389 }
390
391 template<typename Rhs, typename DestDerived>
394 {
395 derived()._solve_vector_with_guess_impl(b,dest.derived());
396 }
397
398 /** \internal default initial guess = 0 */
399 template<typename Rhs,typename Dest>
400 void _solve_impl(const Rhs& b, Dest& x) const
401 {
402 x.setZero();
403 derived()._solve_with_guess_impl(b,x);
404 }
405
406protected:
407 void init()
408 {
409 m_isInitialized = false;
410 m_analysisIsOk = false;
411 m_factorizationIsOk = false;
412 m_maxIterations = -1;
414 }
415
417 typedef typename MatrixWrapper::ActualMatrixType ActualMatrixType;
418
420 {
421 return m_matrixWrapper.matrix();
422 }
423
424 template<typename InputType>
425 void grab(const InputType &A)
426 {
427 m_matrixWrapper.grab(A);
428 }
429
432
435
440};
441
442} // end namespace Eigen
443
444#endif // EIGEN_ITERATIVE_SOLVER_BASE_H
const Block< const Derived, internal::traits< Derived >::RowsAtCompileTime, 1, !IsRowMajor > ConstColXpr
Definition: BlockMethods.h:15
Block< Derived, internal::traits< Derived >::RowsAtCompileTime, 1, !IsRowMajor > ColXpr
Definition: BlockMethods.h:14
#define EIGEN_NOEXCEPT
Definition: Macros.h:1428
#define EIGEN_CONSTEXPR
Definition: Macros.h:797
#define eigen_assert(x)
Definition: Macros.h:1047
Base class for linear iterative solvers.
Definition: IterativeSolverBase.h:144
internal::generic_matrix_wrapper< MatrixType > MatrixWrapper
Definition: IterativeSolverBase.h:416
bool m_analysisIsOk
Definition: IterativeSolverBase.h:439
IterativeSolverBase()
Default constructor.
Definition: IterativeSolverBase.h:166
ComputationInfo info() const
Definition: IterativeSolverBase.h:326
bool m_factorizationIsOk
Definition: IterativeSolverBase.h:439
RealScalar error() const
Definition: IterativeSolverBase.h:305
Index maxIterations() const
Definition: IterativeSolverBase.h:281
Derived & setMaxIterations(Index maxIters)
Sets the max number of iterations.
Definition: IterativeSolverBase.h:289
internal::traits< Derived >::MatrixType MatrixType
Definition: IterativeSolverBase.h:150
ComputationInfo m_info
Definition: IterativeSolverBase.h:438
@ MaxColsAtCompileTime
Definition: IterativeSolverBase.h:158
@ ColsAtCompileTime
Definition: IterativeSolverBase.h:157
Derived & compute(const EigenBase< MatrixDerived > &A)
Initializes the iterative solver with the matrix A for further solving Ax=b problems.
Definition: IterativeSolverBase.h:238
IterativeSolverBase(const EigenBase< MatrixDerived > &A)
Initialize the solver with matrix A for further Ax=b solving.
Definition: IterativeSolverBase.h:182
internal::enable_if< Rhs::ColsAtCompileTime==1||DestDerived::ColsAtCompileTime==1 >::type _solve_with_guess_impl(const Rhs &b, MatrixBase< DestDerived > &dest) const
Definition: IterativeSolverBase.h:393
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: IterativeSolverBase.h:250
MatrixWrapper::ActualMatrixType ActualMatrixType
Definition: IterativeSolverBase.h:417
MatrixType::RealScalar RealScalar
Definition: IterativeSolverBase.h:154
void grab(const InputType &A)
Definition: IterativeSolverBase.h:425
MatrixType::Scalar Scalar
Definition: IterativeSolverBase.h:152
const Preconditioner & preconditioner() const
Definition: IterativeSolverBase.h:275
MatrixWrapper m_matrixWrapper
Definition: IterativeSolverBase.h:430
internal::traits< Derived >::Preconditioner Preconditioner
Definition: IterativeSolverBase.h:151
Derived & analyzePattern(const EigenBase< MatrixDerived > &A)
Initializes the iterative solver for the sparsity pattern of the matrix A for further solving Ax=b pr...
Definition: IterativeSolverBase.h:197
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: IterativeSolverBase.h:253
void init()
Definition: IterativeSolverBase.h:407
Derived & factorize(const EigenBase< MatrixDerived > &A)
Initializes the iterative solver with the numerical values of the matrix A for further solving Ax=b p...
Definition: IterativeSolverBase.h:217
RealScalar m_error
Definition: IterativeSolverBase.h:436
void _solve_impl(const Rhs &b, Dest &x) const
Definition: IterativeSolverBase.h:400
Preconditioner m_preconditioner
Definition: IterativeSolverBase.h:431
MatrixType::StorageIndex StorageIndex
Definition: IterativeSolverBase.h:153
void _solve_with_guess_impl(const Rhs &b, SparseMatrixBase< DestDerived > &aDest) const
Definition: IterativeSolverBase.h:334
~IterativeSolverBase()
Definition: IterativeSolverBase.h:189
SparseSolverBase< Derived > Base
Definition: IterativeSolverBase.h:146
Index m_iterations
Definition: IterativeSolverBase.h:437
Preconditioner & preconditioner()
Definition: IterativeSolverBase.h:272
Index m_maxIterations
Definition: IterativeSolverBase.h:433
internal::enable_if< Rhs::ColsAtCompileTime!=1 &&DestDerived::ColsAtCompileTime!=1 >::type _solve_with_guess_impl(const Rhs &b, MatrixBase< DestDerived > &aDest) const
Definition: IterativeSolverBase.h:368
Derived & setTolerance(const RealScalar &tolerance)
Sets the tolerance threshold used by the stopping criteria.
Definition: IterativeSolverBase.h:265
bool m_isInitialized
Definition: SparseSolverBase.h:119
Derived & derived()
Definition: SparseSolverBase.h:79
RealScalar tolerance() const
Definition: IterativeSolverBase.h:258
RealScalar m_tolerance
Definition: IterativeSolverBase.h:434
const SolveWithGuess< Derived, Rhs, Guess > solveWithGuess(const MatrixBase< Rhs > &b, const Guess &x0) const
Definition: IterativeSolverBase.h:318
Index iterations() const
Definition: IterativeSolverBase.h:296
const ActualMatrixType & matrix() const
Definition: IterativeSolverBase.h:419
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:50
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:180
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:283
Pseudo expression representing a solving operation.
Definition: SolveWithGuess.h:42
Base class of any sparse matrices or sparse expressions.
Definition: SparseMatrixBase.h:28
const Derived & derived() const
Definition: SparseMatrixBase.h:143
A base class for sparse solvers.
Definition: SparseSolverBase.h:68
bool m_isInitialized
Definition: SparseSolverBase.h:119
Derived & derived()
Definition: SparseSolverBase.h:79
const ActualMatrixType & matrix() const
Definition: IterativeSolverBase.h:72
generic_matrix_wrapper()
Definition: IterativeSolverBase.h:63
generic_matrix_wrapper(const InputType &mat)
Definition: IterativeSolverBase.h:68
Ref< const MatrixType > ActualMatrixType
Definition: IterativeSolverBase.h:54
void grab(const EigenBase< MatrixDerived > &mat)
Definition: IterativeSolverBase.h:78
MatrixType m_dummy
Definition: IterativeSolverBase.h:94
void grab(const Ref< const MatrixType > &mat)
Definition: IterativeSolverBase.h:84
ActualMatrixType m_matrix
Definition: IterativeSolverBase.h:95
const ActualMatrixType & matrix() const
Definition: IterativeSolverBase.h:121
void grab(const MatrixType &mat)
Definition: IterativeSolverBase.h:126
generic_matrix_wrapper(const MatrixType &mat)
Definition: IterativeSolverBase.h:117
MatrixType ActualMatrixType
Definition: IterativeSolverBase.h:103
const ActualMatrixType * mp_matrix
Definition: IterativeSolverBase.h:132
generic_matrix_wrapper()
Definition: IterativeSolverBase.h:113
Definition: IterativeSolverBase.h:47
Definition: core.h:1240
ComputationInfo
Enum for reporting the status of a computation.
Definition: Constants.h:440
@ NumericalIssue
The provided data did not satisfy the prerequisites.
Definition: Constants.h:444
@ Success
Computation was successful.
Definition: Constants.h:442
@ NoConvergence
Iterative procedure did not converge.
Definition: Constants.h:446
EIGEN_CONSTEXPR Index size(const T &x)
Definition: Meta.h:479
Namespace containing all symbols from the Eigen library.
Definition: Core:141
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
Definition: Eigen_Colamd.h:50
b
Definition: data.h:44
Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor Matrix...
Definition: EigenBase.h:30
EIGEN_DEVICE_FUNC Derived & derived()
Definition: EigenBase.h:46
Holds information about the various numeric (i.e.
Definition: NumTraits.h:233
Definition: Meta.h:273
ActualMatrixType::template ConstSelfAdjointViewReturnType< UpLo >::Type Type
Definition: IterativeSolverBase.h:56
Definition: IterativeSolverBase.h:19
static MatrixType ms_from
Definition: IterativeSolverBase.h:36
Definition: IterativeSolverBase.h:42
Definition: ForwardDeclarations.h:17