Minsky
tensorInterface.h
Go to the documentation of this file.
1 /*
2  @copyright Russell Standish 2019
3  @author Russell Standish
4  This file is part of Civita.
5 
6  Civita is free software: you can redistribute it and/or modify it
7  under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Civita is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with Civita. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #ifndef CIVITA_TENSORINTERFACE_H
21 #define CIVITA_TENSORINTERFACE_H
22 #include "hypercube.h"
23 #include "index.h"
24 
25 #ifndef CLASSDESC_ACCESS
26 #define CLASSDESC_ACCESS(x)
27 #endif
28 #include <chrono>
29 #include <set>
30 
31 namespace civita
32 {
33  class ITensor;
34  using TensorPtr=std::shared_ptr<ITensor>;
35 
36  class ITensor
37  {
38  public:
40  ITensor() {}
41  ITensor(const Hypercube& hc): m_hypercube(hc) {}
42  ITensor(Hypercube&& hc): m_hypercube(std::move(hc)) {}
43  ITensor(const std::vector<unsigned>& dims) {m_hypercube.dims(dims);}
44  ITensor(const ITensor&)=default;
45  ITensor(ITensor&&)=default;
46  ITensor& operator=(const ITensor&)=default;
47  ITensor& operator=(ITensor&&)=default;
48  virtual ~ITensor() {}
50  virtual const Hypercube& hypercube() const {return m_hypercube;}
51  virtual const Hypercube& hypercube(const Hypercube& hc) {return m_hypercube=hc;}
52  virtual const Hypercube& hypercube(Hypercube&& hc) {return m_hypercube=std::move(hc);}
53  std::size_t rank() const {return hypercube().rank();}
54  std::vector<unsigned> shape() const {return hypercube().dims();}
55 
57  void imposeDimensions(const Dimensions& dimensions) {
58  auto hc=hypercube();
59  for (auto& xv: hc.xvectors)
60  {
61  auto dim=dimensions.find(xv.name);
62  if (dim!=dimensions.end())
63  {
64  xv.dimension=dim->second;
65  xv.imposeDimension();
66  }
67  }
68  hypercube(std::move(hc));
69  }
70 
72  virtual const Index& index() const {return m_index;}
74  virtual double operator[](std::size_t) const=0;
76  virtual std::size_t size() const {
77  std::size_t s=index().size();
78  return s? s: hypercube().numElements();
79  }
80 
82  double atHCIndex(std::size_t hcIdx) const {
83  auto& idx=index();
84  if (idx.empty()) {// this is dense
85  if (hcIdx<size())
86  return (*this)[hcIdx];
87  } else {
88  auto i=idx.linealOffset(hcIdx);
89  if (i<idx.size())
90  return (*this)[i];
91  }
92  return nan(""); //element not found
93  }
94 
95  template <class T>
96  std::size_t hcIndex(const std::initializer_list<T>& indices) const
97  {return hypercube().linealIndex(indices);}
98 
99  template <class T>
100  double operator()(const std::initializer_list<T>& indices) const
101  {return atHCIndex(hcIndex(indices));}
102 
103  using Timestamp=std::chrono::time_point<std::chrono::high_resolution_clock>;
107  virtual Timestamp timestamp() const=0;
108 
110  struct Args
111  {
112  std::string dimension;
113  double val;
114  };
115  virtual void setArgument(const TensorPtr&, const ITensor::Args& args={"",0}) {notImpl();}
116  virtual void setArguments(const TensorPtr&, const TensorPtr&,
117  const ITensor::Args& args={}) {notImpl();}
118  virtual void setArguments(const std::vector<TensorPtr>& a,
119  const ITensor::Args& args={"",0})
120  {if (a.size()) setArgument(a[0], args);}
121  virtual void setArguments(const std::vector<TensorPtr>& a1,
122  const std::vector<TensorPtr>& a2,
123  const ITensor::Args& args={"",0})
124  {setArguments(a1.empty()? TensorPtr(): a1[0], a2.empty()? TensorPtr(): a2[0], args);}
125 
126  protected:
127  Hypercube m_hypercube;
128  Index m_index;
129  void notImpl() const
130  {throw std::runtime_error("setArgument(s) variant not implemented");}
131  };
132 
133 }
134 
135 #endif
void imposeDimensions(const Dimensions &dimensions)
impose dimensions according to dimension map dimensions
virtual void setArguments(const std::vector< TensorPtr > &a1, const std::vector< TensorPtr > &a2, const ITensor::Args &args={"", 0})
double operator()(const std::initializer_list< T > &indices) const
virtual const Hypercube & hypercube() const
information describing the axes, types and labels of this tensor
std::vector< unsigned > shape() const
ITensor(const std::vector< unsigned > &dims)
std::size_t rank() const
virtual const Hypercube & hypercube(const Hypercube &hc)
virtual Timestamp timestamp() const =0
timestamp indicating how old the dependendent data might be. Used in CachedTensorOp to determine when...
virtual const Index & index() const
the index vector - assumed to be ordered and unique
STL namespace.
void notImpl() const
virtual std::size_t size() const
return number of elements in tensor - maybe less than hypercube.numElements if sparse ...
ITensor & operator=(const ITensor &)=default
ITensor(Hypercube &&hc)
virtual const Hypercube & hypercube(Hypercube &&hc)
std::chrono::time_point< std::chrono::high_resolution_clock > Timestamp
std::size_t hcIndex(const std::initializer_list< T > &indices) const
virtual void setArguments(const TensorPtr &, const TensorPtr &, const ITensor::Args &args={})
arguments relevant for tensor expressions, not always meaningful. Exception thrown if not...
virtual void setArgument(const TensorPtr &, const ITensor::Args &args={"", 0})
std::shared_ptr< ITensor > TensorPtr
virtual ~ITensor()
virtual double operator[](std::size_t) const =0
return or compute data at a location
Hypercube m_hypercube
ITensor(const Hypercube &hc)
virtual void setArguments(const std::vector< TensorPtr > &a, const ITensor::Args &args={"", 0})
double atHCIndex(std::size_t hcIdx) const
returns the data value at hypercube index hcIdx, or NaN if
CLASSDESC_ACCESS(ITensor)