start operation rewriting

This commit is contained in:
Christian Zimmermann 2017-08-10 15:12:26 +02:00
parent 3b0f67eb47
commit 1ffffa568f
2 changed files with 121 additions and 1046 deletions

View file

@ -11,790 +11,87 @@ namespace MultiArrayTools
*********************************/ *********************************/
// purely virtual at the moment // purely virtual at the moment
/*********************************
* MultiArrayOperationRoot * /*************************
*********************************/ * OperationMaster *
*************************/
template <typename T, class Range>
void MultiArrayOperationRoot<T,Range>::performAssignment(const MultiArrayOperationBase<T>& in) template <typename T, class... Ranges>
OperationMaster<T,Ranges...>::OperationMaster(MutableMultiArrayBase& ma,
const ContainerRange<Ranges...>::IndexType& index) :
mArrayRef(ma), mIndex()
{ {
//#error "WRITE MAOR INTRINSIC CONTRACT FUNCTION" (*mIndex) = index; // implement corresp member fucntion in MultiIndex
//CHECK;
IndexList il = in.getIndices();
setInternalIndex(il);
in.setInternalIndex(il);
//CHECK;
const size_t endPos = mIndex.max();
std::cout << "assignment: " << endPos << " elements" << std::endl;
// assignment loop
for(mIndex.toFirst(); not mIndex.atEdge(); ++mIndex){
//std::cout << get() << " / " << in.get() << std::endl;
//std::cout << iref.pos() << '\r' << std::flush;
get() = in.get();
//assert(not std::isnan( get() ));
}
//CHECK;
}
template <typename T, class Range>
MultiArrayOperationRoot<T,Range>::
MultiArrayOperationRoot(MutableMultiArrayBase<T,Range>& ma,
const Name& nm) :
MutableMultiArrayOperationBase<T>(),
mArrayRef(ma),
mNm(nm) {}
template <typename T, class Range>
MultiArrayOperationRoot<T,Range>::
MultiArrayOperationRoot(const MultiArrayOperationRoot& in) :
MutableMultiArrayOperationBase<T>(),
mArrayRef(in.mArrayRef),
mNm(in.mNm) {}
template <typename T, class Range>
MultiArrayOperationRoot<T,Range>&
MultiArrayOperationRoot<T,Range>::operator=(const MultiArrayOperationRoot<T,Range>& in)
{
performAssignment(in);
return *this;
}
template <typename T, class Range>
MultiArrayOperationRoot<T,Range>&
MultiArrayOperationRoot<T,Range>::operator=(MultiArrayOperationRoot<T,Range>& in)
{
performAssignment(in);
return *this;
}
template <typename T, class Range>
template <class Range2>
MultiArrayOperationRoot<T,Range>&
MultiArrayOperationRoot<T,Range>::operator=(MultiArrayOperationRoot<T,Range2>& in)
{
performAssignment(in);
return *this;
}
template <typename T, class Range>
template <class Range2>
const MultiArrayOperationRoot<T,Range>&
MultiArrayOperationRoot<T,Range>::operator=(const MultiArrayOperationRoot<T,Range2>& in)
{
performAssignment(in);
return *this;
}
template <typename T, class Range>
template <class Range2>
MultiArrayOperationRoot<T,Range>&
MultiArrayOperationRoot<T,Range>::operator=(ConstMultiArrayOperationRoot<T,Range2>& in)
{
performAssignment(in);
return *this;
}
template <typename T, class Range>
template <class Range2>
const MultiArrayOperationRoot<T,Range>&
MultiArrayOperationRoot<T,Range>::operator=(const ConstMultiArrayOperationRoot<T,Range2>& in)
{
performAssignment(in);
return *this;
}
template <typename T, class Range>
template <class Operation, class... MAOps>
MultiArrayOperationRoot<T,Range>&
MultiArrayOperationRoot<T,Range>::operator=(const MultiArrayOperation<T,Operation,MAOps...>& in)
{
performAssignment(in);
return *this;
} }
template <typename T, class Range> template <typename T, class... Ranges>
template <class Operation, class Range2, class... MAOps> T& OperationMaster<T,Ranges...>::get()
MultiArrayOperationRoot<T,Range>&
MultiArrayOperationRoot<T,Range>::operator=(const MultiArrayContraction<T,Operation,Range2,MAOps...>& in)
{ {
performAssignment(in); return mArrayRef.data()[ mIndex.pos() ];
return *this;
} }
template <typename T, class Range> template <typename T, class... Ranges>
template <class Operation, class... MAOps> const T& OperationMaster<T,Ranges...>::get() const
MultiArrayOperation<T,Operation,MultiArrayOperationRoot<T,Range>, MAOps...>
MultiArrayOperationRoot<T,Range>::operator()(const Operation& op, const MAOps&... secs) const
{ {
//CHECK; return mArrayRef.data()[ mIndex.pos() ];
return MultiArrayOperation<T,Operation,MultiArrayOperationRoot<T,Range>, MAOps...>(op, *this, secs...);
}
template <typename T, class Range>
template <class Range2, class ContractOperation, class... MAOps>
MultiArrayContraction<T,ContractOperation,Range2,MultiArrayOperationRoot<T,Range>,MAOps...>
MultiArrayOperationRoot<T,Range>::contract(const ContractOperation& cop,
const std::string& indexName,
const MAOps&... mao) const
{
typename Range2::IndexType* ind = dynamic_cast<typename Range2::IndexType*>( mIndex.getLinked(indexName) );
return MultiArrayContraction<T,ContractOperation,Range2,
MultiArrayOperationRoot<T,Range>,
MAOps...>(cop, *ind, *this, mao...);
}
template <typename T, class Range>
template <class Range2, class ContractOperation, class... MAOps>
MultiArrayContraction<T,ContractOperation,Range2,MultiArrayOperationRoot<T,Range>,MAOps...>
MultiArrayOperationRoot<T,Range>::contract(const ContractOperation& cop,
const std::string& indexName,
size_t begin,
size_t end,
const MAOps&... mao) const
{
typename Range2::IndexType* ind = dynamic_cast<typename Range2::IndexType*>( mIndex.getLinked(indexName) );
return MultiArrayContraction<T,ContractOperation,Range2,
MultiArrayOperationRoot<T,Range>,
MAOps...>(cop, *ind, begin, end, *this, mao...);
}
template <typename T, class Range>
template<class TotalInRange, class InRange, class OutRange>
MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,Range>
MultiArrayOperationRoot<T,Range>::map(const IndexMapFunction<InRange,OutRange>& imf)
{
//CHECK;
MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,Range> mom(*this, imf);
//CHECK;
return mom;
} }
template <typename T, class Range> /****************************
template <class MAOp> * ConstOperationRoot *
auto MultiArrayOperationRoot<T,Range>::operator+(const MAOp& sec) ****************************/
-> decltype(operator()(std::plus<T>(), sec))
template <typename T, class... Ranges>
ConstOperationRoot<T,CRange,Ranges...>::
ConstOperationRoot(const MultiArrayBase<T,CRange>& ma,
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
mArrayRef(ma), mIndex(mArrayRef)
{ {
return operator()(std::plus<T>(), sec); mIndex(indices...);
} }
template <typename T, class Range> template <typename T, class... Ranges>
template <class MAOp> const T& ConstOperationRoot<T,Ranges...>::get() const
auto MultiArrayOperationRoot<T,Range>::operator-(const MAOp& sec)
-> decltype(operator()(std::minus<T>(), sec))
{ {
return operator()(std::minus<T>(), sec); return mArrayRef[ mIndex ];
}
template <typename T, class Range>
template <class MAOp>
auto MultiArrayOperationRoot<T,Range>::operator*(const MAOp& sec)
-> decltype(operator()(std::multiplies<T>(), sec))
{
return operator()(std::multiplies<T>(), sec);
}
template <typename T, class Range>
template <class MAOp>
auto MultiArrayOperationRoot<T,Range>::operator/(const MAOp& sec)
-> decltype(operator()(std::divides<T>(), sec))
{
//CHECK;
return operator()(std::divides<T>(), sec);
}
template <typename T, class Range>
MultiArrayOperationRoot<T,Range> MultiArrayOperationRoot<T,Range>::copyThis()
{
//CHECK;
return MultiArrayOperationRoot<T,Range>(mArrayRef, mNm);
} }
template <typename T, class Range> /***********************
template <class MAOp> * OperationRoot *
MultiArrayOperationRoot<T,Range>& ***********************/
MultiArrayOperationRoot<T,Range>::operator+=(const MAOp& sec)
template <typename T, class... Ranges>
OperationRoot<T,Ranges...>::
OperationRoot(MutableMultiArrayBase<T,CRange>& ma,
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
mArrayRef(ma), mIndex(mArrayRef)
{ {
return (*this) = copyThis() + sec; mIndex(indices...);
} }
template <typename T, class Range> template <typename T, class... Ranges>
template <class MAOp> const T& OperationRoot<T,Ranges...>::get() const
MultiArrayOperationRoot<T,Range>&
MultiArrayOperationRoot<T,Range>::operator-=(const MAOp& sec)
{ {
return (*this) = copyThis() - sec; return mArrayRef[ mIndex ];
} }
template <typename T, class Range> template <typename T, class... Ranges>
template <class MAOp> T& OperationRoot<T,Ranges...>::get()
MultiArrayOperationRoot<T,Range>&
MultiArrayOperationRoot<T,Range>::operator*=(const MAOp& sec)
{ {
return (*this) = copyThis() * sec; return mArrayRef[ mIndex ];
} }
template <typename T, class Range> /***********************
template <class MAOp> * OperationRoot *
MultiArrayOperationRoot<T,Range>& ***********************/
MultiArrayOperationRoot<T,Range>::operator/=(const MAOp& sec)
template <typename T, class OpFunction, class... Ops>
Operation<T,OpFunction,Ops...>::Operation(Ops&&... ops) : mOps(ops...) {}
template <typename T, class OpFunction, class... Ops>
const T& Operation<T,OpFunction,Ops...>::get() const
{ {
//CHECK; mRes = F(mOps);
return (*this) = copyThis() / sec; return mRes;
} }
template <typename T, class Range>
const MultiArrayBase<T,Range>& MultiArrayOperationRoot<T,Range>::operator*() const
{
return mArrayRef;
}
template <typename T, class Range>
MultiArrayBase<T,Range> const* MultiArrayOperationRoot<T,Range>::operator->() const
{
return &mArrayRef;
}
template <typename T, class Range>
size_t MultiArrayOperationRoot<T,Range>::argNum() const
{
return 1;
}
template <typename T, class Range>
T& MultiArrayOperationRoot<T,Range>::get()
{
//CHECK;
return mArrayRef[mIndex];
}
template <typename T, class Range>
const T& MultiArrayOperationRoot<T,Range>::get() const
{
//CHECK;
return mArrayRef[mIndex];
}
template <typename T, class Range>
const Name& MultiArrayOperationRoot<T,Range>::name() const
{
return mNm;
}
template <typename T, class Range>
MultiArrayOperationRoot<T,Range>& MultiArrayOperationRoot<T,Range>::operator[](const IndexType& ind)
{
mIndex.copyPos(ind);
return *this;
}
template <typename T, class Range>
const MultiArrayOperationRoot<T,Range>& MultiArrayOperationRoot<T,Range>::operator[](const IndexType& ind) const
{
mIndex.copyPos(ind);
return *this;
}
/**************************************
* ConstMultiArrayOperationBase *
**************************************/
template <typename T, class Range>
ConstMultiArrayOperationRoot<T,Range>::
ConstMultiArrayOperationRoot(const MultiArrayBase<T,Range>& ma,
const Name& nm) :
MultiArrayOperationBase<T>(),
mArrayRef(ma),
mNm(nm) {}
template <typename T, class Range>
ConstMultiArrayOperationRoot<T,Range>::
ConstMultiArrayOperationRoot(const MultiArrayOperationRoot<T,Range>& in) :
MultiArrayOperationBase<T>(),
mArrayRef(in.getCont()),
mNm(in.name()) {}
template <typename T, class Range>
ConstMultiArrayOperationRoot<T,Range>::
ConstMultiArrayOperationRoot(const ConstMultiArrayOperationRoot& in) :
MultiArrayOperationBase<T>(),
mArrayRef(in.mArrayRef),
mNm(in.mNm) {}
template <typename T, class Range>
template <class Operation, class... MAOps>
MultiArrayOperation<T,Operation,ConstMultiArrayOperationRoot<T,Range>, MAOps...>
ConstMultiArrayOperationRoot<T,Range>::operator()(const Operation& op, const MAOps&... secs) const
{
//CHECK;
return MultiArrayOperation<T,Operation,ConstMultiArrayOperationRoot<T,Range>, MAOps...>(op, *this, secs...);
}
template <typename T, class Range>
template <class Range2, class ContractOperation, class... MAOps>
MultiArrayContraction<T,ContractOperation,Range2,ConstMultiArrayOperationRoot<T,Range>,MAOps...>
ConstMultiArrayOperationRoot<T,Range>::contract(const ContractOperation& cop,
const std::string& indexName,
const MAOps&... mao) const
{
// !!!!!
return MultiArrayContraction<T,ContractOperation,Range2,
ConstMultiArrayOperationRoot<T,Range>,
MAOps...>(cop, *ind, *this, mao...);
}
template <typename T, class Range>
template <class Range2, class ContractOperation, class... MAOps>
MultiArrayContraction<T,ContractOperation,Range2,ConstMultiArrayOperationRoot<T,Range>,MAOps...>
ConstMultiArrayOperationRoot<T,Range>::contract(const ContractOperation& cop,
const std::string& indexName,
size_t begin,
size_t end,
const MAOps&... mao) const
{
// !!!!
return MultiArrayContraction<T,ContractOperation,Range2,
ConstMultiArrayOperationRoot<T,Range>,
MAOps...>(cop, *ind, begin, end, *this, mao...);
}
template <typename T, class Range>
template <class MAOp>
auto ConstMultiArrayOperationRoot<T,Range>::operator+(const MAOp& sec) const
-> decltype(operator()(std::plus<T>(), sec))
{
return operator()(std::plus<T>(), sec);
}
template <typename T, class Range>
template <class MAOp>
auto ConstMultiArrayOperationRoot<T,Range>::operator-(const MAOp& sec) const
-> decltype(operator()(std::minus<T>(), sec))
{
return operator()(std::minus<T>(), sec);
}
template <typename T, class Range>
template <class MAOp>
auto ConstMultiArrayOperationRoot<T,Range>::operator*(const MAOp& sec) const
-> decltype(operator()(std::multiplies<T>(), sec))
{
return operator()(std::multiplies<T>(), sec);
}
template <typename T, class Range>
template <class MAOp>
auto ConstMultiArrayOperationRoot<T,Range>::operator/(const MAOp& sec) const
-> decltype(operator()(std::divides<T>(), sec))
{
//CHECK;
return operator()(std::divides<T>(), sec);
}
template <typename T, class Range>
ConstMultiArrayOperationRoot<T,Range> ConstMultiArrayOperationRoot<T,Range>::copyThis() const
{
//CHECK;
return ConstMultiArrayOperationRoot<T,Range>(mArrayRef, mNm);
}
template <typename T, class Range>
const MultiArrayBase<T,Range>& ConstMultiArrayOperationRoot<T,Range>::operator*() const
{
return mArrayRef;
}
template <typename T, class Range>
MultiArrayBase<T,Range> const* ConstMultiArrayOperationRoot<T,Range>::operator->() const
{
return &mArrayRef;
}
template <typename T, class Range>
size_t ConstMultiArrayOperationRoot<T,Range>::argNum() const
{
return 1;
}
template <typename T, class Range>
const T& ConstMultiArrayOperationRoot<T,Range>::get() const
{
//CHECK;
return mArrayRef[mIndex];
}
template <typename T, class Range>
const Name& ConstMultiArrayOperationRoot<T,Range>::name() const
{
return mNm;
}
template <typename T, class Range>
const ConstMultiArrayOperationRoot<T,Range>& ConstMultiArrayOperationRoot<T,Range>::operator[](const IndexType& ind) const
{
mIndex.copyPos(ind);
return *this;
}
/********************************
* MultiArrayOperationMap *
********************************/
template <typename T, class InRange, class TotalInRange, class OutRange, class TotalRange>
MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,TotalRange>::
MultiArrayOperationMap(MultiArrayOperationRoot<T,TotalRange>& root,
const IndexMapFunction<InRange,OutRange>& mf) :
MutableMultiArrayOperationBase<T>(),
mMF(mf),
mRoot(root) {}
template <typename T, class InRange, class TotalInRange, class OutRange, class TotalRange>
MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,TotalRange>&
MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,TotalRange>::
operator=(const MultiArrayOperationRoot<T,TotalInRange>& in)
{
mIndex = dynamic_cast<typename TotalInRange::IndexType const&>( in.index() );
mNm = in.name();
typename TotalInRange::IndexType endIndex = mIndex;
++endIndex.toLast();
std::cout << "map assignment: " << endIndex.pos() << " elements" << std::endl;
IndexList il = in.getIndices();
setInternalIndex(il);
in.setInternalIndex(il);
MultiArray<T,TotalRange> cnt(mRoot->range());
MultiArrayOperationRoot<T,TotalRange> cnto(cnt, mRoot.name());
for(mIndex.toFirst(), mMF.eval(); mIndex != endIndex; ++mIndex, mMF.eval()){
get() += in.get();
cnto.get() += 1.;
}
// CHECK whether T / size_t mixture works!!
mRoot /= cnt(mRoot.name(), true);
return *this;
}
template <typename T, class InRange, class TotalInRange, class OutRange, class TotalRange>
MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,TotalRange>&
MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,TotalRange>::
operator=(const ConstMultiArrayOperationRoot<T,TotalInRange>& in)
{
mIndex = dynamic_cast<typename TotalInRange::IndexType const&>( in.index() );
mNm = in.name();
typename TotalInRange::IndexType endIndex = mIndex;
++endIndex.toLast();
std::cout << "map assignment: " << endIndex.pos() << " elements" << std::endl;
IndexList il = in.getIndices();
setInternalIndex(il);
in.setInternalIndex(il);
MultiArray<T,TotalRange> cnt(mRoot->range());
MultiArrayOperationRoot<T,TotalRange> cnto(cnt, mRoot.name());
for(mIndex.toFirst(), mMF.eval(); mIndex != endIndex; ++mIndex, mMF.eval()){
get() += in.get();
cnto.get() += 1.;
}
mRoot.freeIndex();
// CHECK whether T / size_t mixture works!!
mRoot /= cnt(mRoot.name(), true);
return *this;
}
template <typename T, class InRange, class TotalInRange, class OutRange, class TotalRange>
size_t MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,TotalRange>::argNum() const
{
return 1;
}
template <typename T, class InRange, class TotalInRange, class OutRange, class TotalRange>
const T& MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,TotalRange>::get() const
{
return mRoot.get();
}
template <typename T, class InRange, class TotalInRange, class OutRange, class TotalRange>
T& MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,TotalRange>::get()
{
return mRoot.get();
}
/*****************************
* MultiArrayOperation *
*****************************/
template <size_t N>
struct OperationCall
{
template <class Operation, class Tuple, class... MAOps>
static auto callOperation(Operation& op, const Tuple& tp, const MAOps&... args)
-> decltype(OperationCall<N-1>::template callOperation(op, tp, std::get<N>(tp), args...))
{
return OperationCall<N-1>::template callOperation(op, tp, std::get<N>(tp), args...);
}
template <class Operation, class Tuple, class... MAOps>
static auto callOperation(const Operation& op, const Tuple& tp, const MAOps&... args)
-> decltype(OperationCall<N-1>::template callOperation(op, tp, std::get<N>(tp), args...))
{
return OperationCall<N-1>::template callOperation(op, tp, std::get<N>(tp), args...);
}
};
template <>
struct OperationCall<0>
{
template <class Operation, class Tuple, class... MAOps>
static auto callOperation(Operation& op, const Tuple& tp, const MAOps&... args)
-> decltype(op(std::get<0>(tp).get(), args.get()...))
{
return op(std::get<0>(tp).get(), args.get()...);
/*
return op(static_cast<typename Operation::result_type>( std::get<0>(tp).get() ),
static_cast<typename Operation::result_type>( args.get() )...);
*/
}
template <class Operation, class Tuple, class... MAOps>
static auto callOperation(const Operation& op, const Tuple& tp, const MAOps&... args)
-> decltype(op(std::get<0>(tp).get(), args.get()...))
{
return op(std::get<0>(tp).get(), args.get()...);
}
};
template <typename T, class Operation, class... MAOps>
MultiArrayOperation<T,Operation,MAOps...>::
MultiArrayOperation(Operation& op, const MAOps&... args) :
mOp(op),
mArgs(std::make_tuple(args...)) { /*CHECK;*/ }
template <typename T, class Operation, class... MAOps>
MultiArrayOperation<T,Operation,MAOps...>::
MultiArrayOperation(const Operation& op, const MAOps&... args) :
mOp(op),
mArgs(std::make_tuple(args...)) { /*CHECK;*/ }
template <typename T, class Operation, class... MAOps>
template <class Operation2, class... MAOps2>
MultiArrayOperation<T,Operation2,MultiArrayOperation<T,Operation,MAOps...>,MAOps2...>
MultiArrayOperation<T,Operation,MAOps...>::operator()(Operation2& op, const MAOps2&... secs) const
{
return MultiArrayOperation<T,Operation2,MultiArrayOperation<T,Operation,MAOps...>,
MAOps2...>(op, *this, secs...);
}
template <typename T, class Operation, class... MAOps>
template <class Operation2, class... MAOps2>
MultiArrayOperation<T,Operation2,MultiArrayOperation<T,Operation,MAOps...>,MAOps2...>
MultiArrayOperation<T,Operation,MAOps...>::operator()(const Operation2& op, const MAOps2&... secs) const
{
return MultiArrayOperation<T,Operation2,MultiArrayOperation<T,Operation,MAOps...>,
MAOps2...>(op, *this, secs...);
}
template <typename T, class Operation, class... MAOps>
template <class Range2, class ContractOperation, class... MAOps2>
MultiArrayContraction<T,ContractOperation,Range2,MultiArrayOperation<T,Operation,MAOps...>,MAOps2...>
MultiArrayOperation<T,Operation,MAOps...>::
contract(const ContractOperation& cop,
const std::string& indexName,
const MAOps2&... mao) const
{
// !!!
return MultiArrayContraction<T,ContractOperation,Range2,MultiArrayOperation<T,Operation,MAOps...>,
MAOps2...>(cop, *ind, *this, mao...);
}
template <typename T, class Operation, class... MAOps>
template <class MAOp2>
auto MultiArrayOperation<T,Operation,MAOps...>::operator+(const MAOp2& sec)
-> decltype(operator()(std::plus<T>(), sec))
{
return operator()(std::plus<T>(), sec);
}
template <typename T, class Operation, class... MAOps>
template <class MAOp2>
auto MultiArrayOperation<T,Operation,MAOps...>::operator-(const MAOp2& sec)
-> decltype(operator()(std::minus<T>(), sec))
{
return operator()(std::minus<T>(), sec);
}
template <typename T, class Operation, class... MAOps>
template <class MAOp2>
auto MultiArrayOperation<T,Operation,MAOps...>::operator*(const MAOp2& sec)
-> decltype(operator()(std::multiplies<T>(), sec))
{
return operator()(std::multiplies<T>(), sec);
}
template <typename T, class Operation, class... MAOps>
template <class MAOp2>
auto MultiArrayOperation<T,Operation,MAOps...>::operator/(const MAOp2& sec)
-> decltype(operator()(std::divides<T>(), sec))
{
return operator()(std::divides<T>(), sec);
}
template <typename T, class Operation, class... MAOps>
size_t MultiArrayOperation<T,Operation,MAOps...>::argNum() const
{
return sizeof...(MAOps) + 1;
}
template <typename T, class Operation, class... MAOps>
const T& MultiArrayOperation<T,Operation,MAOps...>::get() const
{
//CHECK;
mVal = OperationCall<sizeof...(MAOps)-1>::
template callOperation(mOp, mArgs);
return mVal;
}
/*******************************
* MultiArrayContraction *
*******************************/
template <typename T, class ContractOperation, class Range, class... MAOps>
MultiArrayContraction<T,ContractOperation,Range,MAOps...>::
MultiArrayContraction(const ContractOperation& cop,
const typename Range::IndexType& runIndex,
const MAOps&... mao) :
mOp(cop),
mArgs(std::make_tuple(mao...)),
mBeginIndex(runIndex), mEndIndex(runIndex),
mRunIndex(runIndex)
{
mBeginIndex.toFirst();
++mEndIndex.toLast();
// DON'T link here !!
//linkIndicesTo(&mRunIndex);
}
template <typename T, class ContractOperation, class Range, class... MAOps>
MultiArrayContraction<T,ContractOperation,Range,MAOps...>::
MultiArrayContraction(const ContractOperation& cop,
const typename Range::IndexType& runIndex,
size_t begin,
size_t end,
const MAOps&... mao) :
mOp(cop),
mArgs(std::make_tuple(mao...)),
mBeginIndex(runIndex), mEndIndex(runIndex),
mRunIndex(runIndex)
{
mBeginIndex.setPos(begin);
mEndIndex.setPos(end);
// DON'T link here !!
//linkIndicesTo(&mRunIndex);
}
template <typename T, class ContractOperation, class Range, class... MAOps>
template <class Operation2, class... MAOps2>
MultiArrayOperation<T,Operation2,MultiArrayContraction<T,ContractOperation,Range,MAOps...>,MAOps2...>
MultiArrayContraction<T,ContractOperation,Range,MAOps...>::operator()(Operation2& op, const MAOps2&... secs) const
{
return MultiArrayOperation<T,Operation2,MultiArrayContraction<T,ContractOperation,Range,MAOps...>,
MAOps2...>(op, *this, secs...);
}
template <typename T, class ContractOperation, class Range, class... MAOps>
template <class Operation2, class... MAOps2>
MultiArrayOperation<T,Operation2,MultiArrayContraction<T,ContractOperation,Range,MAOps...>,MAOps2...>
MultiArrayContraction<T,ContractOperation,Range,MAOps...>::operator()(const Operation2& op, const MAOps2&... secs) const
{
return MultiArrayOperation<T,Operation2,MultiArrayContraction<T,ContractOperation,Range,MAOps...>,
MAOps2...>(op, *this, secs...);
}
template <typename T, class ContractOperation, class Range, class... MAOps>
template <class Range2, class ContractOperation2, class... MAOps2>
MultiArrayContraction<T,ContractOperation2,Range2,
MultiArrayContraction<T,ContractOperation,Range,MAOps...>,MAOps2...>
MultiArrayContraction<T,ContractOperation,Range,MAOps...>::
contract(const ContractOperation2& cop,
const std::string& indexName,
const MAOps2&... mao) const
{
//
return MultiArrayContraction<T,ContractOperation2,Range2,MultiArrayContraction<T,ContractOperation,Range,MAOps...>,
MAOps2...>(cop, *ind, *this, mao...);
}
template <typename T, class ContractOperation, class Range, class... MAOps>
template <class MAOp2>
auto MultiArrayContraction<T,ContractOperation,Range,MAOps...>::operator+(const MAOp2& sec)
-> decltype(operator()(std::plus<T>(), sec))
{
return operator()(std::plus<T>(), sec);
}
template <typename T, class ContractOperation, class Range, class... MAOps>
template <class MAOp2>
auto MultiArrayContraction<T,ContractOperation,Range,MAOps...>::operator-(const MAOp2& sec)
-> decltype(operator()(std::minus<T>(), sec))
{
return operator()(std::minus<T>(), sec);
}
template <typename T, class ContractOperation, class Range, class... MAOps>
template <class MAOp2>
auto MultiArrayContraction<T,ContractOperation,Range,MAOps...>::operator*(const MAOp2& sec)
-> decltype(operator()(std::multiplies<T>(), sec))
{
return operator()(std::multiplies<T>(), sec);
}
template <typename T, class ContractOperation, class Range, class... MAOps>
template <class MAOp2>
auto MultiArrayContraction<T,ContractOperation,Range,MAOps...>::operator/(const MAOp2& sec)
-> decltype(operator()(std::divides<T>(), sec))
{
return operator()(std::divides<T>(), sec);
}
template <typename T, class ContractOperation, class Range, class... MAOps>
size_t MultiArrayContraction<T,ContractOperation,Range,MAOps...>::argNum() const
{
return sizeof...(MAOps) + 1;
}
template <typename T, class ContractOperation, class Range, class... MAOps>
const T& MultiArrayContraction<T,ContractOperation,Range,MAOps...>::get() const
{
//CHECK;
mOp.reset();
for(mRunIndex = mBeginIndex ; mRunIndex != mEndIndex; ++mRunIndex){
OperationCall<sizeof...(MAOps)-1>::
template callOperation(mOp, mArgs);
}
mOp.endOp();
return mOp();
}
} }

View file

@ -13,353 +13,131 @@
namespace MultiArrayTools namespace MultiArrayTools
{ {
typedef std::map<Name,std::shared_ptr<IndefinitIndexBase> > IndexList; /*
* OperationBase
* MutableOperationBase
*
* OperationMaster : MutableOperationBase
*
* OperationTemplate<...>
* ConstOperationRoot : OperationBase, OperationTemplate<...>
* OperationRoot : MutableOperationBase,
* OperationTemplate<...>
*
*/
typedef std::map<Name,std::shared_ptr<IndexBase> > IndexList;
template <typename T> template <typename T>
class MultiArrayOperationBase class OperationBase
{ {
public: public:
typedef T value_type; typedef T value_type;
MultiArrayOperationBase() = default; OperationBase() = default;
virtual ~MultiArrayOperationBase(); virtual ~OperationBase();
virtual size_t argNum() const = 0; //virtual size_t argNum() const = 0;
virtual const T& get() const = 0; virtual const T& get() const = 0;
}; };
template <typename T> template <typename T>
class MutableMultiArrayOperationBase : public MultiArrayOperationBase<T> class MutableOperationBase : public OperationBase<T>
{ {
public: public:
MutableMultiArrayOperationBase() = default; MutableOperationBase() = default;
virtual T& get() = 0; virtual T& get() = 0;
}; };
template <typename T, class Range> template <typename T, class... Ranges>
class MultiArrayOperationRoot : public MutableMultiArrayOperationBase<T> class OperationMaster : public MutableOperationBase<T>
{ {
public: public:
typedef MultiArrayOperationBase<T> MAOB; typedef OperationBase<T> OB;
typedef typename Range::IndexType IndexType; typedef typename MultiRange<Ranges...>::IndexType IndexType;
//typedef decltype(MultiArray<T,Range>().begin()) IndexType;
MultiArrayOperationRoot(MutableMultiArrayBase<T,Range>& ma, const Name& nm); OperationMaster(OperationRoot<T,Ranges...>&& root);
MultiArrayOperationRoot(const MultiArrayOperationRoot& in);
MultiArrayOperationRoot& operator=(const MultiArrayOperationRoot& in);
MultiArrayOperationRoot& operator=(MultiArrayOperationRoot& in);
template <class Range2>
MultiArrayOperationRoot& operator=(MultiArrayOperationRoot<T,Range2>& in);
template <class Range2>
const MultiArrayOperationRoot& operator=(const MultiArrayOperationRoot<T,Range2>& in);
template <class Range2>
MultiArrayOperationRoot& operator=(ConstMultiArrayOperationRoot<T,Range2>& in);
template <class Range2>
const MultiArrayOperationRoot& operator=(const ConstMultiArrayOperationRoot<T,Range2>& in);
template <class Operation, class... MAOps>
MultiArrayOperationRoot& operator=(const MultiArrayOperation<T,Operation,MAOps...>& in);
template <class Operation, class Range2, class... MAOps>
MultiArrayOperationRoot<T,Range>&
operator=(const MultiArrayContraction<T,Operation,Range2,MAOps...>& in);
//template <class Operation, class... MAOps>
//MultiArrayOperation<T,Operation,MultiArrayOperationRoot<T,Range>, MAOps...>
//operator()(Operation& op, const MAOps&... secs) const;
template <class Operation, class... MAOps>
MultiArrayOperation<T,Operation,MultiArrayOperationRoot<T,Range>, MAOps...>
operator()(const Operation& op, const MAOps&... secs) const;
template < class Range2, class ContractOperation, class... MAOps>
MultiArrayContraction<T,ContractOperation,Range2,MultiArrayOperationRoot<T,Range>, MAOps...>
contract(const ContractOperation& cop, const std::string& indexName,
const MAOps&... mao) const;
template <class Range2, class ContractOperation, class... MAOps>
MultiArrayContraction<T,ContractOperation,Range2,MultiArrayOperationRoot<T,Range>, MAOps...>
contract(const ContractOperation& cop, const std::string& indexName,
size_t begin,
size_t end,
const MAOps&... mao) const;
template<class TotalInRange, class InRange, class OutRange>
MultiArrayOperationMap<T,InRange,TotalInRange,OutRange,Range>
map(const IndexMapFunction<InRange,OutRange>& imf);
template <class MAOp>
auto operator+(const MAOp& sec) -> decltype(operator()(std::plus<T>(), sec));
template <class MAOp>
auto operator-(const MAOp& sec) -> decltype(operator()(std::minus<T>(), sec));
template <class MAOp>
auto operator*(const MAOp& sec) -> decltype(operator()(std::multiplies<T>(), sec));
template <class MAOp>
auto operator/(const MAOp& sec) -> decltype(operator()(std::divides<T>(), sec));
MultiArrayOperationRoot copyThis();
template <class MAOp>
MultiArrayOperationRoot& operator+=(const MAOp& sec);
template <class MAOp>
MultiArrayOperationRoot& operator-=(const MAOp& sec);
template <class MAOp>
MultiArrayOperationRoot& operator*=(const MAOp& sec);
template <class MAOp>
MultiArrayOperationRoot& operator/=(const MAOp& sec);
const MultiArrayBase<T,Range>& operator*() const;
//MultiArrayBase<T,Range>& operator*();
MultiArrayBase<T,Range> const* operator->() const;
virtual size_t argNum() const override;
// set index -> implement !!!!!
MultiArrayOperationRoot<T,Range>& operator[](const IndexType& ind);
const MultiArrayOperationRoot<T,Range>& operator[](const IndexType& ind) const;
virtual T& get() override; virtual T& get() override;
virtual const T& get() const override; virtual const T& get() const override;
const Name& name() const;
const MultiArrayBase<T,Range>& getCont() const { return mArrayRef; }
template <typename U, class RangeX>
friend class MultiArrayOperationRoot;
template <typename U, class RangeX>
friend class ConstMultiArrayOperationRoot;
protected: protected:
void performAssignment(const MultiArrayOperationBase<T>& in); void performAssignment(const MultiArrayOperationBase<T>& in);
MutableMultiArrayBase<T,Range>& mArrayRef; MutableMultiArrayBase<T,CRange>& mArrayRef;
mutable IndexType mIndex; mutable IndexType mIndex;
Name mNm;
}; };
template <typename T, class Range> template <typename T, class... Ranges>
class ConstMultiArrayOperationRoot : public MultiArrayOperationBase<T> class ConstOperationRoot : public OperationBase<T>,
public OperationTemplate<ConstOperationRoot<T,CRange> >
{ {
public: public:
typedef MultiArrayOperationBase<T> MAOB;
typedef typename Range::IndexType IndexType;
//typedef decltype(MultiArray<T,Range>().begin()) IndexType;
ConstMultiArrayOperationRoot(const MultiArrayBase<T,Range>& ma, const Name& nm);
ConstMultiArrayOperationRoot(const MultiArrayOperationRoot<T,Range>& in);
ConstMultiArrayOperationRoot(const ConstMultiArrayOperationRoot& in);
template <class Operation, class... MAOps> typedef OperationBase<T> OB;
MultiArrayOperation<T,Operation,ConstMultiArrayOperationRoot<T,Range>, MAOps...> typedef OperationTemplate<ConstOperationRoot<T,CRange> > OT;
operator()(const Operation& op, const MAOps&... secs) const; typedef ContainerRange<Ranges...> CRange;
typedef typename CRange::IndexType IndexType;
template <class Range2, class ContractOperation, class... MAOps>
MultiArrayContraction<T,ContractOperation,Range2,ConstMultiArrayOperationRoot<T,Range>, MAOps...>
contract(const ContractOperation& cop, const std::string& indexName,
const MAOps&... mao) const;
template <class Range2, class ContractOperation, class... MAOps> ConstOperationRoot(const MultiArrayBase<T,CRange>& ma,
MultiArrayContraction<T,ContractOperation,Range2,ConstMultiArrayOperationRoot<T,Range>, MAOps...> const std::shared_ptr<typename Ranges::IndexType>&... indices);
contract(const ContractOperation& cop, const std::string& indexName,
size_t begin,
size_t end,
const MAOps&... mao) const;
template <class MAOp>
auto operator+(const MAOp& sec) const -> decltype(operator()(std::plus<T>(), sec));
template <class MAOp>
auto operator-(const MAOp& sec) const -> decltype(operator()(std::minus<T>(), sec));
template <class MAOp>
auto operator*(const MAOp& sec) const -> decltype(operator()(std::multiplies<T>(), sec));
template <class MAOp>
auto operator/(const MAOp& sec) const -> decltype(operator()(std::divides<T>(), sec));
ConstMultiArrayOperationRoot copyThis() const;
const MultiArrayBase<T,Range>& operator*() const;
//MultiArrayBase<T,Range>& operator*();
MultiArrayBase<T,Range> const* operator->() const;
virtual size_t argNum() const override;
// set index -> implement !!!!!
const ConstMultiArrayOperationRoot<T,Range>& operator[](const IndexType& ind) const;
virtual const T& get() const override; virtual const T& get() const override;
const Name& name() const;
const MultiArrayBase<T,Range>& getCont() const { return mArrayRef; }
template <typename U, class RangeX>
friend class ConstMultiArrayOperationRoot;
template <typename U, class RangeX>
friend class MultiArrayOperationRoot;
protected: protected:
MultiArrayBase<T,Range> const& mArrayRef; MultiArrayBase<T,CRange> const& mArrayRef;
mutable IndexType mIndex; std::shared_ptr<IndexType> mIndex;
Name mNm;
}; };
template <typename T, class InRange, class TotalInRange, class OutRange, class TotalRange> template <typename T, class... Ranges>
class MultiArrayOperationMap : public MutableMultiArrayOperationBase<T> class OperationRoot : public MutableOperationBase<T>,
public OperationTemplate<OperationRoot<T,CRange> >
{ {
public: public:
typedef MultiArrayOperationBase<T> MAOB;
MultiArrayOperationMap(MultiArrayOperationRoot<T,TotalRange>& root, typedef OperationBase<T> OB;
const IndexMapFunction<InRange,OutRange>& mf); typedef OperationTemplate<OperationRoot<T,CRange> > OT;
typedef ContainerRange<Ranges...> CRange;
MultiArrayOperationMap(const MultiArrayOperationMap& in) = default; typedef typename CRange::IndexType IndexType;
MultiArrayOperationMap& operator=(const MultiArrayOperationRoot<T,TotalInRange>& in);
MultiArrayOperationMap& operator=(const ConstMultiArrayOperationRoot<T,TotalInRange>& in);
virtual size_t argNum() const override;
OperationRoot(MutableMultiArrayBase<T,CRange>& ma,
const std::shared_ptr<typename Ranges::IndexType>&... indices);
virtual const T& get() const override; virtual const T& get() const override;
virtual T& get() override; virtual T& get() override;
// !!!!
protected: protected:
IndexMapFunction<InRange,OutRange> mMF;
MultiArrayOperationRoot<T,TotalRange>& mRoot; MutableMultiArrayBase<T,CRange>& mArrayRef;
mutable typename TotalInRange::IndexType mIndex; // Index of incoming range std::shared_ptr<IndexType> mIndex;
Name mNm; // Name of incoming range
}; };
template <typename T, class Operation, class... MAOps> template <typename T, class OpFunction, class... Ops>
class MultiArrayOperation : public MultiArrayOperationBase<T> class Operation : public OperationBase<T>,
public OperationTemplate<Operation<T,OpFunction,Ops...> >
{ {
public: public:
typedef MultiArrayOperationBase<T> MAOB;
typedef std::tuple<MAOps...> OBT;
MultiArrayOperation(Operation& op, const MAOps&... secs); typedef OperationBase<T> OB;
MultiArrayOperation(const Operation& op, const MAOps&... secs); typedef OperationTemplate<Operation<T,OpFunction,Ops...> > OT;
typedef OpFunction F;
template <class Operation2, class... MAOps2>
MultiArrayOperation<T,Operation2,MultiArrayOperation<T,Operation,MAOps...>,MAOps2...>
operator()(Operation2& op, const MAOps2&... secs) const;
template <class Operation2, class... MAOps2> Operation(Ops&&... ops);
MultiArrayOperation<T,Operation2,MultiArrayOperation<T,Operation,MAOps...>,MAOps2...>
operator()(const Operation2& op, const MAOps2&... secs) const;
template <class Range2, class ContractOperation, class... MAOps2>
MultiArrayContraction<T,ContractOperation,Range2,MultiArrayOperation<T,Operation,MAOps...>,MAOps2...>
contract(const ContractOperation& cop, const std::string& indexName,
const MAOps2&... mao) const;
template <class MAOp2>
auto operator+(const MAOp2& sec) -> decltype(operator()(std::plus<T>(), sec));
template <class MAOp2>
auto operator-(const MAOp2& sec) -> decltype(operator()(std::minus<T>(), sec));
template <class MAOp2>
auto operator*(const MAOp2& sec) -> decltype(operator()(std::multiplies<T>(), sec));
template <class MAOp2>
auto operator/(const MAOp2& sec) -> decltype(operator()(std::divides<T>(), sec));
virtual size_t argNum() const override;
virtual const T& get() const override; virtual const T& get() const override;
protected: protected:
std::tuple<Ops...> mOps;
mutable T mVal; T res;
Operation mOp;
OBT mArgs; // include first arg also here !!!
}; };
template <typename T, class ContractOperation, class Range, class... MAOps>
class MultiArrayContraction : public MultiArrayOperationBase<T>
{
public:
typedef MultiArrayOperationBase<T> MAOB;
typedef std::tuple<MAOps...> OBT;
typedef typename Range::IndexType RunIndexType;
MultiArrayContraction(const ContractOperation& cop,
const RunIndexType& runIndex,
const MAOps&... mao);
MultiArrayContraction(const ContractOperation& cop,
const RunIndexType& runIndex,
size_t begin,
size_t end,
const MAOps&... mao);
template <class Operation2, class... MAOps2>
MultiArrayOperation<T,Operation2,MultiArrayContraction<T,ContractOperation,Range,MAOps...>,MAOps2...>
operator()(Operation2& op, const MAOps2&... secs) const;
template <class Operation2, class... MAOps2>
MultiArrayOperation<T,Operation2,MultiArrayContraction<T,ContractOperation,Range,MAOps...>,MAOps2...>
operator()(const Operation2& op, const MAOps2&... secs) const;
template <class Range2, class ContractOperation2, class... MAOps2>
MultiArrayContraction<T,ContractOperation2,Range2,
MultiArrayContraction<T,ContractOperation,Range,MAOps...>,MAOps2...>
contract(const ContractOperation2& cop, const std::string& indexName,
const MAOps2&... mao) const;
template <class MAOp2>
auto operator+(const MAOp2& sec) -> decltype(operator()(std::plus<T>(), sec));
template <class MAOp2>
auto operator-(const MAOp2& sec) -> decltype(operator()(std::minus<T>(), sec));
template <class MAOp2>
auto operator*(const MAOp2& sec) -> decltype(operator()(std::multiplies<T>(), sec));
template <class MAOp2>
auto operator/(const MAOp2& sec) -> decltype(operator()(std::divides<T>(), sec));
virtual size_t argNum() const override;
virtual const T& get() const override;
protected:
mutable T mVal;
ContractOperation mOp;
OBT mArgs; // include first arg also here !!!
RunIndexType mBeginIndex;
RunIndexType mEndIndex;
mutable RunIndexType mRunIndex;
};
}
#include "multi_array_operation.cc" #include "multi_array_operation.cc"