# HG changeset patch # User John Roll # Date 1326491864 18000 # Node ID bc56faaa696204f26feaad39a8a977709a353050 # Parent a71fd8e2744ca8e0750e261af19a245b847426e3 Array bit operators. diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -964,11 +964,51 @@ struct functor_traits \ +struct NAME { \ + typedef typename packet_traits::type Packet; \ + inline NAME(const NAME& other) : m_other(other.m_other) { } \ + inline NAME(const Scalar& other) : m_other(other) { } \ + inline Scalar operator() (const Scalar& a) const { return a OP m_other; } \ + const Scalar m_other; \ +}; \ +template \ +struct functor_traits > \ +{ enum { Cost = NumTraits::AddCost, PacketAccess = false }; }; + +EIGEN_MAKE_SCALAR_CWISE_UNARY_FUNCTOR(^ , scalar_bitxor_op) +EIGEN_MAKE_SCALAR_CWISE_UNARY_FUNCTOR(& , scalar_bitand_op) +EIGEN_MAKE_SCALAR_CWISE_UNARY_FUNCTOR(| , scalar_bitor_op) + +#ifdef EIGEN_INCLUDE_ARRAY_BIT_SHIFT + EIGEN_MAKE_SCALAR_CWISE_UNARY_FUNCTOR(>>, scalar_bitshr_op) + EIGEN_MAKE_SCALAR_CWISE_UNARY_FUNCTOR(<<, scalar_bitshl_op) +#endif + +#define EIGEN_MAKE_SCALAR_CWISE_BINARY_FUNCTOR(OP, NAME) \ +template \ +struct NAME { \ + EIGEN_EMPTY_STRUCT_CTOR(NAME) \ + EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a, const Scalar& b) const { return a OP b; } \ +}; \ +template \ +struct functor_traits > { enum { Cost = NumTraits >::AddCost, PacketAccess = false }; }; + +EIGEN_MAKE_SCALAR_CWISE_BINARY_FUNCTOR(|, scalar_bitor_binary_op) +EIGEN_MAKE_SCALAR_CWISE_BINARY_FUNCTOR(&, scalar_bitand_binary_op) +EIGEN_MAKE_SCALAR_CWISE_BINARY_FUNCTOR(^, scalar_bitxor_binary_op) + +#ifdef EIGEN_INCLUDE_ARRAY_BIT_SHIFT + EIGEN_MAKE_SCALAR_CWISE_BINARY_FUNCTOR(>>, scalar_bitshr_binary_op) + EIGEN_MAKE_SCALAR_CWISE_BINARY_FUNCTOR(<<, scalar_bitshl_binary_op) +#endif + } // end namespace internal #endif // EIGEN_FUNCTORS_H diff --git a/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/Eigen/src/plugins/ArrayCwiseBinaryOps.h --- a/Eigen/src/plugins/ArrayCwiseBinaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseBinaryOps.h @@ -172,8 +172,24 @@ operator&&(const EIGEN_CURRENT_STORAGE_B template inline const CwiseBinaryOp operator||(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const { EIGEN_STATIC_ASSERT((internal::is_same::value && internal::is_same::value), THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL); return CwiseBinaryOp(derived(),other.derived()); } + +#define EIGEN_MAKE_SCALAR_CWISE_BINARY_BITOP(OP,FUNCTOR) \ +template \ + inline const CwiseBinaryOp, const Derived, const OtherDerived> \ + operator OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS &other) const \ + { return CwiseBinaryOp, const Derived, const OtherDerived>(derived(),other.derived()); } + +EIGEN_MAKE_SCALAR_CWISE_BINARY_BITOP(| , internal::scalar_bitor_binary_op) +EIGEN_MAKE_SCALAR_CWISE_BINARY_BITOP(& , internal::scalar_bitand_binary_op) +EIGEN_MAKE_SCALAR_CWISE_BINARY_BITOP(^ , internal::scalar_bitxor_binary_op) + +#ifdef EIGEN_INCLUDE_ARRAY_BIT_SHIFT + EIGEN_MAKE_SCALAR_CWISE_BINARY_BITOP(>>, internal::scalar_bitshr_binary_op) + EIGEN_MAKE_SCALAR_CWISE_BINARY_BITOP(<<, internal::scalar_bitshl_binary_op) +#endif + diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -195,8 +195,29 @@ cube() const EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator==, std::equal_to) EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator!=, std::not_equal_to) EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<, std::less) EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<=, std::less_equal) EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>, std::greater) EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>=, std::greater_equal) +#define EIGEN_MAKE_SCALAR_CWISE_UNARY_BITOP(OP,FUNCTOR) \ + inline const CwiseUnaryOp, const Derived> \ + operator OP(const Scalar& scalar) const { \ + return CwiseUnaryOp, const Derived>(derived(), FUNCTOR(scalar)); } + +#define EIGEN_MAKE_SCALAR_CWISE_UNARY_BITOP_COMMUTATIVE(OP,FUNCTOR) \ + EIGEN_MAKE_SCALAR_CWISE_UNARY_BITOP(OP,FUNCTOR) \ + friend inline const CwiseUnaryOp, const Derived> \ + operator OP(const Scalar& scalar,const EIGEN_CURRENT_STORAGE_BASE_CLASS& other)\ + { return other OP scalar; } + + +EIGEN_MAKE_SCALAR_CWISE_UNARY_BITOP_COMMUTATIVE(^, internal::scalar_bitxor_op) +EIGEN_MAKE_SCALAR_CWISE_UNARY_BITOP_COMMUTATIVE(&, internal::scalar_bitand_op) +EIGEN_MAKE_SCALAR_CWISE_UNARY_BITOP_COMMUTATIVE(|, internal::scalar_bitor_op) + +#ifdef EIGEN_INCLUDE_ARRAY_BIT_SHIFT + EIGEN_MAKE_SCALAR_CWISE_UNARY_BITOP(>>, internal::scalar_bitshr_op) + EIGEN_MAKE_SCALAR_CWISE_UNARY_BITOP(<<, internal::scalar_bitshl_op) +#endif + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -95,16 +95,17 @@ ei_add_test(adjoint) ei_add_test(diagonal) ei_add_test(miscmatrices) ei_add_test(commainitializer) ei_add_test(smallvectors) ei_add_test(map) ei_add_test(mapstride) ei_add_test(mapstaticmethods) ei_add_test(array) +ei_add_test(array_bit_ops) ei_add_test(array_for_matrix) ei_add_test(array_replicate) ei_add_test(array_reverse) ei_add_test(triangular) ei_add_test(selfadjoint) ei_add_test(product_selfadjoint) ei_add_test(product_symm) ei_add_test(product_syrk) diff --git a/test/array_bit_ops.cpp b/test/array_bit_ops.cpp new file mode 100644 --- /dev/null +++ b/test/array_bit_ops.cpp @@ -0,0 +1,87 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2011 John Roll +// +// 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 . + +#define EIGEN2_SUPPORT +#define EIGEN_NO_STATIC_ASSERT +#define EIGEN_INCLUDE_ARRAY_BIT_SHIFT +#include "main.h" +#include + +#include +using namespace std; + +#ifdef min +#undef min +#endif + +#ifdef max +#undef max +#endif + +template void array_bit_ops(ArrayType a) +{ + typename ArrayType::Scalar pow = 1; + typename ArrayType::Scalar one = 1; + + a.setConstant(1); + + for ( unsigned int i = 0; i < sizeof(typename ArrayType::Scalar)*8; i++ ) { + + /* The Lhs is generated with bit shifting native types and multiplication. + The Rhs is generated with the array bit operations. + */ + VERIFY(((a*((one<> i ) == a).all()); + VERIFY((((a*pow) >> (a*i)) == a).all()); + } + + pow *= 2; + } +} + +void test_array_bit_ops() +{ + for(int i = 0; i < g_repeat ; i++) { + CALL_SUBTEST_1( array_bit_ops(Array()) ); + CALL_SUBTEST_2( array_bit_ops(Array()) ); + CALL_SUBTEST_3( array_bit_ops(Array()) ); + CALL_SUBTEST_4( array_bit_ops(Array()) ); + CALL_SUBTEST_5( array_bit_ops(Array()) ); + } +}