diff options
author | Benoit Jacob <jacob.benoit.1@gmail.com> | 2008-12-18 20:36:25 +0000 |
---|---|---|
committer | Benoit Jacob <jacob.benoit.1@gmail.com> | 2008-12-18 20:36:25 +0000 |
commit | fabaa6915be063a5390ad78c4ddd86b335691418 (patch) | |
tree | 9dbd25fadf56402587629e76ec9a1dd0a0727739 /Eigen/src/Core | |
parent | b27a3644a24248606092357a0b11aae56e6dbb91 (diff) |
* fix in IO.h, a useless copy was made because of assignment from
Derived to MatrixBase.
* the optimization of eval() for Matrix now consists in a partial
specialization of ei_eval, which returns a reference type for Matrix.
No overriding of eval() in Matrix anymore. Consequence: careful,
ei_eval is no longer guaranteed to give a plain matrix type!
For that, use ei_plain_matrix_type, or the PlainMatrixType typedef.
* so lots of changes to adapt to that everywhere. Hope this doesn't
break (too much) MSVC compilation.
* add code examples for the new image() stuff.
* lower a bit the precision for floats in the unit tests as
we were already doing some workarounds in inverse.cpp and we got some
failed tests.
Diffstat (limited to 'Eigen/src/Core')
-rw-r--r-- | Eigen/src/Core/DiagonalProduct.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/Dot.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/IO.h | 3 | ||||
-rw-r--r-- | Eigen/src/Core/Matrix.h | 8 | ||||
-rw-r--r-- | Eigen/src/Core/MatrixBase.h | 45 | ||||
-rw-r--r-- | Eigen/src/Core/Part.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/Product.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/SolveTriangular.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/util/Macros.h | 1 | ||||
-rw-r--r-- | Eigen/src/Core/util/XprHelper.h | 32 |
10 files changed, 69 insertions, 38 deletions
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<typename T, int N> struct ei_nested_diagonal : ei_nested<T,N> {}; template<typename T, int N> struct ei_nested_diagonal<DiagonalMatrix<T>,N > - : ei_nested<DiagonalMatrix<T>, N, DiagonalMatrix<NestByValue<typename ei_eval<T>::type> > > + : ei_nested<DiagonalMatrix<T>, N, DiagonalMatrix<NestByValue<typename ei_plain_matrix_type<T>::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<typename ei_traits<Derived>::Scalar>::Real MatrixBase< * \sa norm(), normalize() */ template<typename Derived> -inline const typename MatrixBase<Derived>::EvalType +inline const typename MatrixBase<Derived>::PlainMatrixType MatrixBase<Derived>::normalized() const { typedef typename ei_nested<Derived>::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<Derived>::format(const IOFormat& fmt) const /** \internal * print the matrix \a _m to the output stream \a s using the output format \a fmt */ template<typename Derived> -std::ostream & ei_print_matrix(std::ostream & s, const MatrixBase<Derived> & _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<typename Derived> 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<Derived>::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<Derived>::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<Derived>::type PlainMatrixType_ColMajor; + + /** \internal Represents a matrix with all coefficients equal to one another*/ typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType; /** \internal Represents a scalar multiple of a matrix */ typedef CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived> ScalarMultipleReturnType; @@ -331,7 +342,7 @@ template<typename Derived> class MatrixBase Derived& operator*=(const MatrixBase<OtherDerived>& other); template<typename OtherDerived> - typename ei_eval_to_column_major<OtherDerived>::type + typename ei_plain_matrix_type_column_major<OtherDerived>::type solveTriangular(const MatrixBase<OtherDerived>& other) const; template<typename OtherDerived> @@ -343,7 +354,7 @@ template<typename Derived> class MatrixBase RealScalar squaredNorm() const; RealScalar norm2() const; RealScalar norm() const; - const EvalType normalized() const; + const PlainMatrixType normalized() const; void normalize(); Eigen::Transpose<Derived> transpose(); @@ -481,6 +492,8 @@ template<typename Derived> 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<Derived>::type eval() const { @@ -573,35 +586,35 @@ template<typename Derived> class MatrixBase /////////// LU module /////////// - const LU<EvalType> lu() const; - const EvalType inverse() const; - void computeInverse(EvalType *result) const; + const LU<PlainMatrixType> lu() const; + const PlainMatrixType inverse() const; + void computeInverse(PlainMatrixType *result) const; Scalar determinant() const; /////////// Cholesky module /////////// - const LLT<EvalType> llt() const; - const LDLT<EvalType> ldlt() const; + const LLT<PlainMatrixType> llt() const; + const LDLT<PlainMatrixType> ldlt() const; // deprecated: - const Cholesky<EvalType> cholesky() const; - const CholeskyWithoutSquareRoot<EvalType> choleskyNoSqrt() const; + const Cholesky<PlainMatrixType> cholesky() const; + const CholeskyWithoutSquareRoot<PlainMatrixType> choleskyNoSqrt() const; /////////// QR module /////////// - const QR<EvalType> qr() const; + const QR<PlainMatrixType> qr() const; EigenvaluesReturnType eigenvalues() const; RealScalar operatorNorm() const; /////////// SVD module /////////// - SVD<EvalType> svd() const; + SVD<PlainMatrixType> svd() const; /////////// Geometry module /////////// template<typename OtherDerived> - EvalType cross(const MatrixBase<OtherDerived>& other) const; - EvalType unitOrthogonal(void) const; + PlainMatrixType cross(const MatrixBase<OtherDerived>& other) const; + PlainMatrixType unitOrthogonal(void) const; Matrix<Scalar,3,1> 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<MatrixType, Mode>& Part<MatrixType, Mode>::operator=(const Other& ot { if(Other::Flags & EvalBeforeAssigningBit) { - typename ei_eval<Other>::type other_evaluated(other.rows(), other.cols()); + typename MatrixBase<Other>::PlainMatrixType other_evaluated(other.rows(), other.cols()); other_evaluated.template part<Mode>().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<Lhs,Rhs,CacheFriendlyProduct> typedef typename ei_nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested; typedef typename ei_nested<Rhs,Lhs::RowsAtCompileTime, - typename ei_eval_to_column_major<Rhs>::type + typename ei_plain_matrix_type_column_major<Rhs>::type >::type RhsNested; typedef Product<LhsNested, RhsNested, CacheFriendlyProduct> Type; @@ -735,7 +735,7 @@ template<typename T> struct ei_product_copy_rhs typedef typename ei_meta_if< (ei_traits<T>::Flags & RowMajorBit) || (!(ei_traits<T>::Flags & DirectAccessBit)), - typename ei_eval_to_column_major<T>::type, + typename ei_plain_matrix_type_column_major<T>::type, const T& >::ret type; }; @@ -744,7 +744,7 @@ template<typename T> struct ei_product_copy_lhs { typedef typename ei_meta_if< (!(int(ei_traits<T>::Flags) & DirectAccessBit)), - typename ei_eval<T>::type, + typename ei_plain_matrix_type<T>::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<Derived>::solveTriangularInPlace(MatrixBase<OtherDerived>& other enum { copy = ei_traits<OtherDerived>::Flags & RowMajorBit }; typedef typename ei_meta_if<copy, - typename ei_eval_to_column_major<OtherDerived>::type, OtherDerived&>::ret OtherCopy; + typename ei_plain_matrix_type_column_major<OtherDerived>::type, OtherDerived&>::ret OtherCopy; OtherCopy otherCopy(other.derived()); ei_solve_triangular_selector<Derived, typename ei_unref<OtherCopy>::type>::run(derived(), otherCopy); @@ -278,10 +278,10 @@ void MatrixBase<Derived>::solveTriangularInPlace(MatrixBase<OtherDerived>& other */ template<typename Derived> template<typename OtherDerived> -typename ei_eval_to_column_major<OtherDerived>::type +typename ei_plain_matrix_type_column_major<OtherDerived>::type MatrixBase<Derived>::solveTriangular(const MatrixBase<OtherDerived>& other) const { - typename ei_eval_to_column_major<OtherDerived>::type res(other); + typename ei_plain_matrix_type_column_major<OtherDerived>::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<Derived>::Scalar Scalar; \ typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \ typedef typename Base::PacketScalar PacketScalar; \ typedef typename Eigen::ei_nested<Derived>::type Nested; \ -typedef typename Eigen::ei_eval<Derived>::type Eval; \ enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \ ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \ MaxRowsAtCompileTime = Eigen::ei_traits<Derived>::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<int _Rows, int _Cols> 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<typename T, int Sparseness = ei_traits<T>::Flags&SparseBit> class ei_eval; template<typename T> struct ei_eval<T,IsDense> @@ -125,8 +129,30 @@ template<typename T> struct ei_eval<T,IsDense> > type; }; +// for matrices, no need to evaluate, just use a const reference to avoid a useless copy +template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols> +struct ei_eval<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>, IsDense> +{ + typedef const Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type; +}; + +/* 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<typename T> struct ei_plain_matrix_type +{ + typedef Matrix<typename ei_traits<T>::Scalar, + ei_traits<T>::RowsAtCompileTime, + ei_traits<T>::ColsAtCompileTime, + ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor, + ei_traits<T>::MaxRowsAtCompileTime, + ei_traits<T>::MaxColsAtCompileTime + > type; +}; -template<typename T> struct ei_eval_to_column_major +/* ei_plain_matrix_type_column_major : same as ei_plain_matrix_type but guaranteed to be column-major + */ +template<typename T> struct ei_plain_matrix_type_column_major { typedef Matrix<typename ei_traits<T>::Scalar, ei_traits<T>::RowsAtCompileTime, @@ -158,7 +184,7 @@ template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { 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<typename T, int n=1, typename EvalType = typename ei_eval<T>::type> struct ei_nested +template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::type> struct ei_nested { enum { CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost), @@ -170,7 +196,7 @@ template<typename T, int n=1, typename EvalType = typename ei_eval<T>::type> str typename ei_meta_if< (int(ei_traits<T>::Flags) & EvalBeforeNestingBit) || ( int(CostEval) <= int(CostNoEval) ), - EvalType, + PlainMatrixType, const T& >::ret >::ret type; |