From 34d93686db8f2df73b9bd7398ba841b11fbc3a7f Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Thu, 20 Jan 2011 10:36:32 -0500 Subject: [PATCH] lots more EIGEN2_SUPPORT fixes. Now several of the most important core tests build and succeed. --- Eigen/Eigen2Support | 1 + Eigen/src/Core/Flagged.h | 23 +++++++--- Eigen/src/Core/Functors.h | 19 +++++++-- Eigen/src/Core/NumTraits.h | 13 +++--- Eigen/src/Core/ProductBase.h | 4 ++ Eigen/src/Core/util/StaticAssert.h | 10 ++++- Eigen/src/Eigen2Support/Macros.h | 9 +--- Eigen/src/Eigen2Support/MathFunctions.h | 7 +++- Eigen/src/Eigen2Support/Memory.h | 56 +++++++++++++++++++++++++ test/eigen2/array.cpp | 6 +-- test/eigen2/main.h | 31 +++++++------- test/eigen2/sizeof.cpp | 2 +- 12 files changed, 134 insertions(+), 47 deletions(-) create mode 100644 Eigen/src/Eigen2Support/Memory.h diff --git a/Eigen/Eigen2Support b/Eigen/Eigen2Support index 37c2f163d..9cfa9c0a2 100644 --- a/Eigen/Eigen2Support +++ b/Eigen/Eigen2Support @@ -44,6 +44,7 @@ namespace Eigen { */ #include "src/Eigen2Support/Macros.h" +#include "src/Eigen2Support/Memory.h" #include "src/Eigen2Support/Meta.h" #include "src/Eigen2Support/Lazy.h" #include "src/Eigen2Support/Cwise.h" diff --git a/Eigen/src/Core/Flagged.h b/Eigen/src/Core/Flagged.h index 208f51afb..458213ab5 100644 --- a/Eigen/src/Core/Flagged.h +++ b/Eigen/src/Core/Flagged.h @@ -55,6 +55,7 @@ template clas public: typedef MatrixBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Flagged) typedef typename internal::conditional::ret, ExpressionType, const ExpressionType&>::type ExpressionTypeNested; @@ -67,21 +68,31 @@ template clas inline Index outerStride() const { return m_matrix.outerStride(); } inline Index innerStride() const { return m_matrix.innerStride(); } - inline const Scalar coeff(Index row, Index col) const + inline CoeffReturnType coeff(Index row, Index col) const { return m_matrix.coeff(row, col); } + inline CoeffReturnType coeff(Index index) const + { + return m_matrix.coeff(index); + } + + inline const Scalar& coeffRef(Index row, Index col) const + { + return m_matrix.const_cast_derived().coeffRef(row, col); + } + + inline const Scalar& coeffRef(Index index) const + { + return m_matrix.const_cast_derived().coeffRef(index); + } + inline Scalar& coeffRef(Index row, Index col) { return m_matrix.const_cast_derived().coeffRef(row, col); } - inline const Scalar coeff(Index index) const - { - return m_matrix.coeff(index); - } - inline Scalar& coeffRef(Index index) { return m_matrix.const_cast_derived().coeffRef(index); diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index 69f17fb73..40c42d6e4 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -82,16 +82,27 @@ struct functor_traits > { /** \internal * \brief Template functor to compute the conjugate product of two scalars * - * This is a short cut for conj(x) * y which is needed for optimization purpose + * This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y) */ template struct scalar_conj_product_op { - enum { Conj = NumTraits::IsComplex }; + + enum { + Conj = NumTraits::IsComplex, + #ifdef EIGEN2_SUPPORT // in Eigen2, dot product is linear in the first variable + LhsConj = false, + RhsConj = Conj + #else // in Eigen3, dot product is linear in the second variable + LhsConj = Conj, + RhsConj = false + #endif + }; + EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const - { return conj_helper().pmul(a,b); } + { return conj_helper().pmul(a,b); } template EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const - { return conj_helper().pmul(a,b); } + { return conj_helper().pmul(a,b); } }; template struct functor_traits > { diff --git a/Eigen/src/Core/NumTraits.h b/Eigen/src/Core/NumTraits.h index 7f7af9af2..13dae85a4 100644 --- a/Eigen/src/Core/NumTraits.h +++ b/Eigen/src/Core/NumTraits.h @@ -69,12 +69,6 @@ template struct GenericNumTraits AddCost = 1, MulCost = 1 }; - -#ifdef EIGEN2_SUPPORT - enum { - HasFloatingPoint = !IsInteger - }; -#endif typedef T Real; typedef typename internal::conditional< @@ -92,6 +86,13 @@ template struct GenericNumTraits } inline static T highest() { return std::numeric_limits::max(); } inline static T lowest() { return IsInteger ? std::numeric_limits::min() : (-std::numeric_limits::max()); } + +#ifdef EIGEN2_SUPPORT + enum { + HasFloatingPoint = !IsInteger + }; + typedef NonInteger FloatingPoint; +#endif }; template struct NumTraits : GenericNumTraits diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h index f4272e56f..1f2b373cd 100644 --- a/Eigen/src/Core/ProductBase.h +++ b/Eigen/src/Core/ProductBase.h @@ -145,9 +145,13 @@ class ProductBase : public MatrixBase // restrict coeff accessors to 1x1 expressions. No need to care about mutators here since this isnt a Lvalue expression typename Base::CoeffReturnType coeff(Index row, Index col) const { +#ifdef EIGEN2_SUPPORT + return lhs().row(row).cwiseProduct(rhs().col(col).transpose()).sum(); +#else EIGEN_STATIC_ASSERT_SIZE_1x1(Derived) eigen_assert(this->rows() == 1 && this->cols() == 1); return derived().coeff(row,col); +#endif } typename Base::CoeffReturnType coeff(Index i) const diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h index d72a182e5..5f9bd1339 100644 --- a/Eigen/src/Core/util/StaticAssert.h +++ b/Eigen/src/Core/util/StaticAssert.h @@ -171,8 +171,14 @@ ) \ ) -#define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE) \ - EIGEN_STATIC_ASSERT(!NumTraits::IsInteger, THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES) +#ifdef EIGEN2_SUPPORT + #define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE) \ + eigen_assert(!NumTraits::IsInteger); +#else + #define EIGEN_STATIC_ASSERT_NON_INTEGER(TYPE) \ + EIGEN_STATIC_ASSERT(!NumTraits::IsInteger, THIS_FUNCTION_IS_NOT_FOR_INTEGER_NUMERIC_TYPES) +#endif + // static assertion failing if it is guaranteed at compile-time that the two matrix expression types have different sizes #define EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) \ diff --git a/Eigen/src/Eigen2Support/Macros.h b/Eigen/src/Eigen2Support/Macros.h index 0f812a3dc..be11357a1 100644 --- a/Eigen/src/Eigen2Support/Macros.h +++ b/Eigen/src/Eigen2Support/Macros.h @@ -25,13 +25,8 @@ #ifndef EIGEN2_MACROS_H #define EIGEN2_MACROS_H -#ifndef ei_assert - #define ei_assert eigen_assert -#endif - -#ifndef ei_internal_assert - #define ei_internal_assert eigen_internal_assert -#endif +#define ei_assert eigen_assert +#define ei_internal_assert eigen_internal_assert #define EIGEN_ALIGN_128 EIGEN_ALIGN16 diff --git a/Eigen/src/Eigen2Support/MathFunctions.h b/Eigen/src/Eigen2Support/MathFunctions.h index fdcfc01bb..b180685e9 100644 --- a/Eigen/src/Eigen2Support/MathFunctions.h +++ b/Eigen/src/Eigen2Support/MathFunctions.h @@ -40,6 +40,9 @@ template inline T ei_pow (const T& x,const T& y) { return internal:: template inline T ei_random () { return internal::random(); } template inline T ei_random (const T& x, const T& y) { return internal::random(x, y); } +template inline T precision () { return NumTraits::dummy_precision(); } + + template inline bool ei_isMuchSmallerThan(const Scalar& x, const OtherScalar& y, typename NumTraits::Real precision = NumTraits::dummy_precision()) @@ -51,14 +54,14 @@ template inline bool ei_isApprox(const Scalar& x, const Scalar& y, typename NumTraits::Real precision = NumTraits::dummy_precision()) { - return internal::isMuchSmallerThan(x, y, precision); + return internal::isApprox(x, y, precision); } template inline bool ei_isApproxOrLessThan(const Scalar& x, const Scalar& y, typename NumTraits::Real precision = NumTraits::dummy_precision()) { - return internal::isMuchSmallerThan(x, y, precision); + return internal::isApproxOrLessThan(x, y, precision); } #endif // EIGEN2_MATH_FUNCTIONS_H diff --git a/Eigen/src/Eigen2Support/Memory.h b/Eigen/src/Eigen2Support/Memory.h new file mode 100644 index 000000000..aba9a16e7 --- /dev/null +++ b/Eigen/src/Eigen2Support/Memory.h @@ -0,0 +1,56 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 Benoit Jacob +// +// 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 . + +#ifndef EIGEN2_MEMORY_H +#define EIGEN2_MEMORY_H + +inline void* ei_aligned_malloc(size_t size) { return internal::aligned_malloc(size); } +inline void ei_aligned_free(void *ptr) { internal::aligned_free(ptr); } +inline void* ei_aligned_realloc(void *ptr, size_t new_size, size_t old_size) { return internal::aligned_realloc(ptr, new_size, old_size); } + +template inline void* ei_conditional_aligned_malloc(size_t size) +{ + return internal::conditional_aligned_malloc(size); +} +template inline void ei_conditional_aligned_free(void *ptr) +{ + internal::conditional_aligned_free(ptr); +} +template inline void* ei_conditional_aligned_realloc(void* ptr, size_t new_size, size_t old_size) +{ + return internal::conditional_aligned_realloc(ptr, new_size, old_size); +} + +template inline T* ei_aligned_new(size_t size) +{ + return internal::aligned_new(size); +} +template inline void ei_aligned_delete(T *ptr, size_t size) +{ + return internal::aligned_delete(ptr, size); +} + + + +#endif // EIGEN2_MACROS_H diff --git a/test/eigen2/array.cpp b/test/eigen2/array.cpp index 8b4652561..2ea5ebd65 100644 --- a/test/eigen2/array.cpp +++ b/test/eigen2/array.cpp @@ -61,7 +61,7 @@ template void array(const MatrixType& m) VERIFY_IS_APPROX(m1.rowwise().sum().sum(), m1.sum()); if (!ei_isApprox(m1.sum(), (m1+m2).sum())) VERIFY_IS_NOT_APPROX(((m1+m2).rowwise().sum()).sum(), m1.sum()); - VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(ei_scalar_sum_op())); + VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op())); } template void comparisons(const MatrixType& m) @@ -115,8 +115,8 @@ template void comparisons(const MatrixType& m) // count VERIFY(((m1.cwise().abs().cwise()+1).cwise()>RealScalar(0.1)).count() == rows*cols); - VERIFY_IS_APPROX(((m1.cwise().abs().cwise()+1).cwise()>RealScalar(0.1)).colwise().count(), RowVectorXi::Constant(cols,rows)); - VERIFY_IS_APPROX(((m1.cwise().abs().cwise()+1).cwise()>RealScalar(0.1)).rowwise().count(), VectorXi::Constant(rows, cols)); + VERIFY_IS_APPROX(((m1.cwise().abs().cwise()+1).cwise()>RealScalar(0.1)).colwise().count().template cast(), RowVectorXi::Constant(cols,rows)); + VERIFY_IS_APPROX(((m1.cwise().abs().cwise()+1).cwise()>RealScalar(0.1)).rowwise().count().template cast(), VectorXi::Constant(rows, cols)); } template void lpNorm(const VectorType& v) diff --git a/test/eigen2/main.h b/test/eigen2/main.h index 65d56377a..e144a28b1 100644 --- a/test/eigen2/main.h +++ b/test/eigen2/main.h @@ -58,10 +58,10 @@ namespace Eigen // This may happen when a second exceptions is raise in a destructor. static bool no_more_assert = false; - struct ei_assert_exception + struct eigen_assert_exception { - ei_assert_exception(void) {} - ~ei_assert_exception() { Eigen::no_more_assert = false; } + eigen_assert_exception(void) {} + ~eigen_assert_exception() { Eigen::no_more_assert = false; } }; } @@ -77,51 +77,50 @@ namespace Eigen namespace Eigen { static bool ei_push_assert = false; - static std::vector ei_assert_list; + static std::vector eigen_assert_list; } - #define ei_assert(a) \ + #define eigen_assert(a) \ if( (!(a)) && (!no_more_assert) ) \ { \ Eigen::no_more_assert = true; \ - throw Eigen::ei_assert_exception(); \ + throw Eigen::eigen_assert_exception(); \ } \ else if (Eigen::ei_push_assert) \ { \ - ei_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__)" ("EI_PP_MAKE_STRING(__LINE__)") : "#a) ); \ + eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__)" ("EI_PP_MAKE_STRING(__LINE__)") : "#a) ); \ } #define VERIFY_RAISES_ASSERT(a) \ { \ Eigen::no_more_assert = false; \ try { \ - Eigen::ei_assert_list.clear(); \ + Eigen::eigen_assert_list.clear(); \ Eigen::ei_push_assert = true; \ a; \ Eigen::ei_push_assert = false; \ std::cerr << "One of the following asserts should have been raised:\n"; \ - for (uint ai=0 ; ai void verifySizeOf(const MatrixType&) if (MatrixType::RowsAtCompileTime!=Dynamic && MatrixType::ColsAtCompileTime!=Dynamic) VERIFY(sizeof(MatrixType)==sizeof(Scalar)*MatrixType::SizeAtCompileTime); else - VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(int)); + VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(typename MatrixType::Index)); } void test_sizeof()