fixes/more functionalities in MIndex + add 2d Array test

This commit is contained in:
Christian Zimmermann 2022-11-23 01:25:59 +01:00
parent 216bb3f56e
commit 1f27826aff
6 changed files with 132 additions and 9 deletions

View file

@ -130,6 +130,13 @@ namespace CNORXZ
{
return std::make_shared<IndexInterface<I,MetaType>>( *i - n );
}
template <class I1, class I2, typename MType1, typename MType2>
decltype(auto) operator*(const IndexInterface<I1,MType1>& a,
const IndexInterface<I2,MType2>& b)
{
return MIndex<I1,I2>(a.THIS(),b.THIS());
}
}
#endif

View file

@ -87,6 +87,9 @@ namespace CNORXZ
template <class I, typename MetaType>
IndexPtr<I,MetaType> operator-(const IndexPtr<I,MetaType>& i, Int n);
template <class I1, class I2, typename MType1, typename MType2>
decltype(auto) operator*(const IndexInterface<I1,MType1>& a,
const IndexInterface<I2,MType2>& b);
}
#endif

View file

@ -42,6 +42,22 @@ namespace CNORXZ
}
}
template <class BlockType, class... Indices>
inline void GMIndex<BlockType,Indices...>::mkPos()
{
mLex = iter<0,NI>
([&](auto i) { return std::get<i>(mIPack)->lex() * std::get<i>(mLexBlockSizes).val(); },
[](const auto&... e) { return (e + ...); });
if constexpr(not std::is_same<BlockType,None>::value){
IB::mPos = iter<0,NI>
([&](auto i) { return std::get<i>(mIPack)->pos() * std::get<i>(mBlockSizes).val(); },
[](const auto&... e) { return (e + ...); });
}
else {
IB::mPos = mLex;
}
}
template <class BlockType, class... Indices>
template <SizeT... Is>
constexpr decltype(auto) GMIndex<BlockType,Indices...>::mkLexBlockSizes(const IndexPack& ipack, Isq<Is...> is)
@ -120,12 +136,12 @@ namespace CNORXZ
IndexInterface<GMIndex<BlockType,Indices...>,Tuple<typename Indices::MetaType...>>(0),
mRange(rangeCast<RangeType>(i.range())),
mIPack(mkIPack(Isqr<0,NI>{})),
mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<0,NI-1>{})),
mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<1,NI>{})),
mBlockSizes(i.mBlockSizes),
mLMax(mkLMax(mIPack)),
mPMax(mkPMax(mIPack,mBlockSizes))
{
*this = i.pos();
*this = i.lex();
}
template <class BlockType, class... Indices>
@ -134,11 +150,37 @@ namespace CNORXZ
IndexInterface<GMIndex<BlockType,Indices...>,Tuple<typename Indices::MetaType...>>::operator=(0);
mRange = rangeCast<RangeType>(i.range());
mIPack = mkIPack(Isqr<0,NI>{});
mLexBlockSizes = mkLexBlockSizes(mIPack,Isqr<0,NI-1>{});
mLexBlockSizes = mkLexBlockSizes(mIPack,Isqr<1,NI>{});
mBlockSizes = i.mBlockSizes;
mLMax = mkLMax(mIPack);
mPMax = mkPMax(mIPack,mBlockSizes);
return *this = i.pos();
return *this = i.lex();
}
template <class BlockType, class... Indices>
constexpr GMIndex<BlockType,Indices...>::GMIndex(const Indices&... is) :
IndexInterface<GMIndex<BlockType,Indices...>,Tuple<typename Indices::MetaType...>>(0),
mRange(std::dynamic_pointer_cast<RangeType>(mrange(is.range()...))),
mIPack(std::make_shared<Indices>(is)...),
mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<1,NI>{})),
mBlockSizes(),
mLMax(mkLMax(mIPack)),
mPMax(mkPMax(mIPack,mBlockSizes))
{
mkPos();
}
template <class BlockType, class... Indices>
constexpr GMIndex<BlockType,Indices...>::GMIndex(const Sptr<Indices>&... is) :
IndexInterface<GMIndex<BlockType,Indices...>,Tuple<typename Indices::MetaType...>>(0),
mRange(std::dynamic_pointer_cast<RangeType>(mrange(is->range()...))),
mIPack(is...),
mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<1,NI>{})),
mBlockSizes(),
mLMax(mkLMax(mIPack)),
mPMax(mkPMax(mIPack,mBlockSizes))
{
mkPos();
}
template <class BlockType, class... Indices>
@ -146,7 +188,7 @@ namespace CNORXZ
IndexInterface<GMIndex<BlockType,Indices...>,Tuple<typename Indices::MetaType...>>(0),
mRange(rangeCast<RangeType>(range)),
mIPack(mkIPack(Isqr<0,NI>{})),
mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<0,NI-1>{})),
mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<1,NI>{})),
mBlockSizes(),
mLMax(mkLMax(mIPack)),
mPMax(mkPMax(mIPack,mBlockSizes))
@ -159,7 +201,7 @@ namespace CNORXZ
IndexInterface<GMIndex<BlockType,Indices...>,Tuple<typename Indices::MetaType...>>(0),
mRange(rangeCast<RangeType>(range)),
mIPack(mkIPack(Isqr<0,NI>{})),
mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<0,NI-1>{})),
mLexBlockSizes(mkLexBlockSizes(mIPack,Isqr<1,NI>{})),
mBlockSizes(blockSizes),
mLMax(mkLMax(mIPack)),
mPMax(mkPMax(mIPack,mBlockSizes))

View file

@ -33,6 +33,8 @@ namespace CNORXZ
constexpr GMIndex(const GMIndex& i);
constexpr GMIndex& operator=(const GMIndex& i);
constexpr GMIndex(const Indices&... is);
constexpr GMIndex(const Sptr<Indices>&... is);
constexpr GMIndex(const RangePtr& range, SizeT lexpos = 0);
constexpr GMIndex(const RangePtr& range, const BlockType& blockSizes, SizeT lexpos = 0);
@ -79,6 +81,8 @@ namespace CNORXZ
static constexpr decltype(auto) mkPMax(const IndexPack& ipack, const BlockType& blockSizes);
inline void mkPos();
template <SizeT... Is>
constexpr decltype(auto) mkIPack(Isq<Is...> is) const;

View file

@ -83,8 +83,35 @@ namespace CNORXZ
RangePtr operator*(const RangePtr& a, const RangePtr& b)
{
//assert(0); // check segfault + "flatten" yrange (no yrange of yranges etc)
return YRangeFactory({a,b}).create();
CXZ_ASSERT(a != nullptr, "first operand not initialized");
CXZ_ASSERT(b != nullptr, "second operand not initialized");
Vector<RangePtr> rvec;
rvec.reserve(a->dim() + b->dim());
if(a->sub(0) != nullptr){
for(SizeT i = 0; i != a->dim(); ++i){
CXZ_ASSERT(a->sub(i) != nullptr,
"sub range " << i << " of first operand not available");
rvec.push_back(a->sub(i));
}
}
else {
rvec.push_back(a);
}
if(b->sub(0) != nullptr){
for(SizeT i = 0; i != b->dim(); ++i){
CXZ_ASSERT(b->sub(i) != nullptr,
"sub range " << i << " of second operand not available");
rvec.push_back(b->sub(i));
}
}
else {
rvec.push_back(b);
}
return YRangeFactory(rvec).create();
}
} // end namespace CNORXZ

View file

@ -26,11 +26,30 @@ namespace
RangePtr mCR1;
};
class DA_2D_Test : public ::testing::Test
{
protected:
DA_2D_Test()
{
mSize = 5;
mStrMeta = { "another", "test", "string", "vector", "for", "this", "Test" };
mCR1 = CRangeFactory(mSize).create();
mUR1 = URangeFactory<String>(mStrMeta).create();
}
SizeT mSize;
Vector<String> mStrMeta;
RangePtr mCR1;
RangePtr mUR1;
};
TEST_F(DA_1D_Test, Basics)
{
DArray<Double> a(mCR1, ::CNORXZ::Test::Numbers::get(0,mSize));
const DArray<Double> a(mCR1, ::CNORXZ::Test::Numbers::get(0,mSize));
auto crx = std::dynamic_pointer_cast<CRange>(mCR1);
EXPECT_EQ(a.size(), mSize);
EXPECT_FALSE(a.isView());
auto ei = crx->end();
EXPECT_EQ(ei.lex(), mSize);
@ -42,6 +61,27 @@ namespace
EXPECT_THROW({a.at(ei);}, std::runtime_error);
}
TEST_F(DA_2D_Test, Basics)
{
const SizeT ssize = mStrMeta.size();
const SizeT size = mSize * ssize;
const DArray<Double> a(mCR1*mUR1, ::CNORXZ::Test::Numbers::get(0,size));
EXPECT_EQ(a.range()->dim(), 2u);
EXPECT_EQ(a.size(), size);
EXPECT_EQ(a.pmax(), size);
EXPECT_EQ(a.range()->sub(0), mCR1);
EXPECT_EQ(a.range()->sub(1), mUR1);
auto cr1x = std::dynamic_pointer_cast<CRange>(mCR1);
auto ur1x = std::dynamic_pointer_cast<URange<String>>(mUR1);
for(auto ci = cr1x->begin(); ci != cr1x->end(); ++ci){
for(auto ui = ur1x->begin(); ui != ur1x->end(); ++ui){
const SizeT p = ci.lex()*ssize + ui.lex();
EXPECT_EQ((ci*ui).lex(), p); // test this in rutest!!!
EXPECT_EQ( a[ci*ui], a.data()[p] );
}
}
}
} // end namespace
int main(int argc, char** argv)