aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2008-04-05 11:10:54 +0000
committerGravatar Gael Guennebaud <g.gael@free.fr>2008-04-05 11:10:54 +0000
commitb4a156671fbe4e08c5f9cf7d939e2ee845e98283 (patch)
treee7fb53b0e5ec5ff5cfa2d598bcf7a83845af9d12
parent048910caae33dbf6b2359d5264a8be828084906a (diff)
* 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
-rw-r--r--Eigen/Core3
-rw-r--r--Eigen/src/Core/AssociativeFunctors.h106
-rw-r--r--Eigen/src/Core/CwiseBinaryOp.h20
-rw-r--r--Eigen/src/Core/CwiseUnaryOp.h158
-rw-r--r--Eigen/src/Core/ForwardDeclarations.h47
-rw-r--r--Eigen/src/Core/Functors.h420
-rw-r--r--Eigen/src/Core/Matrix.h4
-rw-r--r--Eigen/src/Core/MatrixBase.h13
-rw-r--r--Eigen/src/Core/NumTraits.h27
-rw-r--r--Eigen/src/Core/OperatorEquals.h22
-rw-r--r--Eigen/src/Core/Product.h26
-rw-r--r--Eigen/src/Core/Temporary.h87
-rw-r--r--Eigen/src/Core/Transpose.h4
-rw-r--r--Eigen/src/Core/Util.h2
-rw-r--r--test/linearstructure.cpp16
-rw-r--r--test/product.cpp2
16 files changed, 597 insertions, 360 deletions
diff --git a/Eigen/Core b/Eigen/Core
index bb4fc20c5..22a2ed6f2 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -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
diff --git a/Eigen/src/Core/AssociativeFunctors.h b/Eigen/src/Core/AssociativeFunctors.h
deleted file mode 100644
index cfd1ddbd9..000000000
--- a/Eigen/src/Core/AssociativeFunctors.h
+++ /dev/null
@@ -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
diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h
index 12560284d..f7764e9b4 100644
--- a/Eigen/src/Core/CwiseBinaryOp.h
+++ b/Eigen/src/Core/CwiseBinaryOp.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-=()
diff --git a/Eigen/src/Core/CwiseUnaryOp.h b/Eigen/src/Core/CwiseUnaryOp.h
index ae879a3f5..b26b55be8 100644
--- a/Eigen/src/Core/CwiseUnaryOp.h
+++ b/Eigen/src/Core/CwiseUnaryOp.h
@@ -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>
diff --git a/Eigen/src/Core/ForwardDeclarations.h b/Eigen/src/Core/ForwardDeclarations.h
index b4aaaa005..bf82a0c0a 100644
--- a/Eigen/src/Core/ForwardDeclarations.h
+++ b/Eigen/src/Core/ForwardDeclarations.h
@@ -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
+ };
};
diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h
new file mode 100644
index 000000000..44f982d11
--- /dev/null
+++ b/Eigen/src/Core/Functors.h
@@ -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
diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h
index fa40364c7..b9a47f7b0 100644
--- a/Eigen/src/Core/Matrix.h
+++ b/Eigen/src/Core/Matrix.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() {}
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index 57fc2bdbb..7720433d0 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -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
diff --git a/Eigen/src/Core/NumTraits.h b/Eigen/src/Core/NumTraits.h
index 5ce7e0fca..ba546e86e 100644
--- a/Eigen/src/Core/NumTraits.h
+++ b/Eigen/src/Core/NumTraits.h
@@ -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
};
};
diff --git a/Eigen/src/Core/OperatorEquals.h b/Eigen/src/Core/OperatorEquals.h
index a6165c912..0bed89b7e 100644
--- a/Eigen/src/Core/OperatorEquals.h
+++ b/Eigen/src/Core/OperatorEquals.h
@@ -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
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h
index 93c064322..21a4dd6f9 100644
--- a/Eigen/src/Core/Product.h
+++ b/Eigen/src/Core/Product.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)
{
diff --git a/Eigen/src/Core/Temporary.h b/Eigen/src/Core/Temporary.h
new file mode 100644
index 000000000..981a0c218
--- /dev/null
+++ b/Eigen/src/Core/Temporary.h
@@ -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
diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h
index 3eb5d1f71..f2e547225 100644
--- a/Eigen/src/Core/Transpose.h
+++ b/Eigen/src/Core/Transpose.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
diff --git a/Eigen/src/Core/Util.h b/Eigen/src/Core/Util.h
index 132c0ced8..6ac93b05d 100644
--- a/Eigen/src/Core/Util.h
+++ b/Eigen/src/Core/Util.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 };
diff --git a/test/linearstructure.cpp b/test/linearstructure.cpp
index 475c6325d..6e1364ec4 100644
--- a/test/linearstructure.cpp
+++ b/test/linearstructure.cpp
@@ -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)));
diff --git a/test/product.cpp b/test/product.cpp
index 668c8ca56..ba0c55da6 100644
--- a/test/product.cpp
+++ b/test/product.cpp
@@ -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