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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user