OpenFPM  5.2.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  __host__ __device__ unsigned int getScalar() const { return scalar; }
59 private:
60  void updateSum();
61 };
62 
64 
65 template<unsigned int dim>
67 {
68  exponents.zero();
69  sum = 0;
70 }
71 
72 template<unsigned int dim>
73 Monomial<dim>::Monomial(const Point<dim, unsigned int> &other, unsigned int scalar)
74  : exponents(other), scalar(scalar)
75 {
76  updateSum();
77 }
78 
79 template<unsigned int dim>
80 Monomial<dim>::Monomial(const Point<dim, long int> &other, unsigned int scalar)
81  : scalar(scalar)
82 {
83  for (size_t i = 0; i < other.nvals; ++i)
84  {
85  exponents.get(i) = other.value(i);
86  }
87  updateSum();
88 }
89 
90 template<unsigned int dim>
91 Monomial<dim>::Monomial(const unsigned int other[dim])
92  : Monomial(Point<3, unsigned int>(other)) {}
93 
94 template<unsigned int dim>
96  : exponents(other.exponents),
97  sum(other.sum),
98  scalar(other.scalar) {}
99 
100 template<unsigned int dim>
102 {
103  exponents = other.exponents;
104  sum = other.sum;
105  scalar = other.scalar;
106  return *this;
107 }
108 
109 template<unsigned int dim>
111 {
112  unsigned int partialSum = 0;
113  for (unsigned int i = 0; i < dim; ++i)
114  {
115  partialSum += exponents.value(i);
116  }
117  sum = partialSum;
118 }
119 
120 template<unsigned int dim>
121 unsigned int Monomial<dim>::order() const
122 {
123  return sum;
124 }
125 
126 template<unsigned int dim>
127 unsigned int Monomial<dim>::getExponent(unsigned int i) const
128 {
129  return exponents.value(i);
130 }
131 
132 template<unsigned int dim>
133 void Monomial<dim>::setExponent(unsigned int i, unsigned int value)
134 {
135  exponents.get(i) = value;
136  updateSum();
137 }
138 
139 template<unsigned int dim>
141  (const Monomial<dim> &other) const
142 {
143  return (exponents == other.exponents) && (scalar == other.scalar);
144 }
145 
146 template<unsigned int dim>
147 template<typename T>
148 T Monomial<dim>::evaluate(const Point<dim, T> x) const
149 {
150  T res = scalar;
151  for (unsigned int i = 0; i < dim; ++i)
152  {
153  res *= openfpm::math::intpowlog(x.value(i), getExponent(i));
154  }
155  return res;
156 }
157 
158 template<unsigned int dim>
160 {
161  unsigned int s = scalar;
162  Point<dim, unsigned int> e(exponents);
163  for (unsigned int i = 0; i < dim; ++i)
164  {
165  unsigned int origExp = e.value(i);
166  int targetExp = static_cast<int>(origExp) - static_cast<int>(differentialOrder.value(i));
167  for (int k = origExp; k > targetExp && k >= 0; --k)
168  {
169  s *= k;
170  }
171  e.get(i) = static_cast<unsigned int>(std::max(targetExp, 0));
172  }
173  return Monomial(e, s);
174 }
175 
176 template<unsigned int dim>
177 template<typename T>
178 T Monomial<dim>::evaluate(const T x[dim]) const
179 {
180  return evaluate(Point<dim, T>(x));
181 }
182 
183 
184 #endif //OPENFPM_PDATA_MONOMIALBASISELEMENT_H
__device__ __host__ T & value(size_t i)
Return the reference to the value at coordinate i.
Definition: Point.hpp:434
static const unsigned int nvals
expose the dimension with a different name
Definition: Point.hpp:668
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition: Point.hpp:172
std::string toString() const
Return the string with the point coordinate.
Definition: Point.hpp:413
KeyT const ValueT ValueT OffsetIteratorT OffsetIteratorT int
[in] The number of segments that comprise the sorting data
It model an expression expr1 + ... exprn.
Definition: sum.hpp:93