operation classes

This commit is contained in:
Christian Zimmermann 2017-02-15 19:40:44 +01:00
parent d4f8402f29
commit 211c731273
2 changed files with 327 additions and 57 deletions

244
src/me.cc
View file

@ -143,7 +143,10 @@ namespace ME
void IndefinitIndexBase::freeLinked() void IndefinitIndexBase::freeLinked()
{ {
mLinked = nullptr; if(linked()){
mLinked->freeLinked();
mLinked = nullptr;
}
} }
bool IndefinitIndexBase::linked() const bool IndefinitIndexBase::linked() const
@ -159,6 +162,17 @@ namespace ME
} }
} }
size_t IndefinitIndexBase::max() const
{
return static_cast<size_t>( -1 );
}
size_t IndefinitIndexBase::outOfRange() const
{
int res = pos() - max();
return res > 0 ? static_cast<size_t>(res) : 0;
}
/************** /**************
* IndexBase * * IndexBase *
**************/ **************/
@ -216,6 +230,13 @@ namespace ME
return mRange != i.mRange or mPos != i.mPos; return mRange != i.mRange or mPos != i.mPos;
} }
template <class Index>
size_t IndexBase<Index>::max() const
{
return mRange->size();
}
/******************** /********************
* SingleIndexBase * * SingleIndexBase *
********************/ ********************/
@ -226,12 +247,23 @@ namespace ME
return dynamic_cast<SingleRange*>( mRange )->get(mPos); return dynamic_cast<SingleRange*>( mRange )->get(mPos);
} }
template <typename U, IndexType TYPE>
size_t dim() const
{
return 1;
}
template <typename U, IndexType TYPE> template <typename U, IndexType TYPE>
size_t SingleIndexBase<TYPE>::evaluate(const Index& in) size_t SingleIndexBase<TYPE>::evaluate(const Index& in)
{ {
return in.mPos; return in.mPos;
} }
template <typename U, IndexType TYPE>
void linkTo(IndefinitIndexBase* target)
{
target->link(this);
}
/******************* /*******************
* MultiIndexBase * * MultiIndexBase *
@ -239,6 +271,23 @@ namespace ME
namespace namespace
{ {
template <class MultiIndex, size_t N>
IndefinitIndexBase& getIndex(MultiIndex& in, size_t n)
{
if(n == N){
return in.getIndex<N>();
}
else {
return getIndex<N-1>(in, n);
}
}
template <class MultiIndex>
IndefinitIndexBase& getIndex<MultiIndex,0>(MultiIndex& in, size_t n)
{
return in.getIndex<0>();
}
template <size_t N, class MultiIndex> template <size_t N, class MultiIndex>
size_t evaluate_x(const MultiIndex& index) size_t evaluate_x(const MultiIndex& index)
{ {
@ -252,6 +301,51 @@ namespace ME
const auto& subIndex = index.getIndex<0>(); const auto& subIndex = index.getIndex<0>();
return subIndex.pos(); return subIndex.pos();
} }
template <class MultiIndex>
void plus(MultiIndex& index, size_t digit, int num)
{
IndefinitIndexBase& si = index.getIndex(digit);
si.setPos( si.pos() + num );
size_t oor = si.outOfRange();
if(oor and digit != MultiIndex::mult - 1){
plus(index, digit + 1, 1);
plus(index, digit, oor - max());
}
}
}
template <class... Indices>
MultiIndex& MultiIndex<Indices...>::operator++()
{
setPos( pos() + 1 );
plus(*this, 0, 1);
return *this;
}
template <class... Indices>
MultiIndex& MultiIndex<Indices...>::operator--()
{
setPos( pos() - 1 );
plus(*this, 0, -1);
return *this;
}
template <class... Indices>
MultiIndex& MultiIndex<Indices...>::operator+=(int n)
{
setPos( pos() + n );
plus(*this, 0, n);
return *this;
}
template <class... Indices>
MultiIndex& MultiIndex<Indices...>::operator-=(int n)
{
setPos( pos() - n );
plus(*this, 0, 0-n);
return *this;
} }
template <class... Indices> template <class... Indices>
@ -260,29 +354,88 @@ namespace ME
return evaluate_x<sizeof...(Indices)-1>(in); return evaluate_x<sizeof...(Indices)-1>(in);
} }
template <class... Indices>
size_t MultiIndex<Indices...>::dim() const
{
size_t res = 1;
for(size_t i = 0; i != sMult; ++i){
res *= getIndex(i).dim();
}
return res;
}
template <class... Indices> template <class... Indices>
bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink) bool MultiIndex<Indices...>::link(IndefinitIndexBase* toLink)
{ {
if(toLink->name() == name() and toLink->rangeType() == rangeType()){ if(toLink->rangeType() != rangeType() and toLink->name() == name()){
bool isAlready = false; // throw !!
if(mLinked != nullptr){ }
for(auto& x: *mLinked){
if(x == toLink){ if(toLink->rangeType() == rangeType() and toLink->name() == name()){
isAlready = true; if(mLinked == toLink){
break; return true; // dont link twice the same
} }
} else if(mLinked == nullptr){
mLinked = toLink;
return true;
} }
else { else {
mLinked = new std::vector<IndefinitIndexBase*>(); return mLinked->link(toLink);
} }
if(not isAlready){
mLinked->push_back(toLink);
}
return true;
} }
else { else {
return /*try each element in mIPack*/; return linkLower(toLink);
}
}
template <size_t N>
auto& getIndex() -> decltype(std::get<N>(mIPack))
{
return std::get<N>(mIPack);
}
template <size_t N>
const auto& getIndex() const -> decltype(std::get<N>(mIPack));
{
return std::get<N>(mIPack);
}
template <class... Indices>
IndefinitIndexBase& MultiIndex<Indices...>::getIndex(size_t n)
{
if(n >= sMult){
// throw !!
}
MultiIndex<Indices...>* t = this;
return getIndex<sizeof...(Indices)>(*t, n);
}
template <class... Indices>
const IndefinitIndexBase& MultiIndex<Indices...>::getIndex(size_t n) const
{
if(n >= sMult){
// throw !!
}
MultiIndex<Indices...>* t = this;
return getIndex<sizeof...(Indices)>(*t, n);
}
template <class... Indices>
bool MultiIndex<Indices...>::linkLower(IndefinitIndexBase* toLink)
{
bool res = false;
for(size_t i = 0; i != sMult; ++i){
res |= getIndex(i).link(toLink);
}
return res;
}
template <class... Indices>
void MultiIndex<Indices...>::linkTo(IndefinitIndexBase* target)
{
target->link(this);
for(size_t i = 0; i != sMult; ++i){
getIndex(i).linkTo(target);
} }
} }
@ -290,31 +443,72 @@ namespace ME
* MultiArray * * MultiArray *
*******************/ *******************/
template <typename... Ranges>
void giveNames(const std::string& name, /**/);
template <typename... Ranges>
void giveNames(const std::vector<std::string>& names, /**/);
/*!!!! giveNames(...) !!!!!*/
template <typename T, class Range> template <typename T, class Range>
T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i) T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i)
{ {
return i.pos(); return mCont[ i.pos() ];
} }
template <typename T, class Range> template <typename T, class Range>
const T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i) const const T& MultiArray<T,Is...>::operator()(const typename Range::indexType& i) const
{ {
return i.pos(); return mCont[ i.pos() ];
}
template <typename T, class Range>
template <class... NameTypes>
MultiArrayOperation<T,Range>& operator()(const NameTypes&... str) const
{
auto index = mRange->begin();
// give names... !!!
return MultiArrayOperation<T,Range>(*this, index);
} }
/*************************** /*********************************
* NamedMultiArray * * MultiArrayOperationBase *
***************************/ *********************************/
IndefinitIndexBase& getIndex(const std::string& name) template <typename T, class Range>
template <class Range2>
MultiArrayOperationBase<T,Range>&
MultiArrayOperationBase<T,Range>::operator=(const MultiArrayOperationBase<T, Range2>& in)
{ {
return mIndexNameMap.at(name); // perform operation (iterate head index)
} }
const IndefinitIndexBase& getIndex(const std::string& name) const template <typename T, class Range>
template <class Operation, class... Ranges>
MultiArrayOperation<Operation>
MultiArrayOperationBase<T,Range>::operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs)
{ {
return mIndexNameMap.at(name); // set operation
// set mSecs
// link Indices
}
template <typename T, class Range>
size_t MultiArrayOperationBase<T,Range>::argNum() const
{
return 1;
}
/*****************************
* MultiArrayOperation *
*****************************/
template <typename T, class Range, class Operation, class... Ranges>
size_t MultiArrayOperation<T,Range,Operation,Ranges...>::argNum() const
{
return sizeof...(Ranges) + 1;
} }
} // end namespace ME } // end namespace ME

120
src/me.h
View file

@ -8,6 +8,12 @@
#include <string> #include <string>
#include <map> #include <map>
#define DEFAULT_MEMBERS(__class_name__) __class_name__() = default; \
__class_name__(const __class_name__& in) = default; \
__class_name__& operator=(const __class_name__& in) = default; \
__class_name__(__class_name__&& in) = default; \
__class_name__& operator=(__class_name__&& in) = default
namespace ME namespace ME
{ {
@ -70,6 +76,8 @@ namespace ME
{ {
public: public:
DEFAULT_MEMBERS(MultiRangeType);
MultiRangeType& operator=(RangeType& type); MultiRangeType& operator=(RangeType& type);
MultiRangeType& operator=(const std::vector<MultiRangeType>& multiType); MultiRangeType& operator=(const std::vector<MultiRangeType>& multiType);
@ -101,6 +109,9 @@ namespace ME
virtual RangeBase<Index>* base() = 0; virtual RangeBase<Index>* base() = 0;
virtual bool isSubRange() const; virtual bool isSubRange() const;
protected:
DEFAULT_MEMBERS(RangeBase);
}; };
template <class Range> template <class Range>
@ -115,6 +126,7 @@ namespace ME
public: public:
virtual bool isSubRange() const override; virtual bool isSubRange() const override;
protected: protected:
DEFAULT_MEMBERS(SubRangeBase);
RangeBase<Index>* mBase; RangeBase<Index>* mBase;
std::vector<bool> mOccupation; std::vector<bool> mOccupation;
}; };
@ -129,6 +141,8 @@ namespace ME
class SingleRange : public RangeBase<SingleIndex<U,TYPE> > class SingleRange : public RangeBase<SingleIndex<U,TYPE> >
{ {
public: public:
DEFAULT_MEMBERS(SingleRange);
const U& get(size_t pos) const; const U& get(size_t pos) const;
size_t get(const U& metaPos) const; size_t get(const U& metaPos) const;
@ -141,6 +155,7 @@ namespace ME
{ {
public: public:
DEFAULT_MEMBERS(MultiRange);
static size_t dim = sizeof...(Ranges); static size_t dim = sizeof...(Ranges);
template <size_t N> template <size_t N>
@ -179,11 +194,17 @@ namespace ME
virtual bool link(IndefinitIndexBase* toLink); virtual bool link(IndefinitIndexBase* toLink);
virtual void freeLinked(); virtual void freeLinked();
virtual bool linked() const; virtual bool linked() const;
virtual void linkTo(IndefinitIndexBase* target) = 0;
virtual void setPos(size_t pos); virtual void setPos(size_t pos);
virtual size_t max() const;
virtual size_t outOfRange() const;
protected: protected:
DEFAULT_MEMBERS(IndefinitIndexBase);
std::string mName; std::string mName;
size_t mPos; size_t mPos;
@ -208,6 +229,9 @@ namespace ME
virtual size_t pos() const override; // = mPos; implement !!! virtual size_t pos() const override; // = mPos; implement !!!
protected: protected:
DEFAULT_MEMBERS(IndexBase);
// translate index into position // translate index into position
virtual size_t evaluate(const Index& in) const = 0; virtual size_t evaluate(const Index& in) const = 0;
RangeBase<Index>* mRange; RangeBase<Index>* mRange;
@ -218,13 +242,17 @@ namespace ME
{ {
public: public:
DEFAULT_MEMBERS(SingleIndex);
virtual size_t size() const override; virtual size_t size() const override;
virtual SingleIndexBase& operator=(size_t pos) override; virtual SingleIndexBase& operator=(size_t pos) override;
//virtual SingleIndexBase& operator=(const U& upos); virtual SingleIndexBase& operator=(const U& upos);
//virtual const U& getMetaPos() const; virtual const U& getMetaPos() const;
virtual size_t dim() const override; // = 1
virtual void linkTo(IndefinitIndexBase* target) override;
// = 1
virtual size_t dim() const override; // implement !!!
protected: protected:
virtual size_t evaluate(const Index& in) const override; virtual size_t evaluate(const Index& in) const override;
}; };
@ -234,22 +262,40 @@ namespace ME
{ {
public: public:
DEFAULT_MEMBERS(MultiIndex);
typedef std::tuple<Indices...> IndexPack; typedef std::tuple<Indices...> IndexPack;
static size_t sMult = sizeof...(Indices);
virtual MultiIndex& operator++() override;
virtual MultiIndex& operator--() override;
virtual MultiIndex& operator+=(int n) override;
virtual MultiIndex& operator-=(int n) override;
template <size_t N> template <size_t N>
auto getIndex() -> decltype(std::get<N>(mIPack)); auto& getIndex() -> decltype(std::get<N>(mIPack));
template <size_t N>
const auto& getIndex() const -> decltype(std::get<N>(mIPack));
IndefinitIndexBase& getIndex(size_t n);
const IndefinitIndexBase& getIndex(size_t n) const;
// dimension of MultiRange // dimension of MultiRange
virtual size_t dim() const override; // implement !!! virtual size_t dim() const override; // implement !!!
virtual bool link(IndefinitIndexBase* toLink) override; virtual bool link(IndefinitIndexBase* toLink) override;
virtual void linkTo(IndefinitIndexBase* target) override;
protected: protected:
virtual bool linkLower(IndefinitIndexBase* toLink);
virtual size_t evaluate(const MultiIndex& in) const override; virtual size_t evaluate(const MultiIndex& in) const override;
IndexPack mIPack; IndexPack mIPack;
}; };
/****************** /******************
* MultiArray * * MultiArray *
******************/ ******************/
@ -259,19 +305,14 @@ namespace ME
{ {
public: public:
MultiArray() = default; DEFAULT_MEMBERS(MultiArray);
MultiArray(const MultiArray& in) = default;
MultiArray& operator=(const MultiArray& in) = default;
MultiArray(MultiArray&& in) = default;
MultiArray& operator=(MultiArray&& in) = default;
MultiArray(const Range& range); // !!!! MultiArray(const Range& range); // !!!!
template <class Operation, typename... Strings> template <class... NameTypes>
MultiArrayOperation<T,Range>& operator()(Operation op, const Strings&... str) const; MultiArrayOperation<T,Range>& operator()(const NameTypes&... str) const;
T& operator()(const typename Range::indexType& i); // implement T& operator()(const typename Range::indexType& i);
const T& operator()(const typename Range::indexType& i) const; // implement const T& operator()(const typename Range::indexType& i) const;
private: private:
bool mInit = false; bool mInit = false;
@ -280,25 +321,60 @@ namespace ME
}; };
/*************************** /***************************
* MultiArrayOperation * * MultiArrayOperation *
***************************/ ***************************/
class NamedMultiArray template <typename T, class Range>
class MultiArrayOperationBase
{ {
public: public:
MultiArrayOperation(MultiArray<T,Range>& ma, const IndefinitIndexBase& iib);
// execute AnyOperation // execute AnyOperation
// exception if range types are inconsitent with names // exception if range types are inconsitent with names
template <class Range2, class AnyOperation> template <class Range2>
MultiArrayOperation& operator=(const MultiArrayOperation<T, Range2, AnyOperation>& in); MultiArrayOperationBase& operator=(const MultiArrayOperationBase<T, Range2>& in);
IndefinitIndexBase& getIndex(const std::string& name);
const IndefinitIndexBase& getIndex(const std::string& name) const;
private: template <class Operation, class... Ranges>
std::map<std::string, IndefinitIndexBase> mIndexNameMap; MultiArrayOperation<Operation> operator()(Operation& op, MultiArrayOperationBase<T,Ranges>&... secs);
template <class Range2>
MultiArrayOperation<std::plus<T>,Range2> operator+(MultiArrayOperationBase<T,Range2>& sec);
template <class Range2>
MultiArrayOperation<std::minus<T>,Range2> operator-(MultiArrayOperationBase<T,Range2>& sec);
template <class Range2>
MultiArrayOperation<std::multiplies<T>,Range2> operator*(MultiArrayOperationBase<T,Range2>& sec);
template <class Range2>
MultiArrayOperation<std::divides<T>,Range2> operator/(MultiArrayOperationBase<T,Range2>& sec);
virtual size_t argNum() const;
protected:
MultiArray<T,Range>& mArrayRef;
IndefinitIndexBase* mIibPtr;
};
template <typename T, class Range, class Operation, class... Ranges>
class MultiArrayOperation : public MultiArrayOperationBase<T,Range>
{
public:
virtual size_t argNum() const override;
protected:
Operation mOp;
std::tuple<MultiArrayOperationBase<T,Ranges>... > mSecs;
}; };
// ========= // =========