mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-03-25 18:50:40 +08:00
* make use of the EvalBeforeNestingBit and EvalBeforeAssigningBit
in ei_xpr_copy and operator=, respectively. * added Matrix::lazyAssign() when EvalBeforeAssigningBit must be skipped (mainly internal use only) * all expressions are now stored by const reference * added Temporary xpr: .temporary() must be called on any temporary expression not directly returned by a function (mainly internal use only) * moved all functors in the Functors.h header * added some preliminaries stuff for the explicit vectorization
This commit is contained in:
parent
048910caae
commit
b4a156671f
@ -21,6 +21,7 @@ namespace Eigen {
|
||||
#include "src/Core/MatrixStorage.h"
|
||||
#include "src/Core/Matrix.h"
|
||||
#include "src/Core/Lazy.h"
|
||||
#include "src/Core/Temporary.h"
|
||||
#include "src/Core/CwiseBinaryOp.h"
|
||||
#include "src/Core/CwiseUnaryOp.h"
|
||||
#include "src/Core/Product.h"
|
||||
@ -41,7 +42,7 @@ namespace Eigen {
|
||||
#include "src/Core/IO.h"
|
||||
#include "src/Core/Swap.h"
|
||||
#include "src/Core/CommaInitializer.h"
|
||||
#include "src/Core/AssociativeFunctors.h"
|
||||
#include "src/Core/Functors.h"
|
||||
|
||||
} // namespace Eigen
|
||||
|
||||
|
@ -1,106 +0,0 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra. Eigen itself is part of the KDE project.
|
||||
//
|
||||
// Copyright (C) 2008 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_ASSOCIATIVE_FUNCTORS_H
|
||||
#define EIGEN_ASSOCIATIVE_FUNCTORS_H
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the sum of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator+, class PartialRedux, MatrixBase::sum()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
|
||||
enum { Cost = NumTraits<Scalar>::AddCost };
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the product of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseProduct(), class PartialRedux, MatrixBase::redux()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_product_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
|
||||
enum { Cost = NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the min of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class PartialRedux, MatrixBase::minCoeff()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_min_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
|
||||
enum { Cost = ConditionalJumpCost + NumTraits<Scalar>::AddCost };
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the max of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class PartialRedux, MatrixBase::maxCoeff()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_max_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
|
||||
enum { Cost = ConditionalJumpCost + NumTraits<Scalar>::AddCost };
|
||||
};
|
||||
|
||||
// default ei_functor_traits for STL functors:
|
||||
|
||||
template<typename Result, typename Arg0, typename Arg1>
|
||||
struct ei_functor_traits<std::binary_function<Result,Arg0,Arg1> >
|
||||
{ enum { Cost = 10 }; };
|
||||
|
||||
template<typename Result, typename Arg0>
|
||||
struct ei_functor_traits<std::unary_function<Result,Arg0> >
|
||||
{ enum { Cost = 5 }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::binder2nd<T> >
|
||||
{ enum { Cost = 5 }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::binder1st<T> >
|
||||
{ enum { Cost = 5 }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::greater<T> >
|
||||
{ enum { Cost = 1 }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::less<T> >
|
||||
{ enum { Cost = 1 }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::greater_equal<T> >
|
||||
{ enum { Cost = 1 }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::less_equal<T> >
|
||||
{ enum { Cost = 1 }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::equal_to<T> >
|
||||
{ enum { Cost = 1 }; };
|
||||
|
||||
#endif // EIGEN_ASSOCIATIVE_FUNCTORS_H
|
@ -95,26 +95,6 @@ class CwiseBinaryOp : ei_no_assignment_operator,
|
||||
const BinaryOp m_functor;
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the difference of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator-
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
|
||||
enum { Cost = NumTraits<Scalar>::AddCost };
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the quotient of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseQuotient()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
|
||||
enum { Cost = 2 * NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
/**\returns an expression of the difference of \c *this and \a other
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator-=()
|
||||
|
@ -99,16 +99,6 @@ MatrixBase<Derived>::cwise(const CustomUnaryOp& func) const
|
||||
return CwiseUnaryOp<CustomUnaryOp, Derived>(derived(), func);
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the opposite of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::operator-
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return -a; }
|
||||
enum { Cost = NumTraits<Scalar>::AddCost };
|
||||
};
|
||||
|
||||
/** \returns an expression of the opposite of \c *this
|
||||
*/
|
||||
template<typename Derived>
|
||||
@ -118,16 +108,6 @@ MatrixBase<Derived>::operator-() const
|
||||
return CwiseUnaryOp<ei_scalar_opposite_op<Scalar>, Derived>(derived());
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the absolute value of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseAbs
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_abs(a); }
|
||||
enum { Cost = NumTraits<Scalar>::AddCost };
|
||||
};
|
||||
|
||||
/** \returns an expression of the coefficient-wise absolute value of \c *this
|
||||
*/
|
||||
template<typename Derived>
|
||||
@ -137,16 +117,6 @@ MatrixBase<Derived>::cwiseAbs() const
|
||||
return CwiseUnaryOp<ei_scalar_abs_op<Scalar>,Derived>(derived());
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the squared absolute value of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseAbs2
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_abs2(a); }
|
||||
enum { Cost = NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
/** \returns an expression of the coefficient-wise squared absolute value of \c *this
|
||||
*/
|
||||
template<typename Derived>
|
||||
@ -156,16 +126,6 @@ MatrixBase<Derived>::cwiseAbs2() const
|
||||
return CwiseUnaryOp<ei_scalar_abs2_op<Scalar>,Derived>(derived());
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the conjugate of a complex value
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::conjugate()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_conjugate_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_conj(a); }
|
||||
enum { Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0 };
|
||||
};
|
||||
|
||||
/** \returns an expression of the complex conjugate of *this.
|
||||
*
|
||||
* \sa adjoint() */
|
||||
@ -176,18 +136,6 @@ MatrixBase<Derived>::conjugate() const
|
||||
return CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>(derived());
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to cast a scalar to another type
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cast()
|
||||
*/
|
||||
template<typename Scalar, typename NewType>
|
||||
struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT {
|
||||
typedef NewType result_type;
|
||||
const NewType operator() (const Scalar& a) const { return static_cast<NewType>(a); }
|
||||
enum { Cost = ei_is_same_type<Scalar, NewType>::ret ? 0 : NumTraits<NewType>::AddCost };
|
||||
};
|
||||
|
||||
/** \returns an expression of *this with the \a Scalar type casted to
|
||||
* \a NewScalar.
|
||||
*
|
||||
@ -203,49 +151,6 @@ MatrixBase<Derived>::cast() const
|
||||
return CwiseUnaryOp<ei_scalar_cast_op<Scalar, NewType>, Derived>(derived());
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to multiply a scalar by a fixed other one
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::operator*, MatrixBase::operator/
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct ei_scalar_multiple_op {
|
||||
ei_scalar_multiple_op(const Scalar& other) : m_other(other) {}
|
||||
Scalar operator() (const Scalar& a) const { return a * m_other; }
|
||||
const Scalar m_other;
|
||||
enum { Cost = NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
template<typename Scalar, bool HasFloatingPoint>
|
||||
struct ei_scalar_quotient1_impl {
|
||||
ei_scalar_quotient1_impl(const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
|
||||
Scalar operator() (const Scalar& a) const { return a * m_other; }
|
||||
const Scalar m_other;
|
||||
enum { Cost = NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
template<typename Scalar>
|
||||
struct ei_scalar_quotient1_impl<Scalar,false> {
|
||||
ei_scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
|
||||
Scalar operator() (const Scalar& a) const { return a / m_other; }
|
||||
const Scalar m_other;
|
||||
enum { Cost = 2 * NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to divide a scalar by a fixed other one
|
||||
*
|
||||
* This functor is used to implement the quotient of a matrix by
|
||||
* a scalar where the scalar type is not a floating point type.
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::operator/
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct ei_scalar_quotient1_op : ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint > {
|
||||
ei_scalar_quotient1_op(const Scalar& other)
|
||||
: ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint >(other) {}
|
||||
};
|
||||
|
||||
/** \relates MatrixBase */
|
||||
template<typename Derived>
|
||||
const CwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived>
|
||||
@ -278,16 +183,6 @@ MatrixBase<Derived>::operator/=(const Scalar& other)
|
||||
return *this = *this / other;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the square root of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseSqrt()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_sqrt_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_sqrt(a); }
|
||||
enum { Cost = 5 * NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
/** \returns an expression of the coefficient-wise square root of *this. */
|
||||
template<typename Derived>
|
||||
const CwiseUnaryOp<ei_scalar_sqrt_op<typename ei_traits<Derived>::Scalar>, Derived>
|
||||
@ -296,16 +191,6 @@ MatrixBase<Derived>::cwiseSqrt() const
|
||||
return CwiseUnaryOp<ei_scalar_sqrt_op<Scalar>, Derived>(derived());
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the exponential of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseExp()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_exp(a); }
|
||||
enum { Cost = 5 * NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
/** \returns an expression of the coefficient-wise exponential of *this. */
|
||||
template<typename Derived>
|
||||
const CwiseUnaryOp<ei_scalar_exp_op<typename ei_traits<Derived>::Scalar>, Derived>
|
||||
@ -314,16 +199,6 @@ MatrixBase<Derived>::cwiseExp() const
|
||||
return CwiseUnaryOp<ei_scalar_exp_op<Scalar>, Derived>(derived());
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the logarithm of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseLog()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_log_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_log(a); }
|
||||
enum { Cost = 5 * NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
/** \returns an expression of the coefficient-wise logarithm of *this. */
|
||||
template<typename Derived>
|
||||
const CwiseUnaryOp<ei_scalar_log_op<typename ei_traits<Derived>::Scalar>, Derived>
|
||||
@ -332,16 +207,6 @@ MatrixBase<Derived>::cwiseLog() const
|
||||
return CwiseUnaryOp<ei_scalar_log_op<Scalar>, Derived>(derived());
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the cosine of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseCos()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_cos(a); }
|
||||
enum { Cost = 5 * NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
/** \returns an expression of the coefficient-wise cosine of *this. */
|
||||
template<typename Derived>
|
||||
const CwiseUnaryOp<ei_scalar_cos_op<typename ei_traits<Derived>::Scalar>, Derived>
|
||||
@ -350,16 +215,6 @@ MatrixBase<Derived>::cwiseCos() const
|
||||
return CwiseUnaryOp<ei_scalar_cos_op<Scalar>, Derived>(derived());
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the sine of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseSin()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_sin(a); }
|
||||
enum { Cost = 5 * NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
/** \returns an expression of the coefficient-wise sine of *this. */
|
||||
template<typename Derived>
|
||||
const CwiseUnaryOp<ei_scalar_sin_op<typename ei_traits<Derived>::Scalar>, Derived>
|
||||
@ -368,19 +223,6 @@ MatrixBase<Derived>::cwiseSin() const
|
||||
return CwiseUnaryOp<ei_scalar_sin_op<Scalar>, Derived>(derived());
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to raise a scalar to a power
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwisePow
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct ei_scalar_pow_op {
|
||||
ei_scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
|
||||
Scalar operator() (const Scalar& a) const { return ei_pow(a, m_exponent); }
|
||||
const Scalar m_exponent;
|
||||
enum { Cost = 5 * NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
|
||||
/** \relates MatrixBase */
|
||||
template<typename Derived>
|
||||
const CwiseUnaryOp<ei_scalar_pow_op<typename ei_traits<Derived>::Scalar>, Derived>
|
||||
|
@ -31,6 +31,7 @@ template<typename T> struct NumTraits;
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols, unsigned int _Flags, int _MaxRows, int _MaxCols> class Matrix;
|
||||
template<typename ExpressionType> class Lazy;
|
||||
template<typename ExpressionType> class Temporary;
|
||||
template<typename MatrixType> class Minor;
|
||||
template<typename MatrixType, int BlockRows=Dynamic, int BlockCols=Dynamic> class Block;
|
||||
template<typename MatrixType> class Transpose;
|
||||
@ -69,25 +70,6 @@ template<typename Scalar> struct ei_scalar_quotient1_op;
|
||||
template<typename Scalar> struct ei_scalar_min_op;
|
||||
template<typename Scalar> struct ei_scalar_max_op;
|
||||
|
||||
template<typename T> struct ei_copy_unless_matrix
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename _Scalar, int _Rows, int _Cols, unsigned int _Flags, int _MaxRows, int _MaxCols>
|
||||
struct ei_copy_unless_matrix<Matrix<_Scalar, _Rows, _Cols, _Flags, _MaxRows, _MaxCols> >
|
||||
{
|
||||
typedef const Matrix<_Scalar, _Rows, _Cols, _Flags, _MaxRows, _MaxCols> & type;
|
||||
};
|
||||
|
||||
template<typename T> struct ei_xpr_copy
|
||||
{
|
||||
typedef typename ei_meta_if<T::Flags & TemporaryBit,
|
||||
T,
|
||||
typename ei_copy_unless_matrix<T>::type
|
||||
>::ret type;
|
||||
};
|
||||
|
||||
template<typename T> struct ei_eval
|
||||
{
|
||||
typedef Matrix<typename ei_traits<T>::Scalar,
|
||||
@ -98,27 +80,34 @@ template<typename T> struct ei_eval
|
||||
ei_traits<T>::MaxColsAtCompileTime> type;
|
||||
};
|
||||
|
||||
template<typename T> struct ei_eval_temporary
|
||||
template<typename T> struct ei_xpr_copy
|
||||
{
|
||||
typedef Matrix<typename ei_traits<T>::Scalar,
|
||||
ei_traits<T>::RowsAtCompileTime,
|
||||
ei_traits<T>::ColsAtCompileTime,
|
||||
(ei_traits<T>::Flags | TemporaryBit) & ~(EvalBeforeNestingBit | EvalBeforeAssigningBit),
|
||||
ei_traits<T>::MaxRowsAtCompileTime,
|
||||
ei_traits<T>::MaxColsAtCompileTime> type;
|
||||
typedef typename ei_meta_if< ei_traits<T>::Flags & EvalBeforeNestingBit,
|
||||
typename ei_eval<T>::type, const T&>::ret type;
|
||||
};
|
||||
|
||||
template<typename T> struct ei_xpr_copy<Temporary<T> >
|
||||
{
|
||||
typedef Temporary<T> type;
|
||||
};
|
||||
|
||||
template<typename T, int n=1> struct ei_eval_if_needed_before_nesting
|
||||
{
|
||||
// FIXME should we consider the additional store as well as the creation cost of the temporary ?
|
||||
enum { eval = T::Flags & EvalBeforeNestingBit
|
||||
|| n * NumTraits<typename T::Scalar>::ReadCost < (n-1) * T::CoeffReadCost };
|
||||
typedef typename ei_meta_if<eval, typename ei_eval_temporary<T>::type, T>::ret type;
|
||||
|| n * NumTraits<typename ei_traits<T>::Scalar>::ReadCost < (n-1) * T::CoeffReadCost };
|
||||
typedef typename ei_meta_if<eval, typename ei_eval<T>::type, T>::ret XprType;
|
||||
typedef typename ei_meta_if<eval, typename ei_eval<T>::type, typename T::XprCopy>::ret CopyType;
|
||||
};
|
||||
|
||||
|
||||
template<typename T> struct ei_functor_traits
|
||||
{
|
||||
enum { Cost = T::Cost };
|
||||
enum
|
||||
{
|
||||
Cost = 10,
|
||||
IsVectorizable = false
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
420
Eigen/src/Core/Functors.h
Normal file
420
Eigen/src/Core/Functors.h
Normal file
@ -0,0 +1,420 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra. Eigen itself is part of the KDE project.
|
||||
//
|
||||
// Copyright (C) 2008 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_FUNCTORS_H
|
||||
#define EIGEN_FUNCTORS_H
|
||||
|
||||
// associative functors:
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the sum of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator+, class PartialRedux, MatrixBase::sum()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_sum_op<Scalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
IsVectorizable = NumTraits<Scalar>::PacketSize>0
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the product of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseProduct(), class PartialRedux, MatrixBase::redux()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_product_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_product_op<Scalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::MulCost,
|
||||
IsVectorizable = NumTraits<Scalar>::PacketSize>0
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the min of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class PartialRedux, MatrixBase::minCoeff()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_min_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_min_op<Scalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
IsVectorizable = NumTraits<Scalar>::PacketSize>0
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the max of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class PartialRedux, MatrixBase::maxCoeff()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_max_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_max_op<Scalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
IsVectorizable = NumTraits<Scalar>::PacketSize>0
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// other binary functors:
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the difference of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator-
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_difference_op<Scalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<Scalar>::AddCost,
|
||||
IsVectorizable = NumTraits<Scalar>::PacketSize>0
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the quotient of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseQuotient()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_quotient_op<Scalar> >
|
||||
{ enum { Cost = 2 * NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
|
||||
// unary functors:
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the opposite of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::operator-
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return -a; }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_opposite_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::AddCost, IsVectorizable = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the absolute value of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseAbs
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_abs(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_abs_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::AddCost, IsVectorizable = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the squared absolute value of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseAbs2
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_abs2(a); }
|
||||
enum { Cost = NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_abs2_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the conjugate of a complex value
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::conjugate()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_conjugate_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_conj(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_conjugate_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0, IsVectorizable = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to cast a scalar to another type
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cast()
|
||||
*/
|
||||
template<typename Scalar, typename NewType>
|
||||
struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT {
|
||||
typedef NewType result_type;
|
||||
const NewType operator() (const Scalar& a) const { return static_cast<NewType>(a); }
|
||||
};
|
||||
template<typename Scalar, typename NewType>
|
||||
struct ei_functor_traits<ei_scalar_cast_op<Scalar,NewType> >
|
||||
{ enum { Cost = ei_is_same_type<Scalar, NewType>::ret ? 0 : NumTraits<NewType>::AddCost, IsVectorizable = false }; };
|
||||
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to multiply a scalar by a fixed other one
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::operator*, MatrixBase::operator/
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct ei_scalar_multiple_op {
|
||||
ei_scalar_multiple_op(const Scalar& other) : m_other(other) {}
|
||||
Scalar operator() (const Scalar& a) const { return a * m_other; }
|
||||
const Scalar m_other;
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_multiple_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
template<typename Scalar, bool HasFloatingPoint>
|
||||
struct ei_scalar_quotient1_impl {
|
||||
ei_scalar_quotient1_impl(const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
|
||||
Scalar operator() (const Scalar& a) const { return a * m_other; }
|
||||
const Scalar m_other;
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> >
|
||||
{ enum { Cost = NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
template<typename Scalar>
|
||||
struct ei_scalar_quotient1_impl<Scalar,false> {
|
||||
ei_scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
|
||||
Scalar operator() (const Scalar& a) const { return a / m_other; }
|
||||
const Scalar m_other;
|
||||
enum { Cost = 2 * NumTraits<Scalar>::MulCost };
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,false> >
|
||||
{ enum { Cost = 2 * NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to divide a scalar by a fixed other one
|
||||
*
|
||||
* This functor is used to implement the quotient of a matrix by
|
||||
* a scalar where the scalar type is not a floating point type.
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::operator/
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct ei_scalar_quotient1_op : ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint > {
|
||||
ei_scalar_quotient1_op(const Scalar& other)
|
||||
: ei_scalar_quotient1_impl<Scalar, NumTraits<Scalar>::HasFloatingPoint >(other) {}
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the square root of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseSqrt()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_sqrt_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_sqrt(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_sqrt_op<Scalar> >
|
||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the exponential of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseExp()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_exp(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_exp_op<Scalar> >
|
||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the logarithm of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseLog()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_log_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_log(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_log_op<Scalar> >
|
||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the cosine of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseCos()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_cos(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
|
||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the sine of a scalar
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwiseSin()
|
||||
*/
|
||||
template<typename Scalar> struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT {
|
||||
const Scalar operator() (const Scalar& a) const { return ei_sin(a); }
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_sin_op<Scalar> >
|
||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to raise a scalar to a power
|
||||
*
|
||||
* \sa class CwiseUnaryOp, MatrixBase::cwisePow
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct ei_scalar_pow_op {
|
||||
ei_scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
|
||||
Scalar operator() (const Scalar& a) const { return ei_pow(a, m_exponent); }
|
||||
const Scalar m_exponent;
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct ei_functor_traits<ei_scalar_pow_op<Scalar> >
|
||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
|
||||
// default ei_functor_traits for STL functors:
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::multiplies<T> >
|
||||
{ enum { Cost = NumTraits<T>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::divides<T> >
|
||||
{ enum { Cost = NumTraits<T>::MulCost, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::plus<T> >
|
||||
{ enum { Cost = NumTraits<T>::AddCost, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::minus<T> >
|
||||
{ enum { Cost = NumTraits<T>::AddCost, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::negate<T> >
|
||||
{ enum { Cost = NumTraits<T>::AddCost, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::logical_or<T> >
|
||||
{ enum { Cost = 1, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::logical_and<T> >
|
||||
{ enum { Cost = 1, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::logical_not<T> >
|
||||
{ enum { Cost = 1, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::greater<T> >
|
||||
{ enum { Cost = 1, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::less<T> >
|
||||
{ enum { Cost = 1, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::greater_equal<T> >
|
||||
{ enum { Cost = 1, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::less_equal<T> >
|
||||
{ enum { Cost = 1, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::equal_to<T> >
|
||||
{ enum { Cost = 1, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::not_equal_to<T> >
|
||||
{ enum { Cost = 1, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::binder2nd<T> >
|
||||
{ enum { Cost = ei_functor_traits<T>::Cost, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::binder1st<T> >
|
||||
{ enum { Cost = ei_functor_traits<T>::Cost, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::unary_negate<T> >
|
||||
{ enum { Cost = 1 + ei_functor_traits<T>::Cost, IsVectorizable = false }; };
|
||||
|
||||
template<typename T>
|
||||
struct ei_functor_traits<std::binary_negate<T> >
|
||||
{ enum { Cost = 1 + ei_functor_traits<T>::Cost, IsVectorizable = false }; };
|
||||
|
||||
#ifdef EIGEN_STDEXT_SUPPORT
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct ei_functor_traits<std::project1st<T0,T1> >
|
||||
{ enum { Cost = 0, IsVectorizable = false }; };
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct ei_functor_traits<std::project2nd<T0,T1> >
|
||||
{ enum { Cost = 0, IsVectorizable = false }; };
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct ei_functor_traits<std::select2nd<std::pair<T0,T1> > >
|
||||
{ enum { Cost = 0, IsVectorizable = false }; };
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct ei_functor_traits<std::select1st<std::pair<T0,T1> > >
|
||||
{ enum { Cost = 0, IsVectorizable = false }; };
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct ei_functor_traits<std::unary_compose<T0,T1> >
|
||||
{ enum { Cost = ei_functor_traits<T0>::Cost + ei_functor_traits<T1>::Cost, IsVectorizable = false }; };
|
||||
|
||||
template<typename T0,typename T1,typename T2>
|
||||
struct ei_functor_traits<std::binary_compose<T0,T1,T2> >
|
||||
{ enum { Cost = ei_functor_traits<T0>::Cost + ei_functor_traits<T1>::Cost + ei_functor_traits<T2>::Cost, IsVectorizable = false }; };
|
||||
|
||||
#endif // EIGEN_STDEXT_SUPPORT
|
||||
|
||||
#endif // EIGEN_FUNCTORS_H
|
@ -276,13 +276,13 @@ class Matrix : public MatrixBase<Matrix<_Scalar, _Rows, _Cols,
|
||||
Matrix(const MatrixBase<OtherDerived>& other)
|
||||
: m_storage(other.rows() * other.cols(), other.rows(), other.cols())
|
||||
{
|
||||
*this = other;
|
||||
Base::lazyAssign(other.derived());
|
||||
}
|
||||
/** Copy constructor */
|
||||
Matrix(const Matrix& other)
|
||||
: m_storage(other.rows() * other.cols(), other.rows(), other.cols())
|
||||
{
|
||||
*this = other;
|
||||
Base::lazyAssign(other);
|
||||
}
|
||||
/** Destructor */
|
||||
~Matrix() {}
|
||||
|
@ -175,6 +175,10 @@ template<typename Derived> class MatrixBase
|
||||
template<typename OtherDerived>
|
||||
Derived& operator=(const MatrixBase<OtherDerived>& other);
|
||||
|
||||
/** Copies \a other into *this without evaluating other. \returns a reference to *this. */
|
||||
template<typename OtherDerived>
|
||||
Derived& lazyAssign(const MatrixBase<OtherDerived>& other);
|
||||
|
||||
/** Special case of the template operator=, in order to prevent the compiler
|
||||
* from generating a default operator= (issue hit with g++ 4.1)
|
||||
*/
|
||||
@ -185,7 +189,7 @@ template<typename Derived> class MatrixBase
|
||||
|
||||
/** Overloaded for optimal product evaluation */
|
||||
template<typename Derived1, typename Derived2>
|
||||
Derived& operator=(const Product<Derived1,Derived2,CacheOptimal>& product);
|
||||
Derived& lazyAssign(const Product<Derived1,Derived2,CacheOptimal>& product);
|
||||
|
||||
CommaInitializer operator<< (const Scalar& s);
|
||||
|
||||
@ -252,8 +256,7 @@ template<typename Derived> class MatrixBase
|
||||
*/
|
||||
//@{
|
||||
template<typename OtherDerived>
|
||||
const Product<typename ei_eval_if_needed_before_nesting<Derived, OtherDerived::ColsAtCompileTime>::type,
|
||||
typename ei_eval_if_needed_before_nesting<OtherDerived, ei_traits<Derived>::ColsAtCompileTime>::type>
|
||||
const Product<Derived,OtherDerived>
|
||||
operator*(const MatrixBase<OtherDerived> &other) const;
|
||||
|
||||
template<typename OtherDerived>
|
||||
@ -272,7 +275,8 @@ template<typename Derived> class MatrixBase
|
||||
|
||||
Transpose<Derived> transpose();
|
||||
const Transpose<Derived> transpose() const;
|
||||
const Transpose<CwiseUnaryOp<ei_scalar_conjugate_op<typename ei_traits<Derived>::Scalar>, Derived> > adjoint() const;
|
||||
const Transpose<Temporary<CwiseUnaryOp<ei_scalar_conjugate_op<typename ei_traits<Derived>::Scalar>, Derived> > >
|
||||
adjoint() const;
|
||||
//@}
|
||||
|
||||
/// \name Sub-matrices
|
||||
@ -377,6 +381,7 @@ template<typename Derived> class MatrixBase
|
||||
void swap(const MatrixBase<OtherDerived>& other);
|
||||
|
||||
const Lazy<Derived> lazy() const;
|
||||
const Temporary<Derived> temporary() const;
|
||||
//@}
|
||||
|
||||
/// \name Coefficient-wise operations
|
||||
|
@ -56,7 +56,8 @@ template<> struct NumTraits<int>
|
||||
HasFloatingPoint = 0,
|
||||
ReadCost = 1,
|
||||
AddCost = 1,
|
||||
MulCost = 3
|
||||
MulCost = 1,
|
||||
PacketSize = 4
|
||||
};
|
||||
};
|
||||
|
||||
@ -68,8 +69,9 @@ template<> struct NumTraits<float>
|
||||
IsComplex = 0,
|
||||
HasFloatingPoint = 1,
|
||||
ReadCost = 1,
|
||||
AddCost = 2,
|
||||
MulCost = 6
|
||||
AddCost = 1,
|
||||
MulCost = 1,
|
||||
PacketSize = 4
|
||||
};
|
||||
};
|
||||
|
||||
@ -81,8 +83,9 @@ template<> struct NumTraits<double>
|
||||
IsComplex = 0,
|
||||
HasFloatingPoint = 1,
|
||||
ReadCost = 1,
|
||||
AddCost = 2,
|
||||
MulCost = 6
|
||||
AddCost = 1,
|
||||
MulCost = 1,
|
||||
PacketSize = 2
|
||||
};
|
||||
};
|
||||
|
||||
@ -95,7 +98,8 @@ template<typename _Real> struct NumTraits<std::complex<_Real> >
|
||||
HasFloatingPoint = NumTraits<Real>::HasFloatingPoint,
|
||||
ReadCost = 2,
|
||||
AddCost = 2 * NumTraits<Real>::AddCost,
|
||||
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
|
||||
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost,
|
||||
PacketSize = 0
|
||||
};
|
||||
};
|
||||
|
||||
@ -107,8 +111,9 @@ template<> struct NumTraits<long long int>
|
||||
IsComplex = 0,
|
||||
HasFloatingPoint = 0,
|
||||
ReadCost = 1,
|
||||
AddCost = 2,
|
||||
MulCost = 6
|
||||
AddCost = 1,
|
||||
MulCost = 1,
|
||||
PacketSize = 0
|
||||
};
|
||||
};
|
||||
|
||||
@ -121,7 +126,8 @@ template<> struct NumTraits<long double>
|
||||
HasFloatingPoint = 1,
|
||||
ReadCost = 1,
|
||||
AddCost = 2,
|
||||
MulCost = 6
|
||||
MulCost = 2,
|
||||
PacketSize = 0
|
||||
};
|
||||
};
|
||||
|
||||
@ -134,7 +140,8 @@ template<> struct NumTraits<bool>
|
||||
HasFloatingPoint = 0,
|
||||
ReadCost = 1,
|
||||
AddCost = 1,
|
||||
MulCost = 1
|
||||
MulCost = 1,
|
||||
PacketSize = 0
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -100,7 +100,7 @@ struct ei_vector_operator_equals_unroller<Derived1, Derived2, Dynamic>
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& MatrixBase<Derived>
|
||||
::operator=(const MatrixBase<OtherDerived>& other)
|
||||
::lazyAssign(const MatrixBase<OtherDerived>& other)
|
||||
{
|
||||
if(IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime)
|
||||
// copying a vector expression into a vector
|
||||
@ -111,12 +111,11 @@ Derived& MatrixBase<Derived>
|
||||
&& SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT)
|
||||
ei_vector_operator_equals_unroller
|
||||
<Derived, OtherDerived,
|
||||
SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT ? SizeAtCompileTime : Dynamic
|
||||
SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT ? SizeAtCompileTime : Dynamic
|
||||
>::run(derived(), other.derived());
|
||||
else
|
||||
for(int i = 0; i < size(); i++)
|
||||
coeffRef(i) = other.coeff(i);
|
||||
return derived();
|
||||
}
|
||||
else // copying a matrix expression into a matrix
|
||||
{
|
||||
@ -127,7 +126,7 @@ Derived& MatrixBase<Derived>
|
||||
{
|
||||
ei_matrix_operator_equals_unroller
|
||||
<Derived, OtherDerived,
|
||||
SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT ? SizeAtCompileTime : Dynamic
|
||||
SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT ? SizeAtCompileTime : Dynamic
|
||||
>::run(derived(), other.derived());
|
||||
}
|
||||
else
|
||||
@ -148,8 +147,21 @@ Derived& MatrixBase<Derived>
|
||||
coeffRef(i, j) = other.coeff(i, j);
|
||||
}
|
||||
}
|
||||
return derived();
|
||||
}
|
||||
return derived();
|
||||
}
|
||||
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
Derived& MatrixBase<Derived>
|
||||
::operator=(const MatrixBase<OtherDerived>& other)
|
||||
{
|
||||
if (OtherDerived::Flags & EvalBeforeAssigningBit)
|
||||
{
|
||||
return lazyAssign(other.derived().eval());
|
||||
}
|
||||
else
|
||||
return lazyAssign(other.derived());
|
||||
}
|
||||
|
||||
#endif // EIGEN_OPERATOREQUALS_H
|
||||
|
@ -110,8 +110,12 @@ template<typename Lhs, typename Rhs, int EvalMode> class Product : ei_no_assignm
|
||||
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
|
||||
|
||||
template<typename ArgLhs, typename ArgRhs>
|
||||
Product(const ArgLhs& lhs, const ArgRhs& rhs)
|
||||
typedef typename ei_eval_if_needed_before_nesting<Lhs,Rhs::ColsAtCompileTime>::CopyType CopyLhs;
|
||||
typedef typename ei_eval_if_needed_before_nesting<Rhs,Lhs::RowsAtCompileTime>::CopyType CopyRhs;
|
||||
typedef typename ei_eval_if_needed_before_nesting<Lhs,Rhs::ColsAtCompileTime>::XprType XprLhs;
|
||||
typedef typename ei_eval_if_needed_before_nesting<Rhs,Lhs::RowsAtCompileTime>::XprType XprRhs;
|
||||
|
||||
Product(const Lhs& lhs, const Rhs& rhs)
|
||||
: m_lhs(lhs), m_rhs(rhs)
|
||||
{
|
||||
ei_assert(lhs.cols() == rhs.rows());
|
||||
@ -135,7 +139,7 @@ template<typename Lhs, typename Rhs, int EvalMode> class Product : ei_no_assignm
|
||||
ei_product_unroller<Lhs::ColsAtCompileTime-1,
|
||||
Lhs::ColsAtCompileTime <= EIGEN_UNROLLING_LIMIT
|
||||
? Lhs::ColsAtCompileTime : Dynamic,
|
||||
Lhs, Rhs>
|
||||
XprLhs, XprRhs>
|
||||
::run(row, col, m_lhs, m_rhs, res);
|
||||
else
|
||||
{
|
||||
@ -147,8 +151,8 @@ template<typename Lhs, typename Rhs, int EvalMode> class Product : ei_no_assignm
|
||||
}
|
||||
|
||||
protected:
|
||||
const typename Lhs::XprCopy m_lhs;
|
||||
const typename Rhs::XprCopy m_rhs;
|
||||
const CopyLhs m_lhs;
|
||||
const CopyRhs m_rhs;
|
||||
};
|
||||
|
||||
/** \returns the matrix product of \c *this and \a other.
|
||||
@ -160,14 +164,10 @@ template<typename Lhs, typename Rhs, int EvalMode> class Product : ei_no_assignm
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename OtherDerived>
|
||||
const Product<typename ei_eval_if_needed_before_nesting<Derived, OtherDerived::ColsAtCompileTime>::type,
|
||||
typename ei_eval_if_needed_before_nesting<OtherDerived, ei_traits<Derived>::ColsAtCompileTime>::type>
|
||||
const Product<Derived,OtherDerived>
|
||||
MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
|
||||
{
|
||||
typedef ei_eval_if_needed_before_nesting<Derived, OtherDerived::ColsAtCompileTime> Lhs;
|
||||
typedef ei_eval_if_needed_before_nesting<OtherDerived, Derived::RowsAtCompileTime> Rhs;
|
||||
return Product<typename Lhs::type, typename Rhs::type>
|
||||
(derived(), other.derived());
|
||||
return Product<Derived,OtherDerived>(derived(), other.derived());
|
||||
}
|
||||
|
||||
/** replaces \c *this by \c *this * \a other.
|
||||
@ -184,7 +184,7 @@ MatrixBase<Derived>::operator*=(const MatrixBase<OtherDerived> &other)
|
||||
|
||||
template<typename Derived>
|
||||
template<typename Derived1, typename Derived2>
|
||||
Derived& MatrixBase<Derived>::operator=(const Product<Derived1,Derived2,CacheOptimal>& product)
|
||||
Derived& MatrixBase<Derived>::lazyAssign(const Product<Derived1,Derived2,CacheOptimal>& product)
|
||||
{
|
||||
product._cacheOptimalEval(*this);
|
||||
return derived();
|
||||
@ -207,7 +207,7 @@ void Product<Lhs,Rhs,EvalMode>::_cacheOptimalEval(DestDerived& res) const
|
||||
const Scalar tmp3 = m_rhs.coeff(j+3,k);
|
||||
for (int i=0; i<m_lhs.rows(); ++i)
|
||||
res.coeffRef(i,k) += tmp0 * m_lhs.coeff(i,j) + tmp1 * m_lhs.coeff(i,j+1)
|
||||
+ tmp2 * m_lhs.coeff(i,j+2) + tmp3 * m_lhs.coeff(i,j+3);
|
||||
+ tmp2 * m_lhs.coeff(i,j+2) + tmp3 * m_lhs.coeff(i,j+3);
|
||||
}
|
||||
for (; j<m_lhs.cols(); ++j)
|
||||
{
|
||||
|
87
Eigen/src/Core/Temporary.h
Normal file
87
Eigen/src/Core/Temporary.h
Normal file
@ -0,0 +1,87 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra. Eigen itself is part of the KDE project.
|
||||
//
|
||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.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_TEMPORARY_H
|
||||
#define EIGEN_TEMPORARY_H
|
||||
|
||||
/** \class Temporary
|
||||
*
|
||||
* \brief Expression with the temporary flag set
|
||||
*
|
||||
* \param ExpressionType the type of the object of which we are taking the temporary version
|
||||
*
|
||||
* This class represents the temporary version of an expression.
|
||||
* It is the return type of MatrixBase::temporary()
|
||||
* and most of the time this is the only way it is used.
|
||||
*
|
||||
* \sa MatrixBase::temporary()
|
||||
*/
|
||||
template<typename ExpressionType>
|
||||
struct ei_traits<Temporary<ExpressionType> >
|
||||
{
|
||||
typedef typename ExpressionType::Scalar Scalar;
|
||||
enum {
|
||||
RowsAtCompileTime = ExpressionType::RowsAtCompileTime,
|
||||
ColsAtCompileTime = ExpressionType::ColsAtCompileTime,
|
||||
MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime,
|
||||
MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime,
|
||||
Flags = ExpressionType::Flags,
|
||||
CoeffReadCost = ExpressionType::CoeffReadCost
|
||||
};
|
||||
};
|
||||
|
||||
template<typename ExpressionType> class Temporary
|
||||
: public MatrixBase<Temporary<ExpressionType> >
|
||||
{
|
||||
public:
|
||||
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Temporary)
|
||||
|
||||
Temporary(const ExpressionType& matrix) : m_expression(matrix) {}
|
||||
|
||||
private:
|
||||
|
||||
int _rows() const { return m_expression.rows(); }
|
||||
int _cols() const { return m_expression.cols(); }
|
||||
|
||||
const Scalar _coeff(int row, int col) const
|
||||
{
|
||||
return m_expression.coeff(row, col);
|
||||
}
|
||||
|
||||
protected:
|
||||
const ExpressionType m_expression;
|
||||
};
|
||||
|
||||
/** \returns an expression of the temporary version of *this.
|
||||
*/
|
||||
template<typename Derived>
|
||||
const Temporary<Derived>
|
||||
MatrixBase<Derived>::temporary() const
|
||||
{
|
||||
return Temporary<Derived>(derived());
|
||||
}
|
||||
|
||||
#endif // EIGEN_TEMPORARY_H
|
@ -109,10 +109,10 @@ MatrixBase<Derived>::transpose() const
|
||||
*
|
||||
* \sa transpose(), conjugate(), class Transpose, class ei_scalar_conjugate_op */
|
||||
template<typename Derived>
|
||||
const Transpose<CwiseUnaryOp<ei_scalar_conjugate_op<typename ei_traits<Derived>::Scalar>, Derived> >
|
||||
const Transpose<Temporary<CwiseUnaryOp<ei_scalar_conjugate_op<typename ei_traits<Derived>::Scalar>, Derived > > >
|
||||
MatrixBase<Derived>::adjoint() const
|
||||
{
|
||||
return conjugate().transpose();
|
||||
return conjugate().temporary().transpose();
|
||||
}
|
||||
|
||||
#endif // EIGEN_TRANSPOSE_H
|
||||
|
@ -134,7 +134,7 @@ const unsigned int RowMajorBit = 0x1;
|
||||
const unsigned int EvalBeforeNestingBit = 0x2;
|
||||
const unsigned int EvalBeforeAssigningBit = 0x4;
|
||||
const unsigned int LargeBit = 0x8;
|
||||
const unsigned int TemporaryBit = 0x10;
|
||||
const unsigned int VectorizableBit = 0x10;
|
||||
|
||||
|
||||
enum { ConditionalJumpCost = 5 };
|
||||
|
@ -5,12 +5,12 @@
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// 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
|
||||
@ -18,7 +18,7 @@
|
||||
// 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
|
||||
// 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/>.
|
||||
|
||||
@ -34,10 +34,10 @@ template<typename MatrixType> void linearStructure(const MatrixType& m)
|
||||
|
||||
typedef typename MatrixType::Scalar Scalar;
|
||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
|
||||
|
||||
|
||||
int rows = m.rows();
|
||||
int cols = m.cols();
|
||||
|
||||
|
||||
// this test relies a lot on Random.h, and there's not much more that we can do
|
||||
// to test it, hence I consider that we will have tested Random.h
|
||||
MatrixType m1 = MatrixType::random(rows, cols),
|
||||
@ -54,10 +54,10 @@ template<typename MatrixType> void linearStructure(const MatrixType& m)
|
||||
|
||||
Scalar s1 = ei_random<Scalar>(),
|
||||
s2 = ei_random<Scalar>();
|
||||
|
||||
|
||||
int r = ei_random<int>(0, rows-1),
|
||||
c = ei_random<int>(0, cols-1);
|
||||
|
||||
|
||||
VERIFY_IS_APPROX(-(-m1), m1);
|
||||
VERIFY_IS_APPROX(m1+m1, 2*m1);
|
||||
VERIFY_IS_APPROX(m1+m2-m1, m2);
|
||||
@ -80,7 +80,7 @@ template<typename MatrixType> void linearStructure(const MatrixType& m)
|
||||
m3 = m2; m3 /= s1;
|
||||
VERIFY_IS_APPROX(m3, m2/s1);
|
||||
}
|
||||
|
||||
|
||||
// again, test operator() to check const-qualification
|
||||
VERIFY_IS_APPROX((-m1)(r,c), -(m1(r,c)));
|
||||
VERIFY_IS_APPROX((m1-m2)(r,c), (m1(r,c))-(m2(r,c)));
|
||||
|
@ -62,7 +62,7 @@ template<typename MatrixType> void product(const MatrixType& m)
|
||||
VERIFY_IS_APPROX((m1*m1.transpose())*m2, m1*(m1.transpose()*m2));
|
||||
m3 = m1;
|
||||
m3 *= (m1.transpose() * m2);
|
||||
VERIFY_IS_APPROX(m3, m1*(m1.transpose()*m2));
|
||||
VERIFY_IS_APPROX(m3, m1 * (m1.transpose()*m2));
|
||||
VERIFY_IS_APPROX(m3, m1.lazy() * (m1.transpose()*m2));
|
||||
|
||||
// continue testing Product.h: distributivity
|
||||
|
Loading…
x
Reference in New Issue
Block a user