first operation test works -- yaygit add * there are some memory issues (deletion of index ptr)

This commit is contained in:
Christian Zimmermann 2017-02-22 19:06:23 +01:00
parent b3f7dad655
commit db4ad28f02
8 changed files with 226 additions and 45 deletions

View file

@ -7,6 +7,14 @@ namespace MultiArrayTools
* IndefinitIndexBase * * IndefinitIndexBase *
************************/ ************************/
IndefinitIndexBase::~IndefinitIndexBase()
{
freeLinked();
mLinked = nullptr;
mMajor = nullptr;
mSoftLinked = nullptr;
}
size_t IndefinitIndexBase::pos() const size_t IndefinitIndexBase::pos() const
{ {
return mPos; return mPos;
@ -30,9 +38,9 @@ namespace MultiArrayTools
bool IndefinitIndexBase::link(IndefinitIndexBase* toLink) bool IndefinitIndexBase::link(IndefinitIndexBase* toLink)
{ {
if(toLink->rangeType() != rangeType() and toLink->name() == name()){ if(toLink->rangeType() != rangeType() and toLink->name() == name()){
assert(0);
// throw !! // throw !!
} }
if(toLink->rangeType() == rangeType() and toLink->name() == name()){ if(toLink->rangeType() == rangeType() and toLink->name() == name()){
if(mLinked == toLink){ if(mLinked == toLink){
return true; // dont link twice the same return true; // dont link twice the same
@ -52,10 +60,14 @@ namespace MultiArrayTools
void IndefinitIndexBase::freeLinked() void IndefinitIndexBase::freeLinked()
{ {
if(linked()){ if(mLinked != nullptr){
mLinked->freeLinked(); mLinked->freeLinked();
mLinked = nullptr; mLinked = nullptr;
} }
if(mSoftLinked != nullptr){
mSoftLinked->freeLinked();
mSoftLinked = nullptr;
}
} }
bool IndefinitIndexBase::linked() const bool IndefinitIndexBase::linked() const
@ -66,11 +78,9 @@ namespace MultiArrayTools
void IndefinitIndexBase::setPos(size_t pos) void IndefinitIndexBase::setPos(size_t pos)
{ {
mPos = pos; mPos = pos;
//VCHECK(mName);
if(linked()){ if(linked()){
mLinked->setPos(pos); mLinked->setPos(pos);
mLinked->evalMajor(); mLinked->evalMajor();
//VCHECK(mLinked->name());
} }
} }

View file

@ -18,7 +18,7 @@ namespace MultiArrayTools
{ {
public: public:
DEFAULT_MEMBERS(IndefinitIndexBase); DEFAULT_MEMBERS(IndefinitIndexBase);
virtual ~IndefinitIndexBase() {} virtual ~IndefinitIndexBase();
virtual IndefinitIndexBase& operator=(size_t pos) = 0; virtual IndefinitIndexBase& operator=(size_t pos) = 0;
virtual IndefinitIndexBase& operator++() = 0; virtual IndefinitIndexBase& operator++() = 0;
@ -64,6 +64,7 @@ namespace MultiArrayTools
IndefinitIndexBase* mLinked = nullptr; IndefinitIndexBase* mLinked = nullptr;
IndefinitIndexBase* mMajor = nullptr; IndefinitIndexBase* mMajor = nullptr;
IndefinitIndexBase* mSoftLinked = nullptr;
}; };
template <class Index> template <class Index>

View file

@ -11,7 +11,8 @@ namespace MultiArrayTools
MultiArrayOperationBase<T,Range>:: MultiArrayOperationBase<T,Range>::
MultiArrayOperationBase(MultiArray<T,Range>& ma, MultiArrayOperationBase(MultiArray<T,Range>& ma,
const Name& nm) : mArrayRef(ma), const Name& nm) : mArrayRef(ma),
mIibPtr(new IndexType(mArrayRef.begin())) mIibPtr(new IndexType(mArrayRef.begin())),
mNm(nm)
{ {
mIibPtr->name(nm); mIibPtr->name(nm);
} }
@ -19,7 +20,7 @@ namespace MultiArrayTools
template <typename T, class Range> template <typename T, class Range>
MultiArrayOperationBase<T,Range>::~MultiArrayOperationBase() MultiArrayOperationBase<T,Range>::~MultiArrayOperationBase()
{ {
delete mIibPtr; //delete mIibPtr;
} }
template <typename T, class Range> template <typename T, class Range>
@ -30,11 +31,9 @@ namespace MultiArrayTools
IndexType& iref = dynamic_cast<IndexType&>(*mIibPtr); IndexType& iref = dynamic_cast<IndexType&>(*mIibPtr);
for(iref = mArrayRef.begin().pos(); iref != mArrayRef.end(); ++iref){ for(iref = mArrayRef.begin().pos(); iref != mArrayRef.end(); ++iref){
// build in vectorization later // build in vectorization later
//VCHECK(iref.pos());
//VCHECK(in.mIibPtr->pos());
//VCHECK(in.get());
get() = in.get(); get() = in.get();
} }
mIibPtr->freeLinked();
return *this; return *this;
} }
@ -43,21 +42,62 @@ namespace MultiArrayTools
MultiArrayOperationBase<T,Range>& MultiArrayOperationBase<T,Range>&
MultiArrayOperationBase<T,Range>::operator=(const MultiArrayOperationBase<T, Range2>& in) MultiArrayOperationBase<T,Range>::operator=(const MultiArrayOperationBase<T, Range2>& in)
{ {
//CHECK;
in.linkIndicesTo(mIibPtr); in.linkIndicesTo(mIibPtr);
for(*mIibPtr = mArrayRef.begin(); *mIibPtr != mArrayRef.end(); ++(*mIibPtr)){ for(*mIibPtr = mArrayRef.begin(); *mIibPtr != mArrayRef.end(); ++(*mIibPtr)){
// build in vectorization later // build in vectorization later
get() = in.get(); get() = in.get();
} }
mIibPtr->freeLinked();
return *this; return *this;
} }
template <typename T, class Range> template <typename T, class Range>
template <class Operation, class... Ranges> template <class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...> MultiArrayOperation<T,Range,Operation,Ranges...>
MultiArrayOperationBase<T,Range>::operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs) MultiArrayOperationBase<T,Range>::operator()(Operation& op, const MultiArrayOperationBase<T,Ranges>&... secs)
{ {
return MultiArrayOperation<T,Range,Operation,Ranges...>(op, secs...); return MultiArrayOperation<T,Range,Operation,Ranges...>(mArrayRef, mNm, op, secs...);
}
template <typename T, class Range>
template <class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...>
MultiArrayOperationBase<T,Range>::operator()(const Operation& op,
const MultiArrayOperationBase<T,Ranges>&... secs)
{
return MultiArrayOperation<T,Range,Operation,Ranges...>(mArrayRef, mNm, op, secs...);
}
template <typename T, class Range>
template <class Range2>
MultiArrayOperation<T,Range,std::plus<T>,Range2>
MultiArrayOperationBase<T,Range>::operator+(const MultiArrayOperationBase<T,Range2>& sec)
{
return operator()(std::plus<T>(), sec);
}
template <typename T, class Range>
template <class Range2>
MultiArrayOperation<T,Range,std::minus<T>,Range2>
MultiArrayOperationBase<T,Range>::operator-(const MultiArrayOperationBase<T,Range2>& sec)
{
return operator()(std::minus<T>(), sec);
}
template <typename T, class Range>
template <class Range2>
MultiArrayOperation<T,Range,std::multiplies<T>,Range2>
MultiArrayOperationBase<T,Range>::operator*(const MultiArrayOperationBase<T,Range2>& sec)
{
return operator()(std::multiplies<T>(), sec);
}
template <typename T, class Range>
template <class Range2>
MultiArrayOperation<T,Range,std::divides<T>,Range2>
MultiArrayOperationBase<T,Range>::operator/(const MultiArrayOperationBase<T,Range2>& sec)
{
return operator()(std::divides<T>(), sec);
} }
template <typename T, class Range> template <typename T, class Range>
@ -112,7 +152,7 @@ namespace MultiArrayTools
template <class IndexTuple> template <class IndexTuple>
static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target) static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
{ {
std::get<N>(itp).linkTo(target); std::get<N>(itp).linkIndicesTo(target);
linkTupleIndicesTo<N-1>(itp, target); linkTupleIndicesTo<N-1>(itp, target);
} }
}; };
@ -123,30 +163,63 @@ namespace MultiArrayTools
template <class IndexTuple> template <class IndexTuple>
static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target) static void linkTupleIndicesTo(IndexTuple& itp, IndefinitIndexBase* target)
{ {
std::get<0>(itp).linkTo(target); std::get<0>(itp).linkIndicesTo(target);
} }
}; };
template <size_t N> template <size_t N>
struct OperationCall struct OperationCall
{ {
template <class Operation, class Tuple, class... MBases> template <typename T, class Operation, class Tuple, class... MBases>
auto callOperation(Operation& op, Tuple& tp, MBases&... secs) static auto callOperation(Operation& op, const Tuple& tp, const T& first, const MBases&... secs)
-> decltype(callOperation(op, tp, std::get<N-1>(tp), secs...)) -> decltype(OperationCall<N-1>::template callOperation(op, tp, std::get<N>(tp), secs...))
{ {
return callOperation(op, tp, std::get<N-1>(tp), secs...); return OperationCall<N-1>::template callOperation(op, tp, first, std::get<N>(tp), secs...);
}
template <typename T, class Operation, class Tuple, class... MBases>
static auto callOperation(const Operation& op, const Tuple& tp, const T& first, const MBases&... secs)
-> decltype(OperationCall<N-1>::template callOperation(op, tp, std::get<N>(tp), secs...))
{
return OperationCall<N-1>::template callOperation(op, tp, first, std::get<N>(tp), secs...);
} }
}; };
template <> template <>
struct OperationCall<0> struct OperationCall<0>
{ {
template <class Operation, class Tuple, class... MBases> template <typename T, class Operation, class Tuple, class... MBases>
auto callOperation(Operation& op, Tuple& tp, MBases&... secs) -> decltype(op(secs.get()...)) static auto callOperation(Operation& op, const Tuple& tp, const T& first, const MBases&... secs)
-> decltype(op(first, std::get<0>(tp).get(), secs.get()...))
{ {
return op(secs.get()...); return op(first, std::get<0>(tp).get(), secs.get()...);
}
template <typename T, class Operation, class Tuple, class... MBases>
static auto callOperation(const Operation& op, const Tuple& tp, const T& first, const MBases&... secs)
-> decltype(op(first.get(), std::get<0>(tp).get(), secs.get()...))
{
return op(first, std::get<0>(tp).get(), secs.get()...);
} }
}; };
template <typename T, class Range, class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...>::
MultiArrayOperation(MultiArray<T,Range>& ma, const Name& nm,
Operation& op,
const MultiArrayOperationBase<T,Ranges>&... secs) :
MultiArrayOperationBase<T,Range>(ma, nm),
mOp(op),
mSecs(std::make_tuple(secs...)) {}
template <typename T, class Range, class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...>::
MultiArrayOperation(MultiArray<T,Range>& ma, const Name& nm,
const Operation& op,
const MultiArrayOperationBase<T,Ranges>&... secs) :
MultiArrayOperationBase<T,Range>(ma, nm),
mOp(op),
mSecs(std::make_tuple(secs...)) {}
template <typename T, class Range, class Operation, class... Ranges> template <typename T, class Range, class Operation, class... Ranges>
size_t MultiArrayOperation<T,Range,Operation,Ranges...>::argNum() const size_t MultiArrayOperation<T,Range,Operation,Ranges...>::argNum() const
@ -158,20 +231,24 @@ namespace MultiArrayTools
void MultiArrayOperation<T,Range,Operation,Ranges...>::linkIndicesTo(IndefinitIndexBase* target) const void MultiArrayOperation<T,Range,Operation,Ranges...>::linkIndicesTo(IndefinitIndexBase* target) const
{ {
OB::mIibPtr->linkTo(target); OB::mIibPtr->linkTo(target);
TupleIndicesLinker<sizeof...(Ranges)>::linkTupleIndicesTo(mSecs, target); TupleIndicesLinker<sizeof...(Ranges)-1>::linkTupleIndicesTo(mSecs, target);
} }
template <typename T, class Range, class Operation, class... Ranges> template <typename T, class Range, class Operation, class... Ranges>
T& MultiArrayOperation<T,Range,Operation,Ranges...>::get() T& MultiArrayOperation<T,Range,Operation,Ranges...>::get()
{ {
mVal = OperationCall<sizeof...(Ranges)>::callOperation(mOp, mSecs); mVal = OperationCall<sizeof...(Ranges)-1>::
template callOperation(mOp, mSecs,
OB::mArrayRef[*dynamic_cast<typename OB::IndexType*>(OB::mIibPtr)]);
return mVal; return mVal;
} }
template <typename T, class Range, class Operation, class... Ranges> template <typename T, class Range, class Operation, class... Ranges>
const T& MultiArrayOperation<T,Range,Operation,Ranges...>::get() const const T& MultiArrayOperation<T,Range,Operation,Ranges...>::get() const
{ {
mVal = OperationCall<sizeof...(Ranges)>::callOperation(mOp, mSecs); mVal = OperationCall<sizeof...(Ranges)-1>::
template callOperation(mOp, mSecs,
OB::mArrayRef[*dynamic_cast<typename OB::IndexType*>(OB::mIibPtr)]);
return mVal; return mVal;
} }

View file

@ -33,19 +33,23 @@ namespace MultiArrayTools
template <class Operation, class... Ranges> template <class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...> MultiArrayOperation<T,Range,Operation,Ranges...>
operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs); operator()(Operation& op, const MultiArrayOperationBase<T,Ranges>&... secs);
template <class Operation, class... Ranges>
MultiArrayOperation<T,Range,Operation,Ranges...>
operator()(const Operation& op, const MultiArrayOperationBase<T,Ranges>&... secs);
template <class Range2> template <class Range2>
MultiArrayOperation<T,Range,std::plus<T>,Range2> operator+(MultiArrayOperationBase<T,Range2>& sec); MultiArrayOperation<T,Range,std::plus<T>,Range2> operator+(const MultiArrayOperationBase<T,Range2>& sec);
template <class Range2> template <class Range2>
MultiArrayOperation<T,Range,std::minus<T>,Range2> operator-(MultiArrayOperationBase<T,Range2>& sec); MultiArrayOperation<T,Range,std::minus<T>,Range2> operator-(const MultiArrayOperationBase<T,Range2>& sec);
template <class Range2> template <class Range2>
MultiArrayOperation<T,Range,std::multiplies<T>,Range2> operator*(MultiArrayOperationBase<T,Range2>& sec); MultiArrayOperation<T,Range,std::multiplies<T>,Range2> operator*(const MultiArrayOperationBase<T,Range2>& sec);
template <class Range2> template <class Range2>
MultiArrayOperation<T,Range,std::divides<T>,Range2> operator/(MultiArrayOperationBase<T,Range2>& sec); MultiArrayOperation<T,Range,std::divides<T>,Range2> operator/(const MultiArrayOperationBase<T,Range2>& sec);
virtual size_t argNum() const; virtual size_t argNum() const;
@ -60,12 +64,10 @@ namespace MultiArrayTools
virtual const T& get(IndefinitIndexBase* iibPtr) const; virtual const T& get(IndefinitIndexBase* iibPtr) const;
protected: protected:
// HERE !!!!!!
MultiArray<T,Range>& mArrayRef; MultiArray<T,Range>& mArrayRef;
IndefinitIndexBase mutable* mIibPtr = nullptr; IndefinitIndexBase mutable* mIibPtr = nullptr;
Name mNm;
}; };
template <typename T, class Range, class Operation, class... Ranges> template <typename T, class Range, class Operation, class... Ranges>
@ -74,8 +76,14 @@ namespace MultiArrayTools
public: public:
typedef MultiArrayOperationBase<T,Range> OB; typedef MultiArrayOperationBase<T,Range> OB;
typedef std::tuple<MultiArrayOperationBase<T,Ranges>... > OBT;
MultiArrayOperation(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs); MultiArrayOperation(MultiArray<T,Range>& ma, const Name& nm,
Operation& op, const MultiArrayOperationBase<T,Ranges>&... secs);
MultiArrayOperation(MultiArray<T,Range>& ma, const Name& nm,
const Operation& op, const MultiArrayOperationBase<T,Ranges>&... secs);
virtual size_t argNum() const override; virtual size_t argNum() const override;
virtual void linkIndicesTo(IndefinitIndexBase* target) const override; virtual void linkIndicesTo(IndefinitIndexBase* target) const override;
@ -87,7 +95,7 @@ namespace MultiArrayTools
mutable T mVal; mutable T mVal;
Operation mOp; Operation mOp;
std::tuple<MultiArrayOperationBase<T,Ranges>... > mSecs; OBT mSecs;
}; };

View file

@ -145,7 +145,13 @@ namespace MultiArrayTools
IndexSubOrder<sizeof...(Indices)-1>::subOrd(mIPack, this); IndexSubOrder<sizeof...(Indices)-1>::subOrd(mIPack, this);
IIB::mPos = evaluate(*this); IIB::mPos = evaluate(*this);
} }
template <class... Indices>
MultiIndex<Indices...>::~MultiIndex()
{
IndexSubOrder<sizeof...(Indices)-1>::subOrd(mIPack, nullptr);
}
template <class... Indices> template <class... Indices>
MultiIndex<Indices...>& MultiIndex<Indices...>::operator++() MultiIndex<Indices...>& MultiIndex<Indices...>::operator++()
{ {
@ -256,25 +262,32 @@ namespace MultiArrayTools
template <class... Indices> template <class... Indices>
bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink) bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink)
{ {
if(toLink->rangeType() != rangeType() and toLink->name() == IIB::name()){ if(toLink->rangeType() != rangeType() and
toLink->name() == IIB::name() and
not (IIB::name() == "master")){
// throw !! // throw !!
assert(0); assert(0);
} }
if(toLink->rangeType() == rangeType() and toLink->name() == IIB::name()){ if(toLink->rangeType() == rangeType() and toLink->name() == IIB::name()){
if(IIB::mLinked == toLink){ if(IIB::mLinked == toLink or IIB::mSoftLinked == toLink){
return true; // dont link twice the same return true; // dont link twice the same
} }
else if(IIB::mLinked == nullptr){ else if(IIB::mLinked == nullptr and IIB::mSoftLinked == nullptr){
IIB::mLinked = toLink; IIB::mLinked = toLink;
return true; return true;
} }
else { else {
return IIB::mLinked->link(toLink); if(IIB::mLinked == nullptr){
return IIB::mSoftLinked->link(toLink);
}
else {
return IIB::mLinked->link(toLink);
}
} }
} }
else { else {
if(linkLower(toLink)){ if(linkLower(toLink)){
IIB::mSoftLinked = IIB::mLinked;
IIB::mLinked = nullptr; IIB::mLinked = nullptr;
return true; return true;
} }

View file

@ -38,6 +38,8 @@ namespace MultiArrayTools
MultiIndex(RangeBase<MultiIndex<Indices...> > const* range, MultiIndex(RangeBase<MultiIndex<Indices...> > const* range,
const IndexPack& ipack); const IndexPack& ipack);
virtual ~MultiIndex();
virtual MultiIndex& operator++() override; virtual MultiIndex& operator++() override;
virtual MultiIndex& operator--() override; virtual MultiIndex& operator--() override;
virtual MultiIndex& operator+=(int n) override; virtual MultiIndex& operator+=(int n) override;

View file

@ -48,6 +48,9 @@ namespace MultiArrayTools
bool MultiRangeType::operator==(const MultiRangeType& in) const bool MultiRangeType::operator==(const MultiRangeType& in) const
{ {
if(multi() xor in.multi()){
return false;
}
if(multi()){ if(multi()){
return *mMultiType == *in.mMultiType; return *mMultiType == *in.mMultiType;
} }
@ -58,6 +61,9 @@ namespace MultiArrayTools
bool MultiRangeType::operator!=(const MultiRangeType& in) const bool MultiRangeType::operator!=(const MultiRangeType& in) const
{ {
if(multi() xor in.multi()){
return true;
}
if(multi()){ if(multi()){
return *mMultiType != *in.mMultiType; return *mMultiType != *in.mMultiType;
} }

View file

@ -77,6 +77,32 @@ namespace {
MultiArray3dAny ma3d; MultiArray3dAny ma3d;
}; };
class OperationTest : public ::testing::Test
{
protected:
typedef MAT::SingleRange<char,MAT::RangeType::ANY> Range1dAny;
typedef MAT::MultiRange<Range1dAny,Range1dAny> Range2dAny;
typedef MAT::MultiRange<Range1dAny,Range1dAny,Range1dAny> Range3dAny;
typedef MAT::MultiArray<int,Range2dAny> MultiArray2dAny;
typedef MAT::MultiArray<int,Range3dAny> MultiArray3dAny;
OperationTest() : r1({'a','b','c'}), r2({'a','b','c','d'}), r3({'a','b'}),
ra(r1,r2),
r3d(r1,r2,r3),
ma(ra, {-5,6,2,1,9,54,27,-7,-13,32,90,-67}),
ma3d(r3d, {-5,6,2,1,9,54,27,-7,-13,32,90,-67,
-10,16,-2,101,39,-64,81,-22,14,34,95,-62}) {}
Range1dAny r1;
Range1dAny r2;
Range1dAny r3;
Range2dAny ra;
Range3dAny r3d;
MultiArray2dAny ma;
MultiArray3dAny ma3d;
};
TEST_F(OneDimTest, CorrectExtensions) TEST_F(OneDimTest, CorrectExtensions)
{ {
EXPECT_EQ(ma.size(), 5); EXPECT_EQ(ma.size(), 5);
@ -186,7 +212,7 @@ namespace {
auto i1 = i.template getIndex<0>(); auto i1 = i.template getIndex<0>();
auto i2 = i.template getIndex<1>(); auto i2 = i.template getIndex<1>();
auto i3 = i.template getIndex<2>(); auto i3 = i.template getIndex<2>();
ma3d2("gamma","alpha","beta") = ma3d("alpha","beta","gamma"); ma3d2("gamma","alpha","beta") = ma3d("alpha","beta","gamma");
EXPECT_EQ(ma3d2[i(i1 = 0,i2 = 0,i3 = 0)],-5); EXPECT_EQ(ma3d2[i(i1 = 0,i2 = 0,i3 = 0)],-5);
@ -216,7 +242,45 @@ namespace {
EXPECT_EQ(ma3d2[i(i1 = 0,i2 = 2,i3 = 3)],95); EXPECT_EQ(ma3d2[i(i1 = 0,i2 = 2,i3 = 3)],95);
EXPECT_EQ(ma3d2[i(i1 = 1,i2 = 2,i3 = 3)],-62); EXPECT_EQ(ma3d2[i(i1 = 1,i2 = 2,i3 = 3)],-62);
} }
TEST_F(OperationTest, CorrectlyAdded)
{
MultiArray3dAny ma3d2(r3d);
auto i = ma3d2.begin();
auto i1 = i.template getIndex<0>();
auto i2 = i.template getIndex<1>();
auto i3 = i.template getIndex<2>();
ma3d2("alpha","beta","gamma") = ma3d("alpha","beta","gamma") + ma("alpha","beta");
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 0, i3 = 0)], -10);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 0, i3 = 1)], 1);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 1, i3 = 0)], 8);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 1, i3 = 1)], 7);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 2, i3 = 0)], 11);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 2, i3 = 1)], 56);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 3, i3 = 0)], 28);
EXPECT_EQ(ma3d2[i(i1 = 0, i2 = 3, i3 = 1)], -6);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 0, i3 = 0)], -4);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 0, i3 = 1)], 41);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 1, i3 = 0)], 144);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 1, i3 = 1)], -13);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 2, i3 = 0)], 17);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 2, i3 = 1)], 43);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 3, i3 = 0)], -9);
EXPECT_EQ(ma3d2[i(i1 = 1, i2 = 3, i3 = 1)], 94);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 0, i3 = 0)], 26);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 0, i3 = 1)], -77);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 1, i3 = 0)], 113);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 1, i3 = 1)], 10);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 2, i3 = 0)], 104);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 2, i3 = 1)], 124);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 3, i3 = 0)], 28);
EXPECT_EQ(ma3d2[i(i1 = 2, i2 = 3, i3 = 1)], -129);
}
} // end namespace } // end namespace
int main(int argc, char** argv) int main(int argc, char** argv)