diff options
author | Gael Guennebaud <g.gael@free.fr> | 2009-01-28 16:26:06 +0000 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2009-01-28 16:26:06 +0000 |
commit | 1b194193efeb9eb1930993e53d65404f2fdd54a1 (patch) | |
tree | ab15b3c5d2c09cc3041ca3241bd29f3246dff720 /Eigen/src/Core | |
parent | da555585e27f770bad3dc85ddeaf51df5a582416 (diff) |
Big change in DiagonalMatrix and Geometry/Scaling:
* previous DiagonalMatrix expression is now DiagonalMatrixWrapper
* DiagonalMatrix class is now for storage
* add the DiagonalMatrixBase class to factorize code of the
two previous classes
* remove Scaling class (it is now a global function)
* add UniformScaling helper class
(don't use it directly, use the Scaling function)
* add the Scaling global function to simplify the creation
of scaling objects
There is still a lot to do, in particular about DiagonalProduct for which
the goal is to get rid of the "if()" in the coeff() function. At least
it is not worse than before ! Also need to uptade the tutorial and add more doc.
Diffstat (limited to 'Eigen/src/Core')
-rw-r--r-- | Eigen/src/Core/DiagonalMatrix.h | 244 | ||||
-rw-r--r-- | Eigen/src/Core/DiagonalProduct.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/MatrixBase.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/NestByValue.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/util/ForwardDeclarations.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/util/StaticAssert.h | 3 |
6 files changed, 214 insertions, 49 deletions
diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h index 07eaf0747..975a80bd3 100644 --- a/Eigen/src/Core/DiagonalMatrix.h +++ b/Eigen/src/Core/DiagonalMatrix.h @@ -25,22 +25,208 @@ #ifndef EIGEN_DIAGONALMATRIX_H #define EIGEN_DIAGONALMATRIX_H + +template<typename CoeffsVectorType, typename Derived> +class DiagonalMatrixBase : ei_no_assignment_operator, + public MatrixBase<Derived> +{ + public: + typedef MatrixBase<Derived> Base; + typedef typename ei_traits<Derived>::Scalar Scalar; + typedef typename Base::PacketScalar PacketScalar; + using Base::derived; + + protected: + typedef typename ei_cleantype<CoeffsVectorType>::type _CoeffsVectorType; + + /** Default constructor without initialization */ + inline DiagonalMatrixBase() {} + /** Constructs a diagonal matrix with given dimension */ + inline DiagonalMatrixBase(int dim) : m_coeffs(dim) {} + /** Generic constructor from an expression */ + template<typename OtherDerived> + inline DiagonalMatrixBase(const MatrixBase<OtherDerived>& other) + { + construct_from_expression<OtherDerived>::run(derived(),other.derived()); + } + + template<typename OtherDerived, + bool IsVector = OtherDerived::IsVectorAtCompileTime, + bool IsDiagonal = (OtherDerived::Flags&Diagonal)==Diagonal> + struct construct_from_expression; + + // = vector + template<typename OtherDerived> + struct construct_from_expression<OtherDerived,true,false> + { + static void run(Derived& dst, const OtherDerived& src) + { dst.m_coeffs = src; } + }; + + // = diagonal + template<typename OtherDerived, bool IsVector> + struct construct_from_expression<OtherDerived,IsVector,true> + { + static void run(Derived& dst, const OtherDerived& src) + { dst.m_coeffs = src.diagonal(); } + }; + + public: + + inline DiagonalMatrixBase(const _CoeffsVectorType& coeffs) : m_coeffs(coeffs) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(_CoeffsVectorType); + ei_assert(coeffs.size() > 0); + } + + template<typename OtherDerived, bool IsVector=OtherDerived::IsVectorAtCompileTime> + struct ei_diagonal_product_ctor { + static void run(DiagonalMatrixBase& dst, const OtherDerived& src) + { dst.m_coeffs = src; } + }; + + template<typename OtherDerived> + struct ei_diagonal_product_ctor<OtherDerived,false> { + static void run(DiagonalMatrixBase& dst, const OtherDerived& src) + { + EIGEN_STATIC_ASSERT((OtherDerived::Flags&Diagonal)==Diagonal, THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX); + dst.m_coeffs = src.diagonal(); + } + }; + + template<typename NewType> + inline DiagonalMatrixWrapper<NestByValue<CwiseUnaryOp<ei_scalar_cast_op<Scalar, NewType>, _CoeffsVectorType> > > cast() const + { + return m_coeffs.template cast<NewType>().nestByValue().asDiagonal(); + } + + /** Assignment operator. + * The right-hand-side \a other must be either a vector representing the diagonal + * coefficients or a diagonal matrix expression. + */ + template<typename OtherDerived> + inline Derived& operator=(const MatrixBase<OtherDerived>& other) + { + construct_from_expression<OtherDerived>::run(derived(),other); + return derived(); + } + + inline int rows() const { return m_coeffs.size(); } + inline int cols() const { return m_coeffs.size(); } + + inline const Scalar coeff(int row, int col) const + { + return row == col ? m_coeffs.coeff(row) : static_cast<Scalar>(0); + } + + inline const Scalar coeffRef(int row, int col) const + { + ei_assert(row==col); + return m_coeffs.coeffRef(row); + } + + inline _CoeffsVectorType& diagonal() { return m_coeffs; } + inline const _CoeffsVectorType& diagonal() const { return m_coeffs; } + + protected: + CoeffsVectorType m_coeffs; +}; + /** \class DiagonalMatrix - * \nonstableyet + * \nonstableyet + * + * \brief Represent a diagonal matrix with its storage + * + * \param _Scalar the type of coefficients + * \param _Size the dimension of the matrix + * + * \sa class Matrix + */ +template<typename _Scalar,int _Size> +struct ei_traits<DiagonalMatrix<_Scalar,_Size> > : ei_traits<Matrix<_Scalar,_Size,_Size> > +{ + enum { + Flags = (ei_traits<Matrix<_Scalar,_Size,_Size> >::Flags & HereditaryBits) | Diagonal + }; +}; + +template<typename _Scalar, int _Size> +class DiagonalMatrix + : public DiagonalMatrixBase<Matrix<_Scalar,_Size,1>, DiagonalMatrix<_Scalar,_Size> > +{ + public: + EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalMatrix) + typedef DiagonalMatrixBase<Matrix<_Scalar,_Size,1>, DiagonalMatrix<_Scalar,_Size> > DiagonalBase; + + protected: + typedef Matrix<_Scalar,_Size,1> CoeffVectorType; + using DiagonalBase::m_coeffs; + + public: + + /** Default constructor without initialization */ + inline DiagonalMatrix() : DiagonalBase() + {} + + /** Constructs a diagonal matrix with given dimension */ + inline DiagonalMatrix(int dim) : DiagonalBase(dim) + {} + + /** 2D only */ + inline DiagonalMatrix(const Scalar& sx, const Scalar& sy) + { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(DiagonalMatrix,2,2); + m_coeffs.x() = sx; + m_coeffs.y() = sy; + } + /** 3D only */ + inline DiagonalMatrix(const Scalar& sx, const Scalar& sy, const Scalar& sz) + { + EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(DiagonalMatrix,3,3); + m_coeffs.x() = sx; + m_coeffs.y() = sy; + m_coeffs.z() = sz; + } + + /** copy constructor */ + inline DiagonalMatrix(const DiagonalMatrix& other) : DiagonalBase(other.m_coeffs) + {} + + /** generic constructor from expression */ + template<typename OtherDerived> + explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : DiagonalBase(other) + {} + + DiagonalMatrix& operator=(const DiagonalMatrix& other) + { + m_coeffs = other.m_coeffs; + return *this; + } + + template<typename OtherDerived> + DiagonalMatrix& operator=(const MatrixBase<OtherDerived>& other) + { + EIGEN_STATIC_ASSERT((OtherDerived::Flags&Diagonal)==Diagonal, THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX); + m_coeffs = other.diagonal(); + return *this; + } +}; + +/** \class DiagonalMatrixWrapper + * \nonstableyet * * \brief Expression of a diagonal matrix * * \param CoeffsVectorType the type of the vector of diagonal coefficients * * This class is an expression of a diagonal matrix with given vector of diagonal - * coefficients. It is the return - * type of MatrixBase::diagonal(const OtherDerived&) and most of the time this is - * the only way it is used. + * coefficients. It is the return type of MatrixBase::diagonal(const OtherDerived&) + * and most of the time this is the only way it is used. * - * \sa MatrixBase::diagonal(const OtherDerived&) + * \sa class DiagonalMatrixBase, class DiagonalMatrix, MatrixBase::asDiagonal() */ template<typename CoeffsVectorType> -struct ei_traits<DiagonalMatrix<CoeffsVectorType> > +struct ei_traits<DiagonalMatrixWrapper<CoeffsVectorType> > { typedef typename CoeffsVectorType::Scalar Scalar; typedef typename ei_nested<CoeffsVectorType>::type CoeffsVectorTypeNested; @@ -54,45 +240,19 @@ struct ei_traits<DiagonalMatrix<CoeffsVectorType> > CoeffReadCost = _CoeffsVectorTypeNested::CoeffReadCost }; }; - template<typename CoeffsVectorType> -class DiagonalMatrix : ei_no_assignment_operator, - public MatrixBase<DiagonalMatrix<CoeffsVectorType> > +class DiagonalMatrixWrapper + : public DiagonalMatrixBase<typename CoeffsVectorType::Nested, DiagonalMatrixWrapper<CoeffsVectorType> > { + typedef typename CoeffsVectorType::Nested CoeffsVectorTypeNested; + typedef DiagonalMatrixBase<CoeffsVectorTypeNested, DiagonalMatrixWrapper<CoeffsVectorType> > DiagonalBase; public: - - EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalMatrix) - - // needed to evaluate a DiagonalMatrix<Xpr> to a DiagonalMatrix<NestByValue<Vector> > - template<typename OtherCoeffsVectorType> - inline DiagonalMatrix(const DiagonalMatrix<OtherCoeffsVectorType>& other) : m_coeffs(other.diagonal()) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType); - EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherCoeffsVectorType); - ei_assert(m_coeffs.size() > 0); - } - - inline DiagonalMatrix(const CoeffsVectorType& coeffs) : m_coeffs(coeffs) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(CoeffsVectorType); - ei_assert(coeffs.size() > 0); - } - - inline int rows() const { return m_coeffs.size(); } - inline int cols() const { return m_coeffs.size(); } - - inline const Scalar coeff(int row, int col) const - { - return row == col ? m_coeffs.coeff(row) : static_cast<Scalar>(0); - } - - inline const CoeffsVectorType& diagonal() const { return m_coeffs; } - - protected: - const typename CoeffsVectorType::Nested m_coeffs; + EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalMatrixWrapper) + inline DiagonalMatrixWrapper(const CoeffsVectorType& coeffs) : DiagonalBase(coeffs) + {} }; -/** \nonstableyet +/** \nonstableyet * \returns an expression of a diagonal matrix with *this as vector of diagonal coefficients * * \only_for_vectors @@ -105,13 +265,13 @@ class DiagonalMatrix : ei_no_assignment_operator, * \sa class DiagonalMatrix, isDiagonal() **/ template<typename Derived> -inline const DiagonalMatrix<Derived> +inline const DiagonalMatrixWrapper<Derived> MatrixBase<Derived>::asDiagonal() const { return derived(); } -/** \nonstableyet +/** \nonstableyet * \returns true if *this is approximately equal to a diagonal matrix, * within the precision given by \a prec. * diff --git a/Eigen/src/Core/DiagonalProduct.h b/Eigen/src/Core/DiagonalProduct.h index f33a26f98..83ba96c3c 100644 --- a/Eigen/src/Core/DiagonalProduct.h +++ b/Eigen/src/Core/DiagonalProduct.h @@ -30,9 +30,9 @@ * Unlike ei_nested, if the argument is a DiagonalMatrix and if it must be evaluated, * then it evaluated to a DiagonalMatrix having its own argument evaluated. */ -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_plain_matrix_type<T>::type> > > +template<typename T, int N, bool IsDiagonal = (T::Flags&Diagonal)==Diagonal> struct ei_nested_diagonal : ei_nested<T,N> {}; +template<typename T, int N> struct ei_nested_diagonal<T,N,true> + : ei_nested<T, N, DiagonalMatrix<typename T::Scalar, EIGEN_ENUM_MIN(T::RowsAtCompileTime,T::ColsAtCompileTime)> > {}; // specialization of ProductReturnType diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 1fd02b0af..4dd319985 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -443,7 +443,7 @@ template<typename Derived> class MatrixBase static const BasisReturnType UnitZ(); static const BasisReturnType UnitW(); - const DiagonalMatrix<Derived> asDiagonal() const; + const DiagonalMatrixWrapper<Derived> asDiagonal() const; void fill(const Scalar& value); Derived& setConstant(const Scalar& value); diff --git a/Eigen/src/Core/NestByValue.h b/Eigen/src/Core/NestByValue.h index da79315bf..dfe757447 100644 --- a/Eigen/src/Core/NestByValue.h +++ b/Eigen/src/Core/NestByValue.h @@ -97,6 +97,8 @@ template<typename ExpressionType> class NestByValue { m_expression.const_cast_derived().template writePacket<LoadMode>(index, x); } + + operator const ExpressionType&() const { return m_expression; } protected: const ExpressionType m_expression; diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index a72a40b1b..83c42442b 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -45,7 +45,9 @@ template<typename NullaryOp, typename MatrixType> class CwiseNullaryOp; template<typename UnaryOp, typename MatrixType> class CwiseUnaryOp; template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp; template<typename Lhs, typename Rhs, int ProductMode> class Product; -template<typename CoeffsVectorType> class DiagonalMatrix; +template<typename CoeffsVectorType, typename Derived> class DiagonalMatrixBase; +template<typename CoeffsVectorType> class DiagonalMatrixWrapper; +template<typename _Scalar, int _Size> class DiagonalMatrix; template<typename MatrixType> class DiagonalCoeffs; template<typename MatrixType, int PacketAccess = AsRequested> class Map; template<typename MatrixType, unsigned int Mode> class Part; @@ -117,7 +119,7 @@ template<typename Scalar,int Dim> class Transform; template <typename _Scalar, int _AmbientDim> class ParametrizedLine; template <typename _Scalar, int _AmbientDim> class Hyperplane; template<typename Scalar,int Dim> class Translation; -template<typename Scalar,int Dim> class Scaling; +template<typename Scalar> class UniformScaling; // Sparse module: template<typename Lhs, typename Rhs, int ProductMode> class SparseProduct; diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h index 7ceeabb5f..2c13098a2 100644 --- a/Eigen/src/Core/util/StaticAssert.h +++ b/Eigen/src/Core/util/StaticAssert.h @@ -74,7 +74,8 @@ THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES, THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES, INVALID_MATRIX_TEMPLATE_PARAMETERS, - BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER + BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER, + THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX }; }; |