mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-10 18:59:01 +08:00
Remove evaluators for 2.1 release.
We plan to re-instate them when we branch 2.2 (see bug #388).
This commit is contained in:
parent
0308c11849
commit
3db6455896
@ -352,12 +352,6 @@ using std::ptrdiff_t;
|
||||
#include "src/Core/ArrayBase.h"
|
||||
#include "src/Core/ArrayWrapper.h"
|
||||
|
||||
#ifdef EIGEN_ENABLE_EVALUATORS
|
||||
#include "src/Core/Product.h"
|
||||
#include "src/Core/CoreEvaluators.h"
|
||||
#include "src/Core/AssignEvaluator.h"
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_USE_BLAS
|
||||
#include "src/Core/products/GeneralMatrixMatrix_MKL.h"
|
||||
#include "src/Core/products/GeneralMatrixVector_MKL.h"
|
||||
|
@ -1,682 +0,0 @@
|
||||
// This file is part of Eigen, a lightweight C++ template library
|
||||
// for linear algebra.
|
||||
//
|
||||
// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||
// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>
|
||||
// Copyright (C) 2011 Jitse Niesen <jitse@maths.leeds.ac.uk>
|
||||
//
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef EIGEN_ASSIGN_EVALUATOR_H
|
||||
#define EIGEN_ASSIGN_EVALUATOR_H
|
||||
|
||||
// This implementation is based on Assign.h
|
||||
|
||||
namespace internal {
|
||||
|
||||
/***************************************************************************
|
||||
* Part 1 : the logic deciding a strategy for traversal and unrolling *
|
||||
***************************************************************************/
|
||||
|
||||
// copy_using_evaluator_traits is based on assign_traits
|
||||
// (actually, it's identical)
|
||||
|
||||
template <typename Derived, typename OtherDerived>
|
||||
struct copy_using_evaluator_traits
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
DstIsAligned = Derived::Flags & AlignedBit,
|
||||
DstHasDirectAccess = Derived::Flags & DirectAccessBit,
|
||||
SrcIsAligned = OtherDerived::Flags & AlignedBit,
|
||||
JointAlignment = bool(DstIsAligned) && bool(SrcIsAligned) ? Aligned : Unaligned
|
||||
};
|
||||
|
||||
private:
|
||||
enum {
|
||||
InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime)
|
||||
: int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime)
|
||||
: int(Derived::RowsAtCompileTime),
|
||||
InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime)
|
||||
: int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime)
|
||||
: int(Derived::MaxRowsAtCompileTime),
|
||||
MaxSizeAtCompileTime = Derived::SizeAtCompileTime,
|
||||
PacketSize = packet_traits<typename Derived::Scalar>::size
|
||||
};
|
||||
|
||||
enum {
|
||||
StorageOrdersAgree = (int(Derived::IsRowMajor) == int(OtherDerived::IsRowMajor)),
|
||||
MightVectorize = StorageOrdersAgree
|
||||
&& (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit),
|
||||
MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
|
||||
&& int(DstIsAligned) && int(SrcIsAligned),
|
||||
MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
|
||||
MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess
|
||||
&& (DstIsAligned || MaxSizeAtCompileTime == Dynamic),
|
||||
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
|
||||
so it's only good for large enough sizes. */
|
||||
MaySliceVectorize = MightVectorize && DstHasDirectAccess
|
||||
&& (int(InnerMaxSize)==Dynamic || int(InnerMaxSize)>=3*PacketSize)
|
||||
/* slice vectorization can be slow, so we only want it if the slices are big, which is
|
||||
indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
|
||||
in a fixed-size matrix */
|
||||
};
|
||||
|
||||
public:
|
||||
enum {
|
||||
Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal)
|
||||
: int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
|
||||
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
|
||||
: int(MayLinearize) ? int(LinearTraversal)
|
||||
: int(DefaultTraversal),
|
||||
Vectorized = int(Traversal) == InnerVectorizedTraversal
|
||||
|| int(Traversal) == LinearVectorizedTraversal
|
||||
|| int(Traversal) == SliceVectorizedTraversal
|
||||
};
|
||||
|
||||
private:
|
||||
enum {
|
||||
UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1),
|
||||
MayUnrollCompletely = int(Derived::SizeAtCompileTime) != Dynamic
|
||||
&& int(OtherDerived::CoeffReadCost) != Dynamic
|
||||
&& int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit),
|
||||
MayUnrollInner = int(InnerSize) != Dynamic
|
||||
&& int(OtherDerived::CoeffReadCost) != Dynamic
|
||||
&& int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit)
|
||||
};
|
||||
|
||||
public:
|
||||
enum {
|
||||
Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal))
|
||||
? (
|
||||
int(MayUnrollCompletely) ? int(CompleteUnrolling)
|
||||
: int(MayUnrollInner) ? int(InnerUnrolling)
|
||||
: int(NoUnrolling)
|
||||
)
|
||||
: int(Traversal) == int(LinearVectorizedTraversal)
|
||||
? ( bool(MayUnrollCompletely) && bool(DstIsAligned) ? int(CompleteUnrolling)
|
||||
: int(NoUnrolling) )
|
||||
: int(Traversal) == int(LinearTraversal)
|
||||
? ( bool(MayUnrollCompletely) ? int(CompleteUnrolling)
|
||||
: int(NoUnrolling) )
|
||||
: int(NoUnrolling)
|
||||
};
|
||||
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
static void debug()
|
||||
{
|
||||
EIGEN_DEBUG_VAR(DstIsAligned)
|
||||
EIGEN_DEBUG_VAR(SrcIsAligned)
|
||||
EIGEN_DEBUG_VAR(JointAlignment)
|
||||
EIGEN_DEBUG_VAR(InnerSize)
|
||||
EIGEN_DEBUG_VAR(InnerMaxSize)
|
||||
EIGEN_DEBUG_VAR(PacketSize)
|
||||
EIGEN_DEBUG_VAR(StorageOrdersAgree)
|
||||
EIGEN_DEBUG_VAR(MightVectorize)
|
||||
EIGEN_DEBUG_VAR(MayLinearize)
|
||||
EIGEN_DEBUG_VAR(MayInnerVectorize)
|
||||
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||
EIGEN_DEBUG_VAR(Traversal)
|
||||
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
||||
EIGEN_DEBUG_VAR(MayUnrollInner)
|
||||
EIGEN_DEBUG_VAR(Unrolling)
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Part 2 : meta-unrollers
|
||||
***************************************************************************/
|
||||
|
||||
/************************
|
||||
*** Default traversal ***
|
||||
************************/
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Index, int Stop>
|
||||
struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling
|
||||
{
|
||||
typedef typename DstEvaluatorType::XprType DstXprType;
|
||||
|
||||
enum {
|
||||
outer = Index / DstXprType::InnerSizeAtCompileTime,
|
||||
inner = Index % DstXprType::InnerSizeAtCompileTime
|
||||
};
|
||||
|
||||
EIGEN_STRONG_INLINE static void run(DstEvaluatorType &dstEvaluator,
|
||||
SrcEvaluatorType &srcEvaluator)
|
||||
{
|
||||
dstEvaluator.copyCoeffByOuterInner(outer, inner, srcEvaluator);
|
||||
copy_using_evaluator_DefaultTraversal_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, Index+1, Stop>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Stop>
|
||||
struct copy_using_evaluator_DefaultTraversal_CompleteUnrolling<DstEvaluatorType, SrcEvaluatorType, Stop, Stop>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstEvaluatorType&, SrcEvaluatorType&) { }
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Index, int Stop>
|
||||
struct copy_using_evaluator_DefaultTraversal_InnerUnrolling
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstEvaluatorType &dstEvaluator,
|
||||
SrcEvaluatorType &srcEvaluator,
|
||||
int outer)
|
||||
{
|
||||
dstEvaluator.copyCoeffByOuterInner(outer, Index, srcEvaluator);
|
||||
copy_using_evaluator_DefaultTraversal_InnerUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, Index+1, Stop>
|
||||
::run(dstEvaluator, srcEvaluator, outer);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Stop>
|
||||
struct copy_using_evaluator_DefaultTraversal_InnerUnrolling<DstEvaluatorType, SrcEvaluatorType, Stop, Stop>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstEvaluatorType&, SrcEvaluatorType&, int) { }
|
||||
};
|
||||
|
||||
/***********************
|
||||
*** Linear traversal ***
|
||||
***********************/
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Index, int Stop>
|
||||
struct copy_using_evaluator_LinearTraversal_CompleteUnrolling
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstEvaluatorType &dstEvaluator,
|
||||
SrcEvaluatorType &srcEvaluator)
|
||||
{
|
||||
dstEvaluator.copyCoeff(Index, srcEvaluator);
|
||||
copy_using_evaluator_LinearTraversal_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, Index+1, Stop>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Stop>
|
||||
struct copy_using_evaluator_LinearTraversal_CompleteUnrolling<DstEvaluatorType, SrcEvaluatorType, Stop, Stop>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstEvaluatorType&, SrcEvaluatorType&) { }
|
||||
};
|
||||
|
||||
/**************************
|
||||
*** Inner vectorization ***
|
||||
**************************/
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Index, int Stop>
|
||||
struct copy_using_evaluator_innervec_CompleteUnrolling
|
||||
{
|
||||
typedef typename DstEvaluatorType::XprType DstXprType;
|
||||
typedef typename SrcEvaluatorType::XprType SrcXprType;
|
||||
|
||||
enum {
|
||||
outer = Index / DstXprType::InnerSizeAtCompileTime,
|
||||
inner = Index % DstXprType::InnerSizeAtCompileTime,
|
||||
JointAlignment = copy_using_evaluator_traits<DstXprType,SrcXprType>::JointAlignment
|
||||
};
|
||||
|
||||
EIGEN_STRONG_INLINE static void run(DstEvaluatorType &dstEvaluator,
|
||||
SrcEvaluatorType &srcEvaluator)
|
||||
{
|
||||
dstEvaluator.template copyPacketByOuterInner<Aligned, JointAlignment>(outer, inner, srcEvaluator);
|
||||
enum { NextIndex = Index + packet_traits<typename DstXprType::Scalar>::size };
|
||||
copy_using_evaluator_innervec_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, NextIndex, Stop>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Stop>
|
||||
struct copy_using_evaluator_innervec_CompleteUnrolling<DstEvaluatorType, SrcEvaluatorType, Stop, Stop>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstEvaluatorType&, SrcEvaluatorType&) { }
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Index, int Stop>
|
||||
struct copy_using_evaluator_innervec_InnerUnrolling
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstEvaluatorType &dstEvaluator,
|
||||
SrcEvaluatorType &srcEvaluator,
|
||||
int outer)
|
||||
{
|
||||
dstEvaluator.template copyPacketByOuterInner<Aligned, Aligned>(outer, Index, srcEvaluator);
|
||||
typedef typename DstEvaluatorType::XprType DstXprType;
|
||||
enum { NextIndex = Index + packet_traits<typename DstXprType::Scalar>::size };
|
||||
copy_using_evaluator_innervec_InnerUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, NextIndex, Stop>
|
||||
::run(dstEvaluator, srcEvaluator, outer);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstEvaluatorType, typename SrcEvaluatorType, int Stop>
|
||||
struct copy_using_evaluator_innervec_InnerUnrolling<DstEvaluatorType, SrcEvaluatorType, Stop, Stop>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstEvaluatorType&, SrcEvaluatorType&, int) { }
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Part 3 : implementation of all cases
|
||||
***************************************************************************/
|
||||
|
||||
// copy_using_evaluator_impl is based on assign_impl
|
||||
|
||||
template<typename DstXprType, typename SrcXprType,
|
||||
int Traversal = copy_using_evaluator_traits<DstXprType, SrcXprType>::Traversal,
|
||||
int Unrolling = copy_using_evaluator_traits<DstXprType, SrcXprType>::Unrolling>
|
||||
struct copy_using_evaluator_impl;
|
||||
|
||||
/************************
|
||||
*** Default traversal ***
|
||||
************************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, DefaultTraversal, NoUnrolling>
|
||||
{
|
||||
static void run(DstXprType& dst, const SrcXprType& src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
for(Index outer = 0; outer < dst.outerSize(); ++outer) {
|
||||
for(Index inner = 0; inner < dst.innerSize(); ++inner) {
|
||||
dstEvaluator.copyCoeffByOuterInner(outer, inner, srcEvaluator);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, DefaultTraversal, CompleteUnrolling>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
copy_using_evaluator_DefaultTraversal_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, DstXprType::SizeAtCompileTime>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, DefaultTraversal, InnerUnrolling>
|
||||
{
|
||||
typedef typename DstXprType::Index Index;
|
||||
EIGEN_STRONG_INLINE static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index outerSize = dst.outerSize();
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
copy_using_evaluator_DefaultTraversal_InnerUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, DstXprType::InnerSizeAtCompileTime>
|
||||
::run(dstEvaluator, srcEvaluator, outer);
|
||||
}
|
||||
};
|
||||
|
||||
/***************************
|
||||
*** Linear vectorization ***
|
||||
***************************/
|
||||
|
||||
template <bool IsAligned = false>
|
||||
struct unaligned_copy_using_evaluator_impl
|
||||
{
|
||||
// if IsAligned = true, then do nothing
|
||||
template <typename SrcEvaluatorType, typename DstEvaluatorType>
|
||||
static EIGEN_STRONG_INLINE void run(const SrcEvaluatorType&, DstEvaluatorType&,
|
||||
typename SrcEvaluatorType::Index, typename SrcEvaluatorType::Index) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct unaligned_copy_using_evaluator_impl<false>
|
||||
{
|
||||
// MSVC must not inline this functions. If it does, it fails to optimize the
|
||||
// packet access path.
|
||||
#ifdef _MSC_VER
|
||||
template <typename DstEvaluatorType, typename SrcEvaluatorType>
|
||||
static EIGEN_DONT_INLINE void run(DstEvaluatorType &dstEvaluator,
|
||||
const SrcEvaluatorType &srcEvaluator,
|
||||
typename DstEvaluatorType::Index start,
|
||||
typename DstEvaluatorType::Index end)
|
||||
#else
|
||||
template <typename DstEvaluatorType, typename SrcEvaluatorType>
|
||||
static EIGEN_STRONG_INLINE void run(DstEvaluatorType &dstEvaluator,
|
||||
const SrcEvaluatorType &srcEvaluator,
|
||||
typename DstEvaluatorType::Index start,
|
||||
typename DstEvaluatorType::Index end)
|
||||
#endif
|
||||
{
|
||||
for (typename DstEvaluatorType::Index index = start; index < end; ++index)
|
||||
dstEvaluator.copyCoeff(index, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, LinearVectorizedTraversal, NoUnrolling>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index size = dst.size();
|
||||
typedef packet_traits<typename DstXprType::Scalar> PacketTraits;
|
||||
enum {
|
||||
packetSize = PacketTraits::size,
|
||||
dstIsAligned = int(copy_using_evaluator_traits<DstXprType,SrcXprType>::DstIsAligned),
|
||||
dstAlignment = PacketTraits::AlignedOnScalar ? Aligned : dstIsAligned,
|
||||
srcAlignment = copy_using_evaluator_traits<DstXprType,SrcXprType>::JointAlignment
|
||||
};
|
||||
const Index alignedStart = dstIsAligned ? 0 : first_aligned(&dstEvaluator.coeffRef(0), size);
|
||||
const Index alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
|
||||
|
||||
unaligned_copy_using_evaluator_impl<dstIsAligned!=0>::run(dstEvaluator, srcEvaluator, 0, alignedStart);
|
||||
|
||||
for(Index index = alignedStart; index < alignedEnd; index += packetSize)
|
||||
{
|
||||
dstEvaluator.template copyPacket<dstAlignment, srcAlignment>(index, srcEvaluator);
|
||||
}
|
||||
|
||||
unaligned_copy_using_evaluator_impl<>::run(dstEvaluator, srcEvaluator, alignedEnd, size);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, LinearVectorizedTraversal, CompleteUnrolling>
|
||||
{
|
||||
typedef typename DstXprType::Index Index;
|
||||
EIGEN_STRONG_INLINE static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
enum { size = DstXprType::SizeAtCompileTime,
|
||||
packetSize = packet_traits<typename DstXprType::Scalar>::size,
|
||||
alignedSize = (size/packetSize)*packetSize };
|
||||
|
||||
copy_using_evaluator_innervec_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, alignedSize>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
copy_using_evaluator_DefaultTraversal_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, alignedSize, size>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************
|
||||
*** Inner vectorization ***
|
||||
**************************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, InnerVectorizedTraversal, NoUnrolling>
|
||||
{
|
||||
inline static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index innerSize = dst.innerSize();
|
||||
const Index outerSize = dst.outerSize();
|
||||
const Index packetSize = packet_traits<typename DstXprType::Scalar>::size;
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
for(Index inner = 0; inner < innerSize; inner+=packetSize) {
|
||||
dstEvaluator.template copyPacketByOuterInner<Aligned, Aligned>(outer, inner, srcEvaluator);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, InnerVectorizedTraversal, CompleteUnrolling>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
copy_using_evaluator_innervec_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, DstXprType::SizeAtCompileTime>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, InnerVectorizedTraversal, InnerUnrolling>
|
||||
{
|
||||
typedef typename DstXprType::Index Index;
|
||||
EIGEN_STRONG_INLINE static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index outerSize = dst.outerSize();
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
copy_using_evaluator_innervec_InnerUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, DstXprType::InnerSizeAtCompileTime>
|
||||
::run(dstEvaluator, srcEvaluator, outer);
|
||||
}
|
||||
};
|
||||
|
||||
/***********************
|
||||
*** Linear traversal ***
|
||||
***********************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, LinearTraversal, NoUnrolling>
|
||||
{
|
||||
inline static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
const Index size = dst.size();
|
||||
for(Index i = 0; i < size; ++i)
|
||||
dstEvaluator.copyCoeff(i, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, LinearTraversal, CompleteUnrolling>
|
||||
{
|
||||
EIGEN_STRONG_INLINE static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
copy_using_evaluator_LinearTraversal_CompleteUnrolling
|
||||
<DstEvaluatorType, SrcEvaluatorType, 0, DstXprType::SizeAtCompileTime>
|
||||
::run(dstEvaluator, srcEvaluator);
|
||||
}
|
||||
};
|
||||
|
||||
/**************************
|
||||
*** Slice vectorization ***
|
||||
***************************/
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
struct copy_using_evaluator_impl<DstXprType, SrcXprType, SliceVectorizedTraversal, NoUnrolling>
|
||||
{
|
||||
inline static void run(DstXprType &dst, const SrcXprType &src)
|
||||
{
|
||||
typedef typename evaluator<DstXprType>::type DstEvaluatorType;
|
||||
typedef typename evaluator<SrcXprType>::type SrcEvaluatorType;
|
||||
typedef typename DstXprType::Index Index;
|
||||
|
||||
DstEvaluatorType dstEvaluator(dst);
|
||||
SrcEvaluatorType srcEvaluator(src);
|
||||
|
||||
typedef packet_traits<typename DstXprType::Scalar> PacketTraits;
|
||||
enum {
|
||||
packetSize = PacketTraits::size,
|
||||
alignable = PacketTraits::AlignedOnScalar,
|
||||
dstAlignment = alignable ? Aligned : int(copy_using_evaluator_traits<DstXprType,SrcXprType>::DstIsAligned) ,
|
||||
srcAlignment = copy_using_evaluator_traits<DstXprType,SrcXprType>::JointAlignment
|
||||
};
|
||||
const Index packetAlignedMask = packetSize - 1;
|
||||
const Index innerSize = dst.innerSize();
|
||||
const Index outerSize = dst.outerSize();
|
||||
const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;
|
||||
Index alignedStart = ((!alignable) || copy_using_evaluator_traits<DstXprType,SrcXprType>::DstIsAligned) ? 0
|
||||
: first_aligned(&dstEvaluator.coeffRef(0,0), innerSize);
|
||||
|
||||
for(Index outer = 0; outer < outerSize; ++outer)
|
||||
{
|
||||
const Index alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);
|
||||
// do the non-vectorizable part of the assignment
|
||||
for(Index inner = 0; inner<alignedStart ; ++inner) {
|
||||
dstEvaluator.copyCoeffByOuterInner(outer, inner, srcEvaluator);
|
||||
}
|
||||
|
||||
// do the vectorizable part of the assignment
|
||||
for(Index inner = alignedStart; inner<alignedEnd; inner+=packetSize) {
|
||||
dstEvaluator.template copyPacketByOuterInner<dstAlignment, srcAlignment>(outer, inner, srcEvaluator);
|
||||
}
|
||||
|
||||
// do the non-vectorizable part of the assignment
|
||||
for(Index inner = alignedEnd; inner<innerSize ; ++inner) {
|
||||
dstEvaluator.copyCoeffByOuterInner(outer, inner, srcEvaluator);
|
||||
}
|
||||
|
||||
alignedStart = std::min<Index>((alignedStart+alignedStep)%packetSize, innerSize);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Part 4 : Entry points
|
||||
***************************************************************************/
|
||||
|
||||
// Based on DenseBase::LazyAssign()
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
const DstXprType& copy_using_evaluator(const DstXprType& dst, const SrcXprType& src)
|
||||
{
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
internal::copy_using_evaluator_traits<DstXprType, SrcXprType>::debug();
|
||||
#endif
|
||||
copy_using_evaluator_impl<DstXprType, SrcXprType>::run(const_cast<DstXprType&>(dst), src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
// Based on DenseBase::swap()
|
||||
// TODO: Chech whether we need to do something special for swapping two
|
||||
// Arrays or Matrices.
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void swap_using_evaluator(const DstXprType& dst, const SrcXprType& src)
|
||||
{
|
||||
copy_using_evaluator(SwapWrapper<DstXprType>(const_cast<DstXprType&>(dst)), src);
|
||||
}
|
||||
|
||||
// Based on MatrixBase::operator+= (in CwiseBinaryOp.h)
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void add_assign_using_evaluator(const MatrixBase<DstXprType>& dst, const MatrixBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
// Based on ArrayBase::operator+=
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void add_assign_using_evaluator(const ArrayBase<DstXprType>& dst, const ArrayBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_sum_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
// TODO: Add add_assign_using_evaluator for EigenBase ?
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void subtract_assign_using_evaluator(const MatrixBase<DstXprType>& dst, const MatrixBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void subtract_assign_using_evaluator(const ArrayBase<DstXprType>& dst, const ArrayBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_difference_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void multiply_assign_using_evaluator(const ArrayBase<DstXprType>& dst, const ArrayBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_product_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
template<typename DstXprType, typename SrcXprType>
|
||||
void divide_assign_using_evaluator(const ArrayBase<DstXprType>& dst, const ArrayBase<SrcXprType>& src)
|
||||
{
|
||||
typedef typename DstXprType::Scalar Scalar;
|
||||
SelfCwiseBinaryOp<internal::scalar_quotient_op<Scalar>, DstXprType, SrcXprType> tmp(dst.const_cast_derived());
|
||||
copy_using_evaluator(tmp, src.derived());
|
||||
}
|
||||
|
||||
|
||||
} // namespace internal
|
||||
|
||||
#endif // EIGEN_ASSIGN_EVALUATOR_H
|
File diff suppressed because it is too large
Load Diff
@ -110,18 +110,4 @@ class ProductImpl<Lhs,Rhs,Dense> : public internal::dense_xpr_base<Product<Lhs,R
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
* Implementation of matrix base methods
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/** \internal used to test the evaluator only
|
||||
*/
|
||||
template<typename Lhs,typename Rhs>
|
||||
const Product<Lhs,Rhs>
|
||||
prod(const Lhs& lhs, const Rhs& rhs)
|
||||
{
|
||||
return Product<Lhs,Rhs>(lhs,rhs);
|
||||
}
|
||||
|
||||
#endif // EIGEN_PRODUCT_H
|
||||
|
@ -162,7 +162,6 @@ ei_add_test(nullary)
|
||||
ei_add_test(nesting_ops "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
ei_add_test(zerosized)
|
||||
ei_add_test(dontalign)
|
||||
ei_add_test(evaluators)
|
||||
ei_add_test(sizeoverflow)
|
||||
ei_add_test(prec_inverse_4x4)
|
||||
ei_add_test(vectorwiseop)
|
||||
|
@ -1,264 +0,0 @@
|
||||
#define EIGEN_ENABLE_EVALUATORS
|
||||
#include "main.h"
|
||||
|
||||
using internal::copy_using_evaluator;
|
||||
using namespace std;
|
||||
|
||||
#define VERIFY_IS_APPROX_EVALUATOR(DEST,EXPR) VERIFY_IS_APPROX(copy_using_evaluator(DEST,(EXPR)), (EXPR).eval());
|
||||
#define VERIFY_IS_APPROX_EVALUATOR2(DEST,EXPR,REF) VERIFY_IS_APPROX(copy_using_evaluator(DEST,(EXPR)), (REF).eval());
|
||||
|
||||
void test_evaluators()
|
||||
{
|
||||
// Testing Matrix evaluator and Transpose
|
||||
Vector2d v = Vector2d::Random();
|
||||
const Vector2d v_const(v);
|
||||
Vector2d v2;
|
||||
RowVector2d w;
|
||||
|
||||
VERIFY_IS_APPROX_EVALUATOR(v2, v);
|
||||
VERIFY_IS_APPROX_EVALUATOR(v2, v_const);
|
||||
|
||||
// Testing Transpose
|
||||
VERIFY_IS_APPROX_EVALUATOR(w, v.transpose()); // Transpose as rvalue
|
||||
VERIFY_IS_APPROX_EVALUATOR(w, v_const.transpose());
|
||||
|
||||
copy_using_evaluator(w.transpose(), v); // Transpose as lvalue
|
||||
VERIFY_IS_APPROX(w,v.transpose().eval());
|
||||
|
||||
copy_using_evaluator(w.transpose(), v_const);
|
||||
VERIFY_IS_APPROX(w,v_const.transpose().eval());
|
||||
|
||||
// Testing Array evaluator
|
||||
ArrayXXf a(2,3);
|
||||
ArrayXXf b(3,2);
|
||||
a << 1,2,3, 4,5,6;
|
||||
const ArrayXXf a_const(a);
|
||||
|
||||
VERIFY_IS_APPROX_EVALUATOR(b, a.transpose());
|
||||
|
||||
VERIFY_IS_APPROX_EVALUATOR(b, a_const.transpose());
|
||||
|
||||
// Testing CwiseNullaryOp evaluator
|
||||
copy_using_evaluator(w, RowVector2d::Random());
|
||||
VERIFY((w.array() >= -1).all() && (w.array() <= 1).all()); // not easy to test ...
|
||||
|
||||
VERIFY_IS_APPROX_EVALUATOR(w, RowVector2d::Zero());
|
||||
|
||||
VERIFY_IS_APPROX_EVALUATOR(w, RowVector2d::Constant(3));
|
||||
|
||||
// mix CwiseNullaryOp and transpose
|
||||
VERIFY_IS_APPROX_EVALUATOR(w, Vector2d::Zero().transpose());
|
||||
|
||||
{
|
||||
int s = internal::random<int>(1,100);
|
||||
MatrixXf a(s,s), b(s,s), c(s,s), d(s,s);
|
||||
a.setRandom();
|
||||
b.setRandom();
|
||||
c.setRandom();
|
||||
d.setRandom();
|
||||
VERIFY_IS_APPROX_EVALUATOR(d, (a + b));
|
||||
VERIFY_IS_APPROX_EVALUATOR(d, (a + b).transpose());
|
||||
VERIFY_IS_APPROX_EVALUATOR2(d, prod(a,b).transpose(), (a*b).transpose());
|
||||
VERIFY_IS_APPROX_EVALUATOR2(d, prod(a,b) + prod(b,c), a*b + b*c);
|
||||
|
||||
// copy_using_evaluator(d, a.transpose() + (a.transpose() * (b+b)));
|
||||
// cout << d << endl;
|
||||
}
|
||||
|
||||
// this does not work because Random is eval-before-nested:
|
||||
// copy_using_evaluator(w, Vector2d::Random().transpose());
|
||||
|
||||
// test CwiseUnaryOp
|
||||
VERIFY_IS_APPROX_EVALUATOR(v2, 3 * v);
|
||||
VERIFY_IS_APPROX_EVALUATOR(w, (3 * v).transpose());
|
||||
VERIFY_IS_APPROX_EVALUATOR(b, (a + 3).transpose());
|
||||
VERIFY_IS_APPROX_EVALUATOR(b, (2 * a_const + 3).transpose());
|
||||
|
||||
// test CwiseBinaryOp
|
||||
VERIFY_IS_APPROX_EVALUATOR(v2, v + Vector2d::Ones());
|
||||
VERIFY_IS_APPROX_EVALUATOR(w, (v + Vector2d::Ones()).transpose().cwiseProduct(RowVector2d::Constant(3)));
|
||||
|
||||
// dynamic matrices and arrays
|
||||
MatrixXd mat1(6,6), mat2(6,6);
|
||||
VERIFY_IS_APPROX_EVALUATOR(mat1, MatrixXd::Identity(6,6));
|
||||
VERIFY_IS_APPROX_EVALUATOR(mat2, mat1);
|
||||
copy_using_evaluator(mat2.transpose(), mat1);
|
||||
VERIFY_IS_APPROX(mat2.transpose(), mat1);
|
||||
|
||||
ArrayXXd arr1(6,6), arr2(6,6);
|
||||
VERIFY_IS_APPROX_EVALUATOR(arr1, ArrayXXd::Constant(6,6, 3.0));
|
||||
VERIFY_IS_APPROX_EVALUATOR(arr2, arr1);
|
||||
|
||||
// test direct traversal
|
||||
Matrix3f m3;
|
||||
Array33f a3;
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Identity()); // matrix, nullary
|
||||
// TODO: find a way to test direct traversal with array
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3.transpose(), Matrix3f::Identity().transpose()); // transpose
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, 2 * Matrix3f::Identity()); // unary
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Identity() + m3); // binary
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3.block(0,0,2,2), Matrix3f::Identity().block(1,1,2,2)); // block
|
||||
|
||||
// test linear traversal
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Zero()); // matrix, nullary
|
||||
VERIFY_IS_APPROX_EVALUATOR(a3, Array33f::Zero()); // array
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3.transpose(), Matrix3f::Zero().transpose()); // transpose
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, 2 * Matrix3f::Zero()); // unary
|
||||
VERIFY_IS_APPROX_EVALUATOR(m3, Matrix3f::Zero() + m3); // binary
|
||||
|
||||
// test inner vectorization
|
||||
Matrix4f m4, m4src = Matrix4f::Random();
|
||||
Array44f a4, a4src = Matrix4f::Random();
|
||||
VERIFY_IS_APPROX_EVALUATOR(m4, m4src); // matrix
|
||||
VERIFY_IS_APPROX_EVALUATOR(a4, a4src); // array
|
||||
VERIFY_IS_APPROX_EVALUATOR(m4.transpose(), m4src.transpose()); // transpose
|
||||
// TODO: find out why Matrix4f::Zero() does not allow inner vectorization
|
||||
VERIFY_IS_APPROX_EVALUATOR(m4, 2 * m4src); // unary
|
||||
VERIFY_IS_APPROX_EVALUATOR(m4, m4src + m4src); // binary
|
||||
|
||||
// test linear vectorization
|
||||
MatrixXf mX(6,6), mXsrc = MatrixXf::Random(6,6);
|
||||
ArrayXXf aX(6,6), aXsrc = ArrayXXf::Random(6,6);
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc); // matrix
|
||||
VERIFY_IS_APPROX_EVALUATOR(aX, aXsrc); // array
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX.transpose(), mXsrc.transpose()); // transpose
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX, MatrixXf::Zero(6,6)); // nullary
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX, 2 * mXsrc); // unary
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc + mXsrc); // binary
|
||||
|
||||
// test blocks and slice vectorization
|
||||
VERIFY_IS_APPROX_EVALUATOR(m4, (mXsrc.block<4,4>(1,0)));
|
||||
VERIFY_IS_APPROX_EVALUATOR(aX, ArrayXXf::Constant(10, 10, 3.0).block(2, 3, 6, 6));
|
||||
|
||||
Matrix4f m4ref = m4;
|
||||
copy_using_evaluator(m4.block(1, 1, 2, 3), m3.bottomRows(2));
|
||||
m4ref.block(1, 1, 2, 3) = m3.bottomRows(2);
|
||||
VERIFY_IS_APPROX(m4, m4ref);
|
||||
|
||||
mX.setIdentity(20,20);
|
||||
MatrixXf mXref = MatrixXf::Identity(20,20);
|
||||
mXsrc = MatrixXf::Random(9,12);
|
||||
copy_using_evaluator(mX.block(4, 4, 9, 12), mXsrc);
|
||||
mXref.block(4, 4, 9, 12) = mXsrc;
|
||||
VERIFY_IS_APPROX(mX, mXref);
|
||||
|
||||
// test Map
|
||||
const float raw[3] = {1,2,3};
|
||||
float buffer[3] = {0,0,0};
|
||||
Vector3f v3;
|
||||
Array3f a3f;
|
||||
VERIFY_IS_APPROX_EVALUATOR(v3, Map<const Vector3f>(raw));
|
||||
VERIFY_IS_APPROX_EVALUATOR(a3f, Map<const Array3f>(raw));
|
||||
Vector3f::Map(buffer) = 2*v3;
|
||||
VERIFY(buffer[0] == 2);
|
||||
VERIFY(buffer[1] == 4);
|
||||
VERIFY(buffer[2] == 6);
|
||||
|
||||
// test CwiseUnaryView
|
||||
mat1.setRandom();
|
||||
mat2.setIdentity();
|
||||
MatrixXcd matXcd(6,6), matXcd_ref(6,6);
|
||||
copy_using_evaluator(matXcd.real(), mat1);
|
||||
copy_using_evaluator(matXcd.imag(), mat2);
|
||||
matXcd_ref.real() = mat1;
|
||||
matXcd_ref.imag() = mat2;
|
||||
VERIFY_IS_APPROX(matXcd, matXcd_ref);
|
||||
|
||||
// test Select
|
||||
VERIFY_IS_APPROX_EVALUATOR(aX, (aXsrc > 0).select(aXsrc, -aXsrc));
|
||||
|
||||
// test Replicate
|
||||
mXsrc = MatrixXf::Random(6, 6);
|
||||
VectorXf vX = VectorXf::Random(6);
|
||||
mX.resize(6, 6);
|
||||
VERIFY_IS_APPROX_EVALUATOR(mX, mXsrc.colwise() + vX);
|
||||
matXcd.resize(12, 12);
|
||||
VERIFY_IS_APPROX_EVALUATOR(matXcd, matXcd_ref.replicate(2,2));
|
||||
VERIFY_IS_APPROX_EVALUATOR(matXcd, (matXcd_ref.replicate<2,2>()));
|
||||
|
||||
// test partial reductions
|
||||
VectorXd vec1(6);
|
||||
VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.rowwise().sum());
|
||||
VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.colwise().sum().transpose());
|
||||
|
||||
// test MatrixWrapper and ArrayWrapper
|
||||
mat1.setRandom(6,6);
|
||||
arr1.setRandom(6,6);
|
||||
VERIFY_IS_APPROX_EVALUATOR(mat2, arr1.matrix());
|
||||
VERIFY_IS_APPROX_EVALUATOR(arr2, mat1.array());
|
||||
VERIFY_IS_APPROX_EVALUATOR(mat2, (arr1 + 2).matrix());
|
||||
VERIFY_IS_APPROX_EVALUATOR(arr2, mat1.array() + 2);
|
||||
mat2.array() = arr1 * arr1;
|
||||
VERIFY_IS_APPROX(mat2, (arr1 * arr1).matrix());
|
||||
arr2.matrix() = MatrixXd::Identity(6,6);
|
||||
VERIFY_IS_APPROX(arr2, MatrixXd::Identity(6,6).array());
|
||||
|
||||
// test Reverse
|
||||
VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.reverse());
|
||||
VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.colwise().reverse());
|
||||
VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.rowwise().reverse());
|
||||
arr2.reverse() = arr1;
|
||||
VERIFY_IS_APPROX(arr2, arr1.reverse());
|
||||
|
||||
// test Diagonal
|
||||
VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal());
|
||||
vec1.resize(5);
|
||||
VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal(1));
|
||||
VERIFY_IS_APPROX_EVALUATOR(vec1, mat1.diagonal<-1>());
|
||||
vec1.setRandom();
|
||||
|
||||
mat2 = mat1;
|
||||
copy_using_evaluator(mat1.diagonal(1), vec1);
|
||||
mat2.diagonal(1) = vec1;
|
||||
VERIFY_IS_APPROX(mat1, mat2);
|
||||
|
||||
copy_using_evaluator(mat1.diagonal<-1>(), mat1.diagonal(1));
|
||||
mat2.diagonal<-1>() = mat2.diagonal(1);
|
||||
VERIFY_IS_APPROX(mat1, mat2);
|
||||
|
||||
{
|
||||
// test swapping
|
||||
MatrixXd mat1, mat2, mat1ref, mat2ref;
|
||||
mat1ref = mat1 = MatrixXd::Random(6, 6);
|
||||
mat2ref = mat2 = 2 * mat1 + MatrixXd::Identity(6, 6);
|
||||
swap_using_evaluator(mat1, mat2);
|
||||
mat1ref.swap(mat2ref);
|
||||
VERIFY_IS_APPROX(mat1, mat1ref);
|
||||
VERIFY_IS_APPROX(mat2, mat2ref);
|
||||
|
||||
swap_using_evaluator(mat1.block(0, 0, 3, 3), mat2.block(3, 3, 3, 3));
|
||||
mat1ref.block(0, 0, 3, 3).swap(mat2ref.block(3, 3, 3, 3));
|
||||
VERIFY_IS_APPROX(mat1, mat1ref);
|
||||
VERIFY_IS_APPROX(mat2, mat2ref);
|
||||
|
||||
swap_using_evaluator(mat1.row(2), mat2.col(3).transpose());
|
||||
mat1.row(2).swap(mat2.col(3).transpose());
|
||||
VERIFY_IS_APPROX(mat1, mat1ref);
|
||||
VERIFY_IS_APPROX(mat2, mat2ref);
|
||||
}
|
||||
|
||||
{
|
||||
// test compound assignment
|
||||
const Matrix4d mat_const = Matrix4d::Random();
|
||||
Matrix4d mat, mat_ref;
|
||||
mat = mat_ref = Matrix4d::Identity();
|
||||
add_assign_using_evaluator(mat, mat_const);
|
||||
mat_ref += mat_const;
|
||||
VERIFY_IS_APPROX(mat, mat_ref);
|
||||
|
||||
subtract_assign_using_evaluator(mat.row(1), 2*mat.row(2));
|
||||
mat_ref.row(1) -= 2*mat_ref.row(2);
|
||||
VERIFY_IS_APPROX(mat, mat_ref);
|
||||
|
||||
const ArrayXXf arr_const = ArrayXXf::Random(5,3);
|
||||
ArrayXXf arr, arr_ref;
|
||||
arr = arr_ref = ArrayXXf::Constant(5, 3, 0.5);
|
||||
multiply_assign_using_evaluator(arr, arr_const);
|
||||
arr_ref *= arr_const;
|
||||
VERIFY_IS_APPROX(arr, arr_ref);
|
||||
|
||||
divide_assign_using_evaluator(arr.row(1), arr.row(2) + 1);
|
||||
arr_ref.row(1) /= (arr_ref.row(2) + 1);
|
||||
VERIFY_IS_APPROX(arr, arr_ref);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user