mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
merge
This commit is contained in:
153
Eigen/src/Core/AnyMatrixBase.h
Normal file
153
Eigen/src/Core/AnyMatrixBase.h
Normal file
@@ -0,0 +1,153 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
|
||||
//
|
||||
// Eigen is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Alternatively, you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of
|
||||
// the License, or (at your option) any later version.
|
||||
//
|
||||
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License and a copy of the GNU General Public License along with
|
||||
// Eigen. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef EIGEN_ANYMATRIXBASE_H
|
||||
#define EIGEN_ANYMATRIXBASE_H
|
||||
|
||||
|
||||
/** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
|
||||
*
|
||||
* In other words, an AnyMatrixBase object is an object that can be copied into a MatrixBase.
|
||||
*
|
||||
* Besides MatrixBase-derived classes, this also includes special matrix classes such as diagonal matrices, etc.
|
||||
*
|
||||
* Notice that this class is trivial, it is only used to disambiguate overloaded functions.
|
||||
*/
|
||||
template<typename Derived> struct AnyMatrixBase
|
||||
{
|
||||
typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
|
||||
|
||||
Derived& derived() { return *static_cast<Derived*>(this); }
|
||||
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||
|
||||
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
|
||||
inline int rows() const { return derived().rows(); }
|
||||
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
|
||||
inline int cols() const { return derived().cols(); }
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst = *this; \endcode */
|
||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||
{ derived().evalTo(dst); }
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */
|
||||
template<typename Dest> inline void addToDense(Dest& dst) const
|
||||
{
|
||||
// This is the default implementation,
|
||||
// derived class can reimplement it in a more optimized way.
|
||||
typename Dest::PlainMatrixType res(rows(),cols());
|
||||
evalTo(res);
|
||||
dst += res;
|
||||
}
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */
|
||||
template<typename Dest> inline void subToDense(Dest& dst) const
|
||||
{
|
||||
// This is the default implementation,
|
||||
// derived class can reimplement it in a more optimized way.
|
||||
typename Dest::PlainMatrixType res(rows(),cols());
|
||||
evalTo(res);
|
||||
dst -= res;
|
||||
}
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst.applyOnTheRight(*this); \endcode */
|
||||
template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const
|
||||
{
|
||||
// This is the default implementation,
|
||||
// derived class can reimplement it in a more optimized way.
|
||||
dst = dst * this->derived();
|
||||
}
|
||||
|
||||
/** \internal Don't use it, but do the equivalent: \code dst.applyOnTheLeft(*this); \endcode */
|
||||
template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const
|
||||
{
|
||||
// This is the default implementation,
|
||||
// derived class can reimplement it in a more optimized way.
|
||||
dst = this->derived() * dst;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Implementation of matrix base methods
|
||||
***************************************************************************/
|
||||
|
||||
/** Copies the generic expression \a other into *this. \returns a reference to *this.
|
||||
* The expression must provide a (templated) evalToDense(Derived& dst) const function
|
||||
* which does the actual job. In practice, this allows any user to write its own
|
||||
* special matrix without having to modify MatrixBase */
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& MatrixBase<Derived>::operator=(const AnyMatrixBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().evalTo(derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& MatrixBase<Derived>::operator+=(const AnyMatrixBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().addToDense(derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& MatrixBase<Derived>::operator-=(const AnyMatrixBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().subToDense(derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
/** replaces \c *this by \c *this * \a other.
|
||||
*
|
||||
* \returns a reference to \c *this
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline Derived&
|
||||
MatrixBase<Derived>::operator*=(const AnyMatrixBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().applyThisOnTheRight(derived());
|
||||
return derived();
|
||||
}
|
||||
|
||||
/** replaces \c *this by \c *this * \a other. It is equivalent to MatrixBase::operator*=() */
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline void MatrixBase<Derived>::applyOnTheRight(const AnyMatrixBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().applyThisOnTheRight(derived());
|
||||
}
|
||||
|
||||
/** replaces \c *this by \c *this * \a other. */
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline void MatrixBase<Derived>::applyOnTheLeft(const AnyMatrixBase<OtherDerived> &other)
|
||||
{
|
||||
other.derived().applyThisOnTheLeft(derived());
|
||||
}
|
||||
|
||||
#endif // EIGEN_ANYMATRIXBASE_H
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef EIGEN_MATRIX_H
|
||||
#define EIGEN_MATRIX_H
|
||||
|
||||
template <typename Derived, typename OtherDerived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct ei_conservative_resize_like_impl;
|
||||
|
||||
/** \class Matrix
|
||||
*
|
||||
@@ -308,7 +309,7 @@ class Matrix
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE void resizeLike(const MatrixBase<OtherDerived>& other)
|
||||
{
|
||||
{
|
||||
if(RowsAtCompileTime == 1)
|
||||
{
|
||||
ei_assert(other.isVector());
|
||||
@@ -324,40 +325,28 @@ class Matrix
|
||||
|
||||
/** Resizes \c *this to a \a rows x \a cols matrix while leaving old values of *this untouched.
|
||||
*
|
||||
* This method is intended for dynamic-size matrices, although it is legal to call it on any
|
||||
* matrix as long as fixed dimensions are left unchanged. If you only want to change the number
|
||||
* This method is intended for dynamic-size matrices. If you only want to change the number
|
||||
* of rows and/or of columns, you can use conservativeResize(NoChange_t, int),
|
||||
* conservativeResize(int, NoChange_t).
|
||||
*
|
||||
* The top-left part of the resized matrix will be the same as the overlapping top-left corner
|
||||
* of *this. In case values need to be appended to the matrix they will be uninitialized per
|
||||
* default and set to zero when init_with_zero is set to true.
|
||||
* of *this. In case values need to be appended to the matrix they will be uninitialized.
|
||||
*/
|
||||
inline void conservativeResize(int rows, int cols, bool init_with_zero = false)
|
||||
EIGEN_STRONG_INLINE void conservativeResize(int rows, int cols)
|
||||
{
|
||||
// Note: Here is space for improvement. Basically, for conservativeResize(int,int),
|
||||
// neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
|
||||
// dimensions is dynamic, one could use either conservativeResize(int rows, NoChange_t) or
|
||||
// conservativeResize(NoChange_t, int cols). For these methods new static asserts like
|
||||
// EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
|
||||
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Matrix)
|
||||
PlainMatrixType tmp = init_with_zero ? PlainMatrixType::Zero(rows, cols) : PlainMatrixType(rows,cols);
|
||||
const int common_rows = std::min(rows, this->rows());
|
||||
const int common_cols = std::min(cols, this->cols());
|
||||
tmp.block(0,0,common_rows,common_cols) = this->block(0,0,common_rows,common_cols);
|
||||
this->derived().swap(tmp);
|
||||
conservativeResizeLike(PlainMatrixType(rows, cols));
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE void conservativeResize(int rows, NoChange_t, bool init_with_zero = false)
|
||||
EIGEN_STRONG_INLINE void conservativeResize(int rows, NoChange_t)
|
||||
{
|
||||
// Note: see the comment in conservativeResize(int,int,bool)
|
||||
conservativeResize(rows, cols(), init_with_zero);
|
||||
// Note: see the comment in conservativeResize(int,int)
|
||||
conservativeResize(rows, cols());
|
||||
}
|
||||
|
||||
EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, int cols, bool init_with_zero = false)
|
||||
EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, int cols)
|
||||
{
|
||||
// Note: see the comment in conservativeResize(int,int,bool)
|
||||
conservativeResize(rows(), cols, init_with_zero);
|
||||
// Note: see the comment in conservativeResize(int,int)
|
||||
conservativeResize(rows(), cols);
|
||||
}
|
||||
|
||||
/** Resizes \c *this to a vector of length \a size while retaining old values of *this.
|
||||
@@ -366,21 +355,17 @@ class Matrix
|
||||
* partially dynamic matrices when the static dimension is anything other
|
||||
* than 1. For example it will not work with Matrix<double, 2, Dynamic>.
|
||||
*
|
||||
* When values are appended, they will be uninitialized per default and set
|
||||
* to zero when init_with_zero is set to true.
|
||||
* When values are appended, they will be uninitialized.
|
||||
*/
|
||||
inline void conservativeResize(int size, bool init_with_zero = false)
|
||||
EIGEN_STRONG_INLINE void conservativeResize(int size)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
|
||||
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Matrix)
|
||||
conservativeResizeLike(PlainMatrixType(size));
|
||||
}
|
||||
|
||||
if (RowsAtCompileTime == 1 || ColsAtCompileTime == 1)
|
||||
{
|
||||
PlainMatrixType tmp = init_with_zero ? PlainMatrixType::Zero(size) : PlainMatrixType(size);
|
||||
const int common_size = std::min<int>(this->size(),size);
|
||||
tmp.segment(0,common_size) = this->segment(0,common_size);
|
||||
this->derived().swap(tmp);
|
||||
}
|
||||
template<typename OtherDerived>
|
||||
EIGEN_STRONG_INLINE void conservativeResizeLike(const MatrixBase<OtherDerived>& other)
|
||||
{
|
||||
ei_conservative_resize_like_impl<Matrix, OtherDerived>::run(*this, other);
|
||||
}
|
||||
|
||||
/** Copies the value of the expression \a other into \c *this with automatic resizing.
|
||||
@@ -713,13 +698,45 @@ class Matrix
|
||||
m_storage.data()[1] = y;
|
||||
}
|
||||
|
||||
template<typename MatrixType, typename OtherDerived, bool IsSameType, bool IsDynamicSize>
|
||||
template<typename MatrixType, typename OtherDerived, bool SwapPointers>
|
||||
friend struct ei_matrix_swap_impl;
|
||||
};
|
||||
|
||||
template<typename MatrixType, typename OtherDerived,
|
||||
bool IsSameType = ei_is_same_type<MatrixType, OtherDerived>::ret,
|
||||
bool IsDynamicSize = MatrixType::SizeAtCompileTime==Dynamic>
|
||||
template <typename Derived, typename OtherDerived, bool IsVector>
|
||||
struct ei_conservative_resize_like_impl
|
||||
{
|
||||
static void run(MatrixBase<Derived>& _this, const MatrixBase<OtherDerived>& other)
|
||||
{
|
||||
// Note: Here is space for improvement. Basically, for conservativeResize(int,int),
|
||||
// neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
|
||||
// dimensions is dynamic, one could use either conservativeResize(int rows, NoChange_t) or
|
||||
// conservativeResize(NoChange_t, int cols). For these methods new static asserts like
|
||||
// EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good.
|
||||
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived)
|
||||
EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived)
|
||||
|
||||
typename MatrixBase<Derived>::PlainMatrixType tmp(other);
|
||||
const int common_rows = std::min(tmp.rows(), _this.rows());
|
||||
const int common_cols = std::min(tmp.cols(), _this.cols());
|
||||
tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols);
|
||||
_this.derived().swap(tmp);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Derived, typename OtherDerived>
|
||||
struct ei_conservative_resize_like_impl<Derived,OtherDerived,true>
|
||||
{
|
||||
static void run(MatrixBase<Derived>& _this, const MatrixBase<OtherDerived>& other)
|
||||
{
|
||||
// segment(...) will check whether Derived/OtherDerived are vectors!
|
||||
typename MatrixBase<Derived>::PlainMatrixType tmp(other);
|
||||
const int common_size = std::min<int>(_this.size(),tmp.size());
|
||||
tmp.segment(0,common_size) = _this.segment(0,common_size);
|
||||
_this.derived().swap(tmp);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename MatrixType, typename OtherDerived, bool SwapPointers>
|
||||
struct ei_matrix_swap_impl
|
||||
{
|
||||
static inline void run(MatrixType& matrix, MatrixBase<OtherDerived>& other)
|
||||
@@ -729,7 +746,7 @@ struct ei_matrix_swap_impl
|
||||
};
|
||||
|
||||
template<typename MatrixType, typename OtherDerived>
|
||||
struct ei_matrix_swap_impl<MatrixType, OtherDerived, true, true>
|
||||
struct ei_matrix_swap_impl<MatrixType, OtherDerived, true>
|
||||
{
|
||||
static inline void run(MatrixType& matrix, MatrixBase<OtherDerived>& other)
|
||||
{
|
||||
@@ -741,7 +758,8 @@ template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int
|
||||
template<typename OtherDerived>
|
||||
inline void Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::swap(const MatrixBase<OtherDerived>& other)
|
||||
{
|
||||
ei_matrix_swap_impl<Matrix, OtherDerived>::run(*this, *const_cast<MatrixBase<OtherDerived>*>(&other));
|
||||
enum { SwapPointers = ei_is_same_type<Matrix, OtherDerived>::ret && Base::SizeAtCompileTime==Dynamic };
|
||||
ei_matrix_swap_impl<Matrix, OtherDerived, bool(SwapPointers)>::run(*this, *const_cast<MatrixBase<OtherDerived>*>(&other));
|
||||
}
|
||||
|
||||
/** \defgroup matrixtypedefs Global matrix typedefs
|
||||
|
||||
@@ -26,46 +26,6 @@
|
||||
#ifndef EIGEN_MATRIXBASE_H
|
||||
#define EIGEN_MATRIXBASE_H
|
||||
|
||||
|
||||
/** Common base class for all classes T such that MatrixBase has an operator=(T) and a constructor MatrixBase(T).
|
||||
*
|
||||
* In other words, an AnyMatrixBase object is an object that can be copied into a MatrixBase.
|
||||
*
|
||||
* Besides MatrixBase-derived classes, this also includes special matrix classes such as diagonal matrices, etc.
|
||||
*
|
||||
* Notice that this class is trivial, it is only used to disambiguate overloaded functions.
|
||||
*/
|
||||
template<typename Derived> struct AnyMatrixBase
|
||||
: public ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar,
|
||||
typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>
|
||||
{
|
||||
typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
|
||||
|
||||
Derived& derived() { return *static_cast<Derived*>(this); }
|
||||
const Derived& derived() const { return *static_cast<const Derived*>(this); }
|
||||
/** \returns the number of rows. \sa cols(), RowsAtCompileTime */
|
||||
inline int rows() const { return derived().rows(); }
|
||||
/** \returns the number of columns. \sa rows(), ColsAtCompileTime*/
|
||||
inline int cols() const { return derived().cols(); }
|
||||
|
||||
template<typename Dest> inline void evalTo(Dest& dst) const
|
||||
{ derived().evalTo(dst); }
|
||||
|
||||
template<typename Dest> inline void addToDense(Dest& dst) const
|
||||
{
|
||||
typename Dest::PlainMatrixType res(rows(),cols());
|
||||
evalToDense(res);
|
||||
dst += res;
|
||||
}
|
||||
|
||||
template<typename Dest> inline void subToDense(Dest& dst) const
|
||||
{
|
||||
typename Dest::PlainMatrixType res(rows(),cols());
|
||||
evalToDense(res);
|
||||
dst -= res;
|
||||
}
|
||||
};
|
||||
|
||||
/** \class MatrixBase
|
||||
*
|
||||
* \brief Base class for all matrices, vectors, and expressions
|
||||
@@ -93,11 +53,11 @@ template<typename Derived> struct AnyMatrixBase
|
||||
*/
|
||||
template<typename Derived> class MatrixBase
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
: public AnyMatrixBase<Derived>
|
||||
: public ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar,
|
||||
typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
{
|
||||
public:
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
using ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar,
|
||||
typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>::operator*;
|
||||
@@ -302,21 +262,14 @@ template<typename Derived> class MatrixBase
|
||||
*/
|
||||
Derived& operator=(const MatrixBase& other);
|
||||
|
||||
/** Copies the generic expression \a other into *this. \returns a reference to *this.
|
||||
* The expression must provide a (templated) evalToDense(Derived& dst) const function
|
||||
* which does the actual job. In practice, this allows any user to write its own
|
||||
* special matrix without having to modify MatrixBase */
|
||||
template<typename OtherDerived>
|
||||
Derived& operator=(const AnyMatrixBase<OtherDerived> &other)
|
||||
{ other.derived().evalToDense(derived()); return derived(); }
|
||||
Derived& operator=(const AnyMatrixBase<OtherDerived> &other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
Derived& operator+=(const AnyMatrixBase<OtherDerived> &other)
|
||||
{ other.derived().addToDense(derived()); return derived(); }
|
||||
Derived& operator+=(const AnyMatrixBase<OtherDerived> &other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
Derived& operator-=(const AnyMatrixBase<OtherDerived> &other)
|
||||
{ other.derived().subToDense(derived()); return derived(); }
|
||||
Derived& operator-=(const AnyMatrixBase<OtherDerived> &other);
|
||||
|
||||
template<typename OtherDerived,typename OtherEvalType>
|
||||
Derived& operator=(const ReturnByValue<OtherDerived,OtherEvalType>& func);
|
||||
@@ -437,6 +390,12 @@ template<typename Derived> class MatrixBase
|
||||
template<typename OtherDerived>
|
||||
Derived& operator*=(const AnyMatrixBase<OtherDerived>& other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
void applyOnTheLeft(const AnyMatrixBase<OtherDerived>& other);
|
||||
|
||||
template<typename OtherDerived>
|
||||
void applyOnTheRight(const AnyMatrixBase<OtherDerived>& other);
|
||||
|
||||
template<typename DiagonalDerived>
|
||||
const DiagonalProduct<Derived, DiagonalDerived, DiagonalOnTheRight>
|
||||
operator*(const DiagonalBase<DiagonalDerived> &diagonal) const;
|
||||
@@ -676,8 +635,11 @@ template<typename Derived> class MatrixBase
|
||||
typename ei_traits<Derived>::Scalar minCoeff() const;
|
||||
typename ei_traits<Derived>::Scalar maxCoeff() const;
|
||||
|
||||
typename ei_traits<Derived>::Scalar minCoeff(int* row, int* col = 0) const;
|
||||
typename ei_traits<Derived>::Scalar maxCoeff(int* row, int* col = 0) const;
|
||||
typename ei_traits<Derived>::Scalar minCoeff(int* row, int* col) const;
|
||||
typename ei_traits<Derived>::Scalar maxCoeff(int* row, int* col) const;
|
||||
|
||||
typename ei_traits<Derived>::Scalar minCoeff(int* index) const;
|
||||
typename ei_traits<Derived>::Scalar maxCoeff(int* index) const;
|
||||
|
||||
template<typename BinaryOp>
|
||||
typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
|
||||
|
||||
@@ -434,18 +434,4 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||
return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** replaces \c *this by \c *this * \a other.
|
||||
*
|
||||
* \returns a reference to \c *this
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
inline Derived &
|
||||
MatrixBase<Derived>::operator*=(const AnyMatrixBase<OtherDerived> &other)
|
||||
{
|
||||
return derived() = derived() * other.derived();
|
||||
}
|
||||
|
||||
#endif // EIGEN_PRODUCT_H
|
||||
|
||||
@@ -56,7 +56,7 @@ MatrixBase<Derived>::stableNorm() const
|
||||
{
|
||||
const int blockSize = 4096;
|
||||
RealScalar scale = 0;
|
||||
RealScalar invScale;
|
||||
RealScalar invScale = 1;
|
||||
RealScalar ssq = 0; // sum of square
|
||||
enum {
|
||||
Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? ForceAligned : AsRequested
|
||||
|
||||
@@ -91,9 +91,9 @@ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived>
|
||||
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||
|
||||
template<typename DenseDerived>
|
||||
void evalToDense(MatrixBase<DenseDerived> &other) const;
|
||||
void evalTo(MatrixBase<DenseDerived> &other) const;
|
||||
template<typename DenseDerived>
|
||||
void evalToDenseLazy(MatrixBase<DenseDerived> &other) const;
|
||||
void evalToLazy(MatrixBase<DenseDerived> &other) const;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -546,23 +546,23 @@ void TriangularView<MatrixType, Mode>::lazyAssign(const TriangularBase<OtherDeri
|
||||
* If the matrix is triangular, the opposite part is set to zero. */
|
||||
template<typename Derived>
|
||||
template<typename DenseDerived>
|
||||
void TriangularBase<Derived>::evalToDense(MatrixBase<DenseDerived> &other) const
|
||||
void TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
|
||||
{
|
||||
if(ei_traits<Derived>::Flags & EvalBeforeAssigningBit)
|
||||
{
|
||||
typename Derived::PlainMatrixType other_evaluated(rows(), cols());
|
||||
evalToDenseLazy(other_evaluated);
|
||||
evalToLazy(other_evaluated);
|
||||
other.derived().swap(other_evaluated);
|
||||
}
|
||||
else
|
||||
evalToDenseLazy(other.derived());
|
||||
evalToLazy(other.derived());
|
||||
}
|
||||
|
||||
/** Assigns a triangular or selfadjoint matrix to a dense matrix.
|
||||
* If the matrix is triangular, the opposite part is set to zero. */
|
||||
template<typename Derived>
|
||||
template<typename DenseDerived>
|
||||
void TriangularBase<Derived>::evalToDenseLazy(MatrixBase<DenseDerived> &other) const
|
||||
void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
|
||||
{
|
||||
const bool unroll = DenseDerived::SizeAtCompileTime * Derived::CoeffReadCost / 2
|
||||
<= EIGEN_UNROLLING_LIMIT;
|
||||
|
||||
@@ -77,11 +77,12 @@ template<typename VectorType, int Size, int PacketAccess> class VectorBlock
|
||||
typedef Block<VectorType,
|
||||
ei_traits<VectorType>::RowsAtCompileTime==1 ? 1 : Size,
|
||||
ei_traits<VectorType>::ColsAtCompileTime==1 ? 1 : Size,
|
||||
PacketAccess> Base;
|
||||
PacketAccess> _Base;
|
||||
enum {
|
||||
IsColVector = ei_traits<VectorType>::ColsAtCompileTime==1
|
||||
};
|
||||
public:
|
||||
_EIGEN_GENERIC_PUBLIC_INTERFACE(VectorBlock, _Base)
|
||||
|
||||
using Base::operator=;
|
||||
using Base::operator+=;
|
||||
|
||||
@@ -164,7 +164,7 @@ struct ei_functor_traits<ei_max_coeff_visitor<Scalar> > {
|
||||
/** \returns the minimum of all coefficients of *this
|
||||
* and puts in *row and *col its location.
|
||||
*
|
||||
* \sa MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
|
||||
* \sa MatrixBase::minCoeff(int*), MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
|
||||
*/
|
||||
template<typename Derived>
|
||||
typename ei_traits<Derived>::Scalar
|
||||
@@ -177,6 +177,22 @@ MatrixBase<Derived>::minCoeff(int* row, int* col) const
|
||||
return minVisitor.res;
|
||||
}
|
||||
|
||||
/** \returns the minimum of all coefficients of *this
|
||||
* and puts in *index its location.
|
||||
*
|
||||
* \sa MatrixBase::minCoeff(int*,int*), MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
|
||||
*/
|
||||
template<typename Derived>
|
||||
typename ei_traits<Derived>::Scalar
|
||||
MatrixBase<Derived>::minCoeff(int* index) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
ei_min_coeff_visitor<Scalar> minVisitor;
|
||||
this->visit(minVisitor);
|
||||
*index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
|
||||
return minVisitor.res;
|
||||
}
|
||||
|
||||
/** \returns the maximum of all coefficients of *this
|
||||
* and puts in *row and *col its location.
|
||||
*
|
||||
@@ -193,5 +209,20 @@ MatrixBase<Derived>::maxCoeff(int* row, int* col) const
|
||||
return maxVisitor.res;
|
||||
}
|
||||
|
||||
/** \returns the maximum of all coefficients of *this
|
||||
* and puts in *index its location.
|
||||
*
|
||||
* \sa MatrixBase::maxCoeff(int*,int*), MatrixBase::minCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::maxCoeff()
|
||||
*/
|
||||
template<typename Derived>
|
||||
typename ei_traits<Derived>::Scalar
|
||||
MatrixBase<Derived>::maxCoeff(int* index) const
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
ei_max_coeff_visitor<Scalar> maxVisitor;
|
||||
this->visit(maxVisitor);
|
||||
*index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
|
||||
return maxVisitor.res;
|
||||
}
|
||||
|
||||
#endif // EIGEN_VISITOR_H
|
||||
|
||||
@@ -123,6 +123,7 @@ template<typename MatrixType> class SVD;
|
||||
template<typename MatrixType, unsigned int Options = 0> class JacobiSVD;
|
||||
template<typename MatrixType, int UpLo = LowerTriangular> class LLT;
|
||||
template<typename MatrixType> class LDLT;
|
||||
template<typename VectorsType, typename CoeffsType> class HouseholderSequence;
|
||||
template<typename Scalar> class PlanarRotation;
|
||||
|
||||
// Geometry module:
|
||||
|
||||
@@ -217,7 +217,7 @@ template<unsigned int Flags> struct ei_are_flags_consistent
|
||||
* overloads for complex types */
|
||||
template<typename Derived,typename Scalar,typename OtherScalar,
|
||||
bool EnableIt = !ei_is_same_type<Scalar,OtherScalar>::ret >
|
||||
struct ei_special_scalar_op_base
|
||||
struct ei_special_scalar_op_base : public AnyMatrixBase<Derived>
|
||||
{
|
||||
// dummy operator* so that the
|
||||
// "using ei_special_scalar_op_base::operator*" compiles
|
||||
@@ -225,7 +225,7 @@ struct ei_special_scalar_op_base
|
||||
};
|
||||
|
||||
template<typename Derived,typename Scalar,typename OtherScalar>
|
||||
struct ei_special_scalar_op_base<Derived,Scalar,OtherScalar,true>
|
||||
struct ei_special_scalar_op_base<Derived,Scalar,OtherScalar,true> : public AnyMatrixBase<Derived>
|
||||
{
|
||||
const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,OtherScalar>, Derived>
|
||||
operator*(const OtherScalar& scalar) const
|
||||
|
||||
Reference in New Issue
Block a user