Bugzilla – Attachment 493 Details for
Bug 100
Finalize the array-as-scalar feature
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Forgot Password
Login:
[x]
This bugzilla service is closed. All entries have been migrated to
https://gitlab.com/libeigen/eigen
[patch]
Add Array*::operator=(Scalar), and explicit Array(scalar)
bug100_scalar2array.diff (text/plain), 10.92 KB, created by
Gael Guennebaud
on 2014-09-11 15:04:39 UTC
(
hide
)
Description:
Add Array*::operator=(Scalar), and explicit Array(scalar)
Filename:
MIME Type:
Creator:
Gael Guennebaud
Created:
2014-09-11 15:04:39 UTC
Size:
10.92 KB
patch
obsolete
>diff --git a/Eigen/src/Core/Array.h b/Eigen/src/Core/Array.h >--- a/Eigen/src/Core/Array.h >+++ b/Eigen/src/Core/Array.h >@@ -69,16 +69,31 @@ class Array > * the usage of 'using'. This should be done only for operator=. > */ > template<typename OtherDerived> > EIGEN_DEVICE_FUNC > EIGEN_STRONG_INLINE Array& operator=(const EigenBase<OtherDerived> &other) > { > return Base::operator=(other); > } >+ >+ /** Set all the entries to \a value. >+ * \sa DenseBase::setConstant(), DenseBase::fill() >+ */ >+ /* This overload is needed because the usage of >+ * using Base::operator=; >+ * fails on MSVC. Since the code below is working with GCC and MSVC, we skipped >+ * the usage of 'using'. This should be done only for operator=. >+ */ >+ EIGEN_DEVICE_FUNC >+ EIGEN_STRONG_INLINE Array& operator=(const Scalar &value) >+ { >+ Base::setConstant(value); >+ return *this; >+ } > > /** Copies the value of the expression \a other into \c *this with automatic resizing. > * > * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), > * it will be initialized. > * > * Note that copying a row-vector into a vector (and conversely) is allowed. > * The resizing, if any, is then done in the appropriate way so that row-vectors >@@ -94,17 +109,17 @@ class Array > /** This is a special case of the templated operator=. Its purpose is to > * prevent a default operator= from hiding the templated operator=. > */ > EIGEN_DEVICE_FUNC > EIGEN_STRONG_INLINE Array& operator=(const Array& other) > { > return Base::_set(other); > } >- >+ > /** Default constructor. > * > * For fixed-size matrices, does nothing. > * > * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix > * is called a null matrix. This constructor is the unique way to create null matrices: resizing > * a matrix to 0 is not supported. > * >@@ -139,17 +154,16 @@ class Array > } > Array& operator=(Array&& other) > { > other.swap(*this); > return *this; > } > #endif > >- > #ifndef EIGEN_PARSED_BY_DOXYGEN > template<typename T> > EIGEN_DEVICE_FUNC > EIGEN_STRONG_INLINE explicit Array(const T& x) > { > Base::_check_template_params(); > Base::template _init1<T>(x); > } >diff --git a/Eigen/src/Core/ArrayBase.h b/Eigen/src/Core/ArrayBase.h >--- a/Eigen/src/Core/ArrayBase.h >+++ b/Eigen/src/Core/ArrayBase.h >@@ -118,16 +118,22 @@ template<typename Derived> class ArrayBa > /** Special case of the template operator=, in order to prevent the compiler > * from generating a default operator= (issue hit with g++ 4.1) > */ > EIGEN_DEVICE_FUNC > Derived& operator=(const ArrayBase& other) > { > return internal::assign_selector<Derived,Derived>::run(derived(), other.derived()); > } >+ >+ /** Set all the entries to \a value. >+ * \sa DenseBase::setConstant(), DenseBase::fill() */ >+ EIGEN_DEVICE_FUNC >+ Derived& operator=(const Scalar &value) >+ { Base::setConstant(value); return derived(); } > > EIGEN_DEVICE_FUNC > Derived& operator+=(const Scalar& scalar); > EIGEN_DEVICE_FUNC > Derived& operator-=(const Scalar& scalar); > > template<typename OtherDerived> > EIGEN_DEVICE_FUNC >diff --git a/Eigen/src/Core/PlainObjectBase.h b/Eigen/src/Core/PlainObjectBase.h >--- a/Eigen/src/Core/PlainObjectBase.h >+++ b/Eigen/src/Core/PlainObjectBase.h >@@ -699,58 +699,67 @@ class PlainObjectBase : public internal: > && (internal::is_same<T1,Index>::value) > && Base::SizeAtCompileTime==2,T1>::type* = 0) > { > EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 2) > m_storage.data()[0] = Scalar(val0); > m_storage.data()[1] = Scalar(val1); > } > >+ // The argument is convertible to the Index type and we either have a non 1x1 Matrix, or a dynamic-sized Array, >+ // then the argument is meant to be the size of the object. > template<typename T> > EIGEN_DEVICE_FUNC >- EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if<Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value,T>::type* = 0) >+ EIGEN_STRONG_INLINE void _init1(Index size, typename internal::enable_if< (Base::SizeAtCompileTime!=1 || !internal::is_convertible<T, Scalar>::value) >+ && ((!internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value || Base::SizeAtCompileTime==Dynamic)),T>::type* = 0) > { > // NOTE MSVC 2008 complains if we directly put bool(NumTraits<T>::IsInteger) as the EIGEN_STATIC_ASSERT argument. > const bool is_integer = NumTraits<T>::IsInteger; > EIGEN_STATIC_ASSERT(is_integer, > FLOATING_POINT_ARGUMENT_PASSED__INTEGER_WAS_EXPECTED) > resize(size); > } >+ >+ // We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type can be implicitely converted) > template<typename T> > EIGEN_DEVICE_FUNC > EIGEN_STRONG_INLINE void _init1(const Scalar& val0, typename internal::enable_if<Base::SizeAtCompileTime==1 && internal::is_convertible<T, Scalar>::value,T>::type* = 0) > { > EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1) > m_storage.data()[0] = val0; > } > >+ // We have a 1x1 matrix/array => the argument is interpreted as the value of the unique coefficient (case where scalar type match the index type) > template<typename T> > EIGEN_DEVICE_FUNC > EIGEN_STRONG_INLINE void _init1(const Index& val0, > typename internal::enable_if< (!internal::is_same<Index,Scalar>::value) > && (internal::is_same<Index,T>::value) > && Base::SizeAtCompileTime==1 > && internal::is_convertible<T, Scalar>::value,T*>::type* = 0) > { > EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(PlainObjectBase, 1) > m_storage.data()[0] = Scalar(val0); > } > >+ // Initialize a fixed size matrix from a pointer to raw data > template<typename T> > EIGEN_DEVICE_FUNC > EIGEN_STRONG_INLINE void _init1(const Scalar* data){ > this->_set_noalias(ConstMapType(data)); > } > >+ // Initialize an arbitrary matrix from a dense expression > template<typename T, typename OtherDerived> > EIGEN_DEVICE_FUNC > EIGEN_STRONG_INLINE void _init1(const DenseBase<OtherDerived>& other){ > this->_set_noalias(other); > } > >+ // Initialize an arbitrary matrix from a generic Eigen expression > template<typename T, typename OtherDerived> > EIGEN_DEVICE_FUNC > EIGEN_STRONG_INLINE void _init1(const EigenBase<OtherDerived>& other){ > this->derived() = other; > } > > template<typename T, typename OtherDerived> > EIGEN_DEVICE_FUNC >@@ -761,16 +770,41 @@ class PlainObjectBase : public internal: > } > > template<typename T, typename OtherDerived, int ColsAtCompileTime> > EIGEN_DEVICE_FUNC > EIGEN_STRONG_INLINE void _init1(const RotationBase<OtherDerived,ColsAtCompileTime>& r) > { > this->derived() = r; > } >+ >+ // For fixed -size arrays: >+ template<typename T> >+ EIGEN_DEVICE_FUNC >+ EIGEN_STRONG_INLINE void _init1(const Scalar& val0, >+ typename internal::enable_if< Base::SizeAtCompileTime!=Dynamic >+ && Base::SizeAtCompileTime!=1 >+ && internal::is_convertible<T, Scalar>::value >+ && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T>::type* = 0) >+ { >+ Base::setConstant(val0); >+ } >+ >+ template<typename T> >+ EIGEN_DEVICE_FUNC >+ EIGEN_STRONG_INLINE void _init1(const Index& val0, >+ typename internal::enable_if< (!internal::is_same<Index,Scalar>::value) >+ && (internal::is_same<Index,T>::value) >+ && Base::SizeAtCompileTime!=Dynamic >+ && Base::SizeAtCompileTime!=1 >+ && internal::is_convertible<T, Scalar>::value >+ && internal::is_same<typename internal::traits<Derived>::XprKind,ArrayXpr>::value,T*>::type* = 0) >+ { >+ Base::setConstant(val0); >+ } > > template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> > friend struct internal::matrix_swap_impl; > > /** \internal generic implementation of swap for dense storage since for dynamic-sized matrices of same type it is enough to swap the > * data pointers. > */ > template<typename OtherDerived> >diff --git a/test/array.cpp b/test/array.cpp >--- a/test/array.cpp >+++ b/test/array.cpp >@@ -76,16 +76,38 @@ template<typename ArrayType> void array( > m3 = m1; > VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1); > m3 = m1; > VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1); > m3 = m1; > VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1); > m3 = m1; > VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1); >+ >+ // Conversion from scalar >+ VERIFY_IS_APPROX((m3 = s1), ArrayType::Constant(rows,cols,s1)); >+ VERIFY_IS_APPROX((m3 = 1), ArrayType::Constant(rows,cols,1)); >+ VERIFY_IS_APPROX((m3.topLeftCorner(rows,cols) = 1), ArrayType::Constant(rows,cols,1)); >+ typedef Array<Scalar, >+ ArrayType::RowsAtCompileTime==Dynamic?2:ArrayType::RowsAtCompileTime, >+ ArrayType::ColsAtCompileTime==Dynamic?2:ArrayType::ColsAtCompileTime, >+ ArrayType::Options> FixedArrayType; >+ FixedArrayType f1(s1); >+ VERIFY_IS_APPROX(f1, FixedArrayType::Constant(s1)); >+ FixedArrayType f2(numext::real(s1)); >+ VERIFY_IS_APPROX(f2, FixedArrayType::Constant(numext::real(s1))); >+ FixedArrayType f3((int)100*numext::real(s1)); >+ VERIFY_IS_APPROX(f3, FixedArrayType::Constant((int)100*numext::real(s1))); >+ >+ // Check possible conflicts with 1D ctor >+ typedef Array<Scalar, Dynamic, 1> OneDArrayType; >+ OneDArrayType o1(rows); >+ VERIFY(o1.size()==rows); >+ OneDArrayType o4((int)rows); >+ VERIFY(o4.size()==rows); > } > > template<typename ArrayType> void comparisons(const ArrayType& m) > { > using std::abs; > typedef typename ArrayType::Index Index; > typedef typename ArrayType::Scalar Scalar; > typedef typename NumTraits<Scalar>::Real RealScalar;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 100
: 493