mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-16 14:49:39 +08:00
bug #1630: fix linspaced when requesting smaller packet size than default one.
This commit is contained in:
parent
80f1651f35
commit
48fe78c375
@ -239,7 +239,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomA
|
||||
DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,PacketScalar>(low,high,size));
|
||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar>(low,high,size));
|
||||
}
|
||||
|
||||
/** \deprecated because of accuracy loss. In Eigen 3.3, it is an alias for LinSpaced(const Scalar&,const Scalar&)
|
||||
@ -252,7 +252,7 @@ DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& hig
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,PacketScalar>(low,high,Derived::SizeAtCompileTime));
|
||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar>(low,high,Derived::SizeAtCompileTime));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -283,7 +283,7 @@ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomA
|
||||
DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar,PacketScalar>(low,high,size));
|
||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar>(low,high,size));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -296,7 +296,7 @@ DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar,PacketScalar>(low,high,Derived::SizeAtCompileTime));
|
||||
return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, internal::linspaced_op<Scalar>(low,high,Derived::SizeAtCompileTime));
|
||||
}
|
||||
|
||||
/** \returns true if all coefficients in this matrix are approximately equal to \a val, to within precision \a prec */
|
||||
@ -398,7 +398,7 @@ template<typename Derived>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index newSize, const Scalar& low, const Scalar& high)
|
||||
{
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar,PacketScalar>(low,high,newSize));
|
||||
return derived() = Derived::NullaryExpr(newSize, internal::linspaced_op<Scalar>(low,high,newSize));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -266,9 +266,9 @@ template<typename Derived> class DenseBase
|
||||
/** \internal Represents a matrix with all coefficients equal to one another*/
|
||||
typedef CwiseNullaryOp<internal::scalar_constant_op<Scalar>,PlainObject> ConstantReturnType;
|
||||
/** \internal \deprecated Represents a vector with linearly spaced coefficients that allows sequential access only. */
|
||||
typedef CwiseNullaryOp<internal::linspaced_op<Scalar,PacketScalar>,PlainObject> SequentialLinSpacedReturnType;
|
||||
typedef CwiseNullaryOp<internal::linspaced_op<Scalar>,PlainObject> SequentialLinSpacedReturnType;
|
||||
/** \internal Represents a vector with linearly spaced coefficients that allows random access. */
|
||||
typedef CwiseNullaryOp<internal::linspaced_op<Scalar,PacketScalar>,PlainObject> RandomAccessLinSpacedReturnType;
|
||||
typedef CwiseNullaryOp<internal::linspaced_op<Scalar>,PlainObject> RandomAccessLinSpacedReturnType;
|
||||
/** \internal the return type of MatrixBase::eigenvalues() */
|
||||
typedef Matrix<typename NumTraits<typename internal::traits<Derived>::Scalar>::Real, internal::traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
|
||||
|
||||
|
@ -37,10 +37,10 @@ template<typename Scalar>
|
||||
struct functor_traits<scalar_identity_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
|
||||
|
||||
template <typename Scalar, typename Packet, bool IsInteger> struct linspaced_op_impl;
|
||||
template <typename Scalar, bool IsInteger> struct linspaced_op_impl;
|
||||
|
||||
template <typename Scalar, typename Packet>
|
||||
struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
|
||||
template <typename Scalar>
|
||||
struct linspaced_op_impl<Scalar,/*IsInteger*/false>
|
||||
{
|
||||
linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
|
||||
m_low(low), m_high(high), m_size1(num_steps==1 ? 1 : num_steps-1), m_step(num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1)),
|
||||
@ -56,7 +56,7 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
|
||||
return (i==m_size1)? m_high : (m_low + RealScalar(i)*m_step);
|
||||
}
|
||||
|
||||
template<typename IndexType>
|
||||
template<typename Packet, typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const
|
||||
{
|
||||
// Principle:
|
||||
@ -86,8 +86,8 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/false>
|
||||
const bool m_flip;
|
||||
};
|
||||
|
||||
template <typename Scalar, typename Packet>
|
||||
struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/true>
|
||||
template <typename Scalar>
|
||||
struct linspaced_op_impl<Scalar,/*IsInteger*/true>
|
||||
{
|
||||
linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
|
||||
m_low(low),
|
||||
@ -115,8 +115,8 @@ struct linspaced_op_impl<Scalar,Packet,/*IsInteger*/true>
|
||||
// Forward declaration (we default to random access which does not really give
|
||||
// us a speed gain when using packet access but it allows to use the functor in
|
||||
// nested expressions).
|
||||
template <typename Scalar, typename PacketType> struct linspaced_op;
|
||||
template <typename Scalar, typename PacketType> struct functor_traits< linspaced_op<Scalar,PacketType> >
|
||||
template <typename Scalar> struct linspaced_op;
|
||||
template <typename Scalar> struct functor_traits< linspaced_op<Scalar> >
|
||||
{
|
||||
enum
|
||||
{
|
||||
@ -126,7 +126,7 @@ template <typename Scalar, typename PacketType> struct functor_traits< linspaced
|
||||
IsRepeatable = true
|
||||
};
|
||||
};
|
||||
template <typename Scalar, typename PacketType> struct linspaced_op
|
||||
template <typename Scalar> struct linspaced_op
|
||||
{
|
||||
linspaced_op(const Scalar& low, const Scalar& high, Index num_steps)
|
||||
: impl((num_steps==1 ? high : low),high,num_steps)
|
||||
@ -136,11 +136,11 @@ template <typename Scalar, typename PacketType> struct linspaced_op
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const { return impl(i); }
|
||||
|
||||
template<typename Packet,typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const { return impl.packetOp(i); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const { return impl.template packetOp<Packet>(i); }
|
||||
|
||||
// This proxy object handles the actual required temporaries and the different
|
||||
// implementations (integer vs. floating point).
|
||||
const linspaced_op_impl<Scalar,PacketType,NumTraits<Scalar>::IsInteger> impl;
|
||||
const linspaced_op_impl<Scalar,NumTraits<Scalar>::IsInteger> impl;
|
||||
};
|
||||
|
||||
// Linear access is automatically determined from the operator() prototypes available for the given functor.
|
||||
@ -166,12 +166,12 @@ struct has_unary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value =
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_binary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 1}; };
|
||||
|
||||
template<typename Scalar, typename PacketType,typename IndexType>
|
||||
struct has_nullary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 0}; };
|
||||
template<typename Scalar, typename PacketType,typename IndexType>
|
||||
struct has_unary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 1}; };
|
||||
template<typename Scalar, typename PacketType,typename IndexType>
|
||||
struct has_binary_operator<linspaced_op<Scalar,PacketType>,IndexType> { enum { value = 0}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_nullary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_unary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 1}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_binary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_nullary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 1}; };
|
||||
|
@ -246,6 +246,14 @@ void bug79()
|
||||
VERIFY( (MatrixXd(RowVectorXd::LinSpaced(3, 0, 1)) - RowVector3d(0, 0.5, 1)).norm() < std::numeric_limits<double>::epsilon() );
|
||||
}
|
||||
|
||||
template<int>
|
||||
void bug1630()
|
||||
{
|
||||
Array4d x4 = Array4d::LinSpaced(0.0, 1.0);
|
||||
Array3d x3(Array4d::LinSpaced(0.0, 1.0).head(3));
|
||||
VERIFY_IS_APPROX(x4.head(3), x3);
|
||||
}
|
||||
|
||||
template<int>
|
||||
void nullary_overflow()
|
||||
{
|
||||
@ -272,10 +280,10 @@ void nullary_internal_logic()
|
||||
VERIFY(( internal::has_binary_operator<internal::scalar_identity_op<double> >::value ));
|
||||
VERIFY(( !internal::functor_has_linear_access<internal::scalar_identity_op<double> >::ret ));
|
||||
|
||||
VERIFY(( !internal::has_nullary_operator<internal::linspaced_op<float,float> >::value ));
|
||||
VERIFY(( internal::has_unary_operator<internal::linspaced_op<float,float> >::value ));
|
||||
VERIFY(( !internal::has_binary_operator<internal::linspaced_op<float,float> >::value ));
|
||||
VERIFY(( internal::functor_has_linear_access<internal::linspaced_op<float,float> >::ret ));
|
||||
VERIFY(( !internal::has_nullary_operator<internal::linspaced_op<float> >::value ));
|
||||
VERIFY(( internal::has_unary_operator<internal::linspaced_op<float> >::value ));
|
||||
VERIFY(( !internal::has_binary_operator<internal::linspaced_op<float> >::value ));
|
||||
VERIFY(( internal::functor_has_linear_access<internal::linspaced_op<float> >::ret ));
|
||||
|
||||
// Regression unit test for a weird MSVC bug.
|
||||
// Search "nullary_wrapper_workaround_msvc" in CoreEvaluators.h for the details.
|
||||
@ -296,10 +304,10 @@ void nullary_internal_logic()
|
||||
VERIFY(( !internal::has_binary_operator<internal::scalar_constant_op<float> >::value ));
|
||||
VERIFY(( internal::functor_has_linear_access<internal::scalar_constant_op<float> >::ret ));
|
||||
|
||||
VERIFY(( !internal::has_nullary_operator<internal::linspaced_op<int,int> >::value ));
|
||||
VERIFY(( internal::has_unary_operator<internal::linspaced_op<int,int> >::value ));
|
||||
VERIFY(( !internal::has_binary_operator<internal::linspaced_op<int,int> >::value ));
|
||||
VERIFY(( internal::functor_has_linear_access<internal::linspaced_op<int,int> >::ret ));
|
||||
VERIFY(( !internal::has_nullary_operator<internal::linspaced_op<int> >::value ));
|
||||
VERIFY(( internal::has_unary_operator<internal::linspaced_op<int> >::value ));
|
||||
VERIFY(( !internal::has_binary_operator<internal::linspaced_op<int> >::value ));
|
||||
VERIFY(( internal::functor_has_linear_access<internal::linspaced_op<int> >::ret ));
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,6 +333,7 @@ EIGEN_DECLARE_TEST(nullary)
|
||||
}
|
||||
|
||||
CALL_SUBTEST_6( bug79<0>() );
|
||||
CALL_SUBTEST_6( bug1630<0>() );
|
||||
CALL_SUBTEST_9( nullary_overflow<0>() );
|
||||
CALL_SUBTEST_10( nullary_internal_logic<0>() );
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user