WaveBlocksND
shape_enum.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 #include <stdexcept>
5 
6 #include "../../types.hpp"
7 
8 
9 namespace waveblocks {
10  namespace wavepackets {
11  namespace shapes {
17  template<dim_t D, class MultiIndex>
18  class ShapeSlice
19  {
20  private:
21  std::size_t offset_;
22 
23  std::vector< MultiIndex > table_;
24 
25  // std::unordered_map< MultiIndex, std::size_t > dict_;
26 
27  inline MultiIndex forward_(MultiIndex index, dim_t axis) const
28  {
29  index[axis] += 1;
30  return index;
31  }
32 
33  inline MultiIndex backward_(MultiIndex index, dim_t axis) const
34  {
35  index[axis] -= 1;
36  return index;
37  }
38 
39  public:
40  typedef typename std::vector<MultiIndex>::const_iterator const_iterator;
41 
42  ShapeSlice() = default;
43 
44  ShapeSlice(const ShapeSlice& that) = default;
45 
47  : offset_(that.offset_)
48  , table_(std::move(that.table_))
49  { }
50 
51  ShapeSlice &operator=(const ShapeSlice & that) = default;
52 
54  {
55  offset_ = that.offset_;
56  table_ = std::move(that.table_);
57  return *this;
58  }
59 
60  ShapeSlice(std::size_t offset)
61  : offset_(offset)
62  , table_()
63  {}
64 
65  ShapeSlice(std::vector<MultiIndex>&& table, std::size_t offset)
66  : offset_(offset)
67  , table_(std::move(table))
68  { }
69 
70  std::vector< MultiIndex > & _table()
71  {
72  return table_;
73  }
74 
75  std::vector< MultiIndex > const& _table() const
76  {
77  return table_;
78  }
79 
85  std::size_t offset() const
86  {
87  return offset_;
88  }
89 
93  std::size_t size() const
94  {
95  return table_.size();
96  }
97 
101  const_iterator begin() const
102  {
103  return table_.begin();
104  }
105 
109  const_iterator end() const
110  {
111  return table_.end();
112  }
113 
117  const_iterator cbegin() const
118  {
119  return table_.cbegin();
120  }
121 
125  const_iterator cend() const
126  {
127  return table_.cend();
128  }
129 
143  MultiIndex operator[](std::size_t ordinal) const
144  {
145  assert(ordinal < size());
146 
147  return table_[ordinal];
148  }
149 
163  bool try_find(const MultiIndex& index, std::size_t& ordinal) const
164  {
165  std::less< MultiIndex > comp;
166 
167  auto it = std::lower_bound(table_.begin(), table_.end(), index, comp);
168 
169  if (it != table_.end() && *it == index) {
170  ordinal = it - table_.begin();
171  return true;
172  }
173  else {
174  return false;
175  }
176  }
177 
193  std::size_t find(const MultiIndex& index) const
194  {
195  std::size_t ordinal;
196 
197  if (!try_find(index, ordinal))
198  throw std::invalid_argument("slice does not contain multi-index");
199 
200  return ordinal;
201  }
202 
216  std::array<std::size_t,D> find_backward_neighbours(const MultiIndex& _index) const
217  {
218  auto ordinals = std::array<std::size_t,D>(); //zero initialize
219 
220  MultiIndex index(_index);
221 
222  std::less< MultiIndex > comp;
223 
224  // find last non-zero entry
225  dim_t dlast = D-1;
226  while (dlast >= 0 && index[dlast] == 0) {
227  --dlast;
228  }
229 
230  if (dlast >= 0) {
231  auto lower = table_.begin();
232 
233  auto upper = std::lower_bound(lower, table_.end(), backward_(index, dlast), comp);
234  ordinals[dlast] = upper - table_.begin();
235 
236  for (dim_t i = 0; i < dlast; i++) {
237  if (index[i] != 0) {
238  lower = std::lower_bound(lower, upper, backward_(index, i), comp);
239  ordinals[i] = lower - table_.begin();
240  }
241  }
242  }
243 
244  return ordinals;
245  }
246 
250  bool operator==(const ShapeSlice& that) const
251  {
252  return table_ == that.table_;
253  }
254 
255  bool operator!=(const ShapeSlice& that) const
256  {
257  return table_ != that.table_;
258  }
259  };
260 
352  template<dim_t D, class MultiIndex>
353  class ShapeEnum
354  {
355  private:
358 
359  std::vector< ShapeSlice<D, MultiIndex> > slices_;
360  std::size_t n_entries_;
361  MultiIndex limits_;
362 
363  public:
364  ShapeEnum() = default;
365 
366  ShapeEnum(std::vector< ShapeSlice<D, MultiIndex> >&& slices,
367  std::size_t n_entries,
368  MultiIndex limits)
369  : lower_(0)
370  , upper_(n_entries)
371  , slices_(std::move(slices))
372  , n_entries_(n_entries)
373  , limits_(limits)
374  { }
375 
376  ShapeEnum(const ShapeEnum& that) = default;
377 
379  : lower_(std::move(that.lower_))
380  , upper_(std::move(that.upper_))
381  , slices_(std::move(that.slices_))
382  , n_entries_(that.n_entries_)
383  , limits_(that.limits_)
384  { }
385 
386  ShapeEnum &operator=(const ShapeEnum& that) = default;
387 
389  {
390  n_entries_ = that.n_entries_;
391  limits_ = that.limits_;
392  lower_ = std::move(that.lower_);
393  upper_ = std::move(that.upper_);
394  slices_ = std::move(that.slices_);
395  return *this;
396  }
397 
409  const ShapeSlice<D, MultiIndex>& slice(int islice) const
410  {
411  if (islice < 0)
412  return lower_;
413  else if (islice >= (int)slices_.size())
414  return upper_;
415  else
416  return slices_[islice];
417  }
418 
420  {
421  if (islice < 0)
422  return lower_;
423  else if (islice >= (int)slices_.size())
424  return upper_;
425  else
426  return slices_[islice];
427  }
428 
432  const std::vector< ShapeSlice<D, MultiIndex> >& slices() const
433  {
434  return slices_;
435  }
436 
437  MultiIndex at(std::size_t ordinal) const
438  {
439  for (auto & slice : slices_) {
440  if (slice.offset() + slice.size() > ordinal)
441  return slice[ordinal - slice.offset()];
442  }
443  throw std::runtime_error("ordinal >= shape.n_entries()");
444  }
445 
449  std::size_t n_entries() const
450  {
451  return n_entries_;
452  }
453 
457  int n_slices() const
458  {
459  return (int)slices_.size();
460  }
461 
472  const MultiIndex& limits() const
473  {
474  return limits_;
475  }
476 
489  int limit(dim_t axis) const
490  {
491  return limits_[axis];
492  }
493 
498  bool operator==(const ShapeEnum &that) const
499  {
500  if (n_entries_ != that.n_entries_)
501  return false;
502 
503  for (int islice = n_entries_-1; islice >= 0; islice--) {
504  if (slice(islice) != that.slice(islice))
505  return false;
506  }
507 
508  return true;
509  }
510 
511  bool operator!=(const ShapeEnum &that) const
512  {
513  return !operator==(that);
514  }
515  };
516  }
517  }
518 }
std::vector< MultiIndex > table_
Definition: shape_enum.hpp:23
const MultiIndex & limits() const
Retrieves the minimum bounding box which contains all nodes.
Definition: shape_enum.hpp:472
bool operator!=(const ShapeSlice &that) const
Definition: shape_enum.hpp:255
int limit(dim_t axis) const
Retrieves the -th entry of the minimum bounding box .
Definition: shape_enum.hpp:489
Definition: coefficients_file_parser.cpp:10
ShapeSlice< D, MultiIndex > & slice(int islice)
Definition: shape_enum.hpp:419
std::vector< MultiIndex > const & _table() const
Definition: shape_enum.hpp:75
ShapeSlice(std::size_t offset)
Definition: shape_enum.hpp:60
std::size_t size() const
Definition: shape_enum.hpp:93
int n_slices() const
Retrieves the number of slices.
Definition: shape_enum.hpp:457
Definition: stdarray2stream.hpp:7
A shape enumeration is a complete, ordered list of all lattice nodes that are part of the basis shape...
Definition: shape_enum.hpp:353
MultiIndex at(std::size_t ordinal) const
Definition: shape_enum.hpp:437
const_iterator cend() const
Returns a const-iterator referring to the past-the-end node.
Definition: shape_enum.hpp:125
std::size_t n_entries() const
Retrieves the number of nodes.
Definition: shape_enum.hpp:449
ShapeSlice & operator=(const ShapeSlice &that)=default
bool operator==(const ShapeSlice &that) const
Checks whether both sides are equals by comparison of every node.
Definition: shape_enum.hpp:250
const std::vector< ShapeSlice< D, MultiIndex > > & slices() const
Returns a reference to the array containing all slices.
Definition: shape_enum.hpp:432
std::size_t offset_
Definition: shape_enum.hpp:21
ShapeSlice< D, MultiIndex > lower_
Definition: shape_enum.hpp:356
MultiIndex limits_
Definition: shape_enum.hpp:361
ShapeSlice(std::vector< MultiIndex > &&table, std::size_t offset)
Definition: shape_enum.hpp:65
bool operator==(const ShapeEnum &that) const
Checks whether both enumerations are equals by comparison of every node.
Definition: shape_enum.hpp:498
std::array< std::size_t, D > find_backward_neighbours(const MultiIndex &_index) const
Retrieves the ordinals of all backward neighbours of a lattice node .
Definition: shape_enum.hpp:216
const_iterator cbegin() const
Returns a const-iterator pointing to the first node.
Definition: shape_enum.hpp:117
MultiIndex backward_(MultiIndex index, dim_t axis) const
Definition: shape_enum.hpp:33
const_iterator begin() const
Returns a const-iterator pointing to the first node.
Definition: shape_enum.hpp:101
std::vector< MultiIndex >::const_iterator const_iterator
Definition: shape_enum.hpp:40
ShapeEnum(ShapeEnum &&that)
Definition: shape_enum.hpp:378
const_iterator end() const
Returns a const-iterator referring to the past-the-end node.
Definition: shape_enum.hpp:109
MultiIndex forward_(MultiIndex index, dim_t axis) const
Definition: shape_enum.hpp:27
std::vector< ShapeSlice< D, MultiIndex > > slices_
Definition: shape_enum.hpp:359
bool operator!=(const ShapeEnum &that) const
Definition: shape_enum.hpp:511
std::vector< MultiIndex > & _table()
Definition: shape_enum.hpp:70
bool try_find(const MultiIndex &index, std::size_t &ordinal) const
Retrieves the position of the node , if is part of this slice.
Definition: shape_enum.hpp:163
ShapeSlice< D, MultiIndex > upper_
Definition: shape_enum.hpp:357
std::size_t find(const MultiIndex &index) const
Returns the position of a node.
Definition: shape_enum.hpp:193
The -th slice of a shape enumeration contains all multi-indices that satisfy .
Definition: shape_enum.hpp:18
std::size_t offset() const
Retrieves the number of nodes in all previous slices.
Definition: shape_enum.hpp:85
MultiIndex operator[](std::size_t ordinal) const
Returns the multi-index of the node at position ordinal.
Definition: shape_enum.hpp:143
ShapeSlice(ShapeSlice &&that)
Definition: shape_enum.hpp:46
ShapeEnum(std::vector< ShapeSlice< D, MultiIndex > > &&slices, std::size_t n_entries, MultiIndex limits)
Definition: shape_enum.hpp:366
int dim_t
Definition: types.hpp:16
ShapeEnum & operator=(ShapeEnum &&that)
Definition: shape_enum.hpp:388
const ShapeSlice< D, MultiIndex > & slice(int islice) const
Returns a reference to a slice.
Definition: shape_enum.hpp:409
std::size_t n_entries_
Definition: shape_enum.hpp:360
ShapeSlice & operator=(ShapeSlice &&that)
Definition: shape_enum.hpp:53