generalize map range

This commit is contained in:
Christian Zimmermann 2019-04-03 16:26:53 +02:00
parent 505237c958
commit 6326b32d6a
3 changed files with 45 additions and 35 deletions

View file

@ -14,35 +14,33 @@ namespace MultiArrayTools
* OpExpr * * OpExpr *
**************/ **************/
template <class Op, class Expr, SpaceType STYPE> template <class Op, class Index, class Expr, SpaceType STYPE>
OpExpr<Op,Expr,STYPE>::OpExpr(const Op& mapf, const std::shared_ptr<OIType>& oind, OpExpr<Op,Index,Expr,STYPE>::OpExpr(const Op& mapf, const Index* ind,
size_t step, Expr ex) : size_t step, Expr ex) :
mIndPtr(oind.get()), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()), mIndPtr(ind), mSPos(mIndPtr->pos()), mMax(mIndPtr->max()),
mStep(step), mExpr( ex ), mStep(step), mExpr( ex ),
mOp(mapf), mOp(mapf),
//mExt(ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ))) //mExt(ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr )))
mExt( mOp.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ).extend mExt( mOp.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ).extend
( ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ) ) ) ( ex.rootSteps( reinterpret_cast<std::intptr_t>( mIndPtr ) ) ) )
{ {
assert(mIndPtr != nullptr); assert(mIndPtr != nullptr);
} }
template <class Op, class Expr, SpaceType STYPE> template <class Op, class Index, class Expr, SpaceType STYPE>
inline void OpExpr<Op,Expr,STYPE>::operator()(size_t mlast, inline void OpExpr<Op,Index,Expr,STYPE>::operator()(size_t mlast,
ExtType last) ExtType last)
{ {
constexpr size_t NEXT = Op::SIZE; constexpr size_t NEXT = Op::SIZE;
const ExtType nxpos = last; const ExtType nxpos = last;
const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) ); const size_t pos = mIndPtr->posAt( mOp.get( nxpos ) );
//VCHECK(pos);
const ExtType npos = last + mExt*pos; const ExtType npos = last + mExt*pos;
//VCHECK(npos.next().next().val());
const size_t mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos); const size_t mnpos = PosForward<ForType::DEFAULT>::valuex(mlast, mStep, pos);
mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ) ); mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ) );
} }
template <class Op, class Expr, SpaceType STYPE> template <class Op, class Index, class Expr, SpaceType STYPE>
inline void OpExpr<Op,Expr,STYPE>::operator()(size_t mlast) inline void OpExpr<Op,Index,Expr,STYPE>::operator()(size_t mlast)
{ {
const ExtType last; const ExtType last;
constexpr size_t NEXT = Op::SIZE; constexpr size_t NEXT = Op::SIZE;
@ -53,8 +51,8 @@ namespace MultiArrayTools
mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos )); mExpr(mnpos, Getter<NEXT>::template getX<ExtType>( npos ));
} }
template <class Op, class Expr, SpaceType STYPE> template <class Op, class Index, class Expr, SpaceType STYPE>
auto OpExpr<Op,Expr,STYPE>::rootSteps(std::intptr_t iPtrNum) const auto OpExpr<Op,Index,Expr,STYPE>::rootSteps(std::intptr_t iPtrNum) const
-> ExtType -> ExtType
{ {
return mOp.rootSteps(iPtrNum).extend( mExpr.rootSteps(iPtrNum) ); return mOp.rootSteps(iPtrNum).extend( mExpr.rootSteps(iPtrNum) );
@ -142,7 +140,7 @@ namespace MultiArrayTools
} }
template <class Op, SpaceType XSTYPE, class... Indices> template <class Op, SpaceType XSTYPE, class... Indices>
GenMapIndex<Op,XSTYPE,Indices...>& GenMapIndex<Op,XSTYPE,Indices...>::operator()(std::shared_ptr<Indices>&... indices) GenMapIndex<Op,XSTYPE,Indices...>& GenMapIndex<Op,XSTYPE,Indices...>::operator()(const std::shared_ptr<Indices>&... indices)
{ {
RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, indices...); RPackNum<sizeof...(Indices)-1>::swapIndices(mIPack, indices...);
RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, IB::mPos); RPackNum<sizeof...(Indices)-1>::setIndexPack(mIPack, IB::mPos);
@ -227,6 +225,12 @@ namespace MultiArrayTools
return *this; return *this;
} }
template <class Op, SpaceType XSTYPE, class... Indices>
size_t GenMapIndex<Op,XSTYPE,Indices...>::posAt(const MetaType& metaPos) const
{
return range()->outRange()->getMeta(metaPos);
}
template <class Op, SpaceType XSTYPE, class... Indices> template <class Op, SpaceType XSTYPE, class... Indices>
size_t GenMapIndex<Op,XSTYPE,Indices...>::dim() const size_t GenMapIndex<Op,XSTYPE,Indices...>::dim() const
{ {
@ -291,12 +295,12 @@ namespace MultiArrayTools
template <class Exprs> template <class Exprs>
auto GenMapIndex<Op,XSTYPE,Indices...>::ifor(size_t step, Exprs exs) const auto GenMapIndex<Op,XSTYPE,Indices...>::ifor(size_t step, Exprs exs) const
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh -> decltype(RPackNum<sizeof...(Indices)-1>::mkForh
(step, mIPack, mBlockSizes, OpExpr<Op,Exprs,XSTYPE> (step, mIPack, mBlockSizes, OpExpr<Op,GenMapIndex<Op,XSTYPE,Indices...>,Exprs,XSTYPE>
( range()->map(), mOutIndex, step, exs ) ) ) ( range()->map(), this, step, exs ) ) )
{ {
return RPackNum<sizeof...(Indices)-1>::mkForh return RPackNum<sizeof...(Indices)-1>::mkForh
(step, mIPack, mBlockSizes, OpExpr<Op,Exprs,XSTYPE> (0, mIPack, mBlockSizes, OpExpr<Op,GenMapIndex<Op,XSTYPE,Indices...>,Exprs,XSTYPE>
( range()->map(), mOutIndex, step, exs ) ); ( range()->map(), this, step, exs ) );
} }
template <class Op, SpaceType XSTYPE, class... Indices> template <class Op, SpaceType XSTYPE, class... Indices>
@ -598,11 +602,15 @@ namespace MultiArrayTools
template <class Op, SpaceType XSTYPE, class... Ranges> template <class Op, SpaceType XSTYPE, class... Ranges>
auto GenMapRange<Op,XSTYPE,Ranges...>::explMapMultiplicity() const auto GenMapRange<Op,XSTYPE,Ranges...>::explMapMultiplicity() const
-> MultiArray<size_t,GenMapRange> -> ConstSlice<size_t,GenMapRange>
{ {
auto tmp = mMapMult; /*
auto tmp = mMapMult;
return tmp.format( std::dynamic_pointer_cast<GenMapRange<Op,XSTYPE,Ranges...> > return tmp.format( std::dynamic_pointer_cast<GenMapRange<Op,XSTYPE,Ranges...> >
( std::shared_ptr<RangeBase>( RB::mThis )) ); ( std::shared_ptr<RangeBase>( RB::mThis )) );
*/
return mMapMult.slformat(std::dynamic_pointer_cast<GenMapRange<Op,XSTYPE,Ranges...> >
( std::shared_ptr<RangeBase>( RB::mThis )));
} }
template <class Op, SpaceType XSTYPE, class... Ranges> template <class Op, SpaceType XSTYPE, class... Ranges>

View file

@ -48,19 +48,21 @@ namespace MultiArrayTools
template <class Op, class Expr, SpaceType STYPE = SpaceType::ANY> template <class Op, class Index, class Expr, SpaceType STYPE = SpaceType::ANY>
//template <class MapF, class IndexPack, class Expr, SpaceType STYPE = SpaceType::ANY> //template <class MapF, class IndexPack, class Expr, SpaceType STYPE = SpaceType::ANY>
class OpExpr class OpExpr
{ {
public: public:
typedef SingleIndex<typename Op::value_type,STYPE> OIType; typedef typename Index::OIType OIType;
//typedef SingleIndex<typename Op::value_type,STYPE> OIType;
static constexpr size_t LAYER = Expr::LAYER + 1; static constexpr size_t LAYER = Expr::LAYER + 1;
static constexpr size_t SIZE = Expr::SIZE + Op::SIZE; static constexpr size_t SIZE = Expr::SIZE + Op::SIZE;
private: private:
OpExpr() = default; OpExpr() = default;
const OIType* mIndPtr; const Index* mIndPtr;
//const OIType* mIndPtr;
size_t mSPos; size_t mSPos;
size_t mMax; size_t mMax;
size_t mStep; size_t mStep;
@ -76,7 +78,7 @@ namespace MultiArrayTools
OpExpr& operator=(const OpExpr& in) = default; OpExpr& operator=(const OpExpr& in) = default;
OpExpr& operator=(OpExpr&& in) = default; OpExpr& operator=(OpExpr&& in) = default;
OpExpr(const Op& mapf, const std::shared_ptr<OIType>& oind, size_t step, Expr ex); OpExpr(const Op& mapf, const Index* ind, size_t step, Expr ex);
inline void operator()(size_t mlast, ExtType last); inline void operator()(size_t mlast, ExtType last);
inline void operator()(size_t mlast = 0); inline void operator()(size_t mlast = 0);
@ -102,7 +104,7 @@ namespace MultiArrayTools
typedef GenMapIndex IType; typedef GenMapIndex IType;
typedef SingleIndex<typename Op::value_type,XSTYPE> OIType; typedef SingleIndex<typename Op::value_type,XSTYPE> OIType;
static constexpr IndexType sType() { return IndexType::MULTI; } static constexpr IndexType sType() { return IndexType::SINGLE; }
static constexpr size_t sDim() { return sizeof...(Indices); } static constexpr size_t sDim() { return sizeof...(Indices); }
static constexpr size_t totalDim() { return mkTotalDim<Indices...>(); } static constexpr size_t totalDim() { return mkTotalDim<Indices...>(); }
@ -150,7 +152,7 @@ namespace MultiArrayTools
// MultiIndices CANNOT be influences be its subindices, so there is // MultiIndices CANNOT be influences be its subindices, so there is
// NO foreign/external controll) // NO foreign/external controll)
// Do NOT share index instances between two or more MapIndex instances // Do NOT share index instances between two or more MapIndex instances
GenMapIndex& operator()(std::shared_ptr<Indices>&... indices); GenMapIndex& operator()(const std::shared_ptr<Indices>&... indices);
// ==== >>>>> STATIC POLYMORPHISM <<<<< ==== // ==== >>>>> STATIC POLYMORPHISM <<<<< ====
@ -167,7 +169,8 @@ namespace MultiArrayTools
std::string stringMeta() const; std::string stringMeta() const;
MetaType meta() const; MetaType meta() const;
GenMapIndex& at(const MetaType& metaPos); GenMapIndex& at(const MetaType& metaPos);
size_t posAt(const MetaType& metaPos) const;
size_t dim() const; size_t dim() const;
bool first() const; bool first() const;
bool last() const; bool last() const;
@ -184,7 +187,7 @@ namespace MultiArrayTools
template <class Exprs> template <class Exprs>
auto ifor(size_t step, Exprs exs) const auto ifor(size_t step, Exprs exs) const
-> decltype(RPackNum<sizeof...(Indices)-1>::mkForh -> decltype(RPackNum<sizeof...(Indices)-1>::mkForh
(step, mIPack, mBlockSizes, OpExpr<Op,Exprs,XSTYPE>( range()->map(), mOutIndex, step, exs ) ) ); (step, mIPack, mBlockSizes, OpExpr<Op,GenMapIndex,Exprs,XSTYPE>( range()->map(), this, step, exs ) ) );
// first step arg not used! // first step arg not used!
template <class Exprs> template <class Exprs>
@ -276,7 +279,7 @@ namespace MultiArrayTools
template <size_t N> template <size_t N>
auto getPtr() const -> decltype( std::get<N>( mSpace ) )&; auto getPtr() const -> decltype( std::get<N>( mSpace ) )&;
std::shared_ptr<ORType> outRange() const; std::shared_ptr<ORType> outRange() const;
const Op& map() const; const Op& map() const;
virtual size_t dim() const final; virtual size_t dim() const final;
@ -297,7 +300,7 @@ namespace MultiArrayTools
virtual IndexType end() const final; virtual IndexType end() const final;
const MultiArray<size_t,ORType>& mapMultiplicity() const; const MultiArray<size_t,ORType>& mapMultiplicity() const;
MultiArray<size_t,GenMapRange> explMapMultiplicity() const; ConstSlice<size_t,GenMapRange> explMapMultiplicity() const;
vector<size_t> mapPos() const; vector<size_t> mapPos() const;

View file

@ -376,9 +376,8 @@ namespace {
///auto jj = mkMapI( std::make_shared<plus<size_t> >(), ii1, ii1 ); ///auto jj = mkMapI( std::make_shared<plus<size_t> >(), ii1, ii1 );
res(jj) += ma1(ii1,ii2); res(jj) += ma1(ii1,ii2);
auto mult = mr->mapMultiplicity(); auto mult = mr->explMapMultiplicity();
auto jjx = jj->outIndex(); res2(jj) += ma1(ii1,ii2) / staticcast<double>( mult(jj) );
res2(jj) += ma1(ii1,ii2) / staticcast<double>( mult(jjx) );
MultiArray<double,TRange> form = res.format(mpr1ptr->outRange()); MultiArray<double,TRange> form = res.format(mpr1ptr->outRange());
MultiArray<double,TRange> form2 = res2.format(mpr1ptr->outRange()); MultiArray<double,TRange> form2 = res2.format(mpr1ptr->outRange());
@ -386,7 +385,7 @@ namespace {
EXPECT_EQ( jj->range()->outRange()->size(), static_cast<size_t>( 10 ) ); EXPECT_EQ( jj->range()->outRange()->size(), static_cast<size_t>( 10 ) );
EXPECT_EQ( jj->range()->mapMultiplicity().at(9), static_cast<size_t>( 3 ) ); EXPECT_EQ( jj->range()->mapMultiplicity().at(9), static_cast<size_t>( 3 ) );
EXPECT_EQ( jj->range()->mapMultiplicity().at(3), static_cast<size_t>( 1 ) ); EXPECT_EQ( jj->range()->mapMultiplicity().at(3), static_cast<size_t>( 1 ) );
EXPECT_EQ( form.at(3), -31.71 ); EXPECT_EQ( form.at(3), -31.71 );
EXPECT_EQ( form.at(7), -77.16 ); EXPECT_EQ( form.at(7), -77.16 );
EXPECT_EQ( form.at(9), -18.81 + 72.31 -50.91 ); EXPECT_EQ( form.at(9), -18.81 + 72.31 -50.91 );
@ -397,7 +396,7 @@ namespace {
EXPECT_EQ( form.at(12), -42.53 ); EXPECT_EQ( form.at(12), -42.53 );
EXPECT_EQ( form.at(16), 80.41 ); EXPECT_EQ( form.at(16), 80.41 );
EXPECT_EQ( form.at(18), 6.35 ); EXPECT_EQ( form.at(18), 6.35 );
EXPECT_EQ( form2.at(3), -31.71 ); EXPECT_EQ( form2.at(3), -31.71 );
EXPECT_EQ( form2.at(7), -77.16 ); EXPECT_EQ( form2.at(7), -77.16 );
EXPECT_EQ( xround( form2.at(9) ), xround( (-18.81 + 72.31 -50.91) / 3. ) ); EXPECT_EQ( xround( form2.at(9) ), xround( (-18.81 + 72.31 -50.91) / 3. ) );