* 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:
Gael Guennebaud 2008-04-05 11:10:54 +00:00
parent 048910caae
commit b4a156671f
16 changed files with 597 additions and 360 deletions

View File

@ -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

View File

@ -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

View File

@ -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-=()

View File

@ -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>

View File

@ -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
View 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

View File

@ -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() {}

View File

@ -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

View File

@ -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
};
};

View File

@ -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

View File

@ -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)
{

View 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

View File

@ -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

View File

@ -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 };

View File

@ -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)));

View File

@ -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