diff --git a/Eigen/src/Cholesky/Cholesky.h b/Eigen/src/Cholesky/Cholesky.h index 71549c43e..69e906ee7 100644 --- a/Eigen/src/Cholesky/Cholesky.h +++ b/Eigen/src/Cholesky/Cholesky.h @@ -58,7 +58,7 @@ template class Cholesky inline bool isPositiveDefinite(void) const { return m_isPositiveDefinite; } template - typename Derived::Eval solve(const MatrixBase &b) const EIGEN_DEPRECATED; + typename MatrixBase::PlainMatrixType_ColMajor solve(const MatrixBase &b) const EIGEN_DEPRECATED; template bool solve(const MatrixBase &b, MatrixBase *result) const; @@ -119,11 +119,11 @@ void Cholesky::compute(const MatrixType& a) /** \deprecated */ template template -typename Derived::Eval Cholesky::solve(const MatrixBase &b) const +typename MatrixBase::PlainMatrixType_ColMajor Cholesky::solve(const MatrixBase &b) const { const int size = m_matrix.rows(); ei_assert(size==b.rows()); - typename ei_eval_to_column_major::type x(b); + typename MatrixBase::PlainMatrixType_ColMajor x(b); solveInPlace(x); return x; } @@ -156,10 +156,10 @@ bool Cholesky::solveInPlace(MatrixBase &bAndX) const * \deprecated has been renamed llt() */ template -inline const Cholesky::EvalType> +inline const Cholesky::PlainMatrixType> MatrixBase::cholesky() const { - return Cholesky::type>(derived()); + return Cholesky(derived()); } #endif // EIGEN_CHOLESKY_H diff --git a/Eigen/src/Cholesky/CholeskyWithoutSquareRoot.h b/Eigen/src/Cholesky/CholeskyWithoutSquareRoot.h index bf9951709..b40ba18c0 100644 --- a/Eigen/src/Cholesky/CholeskyWithoutSquareRoot.h +++ b/Eigen/src/Cholesky/CholeskyWithoutSquareRoot.h @@ -175,7 +175,7 @@ bool CholeskyWithoutSquareRoot::solveInPlace(MatrixBase &bA * \deprecated has been renamed ldlt() */ template -inline const CholeskyWithoutSquareRoot::EvalType> +inline const CholeskyWithoutSquareRoot::PlainMatrixType> MatrixBase::choleskyNoSqrt() const { return derived(); diff --git a/Eigen/src/Cholesky/LDLT.h b/Eigen/src/Cholesky/LDLT.h index aa967f6b9..a275e093f 100644 --- a/Eigen/src/Cholesky/LDLT.h +++ b/Eigen/src/Cholesky/LDLT.h @@ -189,7 +189,7 @@ bool LDLT::solveInPlace(MatrixBase &bAndX) const * \returns the Cholesky decomposition without square root of \c *this */ template -inline const LDLT::EvalType> +inline const LDLT::PlainMatrixType> MatrixBase::ldlt() const { return derived(); diff --git a/Eigen/src/Cholesky/LLT.h b/Eigen/src/Cholesky/LLT.h index 2fc658bb7..6e412e20c 100644 --- a/Eigen/src/Cholesky/LLT.h +++ b/Eigen/src/Cholesky/LLT.h @@ -177,10 +177,10 @@ bool LLT::solveInPlace(MatrixBase &bAndX) const * \returns the LLT decomposition of \c *this */ template -inline const LLT::EvalType> +inline const LLT::PlainMatrixType> MatrixBase::llt() const { - return LLT::type>(derived()); + return LLT(derived()); } #endif // EIGEN_LLT_H diff --git a/Eigen/src/Core/DiagonalProduct.h b/Eigen/src/Core/DiagonalProduct.h index ca0b56872..5e23fb066 100644 --- a/Eigen/src/Core/DiagonalProduct.h +++ b/Eigen/src/Core/DiagonalProduct.h @@ -32,7 +32,7 @@ */ template struct ei_nested_diagonal : ei_nested {}; template struct ei_nested_diagonal,N > - : ei_nested, N, DiagonalMatrix::type> > > + : ei_nested, N, DiagonalMatrix::type> > > {}; // specialization of ProductReturnType diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h index c4703adc3..86bebe246 100644 --- a/Eigen/src/Core/Dot.h +++ b/Eigen/src/Core/Dot.h @@ -318,7 +318,7 @@ inline typename NumTraits::Scalar>::Real MatrixBase< * \sa norm(), normalize() */ template -inline const typename MatrixBase::EvalType +inline const typename MatrixBase::PlainMatrixType MatrixBase::normalized() const { typedef typename ei_nested::type Nested; diff --git a/Eigen/src/Core/IO.h b/Eigen/src/Core/IO.h index ca00cae3d..2b00d5bc5 100644 --- a/Eigen/src/Core/IO.h +++ b/Eigen/src/Core/IO.h @@ -122,9 +122,10 @@ MatrixBase::format(const IOFormat& fmt) const /** \internal * print the matrix \a _m to the output stream \a s using the output format \a fmt */ template -std::ostream & ei_print_matrix(std::ostream & s, const MatrixBase & _m, const IOFormat& fmt) +std::ostream & ei_print_matrix(std::ostream & s, const Derived& _m, const IOFormat& fmt) { const typename Derived::Nested m = _m; + int width = 0; if (fmt.flags & AlignCols) { diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index fd4b5cb4a..3cde1e28b 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -426,14 +426,6 @@ class Matrix /** Destructor */ inline ~Matrix() {} - /** Override MatrixBase::eval() since matrices don't need to be evaluated, it is enough to just read them. - * This prevents a useless copy when doing e.g. "m1 = m2.eval()" - */ - inline const Matrix& eval() const - { - return *this; - } - /** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the * data pointers. */ diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index f916dbf2a..bb3cc0532 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -179,9 +179,20 @@ template class MatrixBase int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); } #ifndef EIGEN_PARSED_BY_DOXYGEN - /** \internal the type to which the expression gets evaluated (needed by MSVC) */ - typedef typename ei_eval::type EvalType; - /** \internal Represents a constant matrix */ + /** \internal the plain matrix type corresponding to this expression. Note that is not necessarily + * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const + * reference to a matrix, not a matrix! It guaranteed however, that the return type of eval() is either + * PlainMatrixType or const PlainMatrixType&. + */ + typedef typename ei_plain_matrix_type::type PlainMatrixType; + /** \internal the column-major plain matrix type corresponding to this expression. Note that is not necessarily + * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const + * reference to a matrix, not a matrix! + * The only difference from PlainMatrixType is that PlainMatrixType_ColMajor is guaranteed to be column-major. + */ + typedef typename ei_plain_matrix_type::type PlainMatrixType_ColMajor; + + /** \internal Represents a matrix with all coefficients equal to one another*/ typedef CwiseNullaryOp,Derived> ConstantReturnType; /** \internal Represents a scalar multiple of a matrix */ typedef CwiseUnaryOp, Derived> ScalarMultipleReturnType; @@ -331,7 +342,7 @@ template class MatrixBase Derived& operator*=(const MatrixBase& other); template - typename ei_eval_to_column_major::type + typename ei_plain_matrix_type_column_major::type solveTriangular(const MatrixBase& other) const; template @@ -343,7 +354,7 @@ template class MatrixBase RealScalar squaredNorm() const; RealScalar norm2() const; RealScalar norm() const; - const EvalType normalized() const; + const PlainMatrixType normalized() const; void normalize(); Eigen::Transpose transpose(); @@ -481,6 +492,8 @@ template class MatrixBase /** \returns the matrix or vector obtained by evaluating this expression. * + * Notice that in the case of a plain matrix or vector (not an expression) this function just returns + * a const reference, in order to avoid a useless copy. */ EIGEN_ALWAYS_INLINE const typename ei_eval::type eval() const { @@ -573,35 +586,35 @@ template class MatrixBase /////////// LU module /////////// - const LU lu() const; - const EvalType inverse() const; - void computeInverse(EvalType *result) const; + const LU lu() const; + const PlainMatrixType inverse() const; + void computeInverse(PlainMatrixType *result) const; Scalar determinant() const; /////////// Cholesky module /////////// - const LLT llt() const; - const LDLT ldlt() const; + const LLT llt() const; + const LDLT ldlt() const; // deprecated: - const Cholesky cholesky() const; - const CholeskyWithoutSquareRoot choleskyNoSqrt() const; + const Cholesky cholesky() const; + const CholeskyWithoutSquareRoot choleskyNoSqrt() const; /////////// QR module /////////// - const QR qr() const; + const QR qr() const; EigenvaluesReturnType eigenvalues() const; RealScalar operatorNorm() const; /////////// SVD module /////////// - SVD svd() const; + SVD svd() const; /////////// Geometry module /////////// template - EvalType cross(const MatrixBase& other) const; - EvalType unitOrthogonal(void) const; + PlainMatrixType cross(const MatrixBase& other) const; + PlainMatrixType unitOrthogonal(void) const; Matrix eulerAngles(int a0, int a1, int a2) const; #ifdef EIGEN_MATRIXBASE_PLUGIN diff --git a/Eigen/src/Core/Part.h b/Eigen/src/Core/Part.h index 3cb55fe1d..e51eaeb29 100644 --- a/Eigen/src/Core/Part.h +++ b/Eigen/src/Core/Part.h @@ -157,7 +157,7 @@ inline Part& Part::operator=(const Other& ot { if(Other::Flags & EvalBeforeAssigningBit) { - typename ei_eval::type other_evaluated(other.rows(), other.cols()); + typename MatrixBase::PlainMatrixType other_evaluated(other.rows(), other.cols()); other_evaluated.template part().lazyAssign(other); lazyAssign(other_evaluated); } diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index a844470a7..4e5bea050 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -69,7 +69,7 @@ struct ProductReturnType typedef typename ei_nested::type LhsNested; typedef typename ei_nested::type + typename ei_plain_matrix_type_column_major::type >::type RhsNested; typedef Product Type; @@ -735,7 +735,7 @@ template struct ei_product_copy_rhs typedef typename ei_meta_if< (ei_traits::Flags & RowMajorBit) || (!(ei_traits::Flags & DirectAccessBit)), - typename ei_eval_to_column_major::type, + typename ei_plain_matrix_type_column_major::type, const T& >::ret type; }; @@ -744,7 +744,7 @@ template struct ei_product_copy_lhs { typedef typename ei_meta_if< (!(int(ei_traits::Flags) & DirectAccessBit)), - typename ei_eval::type, + typename ei_plain_matrix_type::type, const T& >::ret type; }; diff --git a/Eigen/src/Core/SolveTriangular.h b/Eigen/src/Core/SolveTriangular.h index 20c0408bd..b58dab01d 100644 --- a/Eigen/src/Core/SolveTriangular.h +++ b/Eigen/src/Core/SolveTriangular.h @@ -236,7 +236,7 @@ void MatrixBase::solveTriangularInPlace(MatrixBase& other enum { copy = ei_traits::Flags & RowMajorBit }; typedef typename ei_meta_if::type, OtherDerived&>::ret OtherCopy; + typename ei_plain_matrix_type_column_major::type, OtherDerived&>::ret OtherCopy; OtherCopy otherCopy(other.derived()); ei_solve_triangular_selector::type>::run(derived(), otherCopy); @@ -278,10 +278,10 @@ void MatrixBase::solveTriangularInPlace(MatrixBase& other */ template template -typename ei_eval_to_column_major::type +typename ei_plain_matrix_type_column_major::type MatrixBase::solveTriangular(const MatrixBase& other) const { - typename ei_eval_to_column_major::type res(other); + typename ei_plain_matrix_type_column_major::type res(other); solveTriangularInPlace(res); return res; } diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index 312d863e7..dc18a425c 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -171,7 +171,6 @@ typedef typename Eigen::ei_traits::Scalar Scalar; \ typedef typename Eigen::NumTraits::Real RealScalar; \ typedef typename Base::PacketScalar PacketScalar; \ typedef typename Eigen::ei_nested::type Nested; \ -typedef typename Eigen::ei_eval::type Eval; \ enum { RowsAtCompileTime = Eigen::ei_traits::RowsAtCompileTime, \ ColsAtCompileTime = Eigen::ei_traits::ColsAtCompileTime, \ MaxRowsAtCompileTime = Eigen::ei_traits::MaxRowsAtCompileTime, \ diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 67d1f8c1b..ae8703958 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -112,6 +112,10 @@ template struct ei_size_at_compile_time enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols }; }; +/* ei_eval : the return type of eval(). For matrices, this is just a const reference + * in order to avoid a useless copy + */ + template::Flags&SparseBit> class ei_eval; template struct ei_eval @@ -125,8 +129,30 @@ template struct ei_eval > type; }; +// for matrices, no need to evaluate, just use a const reference to avoid a useless copy +template +struct ei_eval, IsDense> +{ + typedef const Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type; +}; -template struct ei_eval_to_column_major +/* ei_plain_matrix_type : the difference from ei_eval is that ei_plain_matrix_type is always a plain matrix type, + * whereas ei_eval is a const reference in the case of a matrix + */ +template struct ei_plain_matrix_type +{ + typedef Matrix::Scalar, + ei_traits::RowsAtCompileTime, + ei_traits::ColsAtCompileTime, + ei_traits::Flags&RowMajorBit ? RowMajor : ColMajor, + ei_traits::MaxRowsAtCompileTime, + ei_traits::MaxColsAtCompileTime + > type; +}; + +/* ei_plain_matrix_type_column_major : same as ei_plain_matrix_type but guaranteed to be column-major + */ +template struct ei_plain_matrix_type_column_major { typedef Matrix::Scalar, ei_traits::RowsAtCompileTime, @@ -158,7 +184,7 @@ template struct ei_must_nest_by_value > { enum { ret * const Matrix3d&, because the internal logic of ei_nested determined that since a was already a matrix, there was no point * in copying it into another matrix. */ -template::type> struct ei_nested +template::type> struct ei_nested { enum { CostEval = (n+1) * int(NumTraits::Scalar>::ReadCost), @@ -170,7 +196,7 @@ template::type> str typename ei_meta_if< (int(ei_traits::Flags) & EvalBeforeNestingBit) || ( int(CostEval) <= int(CostNoEval) ), - EvalType, + PlainMatrixType, const T& >::ret >::ret type; diff --git a/Eigen/src/Geometry/OrthoMethods.h b/Eigen/src/Geometry/OrthoMethods.h index d60664cc0..047152d0b 100644 --- a/Eigen/src/Geometry/OrthoMethods.h +++ b/Eigen/src/Geometry/OrthoMethods.h @@ -34,7 +34,7 @@ */ template template -inline typename MatrixBase::EvalType +inline typename MatrixBase::PlainMatrixType MatrixBase::cross(const MatrixBase& other) const { EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Derived,3) @@ -43,7 +43,7 @@ MatrixBase::cross(const MatrixBase& other) const // optimize such a small temporary very well (even within a complex expression) const typename ei_nested::type lhs(derived()); const typename ei_nested::type rhs(other.derived()); - return typename ei_eval::type( + return typename ei_plain_matrix_type::type( lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1), lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2), lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0) @@ -53,7 +53,7 @@ MatrixBase::cross(const MatrixBase& other) const template struct ei_unitOrthogonal_selector { - typedef typename ei_eval::type VectorType; + typedef typename ei_plain_matrix_type::type VectorType; typedef typename ei_traits::Scalar Scalar; typedef typename NumTraits::Real RealScalar; inline static VectorType run(const Derived& src) @@ -96,7 +96,7 @@ struct ei_unitOrthogonal_selector template struct ei_unitOrthogonal_selector { - typedef typename ei_eval::type VectorType; + typedef typename ei_plain_matrix_type::type VectorType; inline static VectorType run(const Derived& src) { return VectorType(-ei_conj(src.y()), ei_conj(src.x())).normalized(); } }; @@ -109,7 +109,7 @@ struct ei_unitOrthogonal_selector * \sa cross() */ template -typename MatrixBase::EvalType +typename MatrixBase::PlainMatrixType MatrixBase::unitOrthogonal() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index d03d176f9..8be2df67a 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h @@ -548,7 +548,7 @@ inline Transform& Transform::operator=(const ScalingType { m_matrix.setZero(); linear().diagonal() = s.coeffs(); - m_matrix(Dim,Dim) = Scalar(1); + m_matrix.coeffRef(Dim,Dim) = Scalar(1); return *this; } @@ -567,7 +567,7 @@ inline Transform& Transform::operator=(const RotationBas linear() = ei_toRotationMatrix(r); translation().setZero(); m_matrix.template block<1,Dim>(Dim,0).setZero(); - m_matrix(Dim,Dim) = Scalar(1); + m_matrix.coeffRef(Dim,Dim) = Scalar(1); return *this; } @@ -610,7 +610,7 @@ Transform::extractRotation(TransformTraits traits) const LinearMatrixType matQ = qr.matrixQ(); LinearMatrixType matR = qr.matrixR(); for (int i=0 ; i XprBlock22; - typedef typename XprBlock22::Eval Block22; + typedef typename MatrixBase::PlainMatrixType Block22; Block22 P_inverse; if(ei_compute_inverse_in_size2_case_with_check(matrix.template block<2,2>(0,0), &P_inverse)) { @@ -216,12 +216,11 @@ struct ei_compute_inverse * \sa inverse() */ template -inline void MatrixBase::computeInverse(EvalType *result) const +inline void MatrixBase::computeInverse(PlainMatrixType *result) const { - typedef typename ei_eval::type MatrixType; ei_assert(rows() == cols()); EIGEN_STATIC_ASSERT(NumTraits::HasFloatingPoint,numeric_type_must_be_floating_point) - ei_compute_inverse::run(eval(), result); + ei_compute_inverse::run(eval(), result); } /** \lu_module @@ -239,9 +238,9 @@ inline void MatrixBase::computeInverse(EvalType *result) const * \sa computeInverse() */ template -inline const typename MatrixBase::EvalType MatrixBase::inverse() const +inline const typename MatrixBase::PlainMatrixType MatrixBase::inverse() const { - EvalType result(rows(), cols()); + PlainMatrixType result(rows(), cols()); computeInverse(&result); return result; } diff --git a/Eigen/src/LU/LU.h b/Eigen/src/LU/LU.h index bd2f30e84..41e33b48f 100644 --- a/Eigen/src/LU/LU.h +++ b/Eigen/src/LU/LU.h @@ -76,7 +76,7 @@ template class LU MatrixType::ColsAtCompileTime, // the number of rows in the "kernel matrix" is the number of cols of the original matrix // so that the product "matrix * kernel = zero" makes sense Dynamic, // we don't know at compile-time the dimension of the kernel - MatrixType::Flags&RowMajorBit, // small optimization as we construct the kernel row by row + MatrixType::Flags&RowMajorBit, MatrixType::MaxColsAtCompileTime, // see explanation for 2nd template parameter MatrixType::MaxColsAtCompileTime // the kernel is a subspace of the domain space, whose dimension is the number // of columns of the original matrix @@ -164,7 +164,8 @@ template class LU * * \sa kernel(), computeImage(), image() */ - void computeKernel(KernelResultType *result) const; + template + void computeKernel(KernelMatrixType *result) const; /** Computes a basis of the image of the matrix, also called the column-space or range of he matrix. * @@ -179,7 +180,8 @@ template class LU * * \sa image(), computeKernel(), kernel() */ - void computeImage(ImageResultType *result) const; + template + void computeImage(ImageMatrixType *result) const; /** \returns the kernel of the matrix, also called its null-space. The columns of the returned matrix * will form a basis of the kernel. @@ -411,7 +413,8 @@ typename ei_traits::Scalar LU::determinant() const } template -void LU::computeKernel(KernelResultType *result) const +template +void LU::computeKernel(KernelMatrixType *result) const { ei_assert(!isInvertible()); const int dimker = dimensionOfKernel(), cols = m_lu.cols(); @@ -434,7 +437,7 @@ void LU::computeKernel(KernelResultType *result) const */ Matrix + MatrixType::MaxColsAtCompileTime, MatrixType::MaxColsAtCompileTime> y(-m_lu.corner(TopRight, m_rank, dimker)); m_lu.corner(TopLeft, m_rank, m_rank) @@ -457,7 +460,8 @@ LU::kernel() const } template -void LU::computeImage(ImageResultType *result) const +template +void LU::computeImage(ImageMatrixType *result) const { ei_assert(m_rank > 0); result->resize(m_originalMatrix.rows(), m_rank); @@ -493,7 +497,7 @@ bool LU::solve( ei_assert(b.rows() == rows); const int smalldim = std::min(rows, m_lu.cols()); - typename OtherDerived::Eval c(b.rows(), b.cols()); + typename OtherDerived::PlainMatrixType c(b.rows(), b.cols()); // Step 1 for(int i = 0; i < rows; ++i) c.row(m_p.coeff(i)) = b.row(i); @@ -540,10 +544,10 @@ bool LU::solve( * \sa class LU */ template -inline const LU::EvalType> +inline const LU::PlainMatrixType> MatrixBase::lu() const { - return eval(); + return LU(eval()); } #endif // EIGEN_LU_H diff --git a/Eigen/src/QR/QR.h b/Eigen/src/QR/QR.h index 94b817a02..c19205816 100644 --- a/Eigen/src/QR/QR.h +++ b/Eigen/src/QR/QR.h @@ -169,10 +169,10 @@ MatrixType QR::matrixQ(void) const * \sa class QR */ template -const QR::EvalType> +const QR::PlainMatrixType> MatrixBase::qr() const { - return eval(); + return QR(eval()); } diff --git a/Eigen/src/QR/SelfAdjointEigenSolver.h b/Eigen/src/QR/SelfAdjointEigenSolver.h index 05060063c..c6bda1115 100644 --- a/Eigen/src/QR/SelfAdjointEigenSolver.h +++ b/Eigen/src/QR/SelfAdjointEigenSolver.h @@ -267,7 +267,7 @@ inline Matrix::Scalar>::Real, ei_ MatrixBase::eigenvalues() const { ei_assert(Flags&SelfAdjointBit); - return SelfAdjointEigenSolver(eval(),false).eigenvalues(); + return SelfAdjointEigenSolver(eval(),false).eigenvalues(); } template @@ -287,7 +287,7 @@ template struct ei_operatorNorm_selector static inline typename NumTraits::Scalar>::Real operatorNorm(const MatrixBase& m) { - typename Derived::Eval m_eval(m); + typename Derived::PlainMatrixType m_eval(m); // FIXME if it is really guaranteed that the eigenvalues are already sorted, // then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough. return ei_sqrt( diff --git a/Eigen/src/SVD/SVD.h b/Eigen/src/SVD/SVD.h index 988316649..b8432c943 100644 --- a/Eigen/src/SVD/SVD.h +++ b/Eigen/src/SVD/SVD.h @@ -538,10 +538,10 @@ bool SVD::solve(const MatrixBase &b, ResultType* resul * \returns the SVD decomposition of \c *this */ template -inline SVD::EvalType> +inline SVD::PlainMatrixType> MatrixBase::svd() const { - return SVD::type>(derived()); + return SVD(derived()); } #endif // EIGEN_SVD_H diff --git a/doc/snippets/LU_computeImage.cpp b/doc/snippets/LU_computeImage.cpp new file mode 100644 index 000000000..5c812cc4c --- /dev/null +++ b/doc/snippets/LU_computeImage.cpp @@ -0,0 +1,13 @@ +MatrixXd m(3,3); +m << 1,1,0, + 1,3,2, + 0,1,1; +cout << "Here is the matrix m:" << endl << m << endl; +LU lu(m); +// allocate the matrix img with the correct size to avoid reallocation +MatrixXd img(m.rows(), lu.rank()); +lu.computeImage(&img); +cout << "Notice that the middle column is the sum of the two others, so the " + << "columns are linearly dependent." << endl; +cout << "Here is a matrix whose columns have the same span but are linearly independent:" + << endl << img << endl; diff --git a/doc/snippets/LU_image.cpp b/doc/snippets/LU_image.cpp new file mode 100644 index 000000000..0d1088a2f --- /dev/null +++ b/doc/snippets/LU_image.cpp @@ -0,0 +1,9 @@ +Matrix3d m; +m << 1,1,0, + 1,3,2, + 0,1,1; +cout << "Here is the matrix m:" << endl << m << endl; +cout << "Notice that the middle column is the sum of the two others, so the " + << "columns are linearly dependent." << endl; +cout << "Here is a matrix whose columns have the same span but are linearly independent:" + << endl << m.lu().image() << endl; diff --git a/test/main.h b/test/main.h index 433c8688b..ec6724ffd 100644 --- a/test/main.h +++ b/test/main.h @@ -162,7 +162,7 @@ namespace Eigen { template inline typename NumTraits::Real test_precision(); template<> inline int test_precision() { return 0; } -template<> inline float test_precision() { return 1e-4f; } +template<> inline float test_precision() { return 1e-3f; } template<> inline double test_precision() { return 1e-6; } template<> inline float test_precision >() { return test_precision(); } template<> inline double test_precision >() { return test_precision(); }