mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
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.
This commit is contained in:
@@ -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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user