OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
Monomial.hpp
1 //
2 // Created by tommaso on 21/03/19.
3 //
4 
5 #ifndef OPENFPM_PDATA_MONOMIALBASISELEMENT_H
6 #define OPENFPM_PDATA_MONOMIALBASISELEMENT_H
7 
8 
9 #include <vector>
10 #include <ostream>
11 #include "Space/Shape/Point.hpp"
12 
13 template<unsigned int dim>
14 class Monomial
15 {
16 // The base idea is that this should behave like a pair <unsigned int, std::vector<unsigned int>>
17 private:
18  unsigned int sum = 0;
19  Point<dim, unsigned int> exponents;
20  unsigned int scalar = 1;
21 
22 public:
23  Monomial();
24 
25  explicit Monomial(const Point<dim, unsigned int> &other, unsigned int scalar = 1);
26 
27  explicit Monomial(const Point<dim, long int> &other, unsigned int scalar = 1);
28 
29  explicit Monomial(const unsigned int other[dim]);
30 
31  Monomial(const Monomial<dim> &other);
32 
33  Monomial<dim> &operator=(const Monomial<dim> &other);
34 
35  bool operator==(const Monomial<dim> &other) const;
36 
37  unsigned int order() const;
38 
39  unsigned int getExponent(unsigned int i) const;
40 
41  void setExponent(unsigned int i, unsigned int value);
42 
43  template<typename T>
44  T evaluate(const Point<dim, T> x) const;
45 
46  template<typename T>
47  T evaluate(const T x[dim]) const;
48 
49  Monomial<dim> getDerivative(const Point<dim, unsigned int> differentialOrder) const;
50 
51  template<typename charT, typename traits>
52  friend std::basic_ostream<charT, traits> &
53  operator<<(std::basic_ostream<charT, traits> &lhs, Monomial<dim> const &rhs)
54  {
55  return lhs << rhs.scalar << " : " << rhs.exponents.toString();
56  }
57 
58 private:
59  void updateSum();
60 };
61 
63 
64 template<unsigned int dim>
66 {
67  exponents.zero();
68  sum = 0;
69 }
70 
71 template<unsigned int dim>
72 Monomial<dim>::Monomial(const Point<dim, unsigned int> &other, unsigned int scalar)
73  : exponents(other), scalar(scalar)
74 {
75  updateSum();
76 }
77 
78 template<unsigned int dim>
79 Monomial<dim>::Monomial(const Point<dim, long int> &other, unsigned int scalar)
80  : scalar(scalar)
81 {
82  for (size_t i = 0; i < other.nvals; ++i)
83  {
84  exponents.get(i) = other.value(i);
85  }
86  updateSum();
87 }
88 
89 template<unsigned int dim>
90 Monomial<dim>::Monomial(const unsigned int other[dim])
91  : Monomial(Point<3, unsigned int>(other)) {}
92 
93 template<unsigned int dim>
95  : exponents(other.exponents),
96  sum(other.sum),
97  scalar(other.scalar) {}
98 
99 template<unsigned int dim>
101 {
102  exponents = other.exponents;
103  sum = other.sum;
104  scalar = other.scalar;
105  return *this;
106 }
107 
108 template<unsigned int dim>
110 {
111  unsigned int partialSum = 0;
112  for (unsigned int i = 0; i < dim; ++i)
113  {
114  partialSum += exponents.value(i);
115  }
116  sum = partialSum;
117 }
118 
119 template<unsigned int dim>
120 unsigned int Monomial<dim>::order() const
121 {
122  return sum;
123 }
124 
125 template<unsigned int dim>
126 unsigned int Monomial<dim>::getExponent(unsigned int i) const
127 {
128  return exponents.value(i);
129 }
130 
131 template<unsigned int dim>
132 void Monomial<dim>::setExponent(unsigned int i, unsigned int value)
133 {
134  exponents.get(i) = value;
135  updateSum();
136 }
137 
138 template<unsigned int dim>
140  (const Monomial<dim> &other) const
141 {
142  return (exponents == other.exponents) && (scalar == other.scalar);
143 }
144 
145 template<unsigned int dim>
146 template<typename T>
147 T Monomial<dim>::evaluate(const Point<dim, T> x) const
148 {
149  T res = scalar;
150  for (unsigned int i = 0; i < dim; ++i)
151  {
152  res *= openfpm::math::intpowlog(x.value(i), getExponent(i));
153  }
154  return res;
155 }
156 
157 template<unsigned int dim>
159 {
160  unsigned int s = scalar;
161  Point<dim, unsigned int> e(exponents);
162  for (unsigned int i = 0; i < dim; ++i)
163  {
164  unsigned int origExp = e.value(i);
165  int targetExp = static_cast<int>(origExp) - static_cast<int>(differentialOrder.value(i));
166  for (int k = origExp; k > targetExp && k >= 0; --k)
167  {
168  s *= k;
169  }
170  e.get(i) = static_cast<unsigned int>(std::max(targetExp, 0));
171  }
172  return Monomial(e, s);
173 }
174 
175 template<unsigned int dim>
176 template<typename T>
177 T Monomial<dim>::evaluate(const T x[dim]) const
178 {
179  return evaluate(Point<dim, T>(x));
180 }
181 
182 
183 #endif //OPENFPM_PDATA_MONOMIALBASISELEMENT_H
T & value(size_t i)
Return the reference to the value at coordinate i.
Definition: Point.hpp:419
std::string toString() const
Return the string with the point coordinate.
Definition: Point.hpp:398
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
static const unsigned int nvals
expose the dimension with a different name
Definition: Point.hpp:653
It model an expression expr1 + ... exprn.
Definition: sum.hpp:92