WaveBlocksND
shape_enumerator.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <vector>
4 #include <memory>
5 
6 #include "../../types.hpp"
7 
8 #include "shape_enum.hpp"
9 #include "shape_base.hpp"
10 
11 
12 namespace waveblocks {
13  namespace wavepackets {
14  namespace shapes {
24  template<dim_t D, class MultiIndex>
26  {
27  public:
31  template<class Shape>
32  ShapeEnum<D,MultiIndex> generate(const Shape& shape) const
33  {
34  std::vector< std::vector<MultiIndex> > mindices;
35 
36  // check multi-index type for compatibility
37  {
38  MultiIndex test;
39  for (dim_t d = 0; d < D; d++) {
40  test[d] = shape.bbox(d);
41  if (test[d] != shape.bbox(d)) {
42  throw std::runtime_error("multi-index type is not suitable. reason: overflow");
43  }
44  }
45  }
46 
47  // initialize slice vectors
48  {
49  std::size_t sum = 0;
50  for (dim_t d = 0; d < D; d++) {
51  sum += shape.bbox(d)+1;
52  }
53 
54  mindices.resize(sum);
55  }
56 
57  // enumerate shape and store all multi-indices
58  {
59  MultiIndex index{}; //zero initialize
60  std::size_t islice = 0;
61 
62  while (true) {
63  // iterate over last axis
64  for (dim_t i = 0; i <= shape.limit(static_cast<std::array<int,D> >(index).data(),D-1); i++) {
65  index[D-1] = i;
66 
67  // if (use_dict)
68  // mindices[islice+i].dict_[index] = mindices[islice+i].table_.size();
69 
70  mindices[islice+i].push_back(index);
71  }
72  index[D-1] = 0;
73 
74  // iterate over other axes
75  if (D > 1) {
76  dim_t j = D-2;
77  while ((int)index[j] == shape.limit(static_cast<std::array<int,D> >(index).data(),j)) {
78  islice -= index[j];
79  index[j] = 0;
80  if (j == 0)
81  goto enumeration_complete;
82  else
83  j = j-1;
84  }
85  islice += 1;
86  index[j] += 1;
87  }
88  else break;
89  }
90  enumeration_complete:
91  (void)0;
92  }
93 
94  std::vector< ShapeSlice<D,MultiIndex> > slices(mindices.size());
95 
96  std::size_t offset = 0; // number of entries in all previous slices
97  std::size_t islice = 0; // ordinal of current slice
98  for (; islice < mindices.size() && mindices[islice].size() != 0; islice++) {
99  ShapeSlice<D,MultiIndex> slice{std::move(mindices[islice]), offset};
100  offset += slice.size();
101 
102  slices[islice] = std::move(slice);
103  }
104 
105  slices.resize(islice);
106 
107  // total number of entries in all slices
108  size_t size = offset;
109 
110  MultiIndex limits;
111  for (dim_t d = 0; d < D; d++)
112  limits[d] = shape.bbox(d);
113 
114  return {std::move(slices), size, limits};
115  }
116 
123  std::shared_ptr<ShapeEnum<D,MultiIndex> > enumerate(AbstractShape<D> const& shape) const
124  {
125  return std::make_shared<ShapeEnum<D,MultiIndex> >(generate<AbstractShape<D> >(shape));
126  }
127 
134  std::shared_ptr<ShapeEnum<D,MultiIndex> > enumerate(AbstractShape<D> const* shape) const
135  {
136  return std::make_shared<ShapeEnum<D,MultiIndex> >(generate<AbstractShape<D> >(*shape));
137  }
138  };
139  }
140  }
141 }
Definition: coefficients_file_parser.cpp:10
std::size_t size() const
Definition: shape_enum.hpp:93
A shape enumeration is a complete, ordered list of all lattice nodes that are part of the basis shape...
Definition: shape_enum.hpp:353
std::shared_ptr< ShapeEnum< D, MultiIndex > > enumerate(AbstractShape< D > const *shape) const
Enumerates all nodes of basis shape described by AbstractShape.
Definition: shape_enumerator.hpp:134
std::shared_ptr< ShapeEnum< D, MultiIndex > > enumerate(AbstractShape< D > const &shape) const
Enumerates all nodes of a basis shape described by AbstractShape.
Definition: shape_enumerator.hpp:123
The -th slice of a shape enumeration contains all multi-indices that satisfy .
Definition: shape_enum.hpp:18
Subclasses provide a description of a basis shape.
Definition: shape_base.hpp:34
Enumerates nodes of a basis shape.
Definition: shape_enumerator.hpp:25
int sum(const point_t< D > Z)
Sum of the components of the point Z.
Definition: combinatorics.hpp:20
int dim_t
Definition: types.hpp:16
ShapeEnum< D, MultiIndex > generate(const Shape &shape) const
Definition: shape_enumerator.hpp:32