Medusa  1.1
Coordinate Free Mehless Method implementation
discretization_helpers.hpp
Go to the documentation of this file.
1 #ifndef MEDUSA_BITS_DOMAINS_DISCRETIZATION_HELPERS_HPP_
2 #define MEDUSA_BITS_DOMAINS_DISCRETIZATION_HELPERS_HPP_
3 
11 #include <medusa/Config.hpp>
13 #include <Eigen/Core>
14 #include <random>
15 
16 namespace mm {
17 
21 namespace discretization_helpers {
22 
34 template <typename vec_t, typename func_t>
35 Range<vec_t> discretizeLineWithDensity(const vec_t& p, const vec_t& q, const func_t& delta_r) {
36  typedef typename vec_t::scalar_t scalar_t;
37  scalar_t dist = (q-p).norm();
38  assert_msg(dist >= 1e-15, "Points %s and %s are equal.", p, q);
39  vec_t dir = (q-p) / dist;
40  scalar_t cur_dist = 0;
41  Range<scalar_t> dists;
42  while (cur_dist < dist) {
43  cur_dist += delta_r(p+cur_dist*dir);
44  dists.push_back(cur_dist);
45  }
46  dists.pop_back();
47  if (dists.size() <= 2) return {};
48  // decide whether to include the last point
49  scalar_t spacing_with_last_point = dist - dists.back();
50  scalar_t spacing_without_last_point = dist - dists[dists.size()-2];
51  scalar_t desired_spacing = delta_r(q);
52  scalar_t error_with = std::abs(1 - spacing_with_last_point / desired_spacing);
53  scalar_t error_without = std::abs(1 - spacing_without_last_point / desired_spacing);
54  if (error_without < error_with) {
55  dists.pop_back();
56  }
57 
58  Range<vec_t> points(dists.size());
59  for (int i = 0; i < dists.size(); ++i) {
60  points[i] = p + dists[i]*dir;
61  }
62  return points;
63 }
64 
74 template <typename scalar_t, int dim>
83  template <typename generator_t>
84  static std::vector<Eigen::Matrix<scalar_t, dim, 1>,
85  Eigen::aligned_allocator<Eigen::Matrix<scalar_t, dim, 1>>> construct(
86  scalar_t radius, int num_samples, generator_t& generator) {
87  scalar_t dphi = 2 * Pi<scalar_t>::value / num_samples;
88  std::uniform_real_distribution<scalar_t> distribution(0, Pi<scalar_t>::value);
89  scalar_t offset = distribution(generator);
90  std::vector<Eigen::Matrix<scalar_t, dim, 1>,
91  Eigen::aligned_allocator<Eigen::Matrix<scalar_t, dim, 1>>> result;
92  for (int i = 0; i < num_samples / 2; ++i) {
93  scalar_t phi = i * dphi + offset;
94  if (phi > Pi<scalar_t>::value) phi -= Pi<scalar_t>::value;
95  int slice_n = static_cast<int>(std::ceil(num_samples * std::sin(phi)));
96  if (slice_n == 0) continue;
98  radius * std::sin(phi), slice_n, generator);
99  Eigen::Matrix<scalar_t, dim, 1> v;
100  for (const auto& p : slice) {
101  v[0] = radius * std::cos(phi);
102  v.template tail<dim - 1>() = p;
103  result.push_back(v);
104  }
105  }
106  return result;
107  }
109  static std::vector<Eigen::Matrix<scalar_t, dim, 1>,
110  Eigen::aligned_allocator<Eigen::Matrix<scalar_t, dim, 1>>> construct(
111  scalar_t radius, int num_samples) {
112  scalar_t dphi = 2 * Pi<scalar_t>::value / num_samples;
113  std::vector<Eigen::Matrix<scalar_t, dim, 1>,
114  Eigen::aligned_allocator<Eigen::Matrix<scalar_t, dim, 1>>> result;
115  for (int i = 0; i < num_samples / 2; ++i) {
116  scalar_t phi = i * dphi;
117  if (phi > Pi<scalar_t>::value) phi -= Pi<scalar_t>::value;
118  int slice_n = static_cast<int>(std::ceil(num_samples * std::sin(phi)));
119  if (slice_n == 0) continue;
121  radius * std::sin(phi), slice_n);
122  Eigen::Matrix<scalar_t, dim, 1> v;
123  for (const auto& p : slice) {
124  v[0] = radius * std::cos(phi);
125  v.template tail<dim - 1>() = p;
126  result.push_back(v);
127  }
128  }
129  return result;
130  }
131 };
132 
134 template <typename scalar_t>
137  template <typename generator_t>
138  static std::vector<Eigen::Matrix<scalar_t, 2, 1>,
139  Eigen::aligned_allocator<Eigen::Matrix<scalar_t, 2, 1>>> construct(
140  scalar_t radius, int num_samples, generator_t& generator) {
141  scalar_t dphi = 2 * Pi<scalar_t>::value / num_samples;
142  std::uniform_real_distribution<scalar_t> distribution(0, 2 * Pi<scalar_t>::value);
143  scalar_t offset = distribution(generator);
144  std::vector<Eigen::Matrix<scalar_t, 2, 1>,
145  Eigen::aligned_allocator<Eigen::Matrix<scalar_t, 2, 1>>> result;
146  for (int i = 0; i < num_samples; ++i) {
147  scalar_t phi = i * dphi + offset;
148  result.emplace_back(radius * std::cos(phi), radius * std::sin(phi));
149  }
150  return result;
151  }
153  static std::vector<Eigen::Matrix<scalar_t, 2, 1>,
154  Eigen::aligned_allocator<Eigen::Matrix<scalar_t, 2, 1>>> construct(
155  scalar_t radius, int num_samples) {
156  scalar_t dphi = 2 * Pi<scalar_t>::value / num_samples;
157  std::vector<Eigen::Matrix<scalar_t, 2, 1>,
158  Eigen::aligned_allocator<Eigen::Matrix<scalar_t, 2, 1>>> result;
159  for (int i = 0; i < num_samples; ++i) {
160  scalar_t phi = i * dphi;
161  result.emplace_back(radius * std::cos(phi), radius * std::sin(phi));
162  }
163  return result;
164  }
165 };
166 
168 template <typename scalar_t>
170  template <typename generator_t>
172  static std::vector<Eigen::Matrix<scalar_t, 1, 1>,
173  Eigen::aligned_allocator<Eigen::Matrix<scalar_t, 1, 1>>> construct(
174  scalar_t radius, int, generator_t&) {
175  return {Eigen::Matrix<scalar_t, 1, 1>(-radius), Eigen::Matrix<scalar_t, 1, 1>(radius)};
176  }
178  static std::vector<Eigen::Matrix<scalar_t, 1, 1>,
179  Eigen::aligned_allocator<Eigen::Matrix<scalar_t, 1, 1>>> construct(
180  scalar_t radius, int) {
181  return {Eigen::Matrix<scalar_t, 1, 1>(-radius), Eigen::Matrix<scalar_t, 1, 1>(radius)};
182  }
183 };
184 
185 } // namespace discretization_helpers
186 } // namespace mm
187 
188 #endif // MEDUSA_BITS_DOMAINS_DISCRETIZATION_HELPERS_HPP_
mm::discretization_helpers::SphereDiscretization< scalar_t, 1 >::construct
static std::vector< Eigen::Matrix< scalar_t, 1, 1 >, Eigen::aligned_allocator< Eigen::Matrix< scalar_t, 1, 1 > > > construct(scalar_t radius, int)
Construct the discretization.
Definition: discretization_helpers.hpp:179
mm
Root namespace for the whole library.
Definition: Gaussian.hpp:14
scalar_t
Scalar scalar_t
Type of the elements, alias of Scalar.
Definition: MatrixBaseAddons.hpp:16
mm::discretization_helpers::SphereDiscretization< scalar_t, 2 >::construct
static std::vector< Eigen::Matrix< scalar_t, 2, 1 >, Eigen::aligned_allocator< Eigen::Matrix< scalar_t, 2, 1 > > > construct(scalar_t radius, int num_samples)
Construct the discretization.
Definition: discretization_helpers.hpp:154
dim
@ dim
Number of elements of this matrix.
Definition: MatrixBaseAddons.hpp:14
assert_msg
#define assert_msg(cond,...)
Assert with better error reporting.
Definition: assert.hpp:75
Config.hpp
mm::discretization_helpers::SphereDiscretization::construct
static std::vector< Eigen::Matrix< scalar_t, dim, 1 >, Eigen::aligned_allocator< Eigen::Matrix< scalar_t, dim, 1 > > > construct(scalar_t radius, int num_samples)
Construct the discretization.
Definition: discretization_helpers.hpp:110
mm::discretization_helpers::discretizeLineWithDensity
Range< vec_t > discretizeLineWithDensity(const vec_t &p, const vec_t &q, const func_t &delta_r)
Returns nodes lying on the line segment pq with approximate distances delta_r.
Definition: discretization_helpers.hpp:35
mm::Range::size
int size() const
Returns number of elements.
Definition: Range_fwd.hpp:185
mm::Pi
Value of Pi in type T. Usage:
Definition: Config.hpp:40
mm::discretization_helpers::SphereDiscretization::construct
static std::vector< Eigen::Matrix< scalar_t, dim, 1 >, Eigen::aligned_allocator< Eigen::Matrix< scalar_t, dim, 1 > > > construct(scalar_t radius, int num_samples, generator_t &generator)
Construct a randomized discretization.
Definition: discretization_helpers.hpp:85
mm::discretization_helpers::SphereDiscretization< scalar_t, 2 >::construct
static std::vector< Eigen::Matrix< scalar_t, 2, 1 >, Eigen::aligned_allocator< Eigen::Matrix< scalar_t, 2, 1 > > > construct(scalar_t radius, int num_samples, generator_t &generator)
Construct a randomized discretization.
Definition: discretization_helpers.hpp:139
mm::discretization_helpers::SphereDiscretization< scalar_t, 1 >::construct
static std::vector< Eigen::Matrix< scalar_t, 1, 1 >, Eigen::aligned_allocator< Eigen::Matrix< scalar_t, 1, 1 > > > construct(scalar_t radius, int, generator_t &)
Construct a randomized discretization.
Definition: discretization_helpers.hpp:173
mm::Range< vec_t >
Range.hpp
mm::discretization_helpers::SphereDiscretization
Discretizes a sphere with given radius uniformly with num_points points on the great circle.
Definition: discretization_helpers.hpp:75