OpenFPM  5.2.0
Project that contain the implementation of distributed structures
Monomial.cuh
1 //
2 // Created by Serhii
3 //
4 
5 #ifndef OPENFPM_PDATA_MONOMIALBASISELEMENT_CUH
6 #define OPENFPM_PDATA_MONOMIALBASISELEMENT_CUH
7 
8 #include "Space/Shape/Point.hpp"
9 
10 
11 template<unsigned int dim>
13 {
14 private:
15  unsigned int sum = 0;
16  unsigned int exponents[dim];
17  unsigned int scalar = 1;
18 
19 public:
20  __host__ __device__ Monomial_gpu();
21  __host__ __device__ Monomial_gpu(const Monomial_gpu<dim> &other);
22  __host__ __device__ Monomial_gpu(const Monomial<dim> &other);
23  __host__ __device__ explicit Monomial_gpu(const Point<dim, unsigned int> &other, unsigned int scalar = 1);
24  __host__ __device__ explicit Monomial_gpu(const Point<dim, long int> &other, unsigned int scalar = 1);
25  __host__ __device__ explicit Monomial_gpu(const unsigned int other[dim]);
26 
27  __host__ __device__ Monomial_gpu<dim> &operator=(const Monomial_gpu<dim> &other);
28  __host__ __device__ Monomial_gpu<dim> &operator=(const Monomial<dim> &other);
29  __host__ __device__ bool operator==(const Monomial_gpu<dim> &other) const;
30  __host__ __device__ void swap(const Monomial_gpu<dim> &other);
31 
32  __host__ __device__ unsigned int order() const;
33  __host__ __device__ unsigned int getExponent(unsigned int i) const;
34  __host__ __device__ void setExponent(unsigned int i, unsigned int value);
35  __host__ __device__ Monomial_gpu<dim> getDerivative(const Point<dim, unsigned int> differentialOrder) const;
36  __host__ __device__ unsigned int getScalar() const { return scalar; }
37 
38  template<typename T> __host__ __device__ T evaluate(const Point<dim, T> x) const;
39  template<typename T> __host__ __device__ T evaluate(const T (&x)[dim]) const;
40 
41 private:
42  __host__ __device__ void updateSum();
43 };
44 
45 template<unsigned int dim>
46 __host__ __device__ Monomial_gpu<dim>::Monomial_gpu()
47 {
48  for (size_t i = 0; i < dim; ++i) exponents[i] = 0;
49  sum = 0;
50 }
51 
52 template<unsigned int dim>
53 __host__ __device__ Monomial_gpu<dim>::Monomial_gpu(const Point<dim, unsigned int> &other, unsigned int scalar) : scalar(scalar)
54 {
55  for (size_t i = 0; i < other.nvals; ++i)
56  exponents[i] = other.value(i);
57  updateSum();
58 }
59 
60 template<unsigned int dim>
61 __host__ __device__ Monomial_gpu<dim>::Monomial_gpu(const Point<dim, long int> &other, unsigned int scalar) : scalar(scalar)
62 {
63  for (size_t i = 0; i < other.nvals; ++i)
64  exponents[i] = other.value(i);
65  updateSum();
66 }
67 
68 template<unsigned int dim>
69 __host__ __device__ Monomial_gpu<dim>::Monomial_gpu(const unsigned int other[dim]) : Monomial_gpu(Point<dim, unsigned int>(other))
70 {
71  for (size_t i = 0; i < dim; ++i)
72  exponents[i] = other[i];
73  updateSum();
74 }
75 
76 template<unsigned int dim>
77 __host__ __device__ Monomial_gpu<dim>::Monomial_gpu(const Monomial_gpu<dim> &other)
78  : sum(other.sum), scalar(other.scalar)
79 {
80  for (size_t i = 0; i < dim; ++i)
81  exponents[i] = other.exponents[i];
82 }
83 
84 template<unsigned int dim>
85 __host__ __device__ Monomial_gpu<dim>::Monomial_gpu(const Monomial<dim> &other)
86  : sum(other.order()), scalar(other.getScalar())
87 {
88  for (size_t i = 0; i < dim; ++i)
89  exponents[i] = other.getExponent(i);
90 }
91 
92 template<unsigned int dim>
93 __host__ __device__ Monomial_gpu<dim> &Monomial_gpu<dim>::operator=(const Monomial_gpu<dim> &other)
94 {
95  for (size_t i = 0; i < dim; ++i)
96  exponents[i] = other.exponents[i];
97 
98  sum = other.sum;
99  scalar = other.scalar;
100  return *this;
101 }
102 
103 template<unsigned int dim>
104 __host__ __device__ Monomial_gpu<dim> &Monomial_gpu<dim>::operator=(const Monomial<dim> &other)
105 {
106  for (size_t i = 0; i < dim; ++i)
107  exponents[i] = other.getExponent(i);
108 
109  sum = other.order();
110  scalar = other.getScalar();
111  return *this;
112 }
113 
114 template<unsigned int dim>
115 __host__ __device__ void Monomial_gpu<dim>::updateSum()
116 {
117  sum = 0;
118  for (unsigned int i = 0; i < dim; ++i)
119  sum += exponents[i];
120 }
121 
122 template<unsigned int dim>
123 __host__ __device__ unsigned int Monomial_gpu<dim>::order() const
124 {
125  return sum;
126 }
127 
128 template<unsigned int dim>
129 __host__ __device__ unsigned int Monomial_gpu<dim>::getExponent(unsigned int i) const
130 {
131  return exponents[i];
132 }
133 
134 template<unsigned int dim>
135 __host__ __device__ void Monomial_gpu<dim>::setExponent(unsigned int i, unsigned int value)
136 {
137  exponents[i] = value;
138  updateSum();
139 }
140 
141 template<unsigned int dim>
142 __host__ __device__ bool Monomial_gpu<dim>::operator==
143  (const Monomial_gpu<dim> &other) const
144 {
145  bool EQ = true;
146 
147  for (size_t i = 0; i < dim; ++i)
148  if (exponents[i] != other[i])
149  EQ = false;
150 
151  return EQ && (scalar == other.scalar);
152 }
153 
154 template<unsigned int dim>
155 template<typename T>
156 __host__ __device__ T Monomial_gpu<dim>::evaluate(const Point<dim, T> x) const
157 {
158  T res = scalar;
159  for (unsigned int i = 0; i < dim; ++i)
160  res *= pow(x[i], getExponent(i));
161 
162  return res;
163 }
164 
165 template<unsigned int dim>
166 template<typename T>
167 __host__ __device__ T Monomial_gpu<dim>::evaluate(const T (& x) [dim]) const
168 {
169  T res = scalar;
170  for (unsigned int i = 0; i < dim; ++i)
171  res *= pow(x[i], getExponent(i));
172 
173  return res;
174 }
175 
176 template<unsigned int dim>
177 __host__ __device__ Monomial_gpu<dim> Monomial_gpu<dim>::getDerivative(const Point<dim, unsigned int> differentialOrder) const
178 {
179  unsigned int s = scalar;
180  Point<dim, unsigned int> e(exponents);
181  for (unsigned int i = 0; i < dim; ++i)
182  {
183  unsigned int origExp = e.value(i);
184  int targetExp = static_cast<int>(origExp) - static_cast<int>(differentialOrder.value(i));
185  for (int k = origExp; k > targetExp && k >= 0; --k)
186  {
187  s *= k;
188  }
189  e.get(i) = static_cast<unsigned int>((targetExp < 0) ? 0 : targetExp);
190  }
191  return Monomial_gpu(e, s);
192 }
193 
194 template<unsigned int dim>
195 __host__ __device__ void Monomial_gpu<dim>::swap(const Monomial_gpu<dim> &other)
196 {
197  sum = other.sum;
198  scalar = other.scalar;
199  for (size_t i = 0; i < dim; ++i)
200  exponents[i] = other.exponents[i];
201 }
202 
203 
204 #endif //OPENFPM_PDATA_MONOMIALBASISELEMENT_CUH
__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
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