mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 03:39:01 +08:00
Pulled latest updates from trunk
This commit is contained in:
commit
ea160a898c
@ -497,9 +497,9 @@ void LDLT<_MatrixType,_UpLo>::_solve_impl(const RhsType &rhs, DstType &dst) cons
|
||||
const typename Diagonal<const MatrixType>::RealReturnType vecD(vectorD());
|
||||
// In some previous versions, tolerance was set to the max of 1/highest and the maximal diagonal entry * epsilon
|
||||
// as motivated by LAPACK's xGELSS:
|
||||
// RealScalar tolerance = numext::maxi(vectorD.array().abs().maxCoeff() *NumTraits<RealScalar>::epsilon(),RealScalar(1) / NumTraits<RealScalar>::highest());
|
||||
// RealScalar tolerance = numext::maxi(vecD.array().abs().maxCoeff() * NumTraits<RealScalar>::epsilon(),RealScalar(1) / NumTraits<RealScalar>::highest());
|
||||
// However, LDLT is not rank revealing, and so adjusting the tolerance wrt to the highest
|
||||
// diagonal element is not well justified and to numerical issues in some cases.
|
||||
// diagonal element is not well justified and leads to numerical issues in some cases.
|
||||
// Moreover, Lapack's xSYTRS routines use 0 for the tolerance.
|
||||
RealScalar tolerance = RealScalar(1) / NumTraits<RealScalar>::highest();
|
||||
|
||||
|
@ -471,18 +471,25 @@ struct dense_assignment_loop<Kernel, SliceVectorizedTraversal, NoUnrolling>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC static inline void run(Kernel &kernel)
|
||||
{
|
||||
typedef packet_traits<typename Kernel::Scalar> PacketTraits;
|
||||
typedef typename Kernel::Scalar Scalar;
|
||||
typedef packet_traits<Scalar> PacketTraits;
|
||||
enum {
|
||||
packetSize = PacketTraits::size,
|
||||
alignable = PacketTraits::AlignedOnScalar,
|
||||
dstAlignment = alignable ? Aligned : int(Kernel::AssignmentTraits::DstIsAligned)
|
||||
dstIsAligned = Kernel::AssignmentTraits::DstIsAligned,
|
||||
dstAlignment = alignable ? Aligned : int(dstIsAligned)
|
||||
};
|
||||
const Scalar *dst_ptr = &kernel.dstEvaluator().coeffRef(0,0);
|
||||
if((!bool(dstIsAligned)) && (Index(dst_ptr) % sizeof(Scalar))>0)
|
||||
{
|
||||
// the pointer is not aligend-on scalar, so alignment is not possible
|
||||
return dense_assignment_loop<Kernel,DefaultTraversal,NoUnrolling>::run(kernel);
|
||||
}
|
||||
const Index packetAlignedMask = packetSize - 1;
|
||||
const Index innerSize = kernel.innerSize();
|
||||
const Index outerSize = kernel.outerSize();
|
||||
const Index alignedStep = alignable ? (packetSize - kernel.outerStride() % packetSize) & packetAlignedMask : 0;
|
||||
Index alignedStart = ((!alignable) || Kernel::AssignmentTraits::DstIsAligned) ? 0
|
||||
: internal::first_aligned(&kernel.dstEvaluator().coeffRef(0,0), innerSize);
|
||||
Index alignedStart = ((!alignable) || bool(dstIsAligned)) ? 0 : internal::first_aligned(dst_ptr, innerSize);
|
||||
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
{
|
||||
|
@ -435,8 +435,7 @@ template<typename Derived> class DenseBase
|
||||
|
||||
template<typename BinaryOp>
|
||||
EIGEN_DEVICE_FUNC
|
||||
typename internal::result_of<BinaryOp(typename internal::traits<Derived>::Scalar,typename internal::traits<Derived>::Scalar)>::type
|
||||
redux(const BinaryOp& func) const;
|
||||
Scalar redux(const BinaryOp& func) const;
|
||||
|
||||
template<typename Visitor>
|
||||
EIGEN_DEVICE_FUNC
|
||||
|
@ -124,7 +124,6 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
: Base(cast_to_pointer_type(dataPtr)), m_stride(stride)
|
||||
{
|
||||
PlainObjectType::Base::_check_template_params();
|
||||
checkPointer(dataPtr);
|
||||
}
|
||||
|
||||
/** Constructor in the dynamic-size vector case.
|
||||
@ -138,7 +137,6 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
: Base(cast_to_pointer_type(dataPtr), size), m_stride(stride)
|
||||
{
|
||||
PlainObjectType::Base::_check_template_params();
|
||||
checkPointer(dataPtr);
|
||||
}
|
||||
|
||||
/** Constructor in the dynamic-size matrix case.
|
||||
@ -153,24 +151,11 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
||||
: Base(cast_to_pointer_type(dataPtr), rows, cols), m_stride(stride)
|
||||
{
|
||||
PlainObjectType::Base::_check_template_params();
|
||||
checkPointer(dataPtr);
|
||||
}
|
||||
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
|
||||
|
||||
protected:
|
||||
|
||||
static void checkPointer(const Scalar* dataPtr)
|
||||
{
|
||||
enum {
|
||||
MightTryToAlignOnScalar = internal::packet_traits<Scalar>::AlignedOnScalar
|
||||
&& bool(internal::traits<Map>::Flags&PacketAccessBit)
|
||||
&& internal::is_lvalue<Map>::value
|
||||
};
|
||||
eigen_assert(EIGEN_IMPLIES(bool(MightTryToAlignOnScalar), (size_t(dataPtr) % sizeof(Scalar)) == 0)
|
||||
&& "input pointer is not aligned on scalar boundary, e.g., use \"EIGEN_ALIGN8 T ptr[N];\" for double or complex<float>");
|
||||
}
|
||||
|
||||
StrideType m_stride;
|
||||
};
|
||||
|
||||
|
@ -406,7 +406,7 @@ protected:
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename Func>
|
||||
EIGEN_STRONG_INLINE typename internal::result_of<Func(typename internal::traits<Derived>::Scalar,typename internal::traits<Derived>::Scalar)>::type
|
||||
typename internal::traits<Derived>::Scalar
|
||||
DenseBase<Derived>::redux(const Func& func) const
|
||||
{
|
||||
eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
|
||||
|
@ -72,6 +72,8 @@ template<typename T>
|
||||
struct functor_traits<std::not_equal_to<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
|
||||
#if(__cplusplus < 201103L)
|
||||
// std::binder* are deprecated since c++11 and will be removed in c++17
|
||||
template<typename T>
|
||||
struct functor_traits<std::binder2nd<T> >
|
||||
{ enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
|
||||
@ -79,6 +81,7 @@ struct functor_traits<std::binder2nd<T> >
|
||||
template<typename T>
|
||||
struct functor_traits<std::binder1st<T> >
|
||||
{ enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::unary_negate<T> >
|
||||
|
@ -265,6 +265,7 @@ template<typename Derived> class QuaternionBase;
|
||||
template<typename Scalar> class Rotation2D;
|
||||
template<typename Scalar> class AngleAxis;
|
||||
template<typename Scalar,int Dim> class Translation;
|
||||
template<typename Scalar,int Dim> class AlignedBox;
|
||||
|
||||
template<typename Scalar, int Options = AutoAlign> class Quaternion;
|
||||
template<typename Scalar,int Dim,int Mode,int _Options=AutoAlign> class Transform;
|
||||
|
@ -2,4 +2,4 @@ Array3d v(1,2,3);
|
||||
v(1) *= 0.0/0.0;
|
||||
v(2) /= 0.0;
|
||||
cout << v << endl << endl;
|
||||
cout << !isFinite(v) << endl;
|
||||
cout << !isfinite(v) << endl;
|
||||
|
@ -2,4 +2,4 @@ Array3d v(1,2,3);
|
||||
v(1) *= 0.0/0.0;
|
||||
v(2) /= 0.0;
|
||||
cout << v << endl << endl;
|
||||
cout << isFinite(v) << endl;
|
||||
cout << isfinite(v) << endl;
|
||||
|
@ -2,4 +2,4 @@ Array3d v(1,2,3);
|
||||
v(1) *= 0.0/0.0;
|
||||
v(2) /= 0.0;
|
||||
cout << v << endl << endl;
|
||||
cout << isInf(v) << endl;
|
||||
cout << isinf(v) << endl;
|
||||
|
@ -2,4 +2,4 @@ Array3d v(1,2,3);
|
||||
v(1) *= 0.0/0.0;
|
||||
v(2) /= 0.0;
|
||||
cout << v << endl << endl;
|
||||
cout << isNaN(v) << endl;
|
||||
cout << isnan(v) << endl;
|
||||
|
@ -225,7 +225,20 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
||||
ldltlo.compute(A);
|
||||
VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix());
|
||||
vecX = ldltlo.solve(vecB);
|
||||
VERIFY_IS_APPROX(A * vecX, vecB);
|
||||
|
||||
if(ldltlo.vectorD().real().cwiseAbs().minCoeff()>RealScalar(0))
|
||||
{
|
||||
VERIFY_IS_APPROX(A * vecX,vecB);
|
||||
}
|
||||
else
|
||||
{
|
||||
RealScalar large_tol = std::sqrt(test_precision<RealScalar>());
|
||||
VERIFY((A * vecX).isApprox(vecB, large_tol));
|
||||
|
||||
++g_test_level;
|
||||
VERIFY_IS_APPROX(A * vecX,vecB);
|
||||
--g_test_level;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
109
test/main.h
109
test/main.h
@ -250,7 +250,7 @@ inline void verify_impl(bool condition, const char *testname, const char *file,
|
||||
|
||||
#define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b))
|
||||
#define VERIFY_IS_NOT_EQUAL(a, b) VERIFY(!test_is_equal(a, b))
|
||||
#define VERIFY_IS_APPROX(a, b) VERIFY(test_isApprox(a, b))
|
||||
#define VERIFY_IS_APPROX(a, b) VERIFY(verifyIsApprox(a, b))
|
||||
#define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_isApprox(a, b))
|
||||
#define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_isMuchSmallerThan(a, b))
|
||||
#define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_isMuchSmallerThan(a, b))
|
||||
@ -324,12 +324,119 @@ inline bool test_isApproxOrLessThan(const long double& a, const long double& b)
|
||||
{ return internal::isApproxOrLessThan(a, b, test_precision<long double>()); }
|
||||
#endif // EIGEN_TEST_NO_LONGDOUBLE
|
||||
|
||||
|
||||
// test_relative_error returns the relative difference between a and b as a real scalar as used in isApprox.
|
||||
template<typename T1,typename T2>
|
||||
typename T1::RealScalar test_relative_error(const EigenBase<T1> &a, const EigenBase<T2> &b)
|
||||
{
|
||||
typedef typename T1::RealScalar RealScalar;
|
||||
typename internal::nested_eval<T1,2>::type ea(a.derived());
|
||||
typename internal::nested_eval<T2,2>::type eb(b.derived());
|
||||
return RealScalar((ea-eb).cwiseAbs2().sum()) / RealScalar((std::min)(eb.cwiseAbs2().sum(),ea.cwiseAbs2().sum()));
|
||||
}
|
||||
|
||||
template<typename T1,typename T2>
|
||||
typename T1::RealScalar test_relative_error(const T1 &a, const T2 &b, const typename T1::Coefficients* = 0)
|
||||
{
|
||||
return test_relative_error(a.coeffs(), b.coeffs());
|
||||
}
|
||||
|
||||
template<typename T1,typename T2>
|
||||
typename T1::Scalar test_relative_error(const T1 &a, const T2 &b, const typename T1::MatrixType* = 0)
|
||||
{
|
||||
return test_relative_error(a.matrix(), b.matrix());
|
||||
}
|
||||
|
||||
template<typename S, int D>
|
||||
S test_relative_error(const Translation<S,D> &a, const Translation<S,D> &b)
|
||||
{
|
||||
return test_relative_error(a.vector(), b.vector());
|
||||
}
|
||||
|
||||
template <typename S, int D, int O>
|
||||
S test_relative_error(const ParametrizedLine<S,D,O> &a, const ParametrizedLine<S,D,O> &b)
|
||||
{
|
||||
return (std::max)(test_relative_error(a.origin(), b.origin()), test_relative_error(a.origin(), b.origin()));
|
||||
}
|
||||
|
||||
template <typename S, int D>
|
||||
S test_relative_error(const AlignedBox<S,D> &a, const AlignedBox<S,D> &b)
|
||||
{
|
||||
return (std::max)(test_relative_error((a.min)(), (b.min)()), test_relative_error((a.max)(), (b.max)()));
|
||||
}
|
||||
|
||||
template<typename Derived> class SparseMatrixBase;
|
||||
template<typename T1,typename T2>
|
||||
typename T1::RealScalar test_relative_error(const MatrixBase<T1> &a, const SparseMatrixBase<T2> &b)
|
||||
{
|
||||
return test_relative_error(a,b.toDense());
|
||||
}
|
||||
|
||||
template<typename Derived> class SparseMatrixBase;
|
||||
template<typename T1,typename T2>
|
||||
typename T1::RealScalar test_relative_error(const SparseMatrixBase<T1> &a, const MatrixBase<T2> &b)
|
||||
{
|
||||
return test_relative_error(a.toDense(),b);
|
||||
}
|
||||
|
||||
template<typename Derived> class SparseMatrixBase;
|
||||
template<typename T1,typename T2>
|
||||
typename T1::RealScalar test_relative_error(const SparseMatrixBase<T1> &a, const SparseMatrixBase<T2> &b)
|
||||
{
|
||||
return test_relative_error(a.toDense(),b.toDense());
|
||||
}
|
||||
|
||||
template<typename T1,typename T2>
|
||||
typename NumTraits<T1>::Real test_relative_error(const T1 &a, const T2 &b, typename internal::enable_if<internal::is_arithmetic<typename NumTraits<T1>::Real>::value, T1>::type* = 0)
|
||||
{
|
||||
typedef typename NumTraits<T1>::Real RealScalar;
|
||||
using std::min;
|
||||
return RealScalar(numext::abs2(a-b))/RealScalar((min)(numext::abs2(a),numext::abs2(b)));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T test_relative_error(const Rotation2D<T> &a, const Rotation2D<T> &b)
|
||||
{
|
||||
return test_relative_error(a.angle(), b.angle());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T test_relative_error(const AngleAxis<T> &a, const AngleAxis<T> &b)
|
||||
{
|
||||
return (std::max)(test_relative_error(a.angle(), b.angle()), test_relative_error(a.axis(), b.axis()));
|
||||
}
|
||||
|
||||
template<typename Type1, typename Type2>
|
||||
inline bool test_isApprox(const Type1& a, const Type2& b)
|
||||
{
|
||||
return a.isApprox(b, test_precision<typename Type1::Scalar>());
|
||||
}
|
||||
|
||||
// get_test_precision is a small wrapper to test_precision allowing to return the scalar precision for either scalars or expressions
|
||||
template<typename T>
|
||||
typename NumTraits<typename T::Scalar>::Real get_test_precision(const typename T::Scalar* = 0)
|
||||
{
|
||||
return test_precision<typename NumTraits<typename T::Scalar>::Real>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
typename NumTraits<T>::Real get_test_precision(typename internal::enable_if<internal::is_arithmetic<typename NumTraits<T>::Real>::value, T>::type* = 0)
|
||||
{
|
||||
return test_precision<typename NumTraits<T>::Real>();
|
||||
}
|
||||
|
||||
// verifyIsApprox is a wrapper to test_isApprox that outputs the relative difference magnitude if the test fails.
|
||||
template<typename Type1, typename Type2>
|
||||
inline bool verifyIsApprox(const Type1& a, const Type2& b)
|
||||
{
|
||||
bool ret = test_isApprox(a,b);
|
||||
if(!ret)
|
||||
{
|
||||
std::cerr << "Difference too large wrt tolerance " << get_test_precision<Type1>() << ", relative error is: " << test_relative_error(a,b) << std::endl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// The idea behind this function is to compare the two scalars a and b where
|
||||
// the scalar ref is a hint about the expected order of magnitude of a and b.
|
||||
// WARNING: the scalar a and b must be positive
|
||||
|
@ -159,6 +159,28 @@ template<typename PlainObjectType> void check_const_correctness(const PlainObjec
|
||||
VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
void map_not_aligned_on_scalar()
|
||||
{
|
||||
typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;
|
||||
typedef typename MatrixType::Index Index;
|
||||
Index size = 11;
|
||||
Scalar* array1 = internal::aligned_new<Scalar>((size+1)*(size+1)+1);
|
||||
Scalar* array2 = reinterpret_cast<Scalar*>(sizeof(Scalar)/2+std::size_t(array1));
|
||||
Map<MatrixType,0,OuterStride<> > map2(array2, size, size, OuterStride<>(size+1));
|
||||
MatrixType m2 = MatrixType::Random(size,size);
|
||||
map2 = m2;
|
||||
VERIFY_IS_EQUAL(m2, map2);
|
||||
|
||||
typedef Matrix<Scalar,Dynamic,1> VectorType;
|
||||
Map<VectorType> map3(array2, size);
|
||||
MatrixType v3 = VectorType::Random(size);
|
||||
map3 = v3;
|
||||
VERIFY_IS_EQUAL(v3, map3);
|
||||
|
||||
internal::aligned_delete(array1, (size+1)*(size+1)+1);
|
||||
}
|
||||
|
||||
void test_mapped_matrix()
|
||||
{
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
@ -183,5 +205,7 @@ void test_mapped_matrix()
|
||||
CALL_SUBTEST_8( map_static_methods(RowVector3d()) );
|
||||
CALL_SUBTEST_9( map_static_methods(VectorXcd(8)) );
|
||||
CALL_SUBTEST_10( map_static_methods(VectorXf(12)) );
|
||||
|
||||
CALL_SUBTEST_11( map_not_aligned_on_scalar<double>() );
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ template<typename Scalar> void mmtr(int size)
|
||||
MatrixColMaj osc(othersize,size); osc.setRandom();
|
||||
MatrixRowMaj sor(size,othersize); sor.setRandom();
|
||||
MatrixRowMaj osr(othersize,size); osr.setRandom();
|
||||
MatrixColMaj sqc(size,size); sqc.setRandom();
|
||||
MatrixRowMaj sqr(size,size); sqr.setRandom();
|
||||
|
||||
Scalar s = internal::random<Scalar>();
|
||||
|
||||
@ -50,6 +52,16 @@ template<typename Scalar> void mmtr(int size)
|
||||
CHECK_MMTR(matc, Upper, -= s*(osc.transpose()*osc.conjugate()));
|
||||
CHECK_MMTR(matr, Lower, -= s*soc*soc.adjoint());
|
||||
CHECK_MMTR(matr, Upper, -= soc*(s*soc.adjoint()));
|
||||
|
||||
CHECK_MMTR(matc, Lower, -= s*sqr*sqc.template triangularView<Upper>());
|
||||
CHECK_MMTR(matc, Upper, = s*sqc*sqr.template triangularView<Upper>());
|
||||
CHECK_MMTR(matc, Lower, += s*sqr*sqc.template triangularView<Lower>());
|
||||
CHECK_MMTR(matc, Upper, = s*sqc*sqc.template triangularView<Lower>());
|
||||
|
||||
CHECK_MMTR(matc, Lower, = (s*sqr).template triangularView<Upper>()*sqc);
|
||||
CHECK_MMTR(matc, Upper, -= (s*sqc).template triangularView<Upper>()*sqc);
|
||||
CHECK_MMTR(matc, Lower, = (s*sqr).template triangularView<Lower>()*sqc);
|
||||
CHECK_MMTR(matc, Upper, += (s*sqc).template triangularView<Lower>()*sqc);
|
||||
}
|
||||
|
||||
void test_product_mmtr()
|
||||
|
@ -135,19 +135,21 @@ struct TensorEvaluator<const TensorConcatenationOp<Axis, LeftArgType, RightArgTy
|
||||
eigen_assert(0 <= m_axis && m_axis < NumDims);
|
||||
const Dimensions& lhs_dims = m_leftImpl.dimensions();
|
||||
const Dimensions& rhs_dims = m_rightImpl.dimensions();
|
||||
int i = 0;
|
||||
for (; i < m_axis; ++i) {
|
||||
eigen_assert(lhs_dims[i] > 0);
|
||||
eigen_assert(lhs_dims[i] == rhs_dims[i]);
|
||||
m_dimensions[i] = lhs_dims[i];
|
||||
}
|
||||
eigen_assert(lhs_dims[i] > 0); // Now i == m_axis.
|
||||
eigen_assert(rhs_dims[i] > 0);
|
||||
m_dimensions[i] = lhs_dims[i] + rhs_dims[i];
|
||||
for (++i; i < NumDims; ++i) {
|
||||
eigen_assert(lhs_dims[i] > 0);
|
||||
eigen_assert(lhs_dims[i] == rhs_dims[i]);
|
||||
m_dimensions[i] = lhs_dims[i];
|
||||
{
|
||||
int i = 0;
|
||||
for (; i < m_axis; ++i) {
|
||||
eigen_assert(lhs_dims[i] > 0);
|
||||
eigen_assert(lhs_dims[i] == rhs_dims[i]);
|
||||
m_dimensions[i] = lhs_dims[i];
|
||||
}
|
||||
eigen_assert(lhs_dims[i] > 0); // Now i == m_axis.
|
||||
eigen_assert(rhs_dims[i] > 0);
|
||||
m_dimensions[i] = lhs_dims[i] + rhs_dims[i];
|
||||
for (++i; i < NumDims; ++i) {
|
||||
eigen_assert(lhs_dims[i] > 0);
|
||||
eigen_assert(lhs_dims[i] == rhs_dims[i]);
|
||||
m_dimensions[i] = lhs_dims[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) {
|
||||
|
@ -142,15 +142,25 @@ struct TensorEvaluator<const TensorImagePatchOp<Rows, Cols, ArgType>, Device>
|
||||
|
||||
switch (op.padding_type()) {
|
||||
case PADDING_VALID:
|
||||
<<<<<<< local
|
||||
m_outputRows = std::ceil((m_inputRows - op.patch_rows() + 1.f) / static_cast<float>(m_row_strides));
|
||||
m_outputCols = std::ceil((m_inputCols - op.patch_cols() + 1.f) / static_cast<float>(m_col_strides));
|
||||
=======
|
||||
m_outputRows = numext::ceil((m_inputRows - op.patch_rows() + 1.f) / static_cast<float>(m_row_strides));
|
||||
m_outputCols = numext::ceil((m_inputCols - op.patch_cols() + 1.f) / static_cast<float>(m_col_strides));
|
||||
>>>>>>> other
|
||||
// Calculate the padding
|
||||
m_rowPaddingTop = ((m_outputRows - 1) * m_row_strides + op.patch_rows() - m_inputRows) / 2;
|
||||
m_colPaddingLeft = ((m_outputCols - 1) * m_col_strides + op.patch_cols() - m_inputCols) / 2;
|
||||
break;
|
||||
case PADDING_SAME:
|
||||
<<<<<<< local
|
||||
m_outputRows = std::ceil(m_inputRows / static_cast<float>(m_row_strides));
|
||||
m_outputCols = std::ceil(m_inputCols / static_cast<float>(m_col_strides));
|
||||
=======
|
||||
m_outputRows = numext::ceil(m_inputRows / static_cast<float>(m_row_strides));
|
||||
m_outputCols = numext::ceil(m_inputCols / static_cast<float>(m_col_strides));
|
||||
>>>>>>> other
|
||||
// Calculate the padding
|
||||
m_rowPaddingTop = ((m_outputRows - 1) * m_row_strides + op.patch_rows() - m_inputRows) / 2;
|
||||
m_colPaddingLeft = ((m_outputCols - 1) * m_col_strides + op.patch_cols() - m_inputCols) / 2;
|
||||
|
@ -185,11 +185,13 @@ struct TensorEvaluator<const TensorPaddingOp<PaddingDimensions, ArgType>, Device
|
||||
{
|
||||
Index inputIndex;
|
||||
if (static_cast<int>(Layout) == static_cast<int>(ColMajor)) {
|
||||
const Index idx = coords[0];
|
||||
if (idx < m_padding[0].first || idx >= m_dimensions[0] - m_padding[0].second) {
|
||||
return Scalar(0);
|
||||
{
|
||||
const Index idx = coords[0];
|
||||
if (idx < m_padding[0].first || idx >= m_dimensions[0] - m_padding[0].second) {
|
||||
return Scalar(0);
|
||||
}
|
||||
inputIndex = idx - m_padding[0].first;
|
||||
}
|
||||
inputIndex = idx - m_padding[0].first;
|
||||
for (int i = 1; i < NumDims; ++i) {
|
||||
const Index idx = coords[i];
|
||||
if (idx < m_padding[i].first || idx >= m_dimensions[i] - m_padding[i].second) {
|
||||
@ -198,11 +200,13 @@ struct TensorEvaluator<const TensorPaddingOp<PaddingDimensions, ArgType>, Device
|
||||
inputIndex += (idx - m_padding[i].first) * m_inputStrides[i];
|
||||
}
|
||||
} else {
|
||||
const Index idx = coords[NumDims-1];
|
||||
if (idx < m_padding[NumDims-1].first || idx >= m_dimensions[NumDims-1] - m_padding[NumDims-1].second) {
|
||||
return Scalar(0);
|
||||
{
|
||||
const Index idx = coords[NumDims-1];
|
||||
if (idx < m_padding[NumDims-1].first || idx >= m_dimensions[NumDims-1] - m_padding[NumDims-1].second) {
|
||||
return Scalar(0);
|
||||
}
|
||||
inputIndex = idx - m_padding[NumDims-1].first;
|
||||
}
|
||||
inputIndex = idx - m_padding[NumDims-1].first;
|
||||
for (int i = NumDims - 2; i >= 0; --i) {
|
||||
const Index idx = coords[i];
|
||||
if (idx < m_padding[i].first || idx >= m_dimensions[i] - m_padding[i].second) {
|
||||
|
@ -197,15 +197,15 @@ template<typename PlainObjectType> class TensorRef : public TensorBase<TensorRef
|
||||
template<typename... IndexTypes> EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const Scalar operator()(Index firstIndex, IndexTypes... otherIndices) const
|
||||
{
|
||||
const std::size_t NumIndices = (sizeof...(otherIndices) + 1);
|
||||
const array<Index, NumIndices> indices{{firstIndex, otherIndices...}};
|
||||
const std::size_t num_indices = (sizeof...(otherIndices) + 1);
|
||||
const array<Index, num_indices> indices{{firstIndex, otherIndices...}};
|
||||
return coeff(indices);
|
||||
}
|
||||
template<typename... IndexTypes> EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE Scalar& coeffRef(Index firstIndex, IndexTypes... otherIndices)
|
||||
{
|
||||
const std::size_t NumIndices = (sizeof...(otherIndices) + 1);
|
||||
const array<Index, NumIndices> indices{{firstIndex, otherIndices...}};
|
||||
const std::size_t num_indices = (sizeof...(otherIndices) + 1);
|
||||
const array<Index, num_indices> indices{{firstIndex, otherIndices...}};
|
||||
return coeffRef(indices);
|
||||
}
|
||||
#else
|
||||
|
@ -10,6 +10,16 @@
|
||||
#include "main.h"
|
||||
#include <unsupported/Eigen/AlignedVector3>
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
template<typename T,typename Derived>
|
||||
T test_relative_error(const AlignedVector3<T> &a, const MatrixBase<Derived> &b)
|
||||
{
|
||||
return test_relative_error(a.coeffs().template head<3>(), b);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename Scalar>
|
||||
void alignedvector3()
|
||||
{
|
||||
|
@ -17,11 +17,11 @@ template <int DataLayout>
|
||||
static void test_simple_reductions() {
|
||||
Tensor<float, 4, DataLayout> tensor(2, 3, 5, 7);
|
||||
tensor.setRandom();
|
||||
array<ptrdiff_t, 2> reduction_axis;
|
||||
reduction_axis[0] = 1;
|
||||
reduction_axis[1] = 3;
|
||||
array<ptrdiff_t, 2> reduction_axis2;
|
||||
reduction_axis2[0] = 1;
|
||||
reduction_axis2[1] = 3;
|
||||
|
||||
Tensor<float, 2, DataLayout> result = tensor.sum(reduction_axis);
|
||||
Tensor<float, 2, DataLayout> result = tensor.sum(reduction_axis2);
|
||||
VERIFY_IS_EQUAL(result.dimension(0), 2);
|
||||
VERIFY_IS_EQUAL(result.dimension(1), 5);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
@ -40,20 +40,20 @@ static void test_simple_reductions() {
|
||||
Tensor<float, 1, DataLayout> sum1 = tensor.sum();
|
||||
VERIFY_IS_EQUAL(sum1.dimension(0), 1);
|
||||
|
||||
array<ptrdiff_t, 4> reduction_axis;
|
||||
reduction_axis[0] = 0;
|
||||
reduction_axis[1] = 1;
|
||||
reduction_axis[2] = 2;
|
||||
reduction_axis[3] = 3;
|
||||
Tensor<float, 1, DataLayout> sum2 = tensor.sum(reduction_axis);
|
||||
array<ptrdiff_t, 4> reduction_axis4;
|
||||
reduction_axis4[0] = 0;
|
||||
reduction_axis4[1] = 1;
|
||||
reduction_axis4[2] = 2;
|
||||
reduction_axis4[3] = 3;
|
||||
Tensor<float, 1, DataLayout> sum2 = tensor.sum(reduction_axis4);
|
||||
VERIFY_IS_EQUAL(sum2.dimension(0), 1);
|
||||
|
||||
VERIFY_IS_APPROX(sum1(0), sum2(0));
|
||||
}
|
||||
|
||||
reduction_axis[0] = 0;
|
||||
reduction_axis[1] = 2;
|
||||
result = tensor.prod(reduction_axis);
|
||||
reduction_axis2[0] = 0;
|
||||
reduction_axis2[1] = 2;
|
||||
result = tensor.prod(reduction_axis2);
|
||||
VERIFY_IS_EQUAL(result.dimension(0), 3);
|
||||
VERIFY_IS_EQUAL(result.dimension(1), 7);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
@ -72,20 +72,20 @@ static void test_simple_reductions() {
|
||||
Tensor<float, 1, DataLayout> prod1 = tensor.prod();
|
||||
VERIFY_IS_EQUAL(prod1.dimension(0), 1);
|
||||
|
||||
array<ptrdiff_t, 4> reduction_axis;
|
||||
reduction_axis[0] = 0;
|
||||
reduction_axis[1] = 1;
|
||||
reduction_axis[2] = 2;
|
||||
reduction_axis[3] = 3;
|
||||
Tensor<float, 1, DataLayout> prod2 = tensor.prod(reduction_axis);
|
||||
array<ptrdiff_t, 4> reduction_axis4;
|
||||
reduction_axis4[0] = 0;
|
||||
reduction_axis4[1] = 1;
|
||||
reduction_axis4[2] = 2;
|
||||
reduction_axis4[3] = 3;
|
||||
Tensor<float, 1, DataLayout> prod2 = tensor.prod(reduction_axis4);
|
||||
VERIFY_IS_EQUAL(prod2.dimension(0), 1);
|
||||
|
||||
VERIFY_IS_APPROX(prod1(0), prod2(0));
|
||||
}
|
||||
|
||||
reduction_axis[0] = 0;
|
||||
reduction_axis[1] = 2;
|
||||
result = tensor.maximum(reduction_axis);
|
||||
reduction_axis2[0] = 0;
|
||||
reduction_axis2[1] = 2;
|
||||
result = tensor.maximum(reduction_axis2);
|
||||
VERIFY_IS_EQUAL(result.dimension(0), 3);
|
||||
VERIFY_IS_EQUAL(result.dimension(1), 7);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
@ -104,20 +104,20 @@ static void test_simple_reductions() {
|
||||
Tensor<float, 1, DataLayout> max1 = tensor.maximum();
|
||||
VERIFY_IS_EQUAL(max1.dimension(0), 1);
|
||||
|
||||
array<ptrdiff_t, 4> reduction_axis;
|
||||
reduction_axis[0] = 0;
|
||||
reduction_axis[1] = 1;
|
||||
reduction_axis[2] = 2;
|
||||
reduction_axis[3] = 3;
|
||||
Tensor<float, 1, DataLayout> max2 = tensor.maximum(reduction_axis);
|
||||
array<ptrdiff_t, 4> reduction_axis4;
|
||||
reduction_axis4[0] = 0;
|
||||
reduction_axis4[1] = 1;
|
||||
reduction_axis4[2] = 2;
|
||||
reduction_axis4[3] = 3;
|
||||
Tensor<float, 1, DataLayout> max2 = tensor.maximum(reduction_axis4);
|
||||
VERIFY_IS_EQUAL(max2.dimension(0), 1);
|
||||
|
||||
VERIFY_IS_APPROX(max1(0), max2(0));
|
||||
}
|
||||
|
||||
reduction_axis[0] = 0;
|
||||
reduction_axis[1] = 1;
|
||||
result = tensor.minimum(reduction_axis);
|
||||
reduction_axis2[0] = 0;
|
||||
reduction_axis2[1] = 1;
|
||||
result = tensor.minimum(reduction_axis2);
|
||||
VERIFY_IS_EQUAL(result.dimension(0), 5);
|
||||
VERIFY_IS_EQUAL(result.dimension(1), 7);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
@ -136,20 +136,20 @@ static void test_simple_reductions() {
|
||||
Tensor<float, 1, DataLayout> min1 = tensor.minimum();
|
||||
VERIFY_IS_EQUAL(min1.dimension(0), 1);
|
||||
|
||||
array<ptrdiff_t, 4> reduction_axis;
|
||||
reduction_axis[0] = 0;
|
||||
reduction_axis[1] = 1;
|
||||
reduction_axis[2] = 2;
|
||||
reduction_axis[3] = 3;
|
||||
Tensor<float, 1, DataLayout> min2 = tensor.minimum(reduction_axis);
|
||||
array<ptrdiff_t, 4> reduction_axis4;
|
||||
reduction_axis4[0] = 0;
|
||||
reduction_axis4[1] = 1;
|
||||
reduction_axis4[2] = 2;
|
||||
reduction_axis4[3] = 3;
|
||||
Tensor<float, 1, DataLayout> min2 = tensor.minimum(reduction_axis4);
|
||||
VERIFY_IS_EQUAL(min2.dimension(0), 1);
|
||||
|
||||
VERIFY_IS_APPROX(min1(0), min2(0));
|
||||
}
|
||||
|
||||
reduction_axis[0] = 0;
|
||||
reduction_axis[1] = 1;
|
||||
result = tensor.mean(reduction_axis);
|
||||
reduction_axis2[0] = 0;
|
||||
reduction_axis2[1] = 1;
|
||||
result = tensor.mean(reduction_axis2);
|
||||
VERIFY_IS_EQUAL(result.dimension(0), 5);
|
||||
VERIFY_IS_EQUAL(result.dimension(1), 7);
|
||||
for (int i = 0; i < 5; ++i) {
|
||||
@ -170,12 +170,12 @@ static void test_simple_reductions() {
|
||||
Tensor<float, 1, DataLayout> mean1 = tensor.mean();
|
||||
VERIFY_IS_EQUAL(mean1.dimension(0), 1);
|
||||
|
||||
array<ptrdiff_t, 4> reduction_axis;
|
||||
reduction_axis[0] = 0;
|
||||
reduction_axis[1] = 1;
|
||||
reduction_axis[2] = 2;
|
||||
reduction_axis[3] = 3;
|
||||
Tensor<float, 1, DataLayout> mean2 = tensor.mean(reduction_axis);
|
||||
array<ptrdiff_t, 4> reduction_axis4;
|
||||
reduction_axis4[0] = 0;
|
||||
reduction_axis4[1] = 1;
|
||||
reduction_axis4[2] = 2;
|
||||
reduction_axis4[3] = 3;
|
||||
Tensor<float, 1, DataLayout> mean2 = tensor.mean(reduction_axis4);
|
||||
VERIFY_IS_EQUAL(mean2.dimension(0), 1);
|
||||
|
||||
VERIFY_IS_APPROX(mean1(0), mean2(0));
|
||||
|
Loading…
x
Reference in New Issue
Block a user