OpenFPM_data  0.1.0
Project that contain the implementation and interfaces for basic structure like vectors, grids, graph ... .
 All Data Structures Namespaces Functions Variables Typedefs Friends
grid_sm.hpp
1 #ifndef GRID_HPP
2 #define GRID_HPP
3 
4 #include "config.h"
5 #include <boost/shared_array.hpp>
6 #include <vector>
7 #include <initializer_list>
8 #include <array>
9 #include "memory/memory.hpp"
10 #include "Space/Shape/Box.hpp"
11 #include "grid_key.hpp"
12 #include <iostream>
13 #include "util/mathutil.hpp"
14 
15 #define PERIODIC 1
16 #define NON_PERIODIC 0
17 
18 // Box need the definition of grid_key_dx_r
19 #define HARDWARE 1
20 
27 class NoCheck
28 {
29 public:
38  static bool valid(size_t v_id, size_t sz)
39  {
40  return true;
41  }
42 };
43 
51 {
52 public:
61  static bool valid(size_t v_id, size_t sz)
62  {
63  return v_id < sz;
64  }
65 };
66 
67 // Declarations;
68 
69 template<unsigned int N, typename T> class grid_sm;
70 template <unsigned int dim> class print_warning_on_adjustment;
71 template<unsigned int dim,typename warn=print_warning_on_adjustment<dim>> class grid_key_dx_iterator_sub;
72 
80 template<unsigned int N, typename T>
81 class grid_sm
82 {
85 
87  size_t size_tot;
88 
90  size_t sz[N];
91 
93  size_t sz_s[N];
94 
104  inline size_t mulLin(size_t a, size_t b)
105  {
106  return a*b;
107  }
108 
118  inline void Initialize(std::vector<size_t> & sz)
119  {
120  // Convert the vector to an array
121  size_t sz_a[N];
122 
123  // Copy
124  for(size_t i = 0 ; i < N ; i++)
125  {
126  sz_a[i] = sz[i];
127  }
128 
129  // Initialize
130  Initialize(sz_a);
131  }
132 
142  inline void Initialize(const size_t (& sz)[N])
143  {
145  sz_s[0] = sz[0];
146  this->sz[0] = sz[0];
147 
148  // set the box
149  box.setHigh(0,sz[0]);
150  box.setLow(0,0);
151 
152  for (size_t i = 1 ; i < N ; i++)
153  {
154  sz_s[i] = sz[i]*sz_s[i-1];
155  this->sz[i] = sz[i];
156 
157  // set the box
158  box.setHigh(i,sz[i]);
159  box.setLow(i,0);
160  }
161  }
162 
169  inline void Initialize()
170  {
172  sz_s[0] = 0;
173  this->sz[0] = 0;
174 
175  // set the box
176  box.setHigh(0,0);
177  box.setLow(0,0);
178 
179  for (size_t i = 1 ; i < N ; i++)
180  {
181  sz_s[i] = sz[i]*sz_s[i-1];
182 
183  // set the box
184  box.setHigh(i,sz[i]);
185  box.setLow(i,0);
186  }
187  }
188 
189 public:
190 
194  inline const Box<N,size_t> & getBox() const
195  {
196  return box;
197  }
198 
205  inline void setDimensions(std::vector<size_t> & dims)
206  {
207  Initialize(dims);
208  size_tot = totalSize(dims);
209  }
210 
216  inline void setDimensions(const size_t (& dims)[N])
217  {
218  Initialize(dims);
219  size_tot = totalSize(dims);
220  }
221 
231  inline bool isLinearizeLinear()
232  {
233  return true;
234  }
235 
242  inline grid_sm()
243  :size_tot(0)
244  {
245  Initialize();
246  }
247 
254  template<typename S> inline grid_sm(const grid_sm<N,S> & g)
255  {
256  box = g.box;
257  size_tot = g.size_tot;
258 
259  for (size_t i = 0 ; i < N ; i++)
260  {
261  sz[i] = g.sz[i];
262  sz_s[i] = g.sz_s[i];
263  }
264  }
265 
266  // Static element to calculate total size
267 
268  inline size_t totalSize(const size_t (& sz)[N])
269  {
270  size_t tSz = 1;
271 
272  for (size_t i = 0 ; i < N ; i++)
273  {
274  tSz *= sz[i];
275  }
276 
277  return tSz;
278  }
279 
280  // Static element to calculate total size
281 
282  inline size_t totalSize(const std::vector<size_t> & sz)
283  {
284  // Convert the vector to an array
285  size_t sz_a[N];
286 
287  // Copy
288  for(size_t i = 0 ; i < N ; i++)
289  {
290  sz_a[i] = sz[i];
291  }
292 
293  return totalSize(sz_a);
294  }
295 
304  inline grid_sm(std::vector<size_t> & sz)
305  : size_tot(totalSize(sz))
306  {
307  Initialize(sz);
308  }
309 
318  inline grid_sm(const size_t (& sz)[N])
319  : size_tot(totalSize(sz))
320  {
321  Initialize(sz);
322  }
323 
332  inline grid_sm(std::vector<size_t> && sz)
333  : size_tot(totalSize(sz))
334  {
335  sz_s[0] = sz[0];
336  this->sz[0] = sz[0];
337  for (size_t i = 1 ; i < sz.size() && N > 1 ; i++)
338  {
339  sz_s[i] = sz[i]*sz_s[i-1];
340  this->sz[i] = sz[i];
341  }
342  }
343 
354  template<typename check=NoCheck> inline mem_id LinId(const grid_key_dx<N> & gk, const char sum_id[N], const size_t (&bc)[N]) const
355  {
356  mem_id lid;
357 
358  // Check the sum produce a valid key
359 
360  if (bc[0] == NON_PERIODIC)
361  {
362  if (check::valid(gk.k[0] + sum_id[0],sz[0]) == false)
363  return -1;
364 
365  lid = gk.k[0] + sum_id[0];
366  }
367  else
368  {
369  lid = openfpm::math::positive_modulo(gk.k[0] + sum_id[0],sz[0]);
370  }
371 
372  for (mem_id i = 1 ; i < N ; i++)
373  {
374  // Check the sum produce a valid key
375 
376  if (bc[i] == NON_PERIODIC)
377  {
378  if (check::valid(gk.k[i] + sum_id[i],sz[i]) == false)
379  return -1;
380 
381  lid += (gk.k[i] + sum_id[i]) * sz_s[i-1];
382  }
383  else
384  {
385  lid += (openfpm::math::positive_modulo(gk.k[i] + sum_id[i],sz[i])) * sz_s[i-1];
386  }
387  }
388 
389  return lid;
390  }
391 
401  inline mem_id LinIdPtr(size_t * k) const
402  {
403  mem_id lid = k[0];
404  for (mem_id i = 1 ; i < N ; i++)
405  {
406  lid += k[i] * sz_s[i-1];
407  }
408 
409  return lid;
410  }
411 
421  inline mem_id LinId(const size_t (& k)[N]) const
422  {
423  mem_id lid = k[0];
424  for (mem_id i = 1 ; i < N ; i++)
425  {
426  lid += k[i] * sz_s[i-1];
427  }
428 
429  return lid;
430  }
431 
441  inline mem_id LinId(const grid_key_dx<N> & gk) const
442  {
443  mem_id lid = gk.k[0];
444  for (mem_id i = 1 ; i < N ; i++)
445  {
446  lid += gk.k[i] * sz_s[i-1];
447  }
448 
449  return lid;
450  }
451 
457  template<typename a, typename ...lT> inline mem_id Lin(a v,lT...t) const
458  {
459 #ifdef DEBUG
460  if (sizeof...(t)+1 > N)
461  {
462  std::cerr << "Error incorrect grid cannot linearize more index than its dimensionality" << "\n";
463  }
464 #endif
465 
466  return v*sz_s[sizeof...(t)-1] + Lin(t...);
467  }
468 
470  template<typename a> inline mem_id Lin(a v) const
471  {
472  return v;
473  }
474 
476 
483  inline grid_key_dx<N> InvLinId(mem_id id) const
484  {
485  // Inversion of linearize
486 
487  grid_key_dx<N> gk;
488 
489  for (mem_id i = 0 ; i < N ; i++)
490  {
491  gk.set_d(i,id % sz[i]);
492  id /= sz[i];
493  }
494 
495  return gk;
496  }
497 
508  //#pragma openfpm layout(get)
509  template<unsigned int dim, unsigned int p> inline mem_id LinId(const grid_key_d<dim,p> & gk) const
510  {
511  mem_id lid = gk.k[0];
512  for (mem_id i = 1 ; i < dim ; i++)
513  {
514  lid += gk.k[i] * sz_s[i-1];
515  }
516 
517  return lid;
518  }
519 
529  //#pragma openfpm layout(get)
530  inline mem_id LinId(mem_id * id) const
531  {
532  mem_id lid = 0;
533  lid += id[0];
534  for (mem_id i = 1 ; i < N ; i++)
535  {
536  lid += id[i] * sz_s[i-1];
537  }
538 
539  return lid;
540  }
541 
543  ~grid_sm() {};
544 
552  inline size_t size() const
553  {
554  return size_tot;
555  };
556 
563  inline grid_sm<N,T> & operator=(const grid_sm<N,T> & g)
564  {
565  box = g.box;
566  size_tot = g.size_tot;
567 
568  for (size_t i = 0 ; i < N ; i++)
569  {
570  sz[i] = g.sz[i];
571  sz_s[i] = g.sz_s[i];
572  }
573 
574  return *this;
575  }
576 
585  inline bool operator==(const grid_sm<N,T> & g)
586  {
587  for (size_t i = 0 ; i < N ; i++)
588  {
589  if (sz[i] != g.sz[i])
590  return false;
591  }
592 
593  if (box != g.box)
594  return false;
595 
596 #ifdef SE_CLASS1
597 
598  if (size_tot != g.size_tot)
599  return false;
600 
601  for (size_t i = 0 ; i < N ; i++)
602  {
603  if (sz_s[i] != g.sz_s[i])
604  return false;
605  }
606 
607 #endif
608  return true;
609  }
610 
617  inline bool operator!=(const grid_sm<N,T> & g)
618  {
619  return ! this->operator==(g);
620  }
621 
633  inline size_t size_s(unsigned int i) const
634  {
635  return sz_s[i];
636  }
637 
647  inline size_t size(unsigned int i) const
648  {
649  return sz[i];
650  }
651 
657  inline std::vector<size_t> getVectorSize()
658  {
659  std::vector<size_t> vect_sz;
660 
661  for (int i = 0 ; i < N ; i++)
662  {
663  vect_sz.push_back(sz[i]);
664  }
665 
666  return vect_sz;
667  }
668 
674  inline const size_t (& getSize() const)[N]
675  {
676  return sz;
677  }
678 
688  {
689  return grid_key_dx_iterator_sub<N>(*this,start,stop);
690  }
691 
697  inline void swap(grid_sm<N,T> & g)
698  {
699  Box<N,size_t> box_t = box;
700  box = g.box;
701  g.box = box_t;
702 
703  size_t tmp = size_tot;
704  size_tot = g.size_tot;
705  g.size_tot = tmp;
706 
707  for (size_t i = 0 ; i < N ; i++)
708  {
709  tmp = sz[i];
710  sz[i] = g.sz[i];
711  g.sz[i] = tmp;
712 
713  tmp = sz_s[i];
714  sz_s[i] = g.sz_s[i];
715  g.sz_s[i] = tmp;
716  }
717  }
718 
720  template <unsigned int,typename> friend class grid_sm;
721 };
722 
723 
724 
725 
733 {
734  size_t dim;
735 
736 public:
737 
744  size_t getDim()
745  {
746  return dim;
747  }
748 
755  :dim(key.dim)
756  {
757  // Allocate the key
758  k = new mem_id[dim];
759 
760  // Copy the key
761  for(unsigned int i = 0 ; i < dim ; i++)
762  {
763  k[i] = key.k[i];
764  }
765  }
766 
774  grid_key_dx_r(size_t dim)
775  :dim(dim)
776  {
777  // Allocate the key
778  k = new mem_id[dim];
779  }
780 
781  ~grid_key_dx_r()
782  {
783  delete [] k;
784  }
785 
787  template<typename a, typename ...T>void set(a v, T...t)
788  {
789  k[dim-1] = v;
790  invert_assign(t...);
791  }
792 
802  mem_id get(size_t i)
803  {
804  return k[i];
805  }
806 
815  void set_d(size_t i, mem_id id)
816  {
817  k[i] = id;
818  }
819 
821  mem_id * k;
822 
823 private:
824 
830  template<typename a, typename ...T>void invert_assign(a v,T...t)
831  {
832  k[sizeof...(T)] = v;
833  invert_assign(t...);
834  }
835 
836  template<typename a, typename ...T>void invert_assign(a v)
837  {
838  k[0] = v;
839  }
840 
841  void invert_assign()
842  {
843  }
844 
845 };
846 
847 
856 {
857  size_t dim;
858 
860  size_t sz;
861 
862  // Actual grid_key position
863  grid_key_dx_r gk;
864 
865 public:
866 
873  size_t getDim()
874  {
875  return dim;
876  }
877 
885  Iterator_g_const(size_t n, size_t sz)
886  :dim(n),sz(sz),gk(n)
887  {
888  // fill gk with the first grid element that satisfied the constrain: 0,1,2,3... dim
889 
890  for (size_t i = 0 ; i < dim ; i++)
891  {
892  gk.set_d(i,dim-i-1);
893  }
894  }
895 
905  {
907 
908  gk.set_d(0,gk.get(0)+1);
909 
911 
912  unsigned int i = 0;
913  for ( ; i < dim-1 ; i++)
914  {
915  size_t id = gk.get(i);
916  if (id >= sz)
917  {
918  // ! overflow, increment the next index
919 
920  id = gk.get(i+1);
921  if (id+i+2 >= sz)
922  {
923  // there is no-way to produce a valid key
924  // there is not need to check the previous index
925  // overflow i+1
926 
927  gk.set_d(i+1,sz);
928  }
929  else
930  {
931 
932  // reinitialize the previous index
933 
934  for (unsigned int s = 0 ; s <= i+1 ; s++)
935  {
936  gk.set_d(i+1-s,id+1+s);
937  }
938  }
939  }
940  else
941  {
942  break;
943  }
944  }
945 
946  return *this;
947  }
948 
957  bool isNext()
958  {
959  // If dimensionless return immediately
960  if (dim == 0)
961  return false;
962 
963  if (gk.get(dim-1) < static_cast<mem_id>(sz-dim+1))
964  {
966 
967  return true;
968  }
969 
971  return false;
972  }
973 
983  {
984  return gk;
985  }
986 };
987 
988 #endif
grid_sm(std::vector< size_t > &sz)
Construct a grid of a specified size.
Definition: grid_sm.hpp:304
grid_sm()
Default constructor.
Definition: grid_sm.hpp:242
mem_id k[dim]
structure that store all the index
Definition: grid_key.hpp:327
size_t sz_s[N]
size of the grid on each stride (used for linearization)
Definition: grid_sm.hpp:93
mem_id Lin(a v) const
Linearize a set of index.
Definition: grid_sm.hpp:470
Iterator_g_const(size_t n, size_t sz)
Constructor.
Definition: grid_sm.hpp:885
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
void set_d(size_t i, mem_id id)
Set the i index.
Definition: grid_sm.hpp:815
grid_key_dx_r(size_t dim)
constructor
Definition: grid_sm.hpp:774
size_t size_s(unsigned int i) const
Definition: grid_sm.hpp:633
void set(a v, T...t)
set the grid key from a list of numbers
Definition: grid_sm.hpp:787
mem_id LinIdPtr(size_t *k) const
Linearization of the set of indexes.
Definition: grid_sm.hpp:401
size_t mulLin(size_t a, size_t b)
It multiplicate two number and return the result.
Definition: grid_sm.hpp:104
size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:552
Emulate grid_key_dx with runtime dimensionality.
Definition: grid_sm.hpp:732
size_t size_tot
total number of the elements in the grid
Definition: grid_sm.hpp:87
const Box< N, size_t > & getBox() const
Return the box enclosing the grid.
Definition: grid_sm.hpp:194
Box< N, size_t > box
Box enclosing the grid.
Definition: grid_sm.hpp:84
void Initialize(std::vector< size_t > &sz)
Initialize the basic structure.
Definition: grid_sm.hpp:118
static bool valid(size_t v_id, size_t sz)
Check is performed.
Definition: grid_sm.hpp:61
void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:472
mem_id LinId(const grid_key_d< dim, p > &gk) const
Linearization of the grid_key_d.
Definition: grid_sm.hpp:509
grid_key_dx_r(grid_key_dx_r &key)
constructor from another key
Definition: grid_sm.hpp:754
size_t sz[N]
size of the grid
Definition: grid_sm.hpp:90
bool operator==(const grid_sm< N, T > &g)
Check if the two grid_sm are the same.
Definition: grid_sm.hpp:585
bool operator!=(const grid_sm< N, T > &g)
Check if the two grid_sm are the same.
Definition: grid_sm.hpp:617
grid_key_dx< N > InvLinId(mem_id id) const
Construct.
Definition: grid_sm.hpp:483
mem_id LinId(const size_t(&k)[N]) const
Linearization of the grid_key_dx.
Definition: grid_sm.hpp:421
void invert_assign(a v, T...t)
Recursively invert the assignment.
Definition: grid_sm.hpp:830
mem_id get(size_t i) const
Get the i index.
Definition: grid_key.hpp:302
void Initialize()
Initialize the basic structure.
Definition: grid_sm.hpp:169
~grid_sm()
Destructor.
Definition: grid_sm.hpp:543
static bool valid(size_t v_id, size_t sz)
No check is performed.
Definition: grid_sm.hpp:38
void swap(grid_sm< N, T > &g)
swap the grid_sm informations
Definition: grid_sm.hpp:697
grid_sm(const grid_sm< N, S > &g)
construct a grid from another grid
Definition: grid_sm.hpp:254
grid_sm< N, T > & operator=(const grid_sm< N, T > &g)
Copy the grid from another grid.
Definition: grid_sm.hpp:563
size_t sz
size of the grid (the grid is assumed a square so equal on each dimension)
Definition: grid_sm.hpp:860
size_t getDim()
Get the dimensionality of the iterator.
Definition: grid_sm.hpp:873
const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition: grid_sm.hpp:674
void Initialize(const size_t(&sz)[N])
Initialize the basic structure.
Definition: grid_sm.hpp:142
void setDimensions(std::vector< size_t > &dims)
Reset the dimension of the grid.
Definition: grid_sm.hpp:205
mem_id Lin(a v, lT...t) const
linearize an arbitrary set of index
Definition: grid_sm.hpp:457
void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:461
bool isLinearizeLinear()
Is linearize additive.
Definition: grid_sm.hpp:231
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:202
grid_sm(std::vector< size_t > &&sz)
Construct a grid of a specified size.
Definition: grid_sm.hpp:332
Iterator_g_const & operator++()
Get the next element.
Definition: grid_sm.hpp:904
mem_id LinId(const grid_key_dx< N > &gk) const
Linearization of the grid_key_dx.
Definition: grid_sm.hpp:441
class that store the information of the grid like number of point on each direction and define the in...
Definition: grid_sm.hpp:69
grid_key_d is the key to access any element in the grid
Definition: grid_key.hpp:364
size_t size(unsigned int i) const
Definition: grid_sm.hpp:647
Class to check if the edge can be created or not.
Definition: grid_sm.hpp:27
std::vector< size_t > getVectorSize()
Return the size of the grid as an std::vector.
Definition: grid_sm.hpp:657
bool isNext()
Check if there is the next element.
Definition: grid_sm.hpp:957
mem_id LinId(mem_id *id) const
Linearization of an array of mem_id (long int)
Definition: grid_sm.hpp:530
void set_d(size_t i, mem_id id)
Set the i index.
Definition: grid_key.hpp:315
mem_id * k
structure that store all the index
Definition: grid_sm.hpp:821
grid_key_dx_iterator_sub< N > getSubIterator(grid_key_dx< N > &start, grid_key_dx< N > &stop) const
Return a sub-grid iterator.
Definition: grid_sm.hpp:687
Class to check if the edge can be created or not.
Definition: grid_sm.hpp:50
mem_id LinId(const grid_key_dx< N > &gk, const char sum_id[N], const size_t(&bc)[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition: grid_sm.hpp:354
void setDimensions(const size_t(&dims)[N])
Reset the dimension of the grid.
Definition: grid_sm.hpp:216
size_t getDim()
Get the dimensionality of the key.
Definition: grid_sm.hpp:744
grid_sm(const size_t(&sz)[N])
Construct a grid of a specified size.
Definition: grid_sm.hpp:318