2017-02-16 11:20:40 +01:00
|
|
|
// -*- C++ -*-
|
|
|
|
|
|
|
|
#ifndef __multi_array_operation_h__
|
|
|
|
#define __multi_array_operation_h__
|
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <tuple>
|
2017-03-22 21:51:54 +01:00
|
|
|
#include <cmath>
|
2017-08-30 17:56:38 +02:00
|
|
|
#include <map>
|
|
|
|
#include <utility>
|
2017-02-16 11:20:40 +01:00
|
|
|
|
|
|
|
#include "base_def.h"
|
2017-12-18 11:19:04 +01:00
|
|
|
#include "mbase_def.h"
|
|
|
|
|
2017-12-18 13:13:13 +01:00
|
|
|
#include "ranges/rheader.h"
|
|
|
|
#include "pack_num.h"
|
2017-02-16 11:20:40 +01:00
|
|
|
|
2018-01-15 18:31:47 +01:00
|
|
|
#include "arith.h"
|
2017-12-25 13:44:55 +01:00
|
|
|
|
2017-02-16 11:20:40 +01:00
|
|
|
namespace MultiArrayTools
|
|
|
|
{
|
|
|
|
|
2017-08-26 22:53:02 +02:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
using namespace MultiArrayHelper;
|
|
|
|
}
|
2018-05-15 21:18:21 +02:00
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
2018-05-18 17:45:40 +02:00
|
|
|
class OperationBase
|
2017-08-11 11:30:27 +02:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
2017-12-25 13:44:55 +01:00
|
|
|
OperationClass& THIS() { return static_cast<OperationClass&>(*this); }
|
|
|
|
const OperationClass& THIS() const { return static_cast<OperationClass const&>(*this); }
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2017-08-11 11:30:27 +02:00
|
|
|
template <class Second>
|
2018-07-19 19:29:52 +02:00
|
|
|
auto operator+(const OperationBase<T,Second>& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,plus<T>,OperationClass,Second>;
|
2017-08-26 17:18:42 +02:00
|
|
|
|
|
|
|
template <class Second>
|
2018-07-19 19:29:52 +02:00
|
|
|
auto operator-(const OperationBase<T,Second>& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,minus<T>,OperationClass,Second>;
|
2017-08-26 17:18:42 +02:00
|
|
|
|
|
|
|
template <class Second>
|
2018-07-19 19:29:52 +02:00
|
|
|
auto operator*(const OperationBase<T,Second>& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,multiplies<T>,OperationClass,Second>;
|
2017-08-26 17:18:42 +02:00
|
|
|
|
|
|
|
template <class Second>
|
2018-07-19 19:29:52 +02:00
|
|
|
auto operator/(const OperationBase<T,Second>& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,divides<T>,OperationClass,Second>;
|
2017-11-05 18:46:38 +01:00
|
|
|
|
2017-11-02 21:20:31 +01:00
|
|
|
template <class IndexType>
|
2018-09-11 18:38:30 +02:00
|
|
|
auto c(const std::shared_ptr<IndexType>& ind) const
|
2017-11-02 21:20:31 +01:00
|
|
|
-> Contraction<T,OperationClass,IndexType>;
|
2018-07-19 19:29:52 +02:00
|
|
|
|
2018-09-11 18:38:30 +02:00
|
|
|
template <class... Indices>
|
|
|
|
auto sl(const std::shared_ptr<Indices>&... inds) const
|
|
|
|
-> ConstSlice<T,typename Indices::RangeType...>;
|
|
|
|
|
2018-09-14 17:50:19 +02:00
|
|
|
template <class... Indices>
|
2018-09-15 16:33:49 +02:00
|
|
|
auto slc(const std::shared_ptr<Indices>&... inds) const
|
2018-09-15 01:58:17 +02:00
|
|
|
-> SliceContraction<T,OperationClass,Indices...>;
|
2018-09-14 17:50:19 +02:00
|
|
|
|
2018-07-19 19:29:52 +02:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
friend OperationClass;
|
2018-05-18 20:23:21 +02:00
|
|
|
friend OperationTemplate<T,OperationClass>;
|
|
|
|
OperationBase() = default;
|
2017-08-11 11:30:27 +02:00
|
|
|
};
|
2018-05-18 17:45:40 +02:00
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
class OperationTemplate : public OperationBase<T,OperationClass>
|
2018-05-18 20:23:21 +02:00
|
|
|
{
|
|
|
|
/* empty per default; specialize if needed */
|
|
|
|
private:
|
|
|
|
OperationTemplate() = default;
|
|
|
|
friend OperationClass;
|
|
|
|
};
|
|
|
|
|
2017-03-16 19:30:43 +01:00
|
|
|
|
2017-10-31 19:22:34 +01:00
|
|
|
template <typename T, class OpClass, class... Ranges>
|
2018-01-05 13:56:16 +01:00
|
|
|
class OperationMaster
|
2017-02-24 15:08:42 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2018-01-07 23:08:16 +01:00
|
|
|
class AssignmentExpr
|
|
|
|
{
|
2018-01-13 18:07:52 +01:00
|
|
|
private:
|
|
|
|
AssignmentExpr() = default;
|
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
OperationMaster& mM;
|
|
|
|
const OpClass& mSec;
|
2018-01-13 18:07:52 +01:00
|
|
|
|
2018-01-07 23:08:16 +01:00
|
|
|
public:
|
2018-01-13 18:07:52 +01:00
|
|
|
|
2018-02-12 00:11:24 +01:00
|
|
|
static constexpr size_t LAYER = 0;
|
|
|
|
static constexpr size_t SIZE = OpClass::SIZE;
|
|
|
|
typedef decltype(mSec.rootSteps()) ExtType;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
AssignmentExpr(OperationMaster& m, const OpClass& sec);
|
2018-01-07 23:08:16 +01:00
|
|
|
|
2018-02-12 00:11:24 +01:00
|
|
|
AssignmentExpr(const AssignmentExpr& in) = default;
|
2018-01-07 23:08:16 +01:00
|
|
|
AssignmentExpr(AssignmentExpr&& in) = default;
|
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
inline void operator()(size_t start = 0) const;
|
|
|
|
inline void operator()(size_t start, ExtType last) const;
|
2018-01-07 23:08:16 +01:00
|
|
|
|
2018-02-12 18:26:56 +01:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const -> ExtType;
|
2018-01-07 23:08:16 +01:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-08-27 17:52:50 +02:00
|
|
|
typedef T value_type;
|
2018-05-18 20:23:21 +02:00
|
|
|
//typedef OperationBase<T> OB;
|
2018-02-15 20:06:14 +01:00
|
|
|
typedef ContainerRange<T,Ranges...> CRange;
|
2018-03-02 13:35:50 +01:00
|
|
|
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
|
|
|
//typedef typename MultiRange<Ranges...>::IndexType IndexType;
|
2018-02-14 16:44:55 +01:00
|
|
|
|
2017-10-31 19:22:34 +01:00
|
|
|
OperationMaster(MutableMultiArrayBase<T,Ranges...>& ma, const OpClass& second,
|
2018-03-02 13:35:50 +01:00
|
|
|
IndexType& index);
|
2017-12-24 18:14:07 +01:00
|
|
|
|
2018-03-17 20:25:16 +01:00
|
|
|
OperationMaster(T* data, const OpClass& second,
|
|
|
|
IndexType& index);
|
|
|
|
|
2018-02-13 16:54:13 +01:00
|
|
|
inline void set(size_t pos, T val) { mDataPtr[pos] = val; }
|
|
|
|
inline void add(size_t pos, T val) { mDataPtr[pos] += val; }
|
|
|
|
inline T get(size_t pos) const;
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
|
2017-12-24 18:14:07 +01:00
|
|
|
void performAssignment(std::intptr_t blockIndexNum);
|
2017-10-31 19:22:34 +01:00
|
|
|
OpClass const& mSecond;
|
2018-03-17 20:25:16 +01:00
|
|
|
//MutableMultiArrayBase<T,Ranges...>& mArrayRef;
|
2018-02-13 15:38:03 +01:00
|
|
|
T* mDataPtr;
|
2018-03-02 13:35:50 +01:00
|
|
|
IndexType mIndex;
|
2017-02-16 11:20:40 +01:00
|
|
|
};
|
2017-08-10 15:12:26 +02:00
|
|
|
|
2017-03-16 19:30:43 +01:00
|
|
|
|
2017-08-10 15:12:26 +02:00
|
|
|
template <typename T, class... Ranges>
|
2018-05-18 17:45:40 +02:00
|
|
|
class ConstOperationRoot : public OperationTemplate<T,ConstOperationRoot<T,Ranges...> >
|
2017-03-16 19:30:43 +01:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
|
|
|
typedef T value_type;
|
2018-05-18 17:45:40 +02:00
|
|
|
typedef OperationBase<T,ConstOperationRoot<T,Ranges...> > OT;
|
2018-02-15 20:06:14 +01:00
|
|
|
typedef ContainerRange<T,Ranges...> CRange;
|
2018-03-02 13:35:50 +01:00
|
|
|
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-02-13 18:18:17 +01:00
|
|
|
static constexpr size_t SIZE = 1;
|
2017-03-16 19:30:43 +01:00
|
|
|
|
2017-08-25 17:02:23 +02:00
|
|
|
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
|
2017-08-10 15:12:26 +02:00
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
2018-03-17 20:25:16 +01:00
|
|
|
|
2018-07-29 19:17:26 +02:00
|
|
|
ConstOperationRoot(std::shared_ptr<MultiArrayBase<T,Ranges...> > maptr,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
|
|
|
|
2018-03-17 20:25:16 +01:00
|
|
|
ConstOperationRoot(const T* data, const IndexType& ind);
|
|
|
|
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2018-02-13 16:54:13 +01:00
|
|
|
inline T get(ET pos) const;
|
2017-08-28 18:28:43 +02:00
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const ConstOperationRoot& set(ET pos) const;
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
MExt<void> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
Expr loop(Expr exp) const;
|
2018-09-11 18:38:30 +02:00
|
|
|
|
|
|
|
const T* data() const;
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
|
2018-03-17 20:25:16 +01:00
|
|
|
//MultiArrayBase<T,Ranges...> const& mArrayRef;
|
2018-02-13 15:38:03 +01:00
|
|
|
const T* mDataPtr;
|
2018-09-11 18:38:30 +02:00
|
|
|
mutable IndexType mIndex;
|
2018-09-15 16:33:49 +02:00
|
|
|
mutable size_t mOff = 0;
|
2018-09-16 15:53:56 +02:00
|
|
|
std::shared_ptr<MultiArrayBase<T,Ranges...> > mMaPtr; // never remove this ptr, otherwise we lose temporary container instances!
|
2017-03-16 19:30:43 +01:00
|
|
|
};
|
2018-07-29 19:17:26 +02:00
|
|
|
|
2018-08-06 12:46:12 +02:00
|
|
|
template <typename T, class Op>
|
|
|
|
class StaticCast : public OperationTemplate<T,StaticCast<T,Op> >
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
const Op& mOp;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef T value_type;
|
|
|
|
typedef OperationBase<T,StaticCast<T,Op> > OT;
|
|
|
|
typedef typename Op::CRange CRange;
|
|
|
|
typedef typename Op::IndexType IndexType;
|
|
|
|
|
|
|
|
static constexpr size_t SIZE = Op::SIZE;
|
|
|
|
|
|
|
|
StaticCast(const Op& op);
|
|
|
|
|
|
|
|
template <class ET>
|
|
|
|
inline T get(ET pos) const;
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const StaticCast& set(ET pos) const;
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2018-08-06 12:46:12 +02:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const
|
|
|
|
-> decltype(mOp.rootSteps(iPtrNum));
|
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
Expr loop(Expr exp) const;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, class Op>
|
|
|
|
StaticCast<T,Op> staticcast(const Op& op)
|
|
|
|
{
|
|
|
|
return StaticCast<T,Op>(op);
|
|
|
|
}
|
|
|
|
|
2018-07-29 19:17:26 +02:00
|
|
|
template <class... Ranges>
|
|
|
|
class MetaOperationRoot : public OperationTemplate<std::tuple<typename Ranges::IndexType...>,
|
|
|
|
MetaOperationRoot<Ranges...> >
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef ContainerIndex<std::tuple<typename Ranges::IndexType::MetaType...>,
|
|
|
|
typename Ranges::IndexType...> IndexType;
|
|
|
|
typedef typename IndexType::MetaType value_type;
|
|
|
|
typedef OperationBase<value_type,MetaOperationRoot<Ranges...> > OT;
|
|
|
|
typedef ContainerRange<value_type,Ranges...> CRange;
|
|
|
|
|
|
|
|
static constexpr size_t SIZE = 1;
|
|
|
|
|
|
|
|
MetaOperationRoot(const IndexType& ind);
|
|
|
|
|
|
|
|
template <class ET>
|
|
|
|
inline value_type get(ET pos) const;
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const MetaOperationRoot& set(ET pos) const;
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2018-07-29 19:17:26 +02:00
|
|
|
MExt<void> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
Expr loop(Expr exp) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
//MultiArrayBase<T,Ranges...> const& mArrayRef;
|
|
|
|
//const T* mDataPtr;
|
|
|
|
IndexType mIndex;
|
|
|
|
};
|
|
|
|
|
2017-08-10 15:12:26 +02:00
|
|
|
template <typename T, class... Ranges>
|
2018-01-05 13:56:16 +01:00
|
|
|
class OperationRoot : public OperationTemplate<T,OperationRoot<T,Ranges...> >
|
2017-03-26 16:55:52 +02:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
|
|
|
typedef T value_type;
|
2018-05-18 17:45:40 +02:00
|
|
|
typedef OperationBase<T,OperationRoot<T,Ranges...> > OT;
|
2018-02-15 20:06:14 +01:00
|
|
|
typedef ContainerRange<T,Ranges...> CRange;
|
2018-03-02 13:35:50 +01:00
|
|
|
typedef ContainerIndex<T,typename Ranges::IndexType...> IndexType;
|
2018-01-04 11:43:45 +01:00
|
|
|
|
2018-02-13 18:18:17 +01:00
|
|
|
static constexpr size_t SIZE = 1;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2017-08-25 17:02:23 +02:00
|
|
|
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
2017-08-10 15:12:26 +02:00
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices);
|
2017-08-11 11:30:27 +02:00
|
|
|
|
2018-03-17 20:25:16 +01:00
|
|
|
OperationRoot(T* data, const IndexType& ind);
|
|
|
|
|
2017-10-31 19:22:34 +01:00
|
|
|
template <class OpClass>
|
|
|
|
OperationMaster<T,OpClass,Ranges...> operator=(const OpClass& in);
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2018-02-13 16:54:13 +01:00
|
|
|
inline T get(ET pos) const;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const OperationRoot& set(ET pos) const;
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
MExt<void> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
Expr loop(Expr exp) const;
|
2018-03-06 13:58:17 +01:00
|
|
|
|
|
|
|
T* data() const;
|
2017-05-24 19:01:02 +02:00
|
|
|
|
2018-09-11 18:38:30 +02:00
|
|
|
template <class... Indices>
|
|
|
|
auto sl(const std::shared_ptr<Indices>&... inds)
|
|
|
|
-> Slice<T,typename Indices::RangeType...>;
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
2017-12-25 13:44:55 +01:00
|
|
|
|
2018-03-17 20:25:16 +01:00
|
|
|
//MutableMultiArrayBase<T,Ranges...>& mArrayRef;
|
2018-02-13 15:38:03 +01:00
|
|
|
T* mDataPtr;
|
2018-09-11 18:38:30 +02:00
|
|
|
mutable IndexType mIndex;
|
2018-09-15 16:33:49 +02:00
|
|
|
mutable size_t mOff = 0;
|
2017-02-16 11:20:40 +01:00
|
|
|
};
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-07-17 20:01:25 +02:00
|
|
|
template <typename T>
|
|
|
|
class OperationValue : public OperationTemplate<T,OperationValue<T> >
|
|
|
|
{
|
2018-07-17 22:10:36 +02:00
|
|
|
public:
|
2018-07-17 20:01:25 +02:00
|
|
|
typedef T value_type;
|
|
|
|
typedef OperationBase<T,OperationValue<T> > OT;
|
|
|
|
typedef ContainerRange<T,NullRange> CRange;
|
|
|
|
typedef ContainerIndex<T,NullIndex> IndexType;
|
|
|
|
|
|
|
|
static constexpr size_t SIZE = 1;
|
|
|
|
|
|
|
|
OperationValue(const T& val);
|
|
|
|
|
|
|
|
template <class ET>
|
|
|
|
inline T get(ET pos) const;
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const OperationValue& set(ET pos) const;
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2018-07-17 20:01:25 +02:00
|
|
|
MExt<void> rootSteps(std::intptr_t iPtrNum = 0) const; // nullptr for simple usage with decltype
|
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
Expr loop(Expr exp) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
T mVal;
|
|
|
|
};
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
template <class Op>
|
|
|
|
size_t sumRootNum()
|
|
|
|
{
|
|
|
|
return typename Op::rootNum();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class Op1, class Op2, class... Ops>
|
|
|
|
size_t sumRootNum()
|
|
|
|
{
|
|
|
|
return typename Op1::rootNum() + sumRootNum<Op2,Ops...>();
|
|
|
|
}
|
2018-01-13 18:07:52 +01:00
|
|
|
|
|
|
|
template <size_t N>
|
|
|
|
struct RootSumN
|
|
|
|
{
|
|
|
|
template <class Op1, class... Ops>
|
|
|
|
struct rs
|
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
static constexpr size_t SIZE = Op1::SIZE + RootSumN<N-1>::template rs<Ops...>::SIZE;
|
2018-01-13 18:07:52 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct RootSumN<0>
|
|
|
|
{
|
|
|
|
template <class Op1>
|
|
|
|
struct rs
|
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
static constexpr size_t SIZE = Op1::SIZE;
|
2018-01-13 18:07:52 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template <class... Ops>
|
|
|
|
struct RootSum
|
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
static constexpr size_t SIZE = RootSumN<sizeof...(Ops)-1>::template rs<Ops...>::SIZE;
|
2018-01-13 18:07:52 +01:00
|
|
|
};
|
|
|
|
|
2017-09-11 12:54:24 +02:00
|
|
|
|
2017-08-10 15:12:26 +02:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
2018-01-05 13:56:16 +01:00
|
|
|
class Operation : public OperationTemplate<T,Operation<T,OpFunction,Ops...> >
|
2017-03-22 11:44:33 +01:00
|
|
|
{
|
|
|
|
public:
|
2017-08-27 17:52:50 +02:00
|
|
|
|
|
|
|
typedef T value_type;
|
2018-05-18 17:45:40 +02:00
|
|
|
typedef OperationBase<T,Operation<T,OpFunction,Ops...> > OT;
|
2017-08-10 15:12:26 +02:00
|
|
|
typedef OpFunction F;
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
static constexpr size_t SIZE = RootSum<Ops...>::SIZE;
|
2018-03-21 19:18:57 +01:00
|
|
|
static constexpr bool FISSTATIC = OpFunction::FISSTATIC;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
|
|
|
private:
|
2018-02-13 15:38:03 +01:00
|
|
|
std::tuple<Ops...> mOps;
|
2018-03-21 19:18:57 +01:00
|
|
|
std::shared_ptr<OpFunction> mF; // only if non-static
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
public:
|
2018-02-13 21:36:41 +01:00
|
|
|
typedef decltype(PackNum<sizeof...(Ops)-1>::template mkSteps<Ops...>(0, mOps)) ETuple;
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2017-08-11 15:26:10 +02:00
|
|
|
Operation(const Ops&... ops);
|
2018-04-28 17:33:57 +02:00
|
|
|
Operation(std::shared_ptr<OpFunction> ff, const Ops&... ops);
|
2017-03-22 11:44:33 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
template <class ET>
|
2018-02-13 16:54:13 +01:00
|
|
|
inline T get(ET pos) const;
|
2017-08-28 18:28:43 +02:00
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const Operation& set(ET pos) const;
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
2018-02-13 15:38:03 +01:00
|
|
|
-> decltype(PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps));
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
auto loop(Expr exp) const
|
|
|
|
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp));
|
2017-08-28 18:28:43 +02:00
|
|
|
|
2017-03-22 11:44:33 +01:00
|
|
|
};
|
2018-03-19 18:38:53 +01:00
|
|
|
|
2018-09-12 20:56:55 +02:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
template <bool FISSTATIC>
|
|
|
|
struct OpMaker
|
|
|
|
{
|
|
|
|
template <class OpFunction, class... Ops>
|
|
|
|
static inline auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
|
|
|
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
|
|
|
{
|
|
|
|
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(f,ops...);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <>
|
|
|
|
struct OpMaker<true>
|
|
|
|
{
|
|
|
|
template <class OpFunction, class... Ops>
|
|
|
|
static inline auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
|
|
|
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
|
|
|
{
|
|
|
|
return Operation<typename OpFunction::value_type,OpFunction,Ops...>(ops...);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-03-21 16:11:05 +01:00
|
|
|
template <class OpFunction, class... Ops>
|
2018-09-12 20:56:55 +02:00
|
|
|
auto mkOperation(const std::shared_ptr<OpFunction>& f, const Ops&... ops)
|
2018-03-21 19:18:57 +01:00
|
|
|
-> Operation<typename OpFunction::value_type,OpFunction,Ops...>
|
2018-03-21 16:11:05 +01:00
|
|
|
{
|
2018-09-12 20:56:55 +02:00
|
|
|
return OpMaker<OpFunction::FISSTATIC>::mkOperation(f, ops...);
|
2018-03-21 16:11:05 +01:00
|
|
|
}
|
2018-07-19 13:00:34 +02:00
|
|
|
|
|
|
|
|
2017-11-04 22:49:55 +01:00
|
|
|
|
2017-11-02 21:20:31 +01:00
|
|
|
template <typename T, class Op, class IndexType>
|
2017-11-04 22:49:55 +01:00
|
|
|
class Contraction : public OperationTemplate<T,Contraction<T,Op,IndexType> >
|
2017-11-01 21:26:45 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
typedef T value_type;
|
2018-05-18 17:45:40 +02:00
|
|
|
typedef OperationBase<T,Contraction<T,Op,IndexType> > OT;
|
2018-01-09 17:24:10 +01:00
|
|
|
|
2018-02-13 18:18:17 +01:00
|
|
|
static constexpr size_t SIZE = Op::SIZE;
|
2018-01-13 18:07:52 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
private:
|
|
|
|
|
|
|
|
const Op& mOp;
|
|
|
|
std::shared_ptr<IndexType> mInd;
|
|
|
|
|
|
|
|
public:
|
2018-01-14 19:15:05 +01:00
|
|
|
typedef decltype(mOp.rootSteps(0)) ETuple;
|
|
|
|
|
2017-11-02 21:20:31 +01:00
|
|
|
Contraction(const Op& op, std::shared_ptr<IndexType> ind);
|
2017-11-01 21:26:45 +01:00
|
|
|
|
2018-02-13 15:38:03 +01:00
|
|
|
template <class ET>
|
2018-02-13 16:54:13 +01:00
|
|
|
inline T get(ET pos) const;
|
2018-01-14 19:15:05 +01:00
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const Contraction& set(ET pos) const;
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
|
|
|
-> decltype(mOp.rootSteps(iPtrNum));
|
|
|
|
|
|
|
|
template <class Expr>
|
2018-09-17 16:21:23 +02:00
|
|
|
auto loop(Expr exp) const -> decltype(mInd->iforh(1,exp));
|
2017-11-01 21:26:45 +01:00
|
|
|
};
|
2018-05-15 21:18:21 +02:00
|
|
|
|
2018-09-14 17:50:19 +02:00
|
|
|
template <typename T, class Op, class... Indices>
|
2018-09-15 01:58:17 +02:00
|
|
|
// class SliceContraction : public OperationTemplate
|
|
|
|
//<MultiArray<T,typename Indices::RangeType...>,
|
|
|
|
//SliceContraction<MultiArray<T,typename Indices::RangeType...>,Op,Indices...> >
|
|
|
|
class SliceContraction : public OperationTemplate<T,SliceContraction<T,Op,Indices...> >
|
2018-09-14 17:50:19 +02:00
|
|
|
{
|
|
|
|
public:
|
2018-09-15 01:58:17 +02:00
|
|
|
typedef MultiArray<T,typename Indices::RangeType...> value_type;
|
|
|
|
typedef OperationTemplate<T,SliceContraction<T,Op,Indices...> > OT;
|
2018-09-14 17:50:19 +02:00
|
|
|
|
|
|
|
static constexpr size_t SIZE = Op::SIZE;
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
2018-09-15 16:33:49 +02:00
|
|
|
const Op& mOp;
|
2018-09-15 01:58:17 +02:00
|
|
|
mutable MultiArray<T,typename Indices::RangeType...> mCont;
|
|
|
|
mutable OperationRoot<T,typename Indices::RangeType...> mTarOp;
|
2018-09-14 17:50:19 +02:00
|
|
|
|
|
|
|
public:
|
|
|
|
typedef decltype(mOp.rootSteps(0)) ETuple;
|
|
|
|
|
2018-09-15 16:33:49 +02:00
|
|
|
SliceContraction(const Op& op, std::shared_ptr<Indices>... ind);
|
2018-09-14 17:50:19 +02:00
|
|
|
|
|
|
|
template <class ET>
|
|
|
|
inline const value_type& get(ET pos) const;
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const SliceContraction& set(ET pos) const;
|
2018-09-15 01:58:17 +02:00
|
|
|
|
2018-09-14 17:50:19 +02:00
|
|
|
auto rootSteps(std::intptr_t iPtrNum = 0) const // nullptr for simple usage with decltype
|
|
|
|
-> decltype(mOp.rootSteps(iPtrNum));
|
|
|
|
|
|
|
|
template <class Expr>
|
|
|
|
auto loop(Expr exp) const -> decltype(mOp.loop(exp)); // no loop
|
|
|
|
|
|
|
|
};
|
2017-08-11 15:26:10 +02:00
|
|
|
}
|
2017-02-16 11:20:40 +01:00
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
/* ========================= *
|
|
|
|
* --- TEMPLATE CODE --- *
|
|
|
|
* ========================= */
|
|
|
|
|
|
|
|
namespace MultiArrayTools
|
|
|
|
{
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
using namespace MultiArrayHelper;
|
|
|
|
}
|
2017-12-26 15:13:50 +01:00
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
/***************************
|
|
|
|
* OperationTemplate *
|
|
|
|
***************************/
|
2018-07-17 20:01:25 +02:00
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class Second>
|
2018-07-19 19:29:52 +02:00
|
|
|
auto OperationBase<T,OperationClass>::operator+(const OperationBase<T,Second>& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,plus<T>,OperationClass,Second>
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-07-19 19:29:52 +02:00
|
|
|
return Operation<T,plus<T>,OperationClass,Second>(THIS(), in.THIS());
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class Second>
|
2018-07-19 19:29:52 +02:00
|
|
|
auto OperationBase<T,OperationClass>::operator-(const OperationBase<T,Second>& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,minus<T>,OperationClass,Second>
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-07-19 19:29:52 +02:00
|
|
|
return Operation<T,minus<T>,OperationClass,Second>(THIS(), in.THIS());
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class Second>
|
2018-07-19 19:29:52 +02:00
|
|
|
auto OperationBase<T,OperationClass>::operator*(const OperationBase<T,Second>& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,multiplies<T>,OperationClass,Second>
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-07-19 19:29:52 +02:00
|
|
|
return Operation<T,multiplies<T>,OperationClass,Second>(THIS(), in.THIS());
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class Second>
|
2018-07-19 19:29:52 +02:00
|
|
|
auto OperationBase<T,OperationClass>::operator/(const OperationBase<T,Second>& in) const
|
2018-01-14 19:15:05 +01:00
|
|
|
-> Operation<T,divides<T>,OperationClass,Second>
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-07-19 19:29:52 +02:00
|
|
|
return Operation<T,divides<T>,OperationClass,Second>(THIS(), in.THIS());
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class IndexType>
|
2018-09-11 18:38:30 +02:00
|
|
|
auto OperationBase<T,OperationClass>::c(const std::shared_ptr<IndexType>& ind) const
|
2017-11-20 21:35:25 +01:00
|
|
|
-> Contraction<T,OperationClass,IndexType>
|
|
|
|
{
|
2017-12-25 13:44:55 +01:00
|
|
|
return Contraction<T,OperationClass,IndexType>(THIS(), ind);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
|
|
|
|
2018-09-11 18:38:30 +02:00
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class... Indices>
|
|
|
|
auto OperationBase<T,OperationClass>::sl(const std::shared_ptr<Indices>&... inds) const
|
|
|
|
-> ConstSlice<T,typename Indices::RangeType...>
|
|
|
|
{
|
|
|
|
ConstSlice<T,typename Indices::RangeType...> out(inds->range()...);
|
2018-09-13 13:28:40 +02:00
|
|
|
out.define(inds...) = THIS();
|
2018-09-11 18:38:30 +02:00
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <typename T, class OperationClass>
|
|
|
|
template <class... Indices>
|
2018-09-15 16:33:49 +02:00
|
|
|
auto OperationBase<T,OperationClass>::slc(const std::shared_ptr<Indices>&... inds) const
|
2018-09-15 01:58:17 +02:00
|
|
|
-> SliceContraction<T,OperationClass,Indices...>
|
|
|
|
{
|
|
|
|
return SliceContraction<T,OperationClass,Indices...>
|
|
|
|
(THIS(), inds...);
|
|
|
|
}
|
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
/*****************************************
|
|
|
|
* OperationMaster::AssignmentExpr *
|
|
|
|
*****************************************/
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
|
|
|
AssignmentExpr(OperationMaster& m, const OpClass& sec) :
|
|
|
|
mM(m), mSec(sec) {}
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
inline void OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
2018-02-13 15:38:03 +01:00
|
|
|
operator()(size_t start, ExtType last) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-09-16 18:53:28 +02:00
|
|
|
//VCHECK(mSec.template get<ExtType>(last));
|
2018-02-13 16:54:13 +01:00
|
|
|
mM.add(start, mSec.template get<ExtType>(last) );
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
2018-02-12 00:11:24 +01:00
|
|
|
typename OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::ExtType
|
2018-01-14 19:15:05 +01:00
|
|
|
OperationMaster<T,OpClass,Ranges...>::AssignmentExpr::
|
2018-02-12 18:26:56 +01:00
|
|
|
rootSteps(std::intptr_t iPtrNum) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
|
|
|
return mSec.rootSteps(iPtrNum);
|
|
|
|
}
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
|
|
|
|
/*************************
|
|
|
|
* OperationMaster *
|
|
|
|
*************************/
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
OperationMaster<T,OpClass,Ranges...>::
|
|
|
|
OperationMaster(MutableMultiArrayBase<T,Ranges...>& ma, const OpClass& second,
|
2018-03-02 13:35:50 +01:00
|
|
|
IndexType& index) :
|
2018-03-17 20:25:16 +01:00
|
|
|
mSecond(second), mDataPtr(ma.data()),
|
2018-03-02 16:37:11 +01:00
|
|
|
mIndex(index)
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
performAssignment(0);
|
2017-12-24 18:14:07 +01:00
|
|
|
}
|
2018-03-17 20:25:16 +01:00
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
|
|
|
OperationMaster<T,OpClass,Ranges...>::
|
|
|
|
OperationMaster(T* data, const OpClass& second,
|
|
|
|
IndexType& index) :
|
|
|
|
mSecond(second), mDataPtr(data),
|
|
|
|
mIndex(index)
|
|
|
|
{
|
|
|
|
performAssignment(0);
|
|
|
|
}
|
|
|
|
|
2017-12-25 13:44:55 +01:00
|
|
|
template <typename T, class OpClass, class... Ranges>
|
2017-12-24 18:14:07 +01:00
|
|
|
void OperationMaster<T,OpClass,Ranges...>::performAssignment(std::intptr_t blockIndexNum)
|
|
|
|
{
|
2018-01-14 19:15:05 +01:00
|
|
|
AssignmentExpr ae(*this, mSecond); // Expression to be executed within loop
|
2018-09-17 16:21:23 +02:00
|
|
|
const auto loop = mSecond.template loop<decltype(mIndex.ifor(1,ae))>( mIndex.ifor(1,ae) );
|
2018-02-13 18:18:17 +01:00
|
|
|
// hidden Loops outside ! -> auto vectorizable
|
2018-01-14 19:15:05 +01:00
|
|
|
loop(); // execute overall loop(s) and so internal hidden loops and so the inherited expressions
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OpClass, class... Ranges>
|
2018-02-13 18:18:17 +01:00
|
|
|
inline T OperationMaster<T,OpClass,Ranges...>::get(size_t pos) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
return mDataPtr[pos];
|
2017-12-26 15:13:50 +01:00
|
|
|
}
|
|
|
|
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
/****************************
|
|
|
|
* ConstOperationRoot *
|
|
|
|
****************************/
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
ConstOperationRoot<T,Ranges...>::
|
|
|
|
ConstOperationRoot(const MultiArrayBase<T,Ranges...>& ma,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
2018-03-17 20:25:16 +01:00
|
|
|
mDataPtr(ma.data()),
|
2018-03-02 16:37:11 +01:00
|
|
|
mIndex( ma.begin() )
|
2018-07-29 19:17:26 +02:00
|
|
|
{
|
|
|
|
//VCHECK(ma.data());
|
|
|
|
mIndex(indices...);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
ConstOperationRoot<T,Ranges...>::
|
|
|
|
ConstOperationRoot(std::shared_ptr<MultiArrayBase<T,Ranges...> > maptr,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
|
|
|
mDataPtr(maptr->data()),
|
2018-09-16 15:53:56 +02:00
|
|
|
mIndex(maptr->begin()),
|
|
|
|
mMaPtr(maptr)
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-03-02 13:35:50 +01:00
|
|
|
mIndex(indices...);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2018-03-17 20:25:16 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
ConstOperationRoot<T,Ranges...>::
|
|
|
|
ConstOperationRoot(const T* data, const IndexType& ind) :
|
|
|
|
mDataPtr(data),
|
|
|
|
mIndex( ind ) { }
|
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
template <typename T, class... Ranges>
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2018-02-13 16:54:13 +01:00
|
|
|
inline T ConstOperationRoot<T,Ranges...>::get(ET pos) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-09-15 01:58:17 +02:00
|
|
|
return mDataPtr[pos.val()+mOff];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const ConstOperationRoot<T,Ranges...>& ConstOperationRoot<T,Ranges...>::set(ET pos) const
|
2018-09-15 01:58:17 +02:00
|
|
|
{
|
|
|
|
mIndex = pos.val();
|
|
|
|
mOff = mIndex.pos();
|
|
|
|
return *this;
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2018-09-11 18:38:30 +02:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
const T* ConstOperationRoot<T,Ranges...>::data() const
|
|
|
|
{
|
|
|
|
return mDataPtr + mIndex().pos();
|
|
|
|
}
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
template <typename T, class... Ranges>
|
2018-02-13 15:38:03 +01:00
|
|
|
MExt<void> ConstOperationRoot<T,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
2018-01-09 17:24:10 +01:00
|
|
|
{
|
2018-03-02 16:37:11 +01:00
|
|
|
return MExt<void>(getStepSize( mIndex, iPtrNum ));
|
2018-02-14 00:38:44 +01:00
|
|
|
//return MExt<void>(getStepSize( getRootIndices( mIndex->info() ), iPtrNum ));
|
2018-01-09 17:24:10 +01:00
|
|
|
}
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
Expr ConstOperationRoot<T,Ranges...>::loop(Expr exp) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-12 00:11:24 +01:00
|
|
|
return exp;
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2018-07-29 19:17:26 +02:00
|
|
|
|
2018-08-06 12:46:12 +02:00
|
|
|
/********************
|
|
|
|
* StaticCast *
|
|
|
|
********************/
|
|
|
|
|
|
|
|
template <typename T, class Op>
|
|
|
|
StaticCast<T,Op>::StaticCast(const Op& op) : mOp(op) {}
|
|
|
|
|
|
|
|
template <typename T, class Op>
|
|
|
|
template <class ET>
|
|
|
|
inline T StaticCast<T,Op>::get(ET pos) const
|
|
|
|
{
|
|
|
|
return static_cast<T>( mOp.get(pos) );
|
|
|
|
}
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <typename T, class Op>
|
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const StaticCast<T,Op>& StaticCast<T,Op>::set(ET pos) const
|
2018-09-15 01:58:17 +02:00
|
|
|
{
|
|
|
|
mOp.set(pos);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-08-06 12:46:12 +02:00
|
|
|
template <typename T, class Op>
|
|
|
|
auto StaticCast<T,Op>::rootSteps(std::intptr_t iPtrNum) const
|
|
|
|
-> decltype(mOp.rootSteps(iPtrNum))
|
|
|
|
{
|
|
|
|
return mOp.rootSteps(iPtrNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class Op>
|
|
|
|
template <class Expr>
|
|
|
|
Expr StaticCast<T,Op>::loop(Expr exp) const
|
|
|
|
{
|
|
|
|
return mOp.loop(exp);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-29 19:17:26 +02:00
|
|
|
/****************************
|
|
|
|
* MetaOperationRoot *
|
|
|
|
****************************/
|
|
|
|
|
|
|
|
template <class... Ranges>
|
|
|
|
MetaOperationRoot<Ranges...>::
|
|
|
|
MetaOperationRoot(const IndexType& ind) :
|
|
|
|
mIndex( ind ) { }
|
|
|
|
|
|
|
|
template <class... Ranges>
|
|
|
|
template <class ET>
|
|
|
|
inline typename MetaOperationRoot<Ranges...>::value_type
|
|
|
|
MetaOperationRoot<Ranges...>::get(ET pos) const
|
|
|
|
{
|
|
|
|
//VCHECK(pos.val());
|
|
|
|
//VCHECK(mDataPtr);
|
|
|
|
//VCHECK(mDataPtr[pos.val()])
|
|
|
|
return mIndex.meta(pos.val());
|
|
|
|
}
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <class... Ranges>
|
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const MetaOperationRoot<Ranges...>& MetaOperationRoot<Ranges...>::set(ET pos) const
|
2018-09-15 01:58:17 +02:00
|
|
|
{
|
|
|
|
mIndex = pos.val();
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-07-29 19:17:26 +02:00
|
|
|
template <class... Ranges>
|
|
|
|
MExt<void> MetaOperationRoot<Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
|
|
|
{
|
|
|
|
return MExt<void>(getStepSize( mIndex, iPtrNum ));
|
|
|
|
//return MExt<void>(getStepSize( getRootIndices( mIndex->info() ), iPtrNum ));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
template <class... Ranges>
|
|
|
|
template <class Expr>
|
|
|
|
Expr MetaOperationRoot<Ranges...>::loop(Expr exp) const
|
|
|
|
{
|
|
|
|
return exp;
|
|
|
|
}
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
/***********************
|
|
|
|
* OperationRoot *
|
|
|
|
***********************/
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
OperationRoot<T,Ranges...>::
|
|
|
|
OperationRoot(MutableMultiArrayBase<T,Ranges...>& ma,
|
|
|
|
const std::shared_ptr<typename Ranges::IndexType>&... indices) :
|
2018-03-17 20:25:16 +01:00
|
|
|
mDataPtr(ma.data()),
|
2018-03-02 16:37:11 +01:00
|
|
|
mIndex( ma.begin() )
|
2017-11-20 21:35:25 +01:00
|
|
|
{
|
2018-03-02 13:35:50 +01:00
|
|
|
mIndex(indices...);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2018-03-02 13:35:50 +01:00
|
|
|
|
2018-03-17 20:25:16 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
OperationRoot<T,Ranges...>::
|
|
|
|
OperationRoot(T* data, const IndexType& ind) :
|
|
|
|
mDataPtr(data),
|
|
|
|
mIndex( ind ) { }
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
template <class OpClass>
|
|
|
|
OperationMaster<T,OpClass,Ranges...> OperationRoot<T,Ranges...>::operator=(const OpClass& in)
|
|
|
|
{
|
2018-03-17 20:25:16 +01:00
|
|
|
return OperationMaster<T,OpClass,Ranges...>(mDataPtr, in, mIndex);
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
template <typename T, class... Ranges>
|
2018-02-12 18:26:56 +01:00
|
|
|
template <class ET>
|
2018-02-13 16:54:13 +01:00
|
|
|
inline T OperationRoot<T,Ranges...>::get(ET pos) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-09-15 01:58:17 +02:00
|
|
|
return mDataPtr[pos.val()+mOff];
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const OperationRoot<T,Ranges...>& OperationRoot<T,Ranges...>::set(ET pos) const
|
2018-09-15 01:58:17 +02:00
|
|
|
{
|
|
|
|
mIndex = pos.val();
|
|
|
|
mOff = mIndex.pos();
|
|
|
|
return *this;
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
template <typename T, class... Ranges>
|
2018-02-13 15:38:03 +01:00
|
|
|
MExt<void> OperationRoot<T,Ranges...>::rootSteps(std::intptr_t iPtrNum) const
|
2018-01-09 17:24:10 +01:00
|
|
|
{
|
2018-03-02 16:37:11 +01:00
|
|
|
return MExt<void>(getStepSize( mIndex, iPtrNum ));
|
|
|
|
//return MExt<void>(getStepSize( mIndex.info(), iPtrNum ));
|
2018-01-09 17:24:10 +01:00
|
|
|
}
|
2018-01-14 19:15:05 +01:00
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
Expr OperationRoot<T,Ranges...>::loop(Expr exp) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-12 00:11:24 +01:00
|
|
|
return exp;
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2018-03-06 13:58:17 +01:00
|
|
|
|
|
|
|
template <typename T, class... Ranges>
|
|
|
|
T* OperationRoot<T,Ranges...>::data() const
|
|
|
|
{
|
2018-09-11 18:38:30 +02:00
|
|
|
return mDataPtr + mIndex().pos();
|
2018-03-06 13:58:17 +01:00
|
|
|
}
|
2018-07-17 20:01:25 +02:00
|
|
|
|
2018-09-11 18:38:30 +02:00
|
|
|
template <typename T, class... Ranges>
|
|
|
|
template <class... Indices>
|
|
|
|
auto OperationRoot<T,Ranges...>::sl(const std::shared_ptr<Indices>&... inds)
|
|
|
|
-> Slice<T,typename Indices::RangeType...>
|
|
|
|
{
|
|
|
|
Slice<T,typename Indices::RangeType...> out(inds->range()...);
|
|
|
|
out.define(inds...) = *this;
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************
|
|
|
|
* OperationValue *
|
|
|
|
************************/
|
2018-07-17 20:01:25 +02:00
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
OperationValue<T>::OperationValue(const T& val) : mVal(val) {}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
template <class ET>
|
|
|
|
inline T OperationValue<T>::get(ET pos) const
|
|
|
|
{
|
|
|
|
return mVal;
|
|
|
|
}
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <typename T>
|
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const OperationValue<T>& OperationValue<T>::set(ET pos) const
|
2018-09-15 01:58:17 +02:00
|
|
|
{
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-07-17 20:01:25 +02:00
|
|
|
template <typename T>
|
|
|
|
MExt<void> OperationValue<T>::rootSteps(std::intptr_t iPtrNum) const
|
|
|
|
{
|
|
|
|
return MExt<void>(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
template <class Expr>
|
|
|
|
Expr OperationValue<T>::loop(Expr exp) const
|
|
|
|
{
|
|
|
|
return exp;
|
|
|
|
}
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
|
|
|
|
/*******************
|
|
|
|
* Operation *
|
|
|
|
*******************/
|
|
|
|
|
|
|
|
template <typename T, class OpFunction, class... Ops>
|
|
|
|
Operation<T,OpFunction,Ops...>::Operation(const Ops&... ops) :
|
2018-04-28 17:33:57 +02:00
|
|
|
mOps(ops...)
|
|
|
|
{
|
|
|
|
static_assert( FISSTATIC, "need function instance for non-static function" );
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OpFunction, class... Ops>
|
|
|
|
Operation<T,OpFunction,Ops...>::Operation(std::shared_ptr<OpFunction> ff,
|
|
|
|
const Ops&... ops) :
|
|
|
|
mOps(ops...),
|
|
|
|
mF(ff)
|
|
|
|
{
|
|
|
|
static_assert( not FISSTATIC, "using instance of function supposed to be static" );
|
|
|
|
}
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
2018-02-13 15:38:03 +01:00
|
|
|
template <class ET>
|
2018-02-13 16:54:13 +01:00
|
|
|
inline T Operation<T,OpFunction,Ops...>::get(ET pos) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-14 00:38:44 +01:00
|
|
|
typedef std::tuple<Ops...> OpTuple;
|
2018-02-13 15:38:03 +01:00
|
|
|
return PackNum<sizeof...(Ops)-1>::
|
2018-04-28 17:33:57 +02:00
|
|
|
template mkOpExpr<SIZE,T,ET,OpTuple,OpFunction>(mF, pos, mOps);
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2017-12-26 15:13:50 +01:00
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const Operation<T,OpFunction,Ops...>& Operation<T,OpFunction,Ops...>::set(ET pos) const
|
2018-09-15 01:58:17 +02:00
|
|
|
{
|
|
|
|
PackNum<sizeof...(Ops)-1>::setOpPos(mOps,pos);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
template <typename T, class OpFunction, class... Ops>
|
2018-01-14 19:15:05 +01:00
|
|
|
auto Operation<T,OpFunction,Ops...>::rootSteps(std::intptr_t iPtrNum) const
|
2018-02-13 15:38:03 +01:00
|
|
|
-> decltype(PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps))
|
2018-01-09 17:24:10 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
return PackNum<sizeof...(Ops)-1>::mkSteps(iPtrNum, mOps);
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class OpFunction, class... Ops>
|
|
|
|
template <class Expr>
|
2018-02-12 00:11:24 +01:00
|
|
|
auto Operation<T,OpFunction,Ops...>::loop(Expr exp) const
|
|
|
|
-> decltype(PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp ))
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-12 00:11:24 +01:00
|
|
|
return PackNum<sizeof...(Ops)-1>::mkLoop( mOps, exp );
|
2018-01-09 17:24:10 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
/*********************
|
|
|
|
* Contraction *
|
|
|
|
*********************/
|
|
|
|
|
|
|
|
template <typename T, class Op, class IndexType>
|
|
|
|
Contraction<T,Op,IndexType>::Contraction(const Op& op, std::shared_ptr<IndexType> ind) :
|
|
|
|
mOp(op),
|
|
|
|
mInd(ind) {}
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2018-01-14 19:15:05 +01:00
|
|
|
// forward loop !!!!
|
|
|
|
template <typename T, class Op, class IndexType>
|
2018-02-13 15:38:03 +01:00
|
|
|
template <class ET>
|
2018-02-13 16:54:13 +01:00
|
|
|
inline T Contraction<T,Op,IndexType>::get(ET pos) const
|
2018-01-14 19:15:05 +01:00
|
|
|
{
|
2018-02-13 15:38:03 +01:00
|
|
|
return mOp.template get<ET>(pos);
|
2018-01-14 19:15:05 +01:00
|
|
|
}
|
2018-02-13 18:18:17 +01:00
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <typename T, class Op, class IndexType>
|
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const Contraction<T,Op,IndexType>& Contraction<T,Op,IndexType>::set(ET pos) const
|
2018-09-15 01:58:17 +02:00
|
|
|
{
|
|
|
|
mOp.set(pos);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-01-09 17:24:10 +01:00
|
|
|
template <typename T, class Op, class IndexType>
|
2018-01-14 19:15:05 +01:00
|
|
|
auto Contraction<T,Op,IndexType>::rootSteps(std::intptr_t iPtrNum) const
|
|
|
|
-> decltype(mOp.rootSteps(iPtrNum))
|
|
|
|
{
|
|
|
|
return mOp.rootSteps(iPtrNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class Op, class IndexType>
|
|
|
|
template <class Expr>
|
2018-09-17 16:21:23 +02:00
|
|
|
auto Contraction<T,Op,IndexType>::loop(Expr exp) const -> decltype(mInd->iforh(1,exp))
|
2018-01-09 17:24:10 +01:00
|
|
|
{
|
2018-09-17 16:21:23 +02:00
|
|
|
return mInd->iforh(1,exp);
|
2018-01-09 17:24:10 +01:00
|
|
|
}
|
|
|
|
|
2018-09-14 17:50:19 +02:00
|
|
|
/**************************
|
|
|
|
* SliceContraction *
|
|
|
|
**************************/
|
|
|
|
|
|
|
|
template <typename T, class Op, class... Indices>
|
2018-09-15 16:33:49 +02:00
|
|
|
SliceContraction<T,Op,Indices...>::SliceContraction(const Op& op,
|
|
|
|
std::shared_ptr<Indices>... ind) :
|
2018-09-14 17:50:19 +02:00
|
|
|
mOp(op),
|
2018-09-15 01:58:17 +02:00
|
|
|
mCont(ind->range()...),
|
|
|
|
mTarOp(mCont,ind...) {}
|
2018-09-14 17:50:19 +02:00
|
|
|
|
|
|
|
// forward loop !!!!
|
|
|
|
template <typename T, class Op, class... Indices>
|
|
|
|
template <class ET>
|
2018-09-15 01:58:17 +02:00
|
|
|
inline const MultiArray<T,typename Indices::RangeType...>&
|
|
|
|
SliceContraction<T,Op,Indices...>::get(ET pos) const
|
2018-09-14 17:50:19 +02:00
|
|
|
{
|
2018-09-15 01:58:17 +02:00
|
|
|
mCont *= 0; // grrr
|
|
|
|
mTarOp = mOp.set(pos); // SET FUNCTION!!
|
2018-09-14 17:50:19 +02:00
|
|
|
return mCont;
|
|
|
|
}
|
|
|
|
|
2018-09-15 01:58:17 +02:00
|
|
|
template <typename T, class Op, class... Indices>
|
|
|
|
template <class ET>
|
2018-09-15 16:33:49 +02:00
|
|
|
inline const SliceContraction<T,Op,Indices...>& SliceContraction<T,Op,Indices...>::set(ET pos) const
|
2018-09-15 01:58:17 +02:00
|
|
|
{
|
|
|
|
mOp.set(pos);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2018-09-14 17:50:19 +02:00
|
|
|
template <typename T, class Op, class... Indices>
|
|
|
|
auto SliceContraction<T,Op,Indices...>::rootSteps(std::intptr_t iPtrNum) const
|
|
|
|
-> decltype(mOp.rootSteps(iPtrNum))
|
|
|
|
{
|
|
|
|
return mOp.rootSteps(iPtrNum);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, class Op, class... Indices>
|
|
|
|
template <class Expr>
|
|
|
|
auto SliceContraction<T,Op,Indices...>::loop(Expr exp) const -> decltype(mOp.loop(exp))
|
|
|
|
{
|
|
|
|
return mOp.loop(exp);
|
|
|
|
}
|
|
|
|
|
2017-11-20 21:35:25 +01:00
|
|
|
}
|
2017-02-16 11:20:40 +01:00
|
|
|
|
2018-05-18 20:23:21 +02:00
|
|
|
#include "type_operations.h"
|
|
|
|
|
2017-02-16 11:20:40 +01:00
|
|
|
#endif
|