Docs: Correct documented claims that the code contradicts

libeigen/eigen!2815

Co-authored-by: Rasmus Munk Larsen <rmlarsen@gmail.com>
This commit is contained in:
Rasmus Munk Larsen
2026-08-14 07:33:02 -07:00
co-authored by Rasmus Munk Larsen
parent 5bdc386dab
commit 410fa16a77
54 changed files with 242 additions and 180 deletions
+1 -1
View File
@@ -55,7 +55,7 @@
*
* \note Some of these methods (like AMD or METIS), need the sparsity pattern
* of the input matrix to be symmetric. When the matrix is structurally unsymmetric,
* Eigen computes internally the pattern of \f$A^T*A\f$ before calling the method.
* Eigen computes internally the pattern of \f$A^T+A\f$ before calling the method.
* If your matrix is already symmetric (at least in structure), you can avoid that
* by calling the method with a SelfAdjointView type.
*
+2 -3
View File
@@ -17,9 +17,8 @@
/** \defgroup ThreadPool_Module ThreadPool Module
*
* This module provides 2 threadpool implementations
* - a simple reference implementation
* - a faster non blocking implementation
* This module provides a non blocking threadpool implementation, Eigen::ThreadPoolTempl, together with the
* Eigen::ThreadPool alias for its default thread environment.
*
* \code
* #include <Eigen/ThreadPool>
+4 -3
View File
@@ -63,7 +63,8 @@ struct LLT_Traits;
* This class supports the \link InplaceDecomposition inplace decomposition \endlink mechanism.
*
* Note that during the decomposition, only the lower (or upper, as defined by UpLo_) triangular part of A is
* considered. Therefore, the strict lower part does not have to store correct values.
* considered. Therefore, the strict upper part (or the strict lower part when UpLo_ is Upper) does not have to
* store correct values.
*
* \sa MatrixBase::llt(), SelfAdjointView::llt(), class LDLT
*/
@@ -205,8 +206,8 @@ class LLT : public SolverBase<LLT<MatrixType_, UpLo_> > {
EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
/** \internal
* Used to compute and store L
* The strict upper part is not used and even not initialized.
* Used to compute and store L, or U when UpLo_ is Upper.
* The strict part of the other triangle is not used and even not initialized.
*/
MatrixType m_matrix;
RealScalar m_l1_norm;
+4 -4
View File
@@ -483,7 +483,7 @@ class CholmodBase : public SparseSolverBase<Derived> {
* \implsparsesolverconcept
*
* This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non
* compressed.
* compressed, except row-major matrices with complex scalars.
*
* \warning Only double precision real and complex scalar types are supported by Cholmod.
*
@@ -540,7 +540,7 @@ class CholmodSimplicialLLT : public CholmodBase<MatrixType_, UpLo_, CholmodSimpl
* \implsparsesolverconcept
*
* This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non
* compressed.
* compressed, except row-major matrices with complex scalars.
*
* \warning Only double precision real and complex scalar types are supported by Cholmod.
*
@@ -611,7 +611,7 @@ class CholmodSimplicialLDLT : public CholmodBase<MatrixType_, UpLo_, CholmodSimp
* \implsparsesolverconcept
*
* This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non
* compressed.
* compressed, except row-major matrices with complex scalars.
*
* \warning Only double precision real and complex scalar types are supported by Cholmod.
*
@@ -674,7 +674,7 @@ class CholmodSupernodalLLT : public CholmodBase<MatrixType_, UpLo_, CholmodSuper
* \implsparsesolverconcept
*
* This class supports all kind of SparseMatrix<>: row or column major; upper, lower, or both; compressed or non
* compressed.
* compressed, except row-major matrices with complex scalars.
*
* \warning Only double precision real and complex scalar types are supported by Cholmod.
*
+1 -2
View File
@@ -102,8 +102,7 @@ class Array : public PlainObjectBase<Array<Scalar_, Rows_, Cols_, Options_, MaxR
* For fixed-size matrices, does nothing.
*
* For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix
* is called a null matrix. This constructor is the unique way to create null matrices: resizing
* a matrix to 0 is not supported.
* is called a null matrix. An existing matrix can also be turned into a null matrix by resizing it to 0.
*
* \sa resize(Index,Index)
*/
+5 -4
View File
@@ -39,10 +39,11 @@ class CwiseUnaryOpImpl;
* \tparam XprType the type of the expression to which we are applying the unary operator
*
* This class represents an expression where a unary operator is applied to an expression.
* It is the return type of all operations taking exactly 1 input expression, regardless of the
* presence of other inputs such as scalars. For example, the operator* in the expression 3*matrix
* is considered unary, because only the right-hand side is an expression, and its
* return type is a specialization of CwiseUnaryOp.
* It is the return type of coefficient-wise operations taking a single input expression, such as unary negation
* or MatrixBase::unaryExpr(). Operators mixing an expression and a scalar, such as the operator* in the expression
* 3*matrix, are binary: the scalar is nested as a CwiseNullaryOp, so the return type is a specialization of
* CwiseBinaryOp. A scalar carried inside the functor does not make the expression binary; ArrayBase::pow(const
* ScalarExponent&) stores its exponent in the functor and still returns a CwiseUnaryOp.
*
* Most of the time, this is the only way that it is used, so you typically don't have to name
* CwiseUnaryOp types explicitly.
+8 -6
View File
@@ -139,7 +139,8 @@ class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
/** \returns the coefficient at given index.
*
* This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
* This method is allowed only for expressions that are vectors at compile time. For matrix expressions having the
* LinearAccessBit, use operator()(Index) instead.
*
* \sa operator[](Index), operator()(Index,Index) const, x() const, y() const,
* z() const, w() const
@@ -154,9 +155,9 @@ class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived> {
/** \returns the coefficient at given index.
*
* This is synonymous to operator[](Index) const.
* For expressions that are vectors at compile time, this is synonymous to operator[](Index) const.
*
* This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
* This method is allowed only for expressions having the LinearAccessBit.
*
* \sa operator[](Index), operator()(Index,Index) const, x() const, y() const,
* z() const, w() const
@@ -355,7 +356,8 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
/** \returns a reference to the coefficient at given index.
*
* This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
* This method is allowed only for expressions that are vectors at compile time. For matrix expressions having the
* LinearAccessBit, use operator()(Index) instead.
*
* \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
*/
@@ -369,9 +371,9 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
/** \returns a reference to the coefficient at given index.
*
* This is synonymous to operator[](Index).
* For expressions that are vectors at compile time, this is synonymous to operator[](Index).
*
* This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
* This method is allowed only for expressions having the LinearAccessBit.
*
* \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
*/
+1 -2
View File
@@ -245,8 +245,7 @@ class Matrix : public PlainObjectBase<Matrix<Scalar_, Rows_, Cols_, Options_, Ma
* For fixed-size matrices, does nothing.
*
* For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix
* is called a null matrix. This constructor is the unique way to create null matrices: resizing
* a matrix to 0 is not supported.
* is called a null matrix. An existing matrix can also be turned into a null matrix by resizing it to 0.
*
* \sa resize(Index,Index)
*/
+2 -2
View File
@@ -559,8 +559,8 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type {
/** \name Map
* These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects,
* while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned
* \a data pointers.
* while the MapAligned() functions return Map objects with \c AlignedMax alignment and thus should be called only
* with \a data pointers aligned on an \c EIGEN_MAX_ALIGN_BYTES boundary.
*
* Here is an example using strides:
* \include Matrix_Map_stride.cpp
+8 -3
View File
@@ -217,9 +217,14 @@ class RefBase : public MapBase<Derived> {
* of rows.
*
* In the const case, if the input expression does not match the above requirement, then it is evaluated into a
* temporary before being passed to the function. Here are some examples: \code MatrixXf A; VectorXf a; foo1(a.head());
* // OK foo1(A.col()); // OK foo1(A.row()); // Compilation error because here innerstride!=1
* foo2(A.row()); // Compilation error because A.row() is a 1xN object while foo2 is expecting a Nx1 object
* temporary before being passed to the function. Here are some examples:
* \code
* MatrixXf A;
* VectorXf a;
* foo1(a.head()); // OK
* foo1(A.col()); // OK
* foo1(A.row()); // Compilation error because here innerstride!=1
* foo2(A.row()); // The 1xN row is accepted as a Nx1 vector, but copied into a temporary
* foo2(A.row().transpose()); // The row is copied into a contiguous temporary
* foo2(2*a); // The expression is evaluated into a temporary
* foo2(A.col().segment(2,4)); // No temporary
+1 -1
View File
@@ -490,7 +490,7 @@ class TriangularViewImpl<MatrixType_, Mode_, Dense> : public TriangularBase<Tria
*
* The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the
* diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this
* is an upper (resp. lower) triangular matrix.
* is a lower (resp. upper) triangular matrix.
*
* Example: \include Triangular_solve.cpp
* Output: \verbinclude Triangular_solve.out
@@ -193,7 +193,7 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psqrt_complex(const P
rho.v = psqrt(pmul(cst_half, padd(a_abs, l)));
// Step 3. Compute [rho0, eta0, rho1, eta1], where
// eta0 = (y0 / l0) / 2, and eta1 = (y1 / l1) / 2.
// eta0 = (y0 / rho0) / 2, and eta1 = (y1 / rho1) / 2.
// set eta = 0 if input is 0 + i0.
RealPacket eta = pandnot(pmul(cst_half, pdiv(a.v, pcplxflip(rho).v)), a_max_zero_mask);
RealPacket real_mask = peven_mask(a.v);
@@ -840,7 +840,9 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet patanh_double(const P
/** \internal \returns the hyperbolic sine of \a x (coeff-wise).
Uses sinh(x) = (exp(x) - exp(-x)) / 2.
Near overflow, uses sinh(x) = sign(x) * exp(|x|) / 2 via ldexp to avoid inf.
For |x| >= 1, the value h = exp(|x|) / 2 is computed once as exp(|x| - 1) * (E/2), where E is Euler's number,
to avoid premature inf, and is shared by both branches: sinh(x) = sign(x) * (h - 1/(4*h)) for |x| <= 20, and
sinh(x) = sign(x) * h for |x| > 20.
For |x| < 1, uses a direct polynomial to avoid catastrophic cancellation.
*/
template <typename Packet>
@@ -867,13 +869,13 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psinh_float(const Pac
const Packet one = pset1<Packet>(1.0f);
const Packet e = pmul(pexp(psub(abs_x, one)), half_e);
// Medium path (1 <= |x| < 20):
// Medium path (1 <= |x| <= 20):
// sinh(x) = (exp(|x|) - exp(-|x|)) / 2
// = (2*e - 1/(2*e)) / 2 = e - 1/(4*e)
const Packet quarter = pset1<Packet>(0.25f);
Packet p_medium = psub(e, pdiv(quarter, e));
// Large path (|x| >= 20): exp(-|x|) is negligible, sinh(x) ~ exp(|x|)/2 = e.
// Large path (|x| > 20): exp(-|x|) is negligible, sinh(x) ~ exp(|x|)/2 = e.
const Packet large_threshold = pset1<Packet>(20.0f);
const Packet large_mask = pcmp_lt(large_threshold, abs_x);
Packet p_large = pselect(large_mask, e, p_medium);
@@ -917,12 +919,12 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psinh_double(const Pa
const Packet one = pset1<Packet>(1.0);
const Packet e = pmul(pexp(psub(abs_x, one)), half_e);
// Medium path (1 <= |x| < 20):
// Medium path (1 <= |x| <= 20):
// sinh(x) = (exp(|x|) - exp(-|x|)) / 2 = e - 1/(4*e)
const Packet quarter = pset1<Packet>(0.25);
Packet p_medium = psub(e, pdiv(quarter, e));
// Large path (|x| >= 20): exp(-|x|) is negligible, sinh(x) ~ exp(|x|)/2 = e.
// Large path (|x| > 20): exp(-|x|) is negligible, sinh(x) ~ exp(|x|)/2 = e.
const Packet large_threshold = pset1<Packet>(20.0);
const Packet large_mask = pcmp_lt(large_threshold, abs_x);
Packet p_large = pselect(large_mask, e, p_medium);
@@ -933,7 +935,9 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psinh_double(const Pa
/** \internal \returns the hyperbolic cosine of \a x (coeff-wise).
Uses cosh(x) = (exp(|x|) + exp(-|x|)) / 2.
Near overflow, uses ldexp(exp(|x| - ln2), -1) to avoid premature inf.
The value h = exp(|x|) / 2 is computed once as exp(|x| - 1) * (E/2), where E is Euler's number, to avoid
premature inf, and is shared by both branches: cosh(x) = h + 1/(4*h) for |x| <= 20, and cosh(x) = h for
|x| > 20.
*/
template <typename Packet>
EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcosh_float(const Packet& x) {
@@ -952,7 +956,7 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcosh_float(const Pac
const Packet quarter = pset1<Packet>(0.25f);
Packet p_medium = padd(e, pdiv(quarter, e));
// Large path (|x| >= 20): exp(-|x|) is negligible, cosh(x) ~ exp(|x|)/2 = e.
// Large path (|x| > 20): exp(-|x|) is negligible, cosh(x) ~ exp(|x|)/2 = e.
const Packet large_threshold = pset1<Packet>(20.0f);
const Packet large_mask = pcmp_lt(large_threshold, abs_x);
return pselect(large_mask, e, p_medium);
@@ -973,7 +977,7 @@ EIGEN_DEFINE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcosh_double(const Pa
const Packet quarter = pset1<Packet>(0.25);
Packet p_medium = padd(e, pdiv(quarter, e));
// Large path (|x| >= 20): exp(-|x|) is negligible, cosh(x) ~ exp(|x|)/2 = e.
// Large path (|x| > 20): exp(-|x|) is negligible, cosh(x) ~ exp(|x|)/2 = e.
const Packet large_threshold = pset1<Packet>(20.0);
const Packet large_mask = pcmp_lt(large_threshold, abs_x);
return pselect(large_mask, e, p_medium);
+5 -3
View File
@@ -47,7 +47,7 @@ inline void manage_multi_threading(Action action, int* v);
// Public APIs.
/** Must be called first when calling Eigen from multiple threads */
/** \deprecated Does nothing. No initialization is required before calling Eigen from multiple threads. */
EIGEN_DEPRECATED_WITH_REASON("Initialization is no longer needed.") inline void initParallel() {}
/** \returns the max number of threads reserved for Eigen
@@ -74,8 +74,10 @@ inline void setNbThreads(int v) { internal::manage_multi_threading(SetAction, &v
inline ThreadPool* setGemmThreadPool(ThreadPool* new_pool) {
static ThreadPool* pool = nullptr;
if (new_pool != nullptr) {
// This will wait for work in all threads in *pool to finish,
// then destroy the old ThreadPool, and then replace it with new_pool.
// This only replaces the stored pointer: work already scheduled on the old
// ThreadPool is not waited for, and the old pool is not destroyed. Since
// this returns the new pool, the caller must keep its own pointer to the
// old one to dispose of it.
pool = new_pool;
// Reset the number of threads to the number of threads on the new pool.
setNbThreads(pool->NumThreads());
+5 -2
View File
@@ -15,9 +15,12 @@
/* Some notes on Eigen's static assertion mechanism:
*
* - in EIGEN_STATIC_ASSERT(CONDITION,MSG) the parameter CONDITION must be a compile time boolean
* expression, and MSG an enum listed in struct internal::static_assertion<true>
* expression, and MSG an identifier that is stringified into the diagnostic; by convention it is written
* ALL_CAPS. Prefer one of the messages already used by the derived EIGEN_STATIC_ASSERT_* macros below.
*
* - currently EIGEN_STATIC_ASSERT can only be used in function scope
* - EIGEN_STATIC_ASSERT expands to a plain static_assert, so it may be used wherever a declaration is allowed,
* including class scope (see e.g. log1p_impl in MathFunctions.h). That is why EIGEN_NO_STATIC_ASSERT removes
* the check outright instead of downgrading it to an eigen_assert, which would only be valid in function scope.
*
*/
+2 -1
View File
@@ -278,7 +278,8 @@ class EigenSolver {
template <typename InputType>
EigenSolver& compute(const EigenBase<InputType>& matrix, bool computeEigenvectors = true);
/** \returns NumericalIssue if the input contains INF or NaN values or overflow occurred. Returns Success otherwise.
/** \returns NumericalIssue if the input contains INF or NaN values or overflow occurred, NoConvergence if the Schur
* decomposition did not converge within the maximum number of iterations, and Success otherwise.
*/
ComputationInfo info() const {
eigen_assert(m_isInitialized && "EigenSolver is not initialized.");
@@ -92,7 +92,8 @@ class GeneralizedSelfAdjointEigenSolver : public SelfAdjointEigenSolver<MatrixTy
* generalized eigenproblem \f$ Ax = \lambda B x \f$ with \a matA the
* selfadjoint matrix \f$ A \f$ and \a matB the positive definite matrix
* \f$ B \f$. Each eigenvector \f$ x \f$ satisfies the property
* \f$ x^* B x = 1 \f$. The eigenvectors are computed if
* \f$ x^* B x = 1 \f$ for \c Ax_lBx and \c ABx_lx, and the property
* \f$ x^* B^{-1} x = 1 \f$ for \c BAx_lx. The eigenvectors are computed if
* \a options contains ComputeEigenvectors.
*
* In addition, the two following variants can be solved via \p options:
@@ -128,7 +129,9 @@ class GeneralizedSelfAdjointEigenSolver : public SelfAdjointEigenSolver<MatrixTy
* - \c BAx_lx: \f$ BAx = \lambda x \f$
* with \a matA the selfadjoint matrix \f$ A \f$ and \a matB the positive definite
* matrix \f$ B \f$.
* In addition, each eigenvector \f$ x \f$ satisfies the property \f$ x^* B x = 1 \f$.
* In addition, each eigenvector \f$ x \f$ satisfies the property \f$ x^* B x = 1 \f$ for \c Ax_lBx and \c ABx_lx.
* For \c BAx_lx, the eigenvectors are instead normalized such that \f$ x^* B^{-1} x = 1 \f$, following the same
* convention as LAPACK's \c ?sygv with \c itype=3.
*
* The eigenvalues() function can be used to retrieve
* the eigenvalues. If \p options contains ComputeEigenvectors, then the
@@ -266,14 +266,16 @@ class HessenbergDecomposition {
};
/** \internal
* Performs a tridiagonal decomposition of \a matA in place.
* Performs a Hessenberg decomposition of \a matA in place.
*
* \param matA the input selfadjoint matrix
* \param matA the input square matrix
* \param hCoeffs returned Householder coefficients
*
* The result is written in the lower triangular part of \a matA.
* The result is written in the whole of \a matA: the upper part, including
* the subdiagonal, holds the Hessenberg matrix H, while the part strictly
* below the subdiagonal holds the Householder vectors.
*
* Implemented from Golub's "%Matrix Computations", algorithm 8.3.1.
* Implemented from Golub's "%Matrix Computations", algorithm 7.4.2.
*
* \sa packedMatrix()
*/
+3 -1
View File
@@ -242,8 +242,10 @@ struct unitOrthogonal_selector<Derived, 2> {
*
* \returns a unit vector which is orthogonal to \c *this
*
* The size of \c *this must be at least 2. If the size is exactly 2,
* The size of \c *this must be at least 2. If the size is exactly 2 at compile time,
* then the returned vector is a counter-clockwise rotation of \c *this, i.e., (-y,x).normalized().
* A vector whose size is only known at runtime takes the generic code path even when its size is 2,
* and then returns the clockwise rotation (y,-x).normalized() if |y| > |x|.
*
* \sa cross()
*/
+7 -4
View File
@@ -172,10 +172,13 @@ struct transform_make_affine;
* that case the last matrix row can be ignored, and the product returns non
* homogeneous vectors.
*
* Since, for instance, a Dim x Dim matrix is interpreted as a linear transformation,
* it is not possible to directly transform Dim vectors stored in a Dim x Dim matrix.
* The solution is either to use a Dim x Dynamic matrix or explicitly request a
* vector transformation by making the vector homogeneous:
* In particular, a Dim x Dim matrix on the right-hand side of a Transform is not
* interpreted as a linear transformation: like any Dim x n matrix, its columns are
* transformed as points, so that for Mode!=Projective, T*m returns the Dim x Dim matrix
* (T.linear()*m).colwise() + T.translation(). A Dim x Dim matrix is interpreted as a linear
* transformation in the other direction of the product, and when it is assigned to a Transform,
* passed to a Transform constructor, or given to rotate()/prerotate().
* To obtain the result in homogeneous coordinates, make the points homogeneous explicitly:
* \code
* m' = T * m.colwise().homogeneous();
* \endcode
+5 -2
View File
@@ -225,8 +225,11 @@ class HouseholderSequence : public EigenBase<HouseholderSequence<VectorsType, Co
.setShift(m_shift);
}
/** \returns an expression of the complex conjugate of \c *this if Cond==true,
* returns \c *this otherwise.
/** \returns a %HouseholderSequence over the vectors and coefficients of \c *this, complex-conjugated if
* Cond==true.
*
* \warning Unlike conjugate(), this function does not propagate the state of \c *this: the returned sequence uses
* the defaults of the two-argument constructor, that is, not reversed, full length and zero shift.
*/
template <bool Cond>
EIGEN_DEVICE_FUNC inline std::conditional_t<Cond, ConjugateReturnType, ConstHouseholderSequence> conjugateIf() const {
+2 -2
View File
@@ -147,8 +147,8 @@ struct traits<BiCGSTAB<MatrixType_, Preconditioner_> > {
* \implsparsesolverconcept
*
* The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()
* and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations
* and NumTraits<Scalar>::epsilon() for the tolerance.
* and setTolerance() methods. The defaults are twice the number of columns of the matrix for the maximal
* number of iterations and NumTraits<Scalar>::epsilon() for the tolerance.
*
* The tolerance corresponds to the relative residual error: |Ax-b|/|b|
*
@@ -124,8 +124,8 @@ struct traits<ConjugateGradient<MatrixType_, UpLo_, Preconditioner_> > {
* \implsparsesolverconcept
*
* The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()
* and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations
* and NumTraits<Scalar>::epsilon() for the tolerance.
* and setTolerance() methods. The defaults are twice the number of columns of the matrix for the maximal
* number of iterations and NumTraits<Scalar>::epsilon() for the tolerance.
*
* The tolerance corresponds to the relative residual error: |Ax-b|/|b|
*
+2 -2
View File
@@ -232,8 +232,8 @@ struct traits<GMRES<MatrixType_, Preconditioner_> > {
* \tparam Preconditioner_ the type of the preconditioner. Default is DiagonalPreconditioner
*
* The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()
* and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations
* and NumTraits<Scalar>::epsilon() for the tolerance.
* and setTolerance() methods. The defaults are twice the number of columns of the matrix for the maximal
* number of iterations and NumTraits<Scalar>::epsilon() for the tolerance.
*
* When a left preconditioner M is used, GMRES applies the stopping criterion to the preconditioned
* system M^{-1} A x = M^{-1} b. The reported error is therefore
+2 -2
View File
@@ -282,8 +282,8 @@ struct traits<Eigen::IDRS<MatrixType_, Preconditioner_> > {
* \implsparsesolverconcept
*
* The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()
* and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations
* and NumTraits<Scalar>::epsilon() for the tolerance.
* and setTolerance() methods. The defaults are twice the number of columns of the matrix for the maximal
* number of iterations and NumTraits<Scalar>::epsilon() for the tolerance.
*
* The tolerance corresponds to the relative residual error: |Ax-b|/|b|
*
@@ -222,7 +222,9 @@ class IterativeSolverBase : public SparseSolverBase<Derived> {
/** Sets the tolerance threshold used by the stopping criteria.
*
* This value is used as an upper bound to the relative residual error: |Ax-b|/|b|.
* This value is used as an upper bound to the relative residual error: |Ax-b|/|b|, or to the measure the solver
* documents instead; LeastSquaresConjugateGradient bounds the normal-equation residual |A'(Ax-b)|/|A'b|, and
* LSMR bounds |A'(Ax-b)|/(|A| |Ax-b|).
* The default value is the machine precision given by NumTraits<Scalar>::epsilon()
*/
Derived& setTolerance(const RealScalar& tolerance) {
@@ -257,7 +259,9 @@ class IterativeSolverBase : public SparseSolverBase<Derived> {
}
/** \returns the tolerance error reached during the last solve.
* It is a close approximation of the true relative residual error |Ax-b|/|b|.
* It is a close approximation of the true relative residual error |Ax-b|/|b|, unless the solver documents a
* different measure: LeastSquaresConjugateGradient reports the normal-equation residual |A'(Ax-b)|/|A'b|, and
* LSMR reports the normal-equation residual estimate |A'(Ax-b)|/(|A| |Ax-b|).
*/
RealScalar error() const {
eigen_assert(m_isInitialized && "IterativeSolverBase is not initialized.");
+6
View File
@@ -312,6 +312,12 @@ struct traits<LSMR<MatrixType_, Preconditioner_> > {
* and \c btol (relative error assumed in \c b); they can also be set
* independently via setToleranceA() and setToleranceB().
*
* Unlike most other iterative solvers, error() does not report the relative
* residual \f$ ||Ax-b||/||b|| \f$: it reports the estimate
* \f$ ||A^T r|| / (||A||\,||r||) \f$, with \f$ r = b - Ax \f$, of the relative
* residual of the normal equations, the quantity that the least-squares
* stopping rule bounds by \c atol.
*
* The setDamping() method enables Tikhonov regularization: with a damping
* \f$ \lambda > 0 \f$ the solver minimizes
* \f$ ||Ax-b||^2 + \lambda^2 ||x||^2 \f$, for which a unique solution always
@@ -126,8 +126,8 @@ struct traits<LeastSquaresConjugateGradient<MatrixType_, Preconditioner_> > {
* \implsparsesolverconcept
*
* The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()
* and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations
* and NumTraits<Scalar>::epsilon() for the tolerance.
* and setTolerance() methods. The defaults are twice the number of columns of the matrix for the maximal
* number of iterations and NumTraits<Scalar>::epsilon() for the tolerance.
*
* This class can be used as the direct solver classes. Here is a typical usage example:
\code
+3 -3
View File
@@ -165,11 +165,11 @@ struct traits<MINRES<MatrixType_, UpLo_, Preconditioner_> > {
* \tparam MatrixType_ the type of the sparse matrix A, can be a dense or a sparse matrix.
* \tparam UpLo_ the triangular part that will be used for the computations. It can be Lower,
* Upper, or Lower|Upper in which the full matrix entries will be considered. Default is Lower.
* \tparam Preconditioner_ the type of the preconditioner. Default is DiagonalPreconditioner
* \tparam Preconditioner_ the type of the preconditioner. Default is IdentityPreconditioner
*
* The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()
* and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations
* and NumTraits<Scalar>::epsilon() for the tolerance.
* and setTolerance() methods. The defaults are twice the number of columns of the matrix for the maximal
* number of iterations and NumTraits<Scalar>::epsilon() for the tolerance.
*
* This class can be used as the direct solver classes. Here is a typical usage example:
* \code
+3 -3
View File
@@ -38,8 +38,8 @@ struct traits<PartialPivLU<MatrixType_, PermutationIndex_> > : traits<MatrixType
* \tparam MatrixType_ the type of the matrix of which we are computing the LU decomposition
*
* This class represents a LU decomposition of a \b square \b invertible matrix, with partial pivoting: the matrix A
* is decomposed as A = PLU where L is unit-lower-triangular, U is upper-triangular, and P
* is a permutation matrix.
* is decomposed as \f$ A = P^{-1} L U \f$ where L is unit-lower-triangular, U is upper-triangular, and
* \f$ P \f$ is the permutation matrix returned by permutationP(), so that \f$ P A = L U \f$.
*
* Typically, partial pivoting LU decomposition is only considered numerically stable for square invertible
* matrices. Thus LAPACK's dgesv and dgesvx require the matrix to be square and invertible. The present class
@@ -356,7 +356,7 @@ struct generic_partial_lu_impl {
lu.col(k).tail(fix<RRows>(rrows)) /= lu.coeff(k, k);
} else if (first_zero_pivot == -1) {
// the pivot is exactly zero, we record the index of the first pivot which is exactly 0,
// and continue the factorization such we still have A = PLU
// and continue the factorization such we still have P A = L U
first_zero_pivot = k;
}
+2 -2
View File
@@ -19,8 +19,8 @@ namespace Eigen {
*
* If A is the original matrix and Ap is the permuted matrix,
* the fill-reducing permutation is defined as follows :
* Row (column) i of A is the matperm(i) row (column) of Ap.
* WARNING: As computed by METIS, this corresponds to the vector iperm (instead of perm)
* Row (column) i of Ap is the matperm(i) row (column) of A.
* WARNING: As computed by METIS, this corresponds to the vector perm (instead of iperm)
*/
template <typename StorageIndex>
class MetisOrdering {
+4 -2
View File
@@ -476,7 +476,8 @@ class PastixLU : public PastixBase<PastixLU<MatrixType_> > {
* The vectors or matrices X and B can be either dense or sparse
*
* \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
* \tparam UpLo The part of the matrix to use : Lower or Upper. The default is Lower as required by PaStiX
* \tparam UpLo The part of the matrix to use : Lower or Upper. This parameter has no default: either part is accepted
* and copied to the lower part required by PaStiX.
*
* \implsparsesolverconcept
*
@@ -551,7 +552,8 @@ class PastixLLT : public PastixBase<PastixLLT<MatrixType_, UpLo_> > {
* The vectors or matrices X and B can be either dense or sparse
*
* \tparam MatrixType the type of the sparse matrix A, it must be a SparseMatrix<>
* \tparam UpLo The part of the matrix to use : Lower or Upper. The default is Lower as required by PaStiX
* \tparam UpLo The part of the matrix to use : Lower or Upper. This parameter has no default: either part is accepted
* and copied to the lower part required by PaStiX.
*
* \implsparsesolverconcept
*
+4 -3
View File
@@ -60,8 +60,8 @@ struct traits<SPQR_QProduct<SPQRType, Derived> > {
* Use matrixQ() to get an expression and matrixQ().transpose() to get the transpose.
* You can then apply it to a vector.
*
* R is the sparse triangular factor. Use matrixQR() to get it as SparseMatrix.
* NOTE : The Index type of R is always SuiteSparse_long. You can get it with SPQR::Index
* R is the sparse triangular factor. Use matrixR() to get it as SparseMatrix.
* NOTE : The storage index type of R is always SuiteSparse_long. You can get it with SPQR::StorageIndex
*
* \tparam MatrixType_ The type of the sparse matrix A, must be a column-major SparseMatrix<>
*
@@ -221,7 +221,8 @@ class SPQR : public SparseSolverBase<SPQR<MatrixType_> > {
}
/**
* Gets the rank of the matrix.
* It should be equal to matrixQR().cols if the matrix is full-rank
* It should be equal to matrixR().rows() if the matrix is full-rank; matrixR().cols() is always the number of
* columns of the input matrix.
*/
Index rank() const {
eigen_assert(m_isInitialized && "Decomposition is not initialized.");
+1 -1
View File
@@ -231,7 +231,7 @@ class SVDBase : public SolverBase<SVDBase<Derived> > {
* This is not used for the SVD decomposition itself.
*
* When it needs to get the threshold value, Eigen calls threshold().
* The default is \c NumTraits<Scalar>::epsilon()
* The default is \c NumTraits<Scalar>::epsilon() scaled by the number of singular values, \c max(1,min(rows,cols)).
*
* \param threshold The new value to use as the threshold.
*
+7 -1
View File
@@ -167,7 +167,13 @@ class SparseMapBase<Derived, WriteAccessors> : public SparseMapBase<Derived, Rea
inline StorageIndex* innerNonZeroPtr() { return Base::m_innerNonZeros; }
//----------------------------------------
/** \copydoc SparseMatrix::coeffRef */
/** \returns a non-const reference to the value of the matrix at position \a row, \a col
*
* The element must already exist: unlike SparseMatrix::coeffRef, this function cannot insert a new one because
* \c *this does not own the buffers it points to.
*
* This is a O(log(nnz_j)) operation (binary search).
*/
inline Scalar& coeffRef(Index row, Index col) {
const Index outer = IsRowMajor ? row : col;
const Index inner = IsRowMajor ? col : row;
+6 -3
View File
@@ -278,8 +278,9 @@ class SparseMatrix : public SparseCompressedBase<SparseMatrix<Scalar_, Options_,
/** \returns a reference to a novel non zero coefficient with coordinates \a row x \a col.
* The non zero coefficient must \b not already exist.
*
* If the matrix \c *this is in compressed mode, then \c *this is turned into uncompressed
* mode while reserving room for 2 x this->innerSize() non zeros if reserve(Index) has not been called earlier.
* If the matrix \c *this is in compressed mode, then \c *this is turned into uncompressed mode with no spare room;
* whenever an insertion finds no free slot in any inner vector, room for one additional element per inner vector is
* reserved.
* In this case, the insertion procedure is optimized for a \e sequential insertion mode where elements are assumed to
* be inserted by increasing outer-indices.
*
@@ -636,7 +637,8 @@ class SparseMatrix : public SparseCompressedBase<SparseMatrix<Scalar_, Options_,
prune(default_prunning_func(reference, epsilon));
}
/** Turns the matrix into compressed format, and suppresses all nonzeros which do not satisfy the predicate \a keep.
/** Suppresses all nonzeros which do not satisfy the predicate \a keep. The storage format is preserved: an
* uncompressed matrix remains uncompressed, so call makeCompressed() if a compressed result is required.
* The functor type \a KeepFunc must implement the following function:
* \code
* bool operator() (const Index& row, const Index& col, const Scalar& value) const;
@@ -1357,6 +1359,7 @@ void SparseMatrix<Scalar, Options_, StorageIndex_>::setFromTriplets(const InputI
/** The same as setFromTriplets but triplets are assumed to be pre-sorted. This is faster and requires less temporary
* storage. Two triplets `a` and `b` are appropriately ordered if: \code ColMajor: ((a.col() != b.col()) ? (a.col() <
* b.col()) : (a.row() < b.row()) RowMajor: ((a.row() != b.row()) ? (a.row() < b.row()) : (a.col() < b.col()) \endcode
* If the range is empty, the initial contents of \c *this are left untouched instead of being destroyed.
*/
template <typename Scalar, int Options_, typename StorageIndex_>
template <typename InputIterators>
@@ -140,6 +140,8 @@ class SparseSelfAdjointView : public EigenBase<SparseSelfAdjointView<MatrixType,
/** Perform a symmetric rank K update of the selfadjoint matrix \c *this:
* \f$ this = this + \alpha ( u u^* ) \f$ where \a u is a vector or matrix.
* As a special case, if \a alpha is zero then the previous contents of \c *this are discarded and overwritten,
* yielding \f$ this = u u^* \f$ instead of leaving \c *this unchanged.
*
* \returns a reference to \c *this
*
+1 -1
View File
@@ -294,7 +294,7 @@ class SparseLU : public SparseSolverBase<SparseLU<MatrixType_, OrderingType_>>,
inline const PermutationType& rowsPermutation() const { return m_perm_r; }
/** \brief Give the column matrix permutation.
*
* \returns a reference to the column matrix permutation\f$ P_c^T \f$ such that \f$P_r A P_c^T = L U\f$
* \returns a reference to the column matrix permutation \f$ P_c \f$ such that \f$P_r A P_c^T = L U\f$
* \sa rowsPermutation()
*/
inline const PermutationType& colsPermutation() const { return m_perm_c; }
+2 -2
View File
@@ -443,7 +443,7 @@ class SuperLUBase : public SparseSolverBase<Derived> {
*
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
*
* \warning This class is only for the 4.x versions of SuperLU. The 3.x and 5.x versions are not supported.
* \warning This class requires at least version 4.0 of SuperLU. The 3.x versions are not supported.
*
* \implsparsesolverconcept
*
@@ -753,7 +753,7 @@ typename SuperLU<MatrixType>::Scalar SuperLU<MatrixType>::determinant() const {
* factorization using the SuperLU library. This class is aimed to be used as a preconditioner of the iterative linear
* solvers.
*
* \warning This class is only for the 4.x versions of SuperLU. The 3.x and 5.x versions are not supported.
* \warning This class requires at least version 4.0 of SuperLU. The 3.x versions are not supported.
*
* \tparam MatrixType_ the type of the sparse matrix A, it must be a SparseMatrix<>
*
+4 -4
View File
@@ -1338,16 +1338,16 @@ EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const ConstInnerVectorReturnType
return ConstInnerVectorReturnType(derived(), outer);
}
/// \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
/// is col-major (resp. row-major).
/// \returns the \a outerSize consecutive columns (resp. rows) of the matrix \c *this starting at \a outerStart
/// if \c *this is col-major (resp. row-major).
///
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) {
return InnerVectorsReturnType(derived(), IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart,
IsRowMajor ? outerSize : rows(), IsRowMajor ? cols() : outerSize);
}
/// \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
/// is col-major (resp. row-major). Read-only.
/// \returns the \a outerSize consecutive columns (resp. rows) of the matrix \c *this starting at \a outerStart
/// if \c *this is col-major (resp. row-major). Read-only.
///
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE const ConstInnerVectorsReturnType innerVectors(Index outerStart,
Index outerSize) const {
+5 -5
View File
@@ -99,13 +99,13 @@ Vector3f A;
A << 1, 2, 3;
Vector3f B = ((1 < 0) ? (A.reverse()) : A);
\endcode
This example will return <code>B = 3, 2, 1</code>. Do you see why?
The reason is that in c++ the type of the \c ELSE statement is inferred from the type of the \c THEN expression such that both match.
Since \c THEN is a <code>Reverse<Vector3f></code>, the \c ELSE statement A is converted to a <code>Reverse<Vector3f></code>, and the compiler thus generates:
This example will return <code>B = 1, 2, 3</code>. Do you see why?
The reason is that in c++ both statements of the ternary operator must be converted to a common type.
The constructor of <code>Reverse<Vector3f></code> from a \c Vector3f is \c explicit, so the \c ELSE statement A cannot be converted to a <code>Reverse<Vector3f></code>; the common type is \c Vector3f instead, and the compiler thus generates:
\code
Vector3f B = ((1 < 0) ? (A.reverse()) : Reverse<Vector3f>(A));
Vector3f B = ((1 < 0) ? Vector3f(A.reverse()) : Vector3f(A));
\endcode
In this very particular case, a workaround would be to call A.reverse().eval() for the \c THEN statement, but the safest and fastest is really to avoid this ternary operator with %Eigen's expressions and use a if/else construct.
The value is the expected one here, but the selected statement is silently evaluated into a temporary plain object, and two different %Eigen expression types often have no common type at all, in which case the ternary operator does not even compile. The safest and fastest is really to avoid this ternary operator with %Eigen's expressions and use a if/else construct.
\section TopicPitfalls_pass_by_value Pass-by-value
+3 -2
View File
@@ -73,8 +73,9 @@ run time. However, these assertions do cost time and can thus be turned off.
- \b EIGEN_NO_DEBUG - disables %Eigen's assertions if defined. Not defined by default, unless the
\c NDEBUG macro is defined (this is a standard C++ macro which disables all asserts).
- \b EIGEN_NO_STATIC_ASSERT - if defined, compile-time static assertions are replaced by runtime assertions;
this saves compilation time. Not defined by default.
- \b EIGEN_NO_STATIC_ASSERT - if defined, %Eigen's compile-time static assertions are removed rather than
downgraded: the misuse they guard against is then reported neither at compile time nor at run time.
Not defined by default.
- \b eigen_assert - macro with one argument that is used inside %Eigen for assertions. By default, it is
basically defined to be \c assert, which aborts the program if the assertion is violated. Redefine this
macro if you want to do something else, like throwing an exception.
+3 -3
View File
@@ -611,10 +611,10 @@ vec.reverseInPlace()
\subsection QuickRef_Replicate Replicate
Vectors, matrices, rows, and/or columns can be replicated in any direction (see DenseBase::replicate(), VectorwiseOp::replicate())
\code
vec.replicate(times) vec.replicate<Times>
vec.replicate(times, 1) vec.replicate<Times, 1>()
mat.replicate(vertical_times, horizontal_times) mat.replicate<VerticalTimes, HorizontalTimes>()
mat.colwise().replicate(vertical_times, horizontal_times) mat.colwise().replicate<VerticalTimes, HorizontalTimes>()
mat.rowwise().replicate(vertical_times, horizontal_times) mat.rowwise().replicate<VerticalTimes, HorizontalTimes>()
mat.colwise().replicate(times) mat.colwise().replicate<Times>()
mat.rowwise().replicate(times) mat.rowwise().replicate<Times>()
\endcode
+2 -2
View File
@@ -153,8 +153,8 @@ It is easy to perform arithmetic operations on sparse matrices provided that the
\code
perm.indices(); // Reference to the vector of indices
sm1.twistedBy(perm); // Permute rows and columns
sm2 = sm1 * perm; // Permute the rows
sm2 = perm * sm1; // Permute the columns
sm2 = sm1 * perm; // Permute the columns
sm2 = perm * sm1; // Permute the rows
\endcode
</td>
<td>
+13 -29
View File
@@ -32,37 +32,20 @@ Matrix3d() + Matrix4d(); // adding matrices of different sizes
Matrix4cd() * Vector3cd(); // invalid product known at compile time
\endcode
Static assertions are defined in StaticAssert.h. If there is native static_assert, we use it. Otherwise, we have implemented an assertion macro that can show a limited range of messages.
One can easily come up with static assertions without messages, such as:
Static assertions are defined in StaticAssert.h. EIGEN_STATIC_ASSERT(CONDITION,MSG) expands to the native
<tt>static_assert</tt>:
\code
#define STATIC_ASSERT(x) \
switch(0) { case 0: case x:; }
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X, #MSG);
\endcode
However, the example above obviously cannot tell why the assertion failed. Therefore, we define a \c struct in namespace Eigen::internal to handle available messages.
\c CONDITION must be a compile-time boolean expression. \c MSG is not evaluated: it is stringified into the
diagnostic, which is why the messages are written ALL_CAPS_AND_THEY_ARE_SHOUTING, as in
\c YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX. Use one of the existing messages where it fits; see StaticAssert.h
for the established names.
\code
template<bool condition>
struct static_assertion {};
template<>
struct static_assertion<true>
{
enum {
YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX,
YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES,
// see StaticAssert.h for all enums.
};
};
\endcode
And then, we define EIGEN_STATIC_ASSERT(CONDITION,MSG) to access Eigen::internal::static_assertion<bool(CONDITION)>::MSG. If the condition evaluates into \c false, your compiler displays a lot of messages explaining there is no MSG in static_assert<false>. Nevertheless, this is \a not in what we are interested. As you can see, all members of static_assert<true> are ALL_CAPS_AND_THEY_ARE_SHOUTING.
\warning
When using this macro, MSG should be a member of static_assertion<true>, or the static assertion \b always fails.
Currently, it can only be used in function scope.
Because it expands to a declaration, EIGEN_STATIC_ASSERT can be used wherever a declaration is allowed, including
class scope — see for instance \c log1p_impl in MathFunctions.h.
\subsection DerivedStaticAssert Derived static assertions
@@ -96,13 +79,14 @@ See StaticAssert.h for details such as what messages they throw.
\subsection DisableStaticAssert Disabling static assertions
If \c EIGEN_NO_STATIC_ASSERT is defined, static assertions turn into <tt>eigen_assert</tt>'s, working like:
If \c EIGEN_NO_STATIC_ASSERT is defined, the static assertions are removed entirely:
\code
#define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG);
#define EIGEN_STATIC_ASSERT(CONDITION,MSG)
\endcode
This saves compile time but consumes more run time. \c EIGEN_NO_STATIC_ASSERT is undefined by default.
They are not downgraded to run-time checks, so the misuse they guard against is reported neither at compile time
nor at run time. \c EIGEN_NO_STATIC_ASSERT is undefined by default.
*/
}
+7 -4
View File
@@ -7,7 +7,9 @@ namespace Eigen {
%Eigen provides native CMake support which allows the library to be easily
used in CMake projects.
\note %CMake 3.5 (or later) is required to enable this functionality.
\note Configuring and installing %Eigen requires %CMake 3.17 (or later). The generated `Eigen3Config.cmake`
imposes no version floor of its own, so a project consuming an already-installed %Eigen may use an older %CMake;
the \ref title_fetchcontent route below adds %Eigen's own build to your project and so requires 3.17 as well.
%Eigen exports a CMake target called `Eigen3::Eigen` which can be imported
using the `find_package` CMake command and used by calling
@@ -62,14 +64,15 @@ endif (TARGET Eigen3::Eigen)
\section title_fetchcontent Using FetchContent
Starting with CMake 3.11, you can use the
You can use the
<a href="https://cmake.org/cmake/help/latest/module/FetchContent.html">FetchContent</a>
module to download and include %Eigen directly in your project without
installing it first.
installing it first. This adds %Eigen's own build to your project, so it requires
%CMake 3.17 rather than the 3.11 that introduced FetchContent.
A basic example:
\code{.cmake}
cmake_minimum_required(VERSION 3.11)
cmake_minimum_required(VERSION 3.17)
project(myproject)
include(FetchContent)
+1 -1
View File
@@ -147,7 +147,7 @@ glLoadMatrixf(t.data());\endcode</td></tr>
OpenGL compatibility \b 2D </td><td>\code
Affine3f aux(Affine3f::Identity());
aux.linear().topLeftCorner<2,2>() = t.linear();
aux.translation().start<2>() = t.translation();
aux.translation().head<2>() = t.translation();
glLoadMatrixf(aux.data());\endcode</td></tr>
</table>
+4 -3
View File
@@ -271,9 +271,10 @@ singular matrix). On \ref TopicLinearAlgebraDecompositions "this table" you can
whether they are rank-revealing or not.
Rank-revealing decompositions offer at least a rank() method. They can also offer convenience methods such as isInvertible(),
and some are also providing methods to compute the kernel (null-space) and image (column-space) of the matrix.
ColPivHouseholderQR, CompleteOrthogonalDecomposition, and FullPivLU all provide these methods. Here is an example using
FullPivLU:
and FullPivLU is the only one that additionally computes the kernel (null-space) and the image (column-space) of the matrix,
through kernel() and image(). ColPivHouseholderQR and CompleteOrthogonalDecomposition are faster rank-revealing
factorizations providing rank() and isInvertible() but no null-space basis; CompleteOrthogonalDecomposition also offers
pseudoInverse(). Here is an example using FullPivLU:
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
+1 -1
View File
@@ -219,7 +219,7 @@ A typical scenario of this approach is illustrated below:
5: mat.makeCompressed(); // optional
\endcode
- The key ingredient here is the line 2 where we reserve room for 6 non-zeros per column. In many cases, the number of non-zeros per column or row can easily be known in advance. If it varies significantly for each inner vector, then it is possible to specify a reserve size for each inner vector by providing a vector object with an `operator[](int j)` returning the reserve size of the \c j-th inner vector (e.g., via a `VectorXi` or `std::vector<int>`). If only a rought estimate of the number of nonzeros per inner-vector can be obtained, it is highly recommended to overestimate it rather than the opposite. If this line is omitted, then the first insertion of a new element will reserve room for 2 elements per inner vector.
- The key ingredient here is the line 2 where we reserve room for 6 non-zeros per column. In many cases, the number of non-zeros per column or row can easily be known in advance. If it varies significantly for each inner vector, then it is possible to specify a reserve size for each inner vector by providing a vector object with an `operator[](int j)` returning the reserve size of the \c j-th inner vector (e.g., via a `VectorXi` or `std::vector<int>`). If only a rought estimate of the number of nonzeros per inner-vector can be obtained, it is highly recommended to overestimate it rather than the opposite. If this line is omitted, then the first insertion of a new element will reserve room for one element per inner vector, and room for one more element per inner vector is reserved again whenever an insertion finds no free slot in any inner vector.
- The line 4 performs a sorted insertion. In this example, the ideal case is when the \c j-th column is not full and contains non-zeros whose inner-indices are smaller than \c i. In this case, this operation boils down to trivial O(1) operation.
- When calling `insert(i,j)` the element `i`, `j` must not already exists, otherwise use the `coeffRef(i,j)` method that will allow to, e.g., accumulate values. This method first performs a binary search and finally calls `insert(i,j)` if the element does not already exist. It is more flexible than `insert()` but also more costly.
- The line 5 suppresses the remaining empty space and transforms the matrix into a compressed column storage.
@@ -71,9 +71,9 @@ class ArpackGeneralizedSelfAdjointEigenSolver {
* Must be less than the size of the input matrix, or an error is returned.
* \param[in] eigs_sigma String containing either "LM", "SM", "LA", or "SA", with
* respective meanings to find the largest magnitude, smallest magnitude,
* largest algebraic, or smallest algebraic eigenvalues. Alternatively, this
* value can contain floating point value in string form, in which case the
* eigenvalues closest to this value will be found.
* largest algebraic, or smallest algebraic eigenvalues. Passing a floating
* point value in string form, to find the eigenvalues closest to that value,
* is not supported yet and triggers an assertion.
* \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
* \param[in] tol What tolerance to find the eigenvalues to. Default is 0, which
* means machine precision.
@@ -104,9 +104,9 @@ class ArpackGeneralizedSelfAdjointEigenSolver {
* Must be less than the size of the input matrix, or an error is returned.
* \param[in] eigs_sigma String containing either "LM", "SM", "LA", or "SA", with
* respective meanings to find the largest magnitude, smallest magnitude,
* largest algebraic, or smallest algebraic eigenvalues. Alternatively, this
* value can contain floating point value in string form, in which case the
* eigenvalues closest to this value will be found.
* largest algebraic, or smallest algebraic eigenvalues. Passing a floating
* point value in string form, to find the eigenvalues closest to that value,
* is not supported yet and triggers an assertion.
* \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
* \param[in] tol What tolerance to find the eigenvalues to. Default is 0, which
* means machine precision.
@@ -136,9 +136,9 @@ class ArpackGeneralizedSelfAdjointEigenSolver {
* Must be less than the size of the input matrix, or an error is returned.
* \param[in] eigs_sigma String containing either "LM", "SM", "LA", or "SA", with
* respective meanings to find the largest magnitude, smallest magnitude,
* largest algebraic, or smallest algebraic eigenvalues. Alternatively, this
* value can contain floating point value in string form, in which case the
* eigenvalues closest to this value will be found.
* largest algebraic, or smallest algebraic eigenvalues. Passing a floating
* point value in string form, to find the eigenvalues closest to that value,
* is not supported yet and triggers an assertion.
* \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
* \param[in] tol What tolerance to find the eigenvalues to. Default is 0, which
* means machine precision.
@@ -162,9 +162,9 @@ class ArpackGeneralizedSelfAdjointEigenSolver {
* Must be less than the size of the input matrix, or an error is returned.
* \param[in] eigs_sigma String containing either "LM", "SM", "LA", or "SA", with
* respective meanings to find the largest magnitude, smallest magnitude,
* largest algebraic, or smallest algebraic eigenvalues. Alternatively, this
* value can contain floating point value in string form, in which case the
* eigenvalues closest to this value will be found.
* largest algebraic, or smallest algebraic eigenvalues. Passing a floating
* point value in string form, to find the eigenvalues closest to that value,
* is not supported yet and triggers an assertion.
* \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.
* \param[in] tol What tolerance to find the eigenvalues to. Default is 0, which
* means machine precision.
@@ -212,9 +212,9 @@ class ArpackGeneralizedSelfAdjointEigenSolver {
*
* \pre The eigenvalues have been computed before.
*
* The eigenvalues are repeated according to their algebraic multiplicity,
* so there are as many eigenvalues as rows in the matrix. The eigenvalues
* are sorted in increasing order.
* The returned vector has \c nbrEigenvalues entries, as requested when calling
* compute(): ARPACK is a partial eigensolver and cannot compute the whole
* spectrum. The eigenvalues are sorted in increasing order.
*
* Example: \include SelfAdjointEigenSolver_eigenvalues.cpp
* Output: \verbinclude SelfAdjointEigenSolver_eigenvalues.out
@@ -215,8 +215,13 @@ class EulerAngles : public RotationBase<EulerAngles<Scalar_, _System>, 3> {
/** \returns A read-write reference to the angle of the third angle. */
Scalar& gamma() { return m_angles[2]; }
/** \returns The Euler angles rotation inverse (which is as same as the negative),
* (-alpha, -beta, -gamma).
/** \returns The Euler angles with each angle negated, (-alpha, -beta, -gamma).
*
* \note In general these angles do not describe the inverse rotation: inverting
* \f$ R = R_\alpha R_\beta R_\gamma \f$ also reverses the order of the three factors. They do describe it
* whenever the three elemental rotations commute, for instance when at most one of the angles is nonzero,
* and, for a system whose first and third axes coincide (a proper Euler system such as ZXZ), whenever
* \f$ \alpha = \gamma \f$, for any \f$ \beta \f$.
*/
EulerAngles inverse() const {
EulerAngles res;
@@ -224,8 +229,10 @@ class EulerAngles : public RotationBase<EulerAngles<Scalar_, _System>, 3> {
return res;
}
/** \returns The Euler angles rotation negative (which is as same as the inverse),
/** \returns The Euler angles negative (which is the same as inverse()),
* (-alpha, -beta, -gamma).
*
* \sa inverse()
*/
EulerAngles operator-() const { return inverse(); }
@@ -135,8 +135,8 @@ struct GoogleSparseHashMapTraits {
* - \b GoogleSparseHashMapTraits: corresponds to google::sparse_hash_map (best memory consumption, relatively good
* performance)
*
* The default map implementation depends on the availability, and the preferred order is:
* GoogleSparseHashMapTraits, StdUnorderedMapTraits, and finally StdMapTraits.
* The default map implementation is GoogleDenseHashMapTraits if EIGEN_GOOGLEHASH_SUPPORT is defined, and
* StdUnorderedMapTraits otherwise; StdMapTraits is never selected by default.
*
* For performance and memory consumption reasons it is highly recommended to use one of
* Google's hash_map implementations. To enable the support for them, you must define
+20 -7
View File
@@ -447,11 +447,14 @@ overloads for the `()` operator that let you access individual values in
the expression.
`TensorRef` is convenient, because the Operation themselves do
not provide a way to access individual elements.
A read-only expression must be wrapped in a `TensorRef<const Tensor<...>>`; the
mutable `TensorRef<Tensor<...>>` statically requires an lvalue expression such
as a `Tensor` or a slice.
```cpp
// Create a TensorRef for the expression. The expression is not
// evaluated yet.
TensorRef<Tensor<float, 3>> ref = ((t1 + t2) * 0.2f).exp();
TensorRef<const Tensor<float, 3>> ref = ((t1 + t2) * 0.2f).exp();
// Use "ref" to access individual elements. The expression is evaluated
// on the fly.
@@ -703,7 +706,7 @@ std::cout << "Size: " << a.size();
### Getting Dimensions From An Operation
A few operations provide `dimensions()` directly,
e.g. `TensorSlicingOp`. Most operations defer calculating dimensions
e.g. `TensorReshapingOp`. Most operations defer calculating dimensions
until the operation is being evaluated. If you need access to the dimensions
of a deferred operation, you can wrap it in a `TensorRef` (see
**Assigning to a TensorRef** above), which provides
@@ -1496,9 +1499,12 @@ The following boolean operators are supported:
* `operator|(const OtherDerived& other)`
* `operator^(const OtherDerived& other)`
The resulting tensor retains the input scalar type.
The comparison operators (`<`, `<=`, `>`, `>=`, `==`, `!=`) produce a tensor
whose scalar type is `bool`. The boolean and bitwise operators retain the
input scalar type.
Scalar comparison variants are also available (e.g. `a < 0.5f`).
Scalar comparison variants are also available (e.g. `a < 0.5f`), and likewise
produce a `bool` tensor.
## Selection (select(const ThenDerived& thenTensor, const ElseDerived& elseTensor)
@@ -2630,7 +2636,7 @@ This code results in the following output when the data layout is RowMajor:
6 7
10 11
### (Operation) extract_image_patches(const Index patch_rows, const Index patch_cols, const Index row_stride, const Index col_stride, const PaddingType padding_type)
### (Operation) extract_image_patches(const Index patch_rows, const Index patch_cols, const Index row_stride, const Index col_stride, ...)
Returns a tensor of coefficient image patches extracted from the input tensor,
which is expected to have dimensions ordered as follows (depending on the data
@@ -2653,6 +2659,13 @@ used to index each patch. The patch index in the output tensor depends on the
data layout of the input tensor: the patch index is the 4'th dimension in
`ColMajor` layout, and the 4'th from the last dimension in `RowMajor` layout.
All the arguments are optional and default to 1, except for the two trailing
ones. `in_row_stride` and `in_col_stride` dilate the patch, so that it samples
every `in_row_stride`'th input row and every `in_col_stride`'th input column.
`padding_type` selects `PADDING_SAME` (the default) or `PADDING_VALID`, and
`padding_value` (`Scalar(0)` by default) is used for the coefficients of a
patch that fall outside the input.
For example, given the following input tensor with the following dimension
sizes:
- depth: 2
@@ -2671,7 +2684,7 @@ Tensor<float, 4, RowMajor> tensor_row_major = tensor.swap_layout();
```cpp
Tensor<float, 5> twod_patch;
twod_patch = tensor.extract_image_patches<2, 2>();
twod_patch = tensor.extract_image_patches(2, 2);
// twod_patch.dimension(0) == 2
// twod_patch.dimension(1) == 2
// twod_patch.dimension(2) == 2
@@ -2683,7 +2696,7 @@ twod_patch = tensor.extract_image_patches<2, 2>();
```cpp
Tensor<float, 5, RowMajor> twod_patch_row_major;
twod_patch_row_major = tensor_row_major.extract_image_patches<2, 2>();
twod_patch_row_major = tensor_row_major.extract_image_patches(2, 2);
// twod_patch_row_major.dimension(0) == 7
// twod_patch_row_major.dimension(1) == 3*5
// twod_patch_row_major.dimension(2) == 2
+7 -7
View File
@@ -35,9 +35,9 @@ namespace Eigen {
* \tparam Options_ A combination of either \b #RowMajor or \b #ColMajor, and of either
* \b #AutoAlign or \b #DontAlign.
* The former controls \ref TopicStorageOrders "storage order", and defaults to column-major. The latter
* controls alignment, which is required for vectorization. It defaults to aligning tensors. Note that tensors currently
* do not support any operations that profit from vectorization. Support for such operations (i.e. adding two tensors
* etc.) is planned.
* controls alignment, which is required for vectorization. It defaults to aligning tensors. Tensor expressions such as
* the sum of two tensors are evaluated with packet instructions whenever the evaluators involved support packet
* access.
*
* You can access elements of tensors using normal subscripting:
*
@@ -56,10 +56,10 @@ namespace Eigen {
* <dt><b>Relation to other parts of Eigen:</b></dt>
* <dd>The midterm development goal for this class is to have a similar hierarchy as Eigen uses for matrices, so that
* taking blocks or using tensors in expressions is easily possible, including an interface with the vector/matrix code
* by providing .asMatrix() and .asVector() (or similar) methods for rank 2 and 1 tensors. However, currently, the
* %Tensor class does not provide any of these features and is only available as a stand-alone class that just allows
* for coefficient access. Also, when fixed-size tensors are implemented, the number of template arguments is likely to
* change dramatically.</dd>
* by providing .asMatrix() and .asVector() (or similar) methods for rank 2 and 1 tensors. Taking blocks and using
* tensors in expressions is already supported through \c TensorBase; interoperability with the vector/matrix code
* currently relies on wrapping the data in a \c Map or a \c TensorMap instead of dedicated methods. Fixed-size tensors
* are provided by the separate \c TensorFixedSize class.</dd>
* </dl>
*
* \ref TopicStorageOrders