polyhedral-gravity 3.0__tar.gz → 3.2rc1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. {polyhedral_gravity-3.0/polyhedral_gravity.egg-info → polyhedral_gravity-3.2rc1}/PKG-INFO +1 -1
  2. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/cmake/pybind11.cmake +3 -4
  3. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/cmake/spdlog.cmake +3 -4
  4. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/cmake/tbb.cmake +3 -3
  5. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/cmake/yaml.cmake +3 -3
  6. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1/polyhedral_gravity.egg-info}/PKG-INFO +1 -1
  7. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/polyhedral_gravity.egg-info/SOURCES.txt +2 -0
  8. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/setup.py +1 -1
  9. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/model/GravityModelData.h +33 -16
  10. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/model/GravityModelDetail.cpp +12 -12
  11. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/model/GravityModelDetail.h +1 -0
  12. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/model/Polyhedron.cpp +3 -3
  13. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/model/Polyhedron.h +5 -4
  14. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/util/UtilityConstants.h +0 -9
  15. polyhedral_gravity-3.2rc1/src/polyhedralGravity/util/UtilityFloatArithmetic.cpp +51 -0
  16. polyhedral_gravity-3.2rc1/src/polyhedralGravity/util/UtilityFloatArithmetic.h +73 -0
  17. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravityPython/PolyhedralGravityPython.cpp +3 -3
  18. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/CMakeLists.txt +0 -0
  19. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/LICENSE +0 -0
  20. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/MANIFEST.in +0 -0
  21. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/README.md +0 -0
  22. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/cmake/FindSphinx.cmake +0 -0
  23. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/cmake/gtest.cmake +0 -0
  24. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/cmake/tetgen.cmake +0 -0
  25. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/cmake/thrust.cmake +0 -0
  26. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/cmake/xsimd.cmake +0 -0
  27. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/polyhedral_gravity.egg-info/dependency_links.txt +0 -0
  28. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/polyhedral_gravity.egg-info/not-zip-safe +0 -0
  29. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/polyhedral_gravity.egg-info/top_level.txt +0 -0
  30. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/setup.cfg +0 -0
  31. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/CMakeLists.txt +0 -0
  32. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/main.cpp +0 -0
  33. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/CMakeLists.txt +0 -0
  34. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/input/ConfigSource.h +0 -0
  35. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/input/DataSource.h +0 -0
  36. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/input/TetgenAdapter.cpp +0 -0
  37. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/input/TetgenAdapter.h +0 -0
  38. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/input/YAMLConfigReader.cpp +0 -0
  39. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/input/YAMLConfigReader.h +0 -0
  40. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/model/GravityEvaluable.cpp +0 -0
  41. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/model/GravityEvaluable.h +0 -0
  42. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/model/GravityModel.cpp +0 -0
  43. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/model/GravityModel.h +0 -0
  44. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/output/CSVWriter.cpp +0 -0
  45. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/output/CSVWriter.h +0 -0
  46. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/output/Logging.cpp +0 -0
  47. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/output/Logging.h +0 -0
  48. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/util/UtilityContainer.h +0 -0
  49. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravity/util/UtilityThrust.h +0 -0
  50. {polyhedral_gravity-3.0 → polyhedral_gravity-3.2rc1}/src/polyhedralGravityPython/CMakeLists.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polyhedral_gravity
3
- Version: 3.0
3
+ Version: 3.2rc1
4
4
  Summary: Package to compute full gravity tensor of a given constant density polyhedron for arbitrary points according to the geodetic convention
5
5
  Author: Jonas Schuhmacher
6
6
  Author-email: jonas.schuhmacher@tum.de
@@ -2,7 +2,7 @@ include(FetchContent)
2
2
 
3
3
  message(STATUS "Setting up pybind11")
4
4
 
5
- find_package(pybind11 2.10.4 QUIET)
5
+ find_package(pybind11 2.12.0 QUIET)
6
6
 
7
7
  if (${pybind11_FOUND})
8
8
 
@@ -12,11 +12,10 @@ else()
12
12
 
13
13
  message(STATUS "Using pybind11 from git repository")
14
14
 
15
- #Fetches the version 2.10.4 from the official github of pybind11
16
15
  FetchContent_Declare(pybind11
17
16
  GIT_REPOSITORY https://github.com/pybind/pybind11
18
- GIT_TAG v2.10.4
19
- )
17
+ GIT_TAG v2.12.0
18
+ )
20
19
 
21
20
  FetchContent_MakeAvailable(pybind11)
22
21
 
@@ -2,7 +2,7 @@ include(FetchContent)
2
2
 
3
3
  message(STATUS "Setting up spdlog")
4
4
 
5
- find_package(spdlog 1.11.0 QUIET)
5
+ find_package(spdlog 1.14.1 QUIET)
6
6
 
7
7
  if (${spdlog_FOUND})
8
8
 
@@ -12,11 +12,10 @@ else()
12
12
 
13
13
  message(STATUS "Using spdlog from git repository")
14
14
 
15
- #Fetches the version 1.11.0 for spdlog
16
15
  FetchContent_Declare(spdlog
17
16
  GIT_REPOSITORY https://github.com/gabime/spdlog.git
18
- GIT_TAG v1.11.0
19
- )
17
+ GIT_TAG v1.14.1
18
+ )
20
19
 
21
20
  # Disable stuff we don't need
22
21
  option(SPDLOG_BUILD_EXAMPLE "" OFF)
@@ -2,11 +2,11 @@ include(FetchContent)
2
2
 
3
3
  message(STATUS "Setting up tbb via CMake")
4
4
 
5
- #Fetches the version v2021.5.0 from the official github of tbb
5
+ #Fetches the version v2021.12.0 from the official github of tbb
6
6
  FetchContent_Declare(tbb
7
7
  GIT_REPOSITORY https://github.com/oneapi-src/oneTBB.git
8
- GIT_TAG v2021.5.0
9
- )
8
+ GIT_TAG v2021.12.0
9
+ )
10
10
 
11
11
  # Disable tests & and do not treat tbb-compile errors as warnings
12
12
  option(TBB_TEST "Enable testing" OFF)
@@ -2,7 +2,7 @@ include(FetchContent)
2
2
 
3
3
  message(STATUS "Setting up yaml-cpp")
4
4
 
5
- find_package(yaml-cpp 0.7.0 QUIET)
5
+ find_package(yaml-cpp 0.8.0 QUIET)
6
6
 
7
7
  if (${yaml-cpp_FOUND})
8
8
 
@@ -10,10 +10,10 @@ if (${yaml-cpp_FOUND})
10
10
 
11
11
  else()
12
12
 
13
- #Fetches the version 0.7.0 for yaml-cpp
13
+ #Fetches the version 0.8.0 for yaml-cpp
14
14
  FetchContent_Declare(yaml-cpp
15
15
  GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git
16
- GIT_TAG yaml-cpp-0.7.0
16
+ GIT_TAG 0.8.0
17
17
  )
18
18
 
19
19
  # Disable everything we don't need
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: polyhedral_gravity
3
- Version: 3.0
3
+ Version: 3.2rc1
4
4
  Summary: Package to compute full gravity tensor of a given constant density polyhedron for arbitrary points according to the geodetic convention
5
5
  Author: Jonas Schuhmacher
6
6
  Author-email: jonas.schuhmacher@tum.de
@@ -41,6 +41,8 @@ src/polyhedralGravity/output/Logging.cpp
41
41
  src/polyhedralGravity/output/Logging.h
42
42
  src/polyhedralGravity/util/UtilityConstants.h
43
43
  src/polyhedralGravity/util/UtilityContainer.h
44
+ src/polyhedralGravity/util/UtilityFloatArithmetic.cpp
45
+ src/polyhedralGravity/util/UtilityFloatArithmetic.h
44
46
  src/polyhedralGravity/util/UtilityThrust.h
45
47
  src/polyhedralGravityPython/CMakeLists.txt
46
48
  src/polyhedralGravityPython/PolyhedralGravityPython.cpp
@@ -175,7 +175,7 @@ picture_in_readme = '''<p align="center">
175
175
  # --------------------------------------------------------------------------------
176
176
  setup(
177
177
  name="polyhedral_gravity",
178
- version="3.0",
178
+ version="3.2rc1",
179
179
  author="Jonas Schuhmacher",
180
180
  author_email="jonas.schuhmacher@tum.de",
181
181
  description="Package to compute full gravity tensor of a given constant density polyhedron for arbitrary points "
@@ -6,7 +6,7 @@
6
6
  #include <algorithm>
7
7
  #include <tuple>
8
8
  #include "polyhedralGravity/util/UtilityContainer.h"
9
- #include "polyhedralGravity/util/UtilityConstants.h"
9
+ #include "polyhedralGravity/util/UtilityFloatArithmetic.h"
10
10
 
11
11
  namespace polyhedralGravity {
12
12
 
@@ -76,20 +76,23 @@ namespace polyhedralGravity {
76
76
  double s2;
77
77
 
78
78
  /**
79
- * Checks two Distance structs for equality.
80
- * @warning This method compares doubles! So only exact copies will evaluate to true.
79
+ * Checks two Distance structs for equality with another one by ensuring that the members are
80
+ * almost equal.
81
81
  * @param rhs the other Distance struct
82
82
  * @return true if equal
83
83
  *
84
84
  * @note Just used for testing purpose
85
85
  */
86
86
  bool operator==(const Distance &rhs) const {
87
- return l1 == rhs.l1 && l2 == rhs.l2 && s1 == rhs.s1 && s2 == rhs.s2;
87
+ return util::almostEqualRelative(l1, rhs.l1) &&
88
+ util::almostEqualRelative(l2, rhs.l2) &&
89
+ util::almostEqualRelative(s1, rhs.s1) &&
90
+ util::almostEqualRelative(s2, rhs.s2);
88
91
  }
89
92
 
90
93
  /**
91
- * Checks two Distance structs for inequality.
92
- * @warning This method compares doubles! So only exact copies will evaluate to false.
94
+ * Checks two Distance structs for inequality with another one by ensuring that the members are
95
+ * not almost equal.
93
96
  * @param rhs the other Distance struct
94
97
  * @return false if unequal
95
98
  *
@@ -130,20 +133,20 @@ namespace polyhedralGravity {
130
133
  double an;
131
134
 
132
135
  /**
133
- * Checks two TranscendentalExpressions for equality.
134
- * @warning This method compares doubles! So only exact copies will evaluate to true.
136
+ * Checks two TranscendentalExpressions for equality with another one by ensuring that the members are
137
+ * almost equal.
135
138
  * @param rhs the other TranscendentalExpressions
136
139
  * @return true if equal
137
140
  *
138
141
  * @note Just used for testing purpose
139
142
  */
140
143
  bool operator==(const TranscendentalExpression &rhs) const {
141
- return ln == rhs.ln && an == rhs.an;
144
+ return util::almostEqualRelative(ln, rhs.ln) && util::almostEqualRelative(an, rhs.an);
142
145
  }
143
146
 
144
147
  /**
145
- * Checks two TranscendentalExpressions for inequality.
146
- * @warning This method compares doubles! So only exact copies will evaluate to false.
148
+ * Checks two TranscendentalExpressions for inequality with another one by ensuring that the members are
149
+ * not almost equal.
147
150
  * @param rhs the other TranscendentalExpressions
148
151
  * @return false if unequal
149
152
  *
@@ -191,20 +194,23 @@ namespace polyhedralGravity {
191
194
  double d;
192
195
 
193
196
  /**
194
- * Checking the equality of two this Hessian Plane with another one by comparing their members.
195
- * @warning This method compares doubles! So only exact copies will evaluate to true.
197
+ * Checking the equality of two this Hessian Plane with another one by ensuring that the members are
198
+ * almost equal.
196
199
  * @param rhs other HessianPlane
197
200
  * @return true if equal
198
201
  *
199
202
  * @note Just used for testing purpose
200
203
  */
201
204
  bool operator==(const HessianPlane &rhs) const {
202
- return a == rhs.a && b == rhs.b && c == rhs.c && d == rhs.d;
205
+ return util::almostEqualRelative(a, rhs.a) &&
206
+ util::almostEqualRelative(b, rhs.b) &&
207
+ util::almostEqualRelative(c, rhs.c) &&
208
+ util::almostEqualRelative(d, rhs.d);
203
209
  }
204
210
 
205
211
  /**
206
- * Checking the inequality of two this Hessian Plane with another one by comparing their members.
207
- * @warning This method compares doubles! So only exact copies will evaluate to false.
212
+ * Checking the inequality of two this Hessian Plane with another one by ensuring that the members are
213
+ * not almost equal.
208
214
  * @param rhs other HessianPlane
209
215
  * @return true if unequal
210
216
  *
@@ -213,6 +219,17 @@ namespace polyhedralGravity {
213
219
  bool operator!=(const HessianPlane &rhs) const {
214
220
  return !(rhs == *this);
215
221
  }
222
+
223
+ /**
224
+ * Pretty output of this struct on the given ostream.
225
+ * @param os the ostream
226
+ * @param hessianPlane a HessianPlane
227
+ * @return os
228
+ */
229
+ friend std::ostream &operator<<(std::ostream &os, const HessianPlane &hessianPlane) {
230
+ os << "a: " << hessianPlane.a << " b: " << hessianPlane.b << " c: " << hessianPlane.c << " d: " << hessianPlane.d;
231
+ return os;
232
+ }
216
233
  };
217
234
 
218
235
  }
@@ -28,7 +28,7 @@ namespace polyhedralGravity::GravityModel::detail {
28
28
  //Calculate N_i * -G_i1 where * is the dot product and then use the inverted sgn
29
29
  //We abstain on the double multiplication with -1 in the line above and beyond since two
30
30
  //times multiplying with -1 equals no change
31
- return sgn(dot(planeUnitNormal, vertex0), util::EPSILON);
31
+ return sgn(dot(planeUnitNormal, vertex0), util::EPSILON_ZERO_OFFSET);
32
32
  }
33
33
 
34
34
  HessianPlane computeHessianPlane(const Array3 &p, const Array3 &q, const Array3 &r) {
@@ -95,7 +95,7 @@ namespace polyhedralGravity::GravityModel::detail {
95
95
  segmentNormalOrientations.begin(),
96
96
  [&projectionPointOnPlane](const Array3 &segmentUnitNormal, const Array3 &vertex) {
97
97
  using namespace util;
98
- return sgn((dot(segmentUnitNormal, projectionPointOnPlane - vertex)), util::EPSILON) * -1.0;
98
+ return sgn((dot(segmentUnitNormal, projectionPointOnPlane - vertex)), util::EPSILON_ZERO_OFFSET) * -1.0;
99
99
  });
100
100
  return segmentNormalOrientations;
101
101
  }
@@ -190,8 +190,8 @@ namespace polyhedralGravity::GravityModel::detail {
190
190
 
191
191
  //4. Option: |s1 - l1| == 0 && |s2 - l2| == 0 Computation point P is located from the beginning on
192
192
  // the direction of a specific segment (P coincides with P' and P'')
193
- if (std::abs(distance.s1 - distance.l1) < EPSILON &&
194
- std::abs(distance.s2 - distance.l2) < EPSILON) {
193
+ if (std::abs(distance.s1 - distance.l1) < EPSILON_ZERO_OFFSET &&
194
+ std::abs(distance.s2 - distance.l2) < EPSILON_ZERO_OFFSET) {
195
195
  //4. Option - Case 2: P is located on the segment from its right side
196
196
  // s1 = -|s1|, s2 = -|s2|, l1 = -|l1|, l2 = -|l2|
197
197
  if (distance.s2 < distance.s1) {
@@ -200,7 +200,7 @@ namespace polyhedralGravity::GravityModel::detail {
200
200
  distance.l1 *= -1.0;
201
201
  distance.l2 *= -1.0;
202
202
  return distance;
203
- } else if (std::abs(distance.s2 - distance.s1) < EPSILON) {
203
+ } else if (std::abs(distance.s2 - distance.s1) < EPSILON_ZERO_OFFSET) {
204
204
  //4. Option - Case 1: P is located inside the segment (s2 == s1)
205
205
  // s1 = -|s1|, s2 = |s2|, l1 = -|l1|, l2 = |l2|
206
206
  distance.s1 *= -1.0;
@@ -264,9 +264,9 @@ namespace polyhedralGravity::GravityModel::detail {
264
264
  // If sigma_pq == 0 && either of the distances of P' to the two segment endpoints == 0 OR
265
265
  // the 1D and 3D distances are smaller than some EPSILON
266
266
  // then LN_pq can be set to zero
267
- if ((segmentNormalOrientation == 0.0 && (r1Norm < EPSILON || r2Norm < EPSILON)) ||
268
- (std::abs(distance.s1 + distance.s2) < EPSILON &&
269
- std::abs(distance.l1 + distance.l2) < EPSILON)) {
267
+ if ((segmentNormalOrientation == 0.0 && (r1Norm < EPSILON_ZERO_OFFSET || r2Norm < EPSILON_ZERO_OFFSET)) ||
268
+ (std::abs(distance.s1 + distance.s2) < EPSILON_ZERO_OFFSET &&
269
+ std::abs(distance.l1 + distance.l2) < EPSILON_ZERO_OFFSET)) {
270
270
  transcendentalExpressionPerSegment.ln = 0.0;
271
271
  } else {
272
272
  //Implementation of
@@ -277,7 +277,7 @@ namespace polyhedralGravity::GravityModel::detail {
277
277
 
278
278
  //Compute AN_pq according to (15)
279
279
  // If h_p == 0 or h_pq == 0 then AN_pq is zero, too (distances are always positive!)
280
- if (planeDistance < EPSILON || segmentDistance < EPSILON) {
280
+ if (planeDistance < EPSILON_ZERO_OFFSET || segmentDistance < EPSILON_ZERO_OFFSET) {
281
281
  transcendentalExpressionPerSegment.an = 0.0;
282
282
  } else {
283
283
  //Implementation of:
@@ -331,7 +331,7 @@ namespace polyhedralGravity::GravityModel::detail {
331
331
  const unsigned int j = thrust::get<2>(tuple);
332
332
 
333
333
  //segmentNormalOrientation != 0.0
334
- if (std::abs(segmentNormalOrientation) > EPSILON) {
334
+ if (std::abs(segmentNormalOrientation) > EPSILON_ZERO_OFFSET) {
335
335
  return false;
336
336
  }
337
337
 
@@ -358,14 +358,14 @@ namespace polyhedralGravity::GravityModel::detail {
358
358
  j = thrust::get<1>(tuple);
359
359
 
360
360
  //segmentNormalOrientation != 0.0
361
- if (std::abs(segmentNormalOrientation) > EPSILON) {
361
+ if (std::abs(segmentNormalOrientation) > EPSILON_ZERO_OFFSET) {
362
362
  return false;
363
363
  }
364
364
 
365
365
  r1Norm = projectionPointVertexNorms[(j + 1) % 3];
366
366
  r2Norm = projectionPointVertexNorms[j];
367
367
  //r1Norm == 0.0 || r2Norm == 0.0
368
- return r1Norm < EPSILON || r2Norm < EPSILON;
368
+ return r1Norm < EPSILON_ZERO_OFFSET || r2Norm < EPSILON_ZERO_OFFSET;
369
369
  })) {
370
370
  using namespace util;
371
371
  //Two segment vectors G_1 and G_2 of this plane
@@ -21,6 +21,7 @@
21
21
  #include "polyhedralGravity/util/UtilityConstants.h"
22
22
  #include "polyhedralGravity/util/UtilityContainer.h"
23
23
  #include "polyhedralGravity/util/UtilityThrust.h"
24
+ #include "polyhedralGravity/util/UtilityFloatArithmetic.h"
24
25
  #include "polyhedralGravity/output/Logging.h"
25
26
 
26
27
  namespace polyhedralGravity::GravityModel::detail {
@@ -202,7 +202,7 @@ namespace polyhedralGravity {
202
202
  const Array3 rayVector = normal(segmentVector1, segmentVector2);
203
203
 
204
204
  // The origin of the array has a slight offset in direction of the normal
205
- const Array3 rayOrigin = centroid + (rayVector * EPSILON);
205
+ const Array3 rayOrigin = centroid + (rayVector * EPSILON_ZERO_OFFSET);
206
206
 
207
207
  // Count every triangular face which is intersected by the ray
208
208
  const auto &[begin, end] = this->transformIterator();
@@ -224,7 +224,7 @@ namespace polyhedralGravity {
224
224
  const Array3 edge2 = triangle[2] - triangle[0];
225
225
  const Array3 h = cross(rayVector, edge2);
226
226
  const double a = dot(edge1, h);
227
- if (a > -EPSILON && a < EPSILON) {
227
+ if (a > -EPSILON_ZERO_OFFSET && a < EPSILON_ZERO_OFFSET) {
228
228
  return nullptr;
229
229
  }
230
230
 
@@ -242,7 +242,7 @@ namespace polyhedralGravity {
242
242
  }
243
243
 
244
244
  const double t = f * dot(edge2, q);
245
- if (t > EPSILON) {
245
+ if (t > EPSILON_ZERO_OFFSET) {
246
246
  return std::make_unique<Array3>(rayOrigin + rayVector * t);
247
247
  } else {
248
248
  return nullptr;
@@ -22,6 +22,7 @@
22
22
  #include "thrust/iterator/transform_iterator.h"
23
23
  #include "polyhedralGravity/util/UtilityContainer.h"
24
24
  #include "polyhedralGravity/util/UtilityConstants.h"
25
+ #include "polyhedralGravity/util/UtilityFloatArithmetic.h"
25
26
 
26
27
  namespace polyhedralGravity {
27
28
 
@@ -150,7 +151,7 @@ namespace polyhedralGravity {
150
151
  *
151
152
  * @note ASSERTS PRE-CONDITION that the in the indexing in the faces vector starts with zero!
152
153
  * @throws std::invalid_argument if no face contains the node zero indicating mathematical index
153
- * @throws std::invalid_argument dpending on the {@param integrity} flag
154
+ * @throws std::invalid_argument dpending on the {@link integrity} flag
154
155
  */
155
156
  Polyhedron(
156
157
  const std::vector<Array3> &vertices,
@@ -169,7 +170,7 @@ namespace polyhedralGravity {
169
170
  *
170
171
  * @note ASSERTS PRE-CONDITION that the in the indexing in the faces vector starts with zero!
171
172
  * @throws std::invalid_argument if no face contains the node zero indicating mathematical index
172
- * @throws std::invalid_argument dpending on the {@param integrity} flag
173
+ * @throws std::invalid_argument dpending on the {@link integrity} flag
173
174
  */
174
175
  Polyhedron(
175
176
  const PolyhedralSource &polyhedralSource,
@@ -187,7 +188,7 @@ namespace polyhedralGravity {
187
188
  *
188
189
  * @note ASSERTS PRE-CONDITION that the in the indexing in the faces vector starts with zero!
189
190
  * @throws std::invalid_argument if no face contains the node zero indicating mathematical index
190
- * @throws std::invalid_argument dpending on the {@param integrity} flag
191
+ * @throws std::invalid_argument dpending on the {@link integrity} flag
191
192
  */
192
193
  Polyhedron(const PolyhedralFiles &polyhedralFiles, double density,
193
194
  const NormalOrientation &orientation = NormalOrientation::OUTWARDS,
@@ -203,7 +204,7 @@ namespace polyhedralGravity {
203
204
  *
204
205
  * @note ASSERTS PRE-CONDITION that the in the indexing in the faces vector starts with zero!
205
206
  * @throws std::invalid_argument if no face contains the node zero indicating mathematical index
206
- * @throws std::invalid_argument dpending on the {@param integrity} flag
207
+ * @throws std::invalid_argument dpending on the {@link integrity} flag
207
208
  */
208
209
  Polyhedron(const std::variant<PolyhedralSource, PolyhedralFiles> &polyhedralSource, double density,
209
210
  const NormalOrientation &orientation = NormalOrientation::OUTWARDS,
@@ -2,15 +2,6 @@
2
2
 
3
3
  namespace polyhedralGravity::util {
4
4
 
5
- /**
6
- * The EPSILON used in the polyhedral gravity model.
7
- * @related Used to determine if a floating point number is equal to zero as threshold for rounding errors
8
- * @related Used for the sgn() function to determine the sign of a double value. Different compilers
9
- * produce different results if no EPSILON is applied for the comparison!
10
- */
11
- constexpr double EPSILON = 1e-14;
12
-
13
-
14
5
  /**
15
6
  * PI with enough precision
16
7
  */
@@ -0,0 +1,51 @@
1
+ #include "UtilityFloatArithmetic.h"
2
+
3
+
4
+ namespace polyhedralGravity::util {
5
+
6
+ template<typename FloatType>
7
+ bool almostEqualUlps(FloatType lhs, FloatType rhs, int ulpDistance) {
8
+ static_assert(std::is_same_v<FloatType, float> || std::is_same_v<FloatType, double>,
9
+ "Template argument must be FloatType: Either float or double!");
10
+
11
+ // In case the floats are equal in their representation, return true
12
+ if (lhs == rhs) {
13
+ return true;
14
+ }
15
+
16
+ // In case the signs mismatch, return false
17
+ if (lhs < static_cast<FloatType>(0.0) && rhs > static_cast<FloatType>(0.0) ||
18
+ lhs > static_cast<FloatType>(0.0) && rhs < static_cast<FloatType>(0.0)) {
19
+ return false;
20
+ }
21
+
22
+ if constexpr (std::is_same_v<FloatType, float>) {
23
+ // In case of float, compute ULP distance by interpreting float as 32-bit integer
24
+ return reinterpret_cast<std::int32_t&>(rhs) - reinterpret_cast<std::int32_t&>(lhs) <= ulpDistance;
25
+ }
26
+ else if constexpr (std::is_same_v<FloatType, double>) {
27
+ // In case of double, compute ULP distance by interpreting double as 64-bit integer
28
+ return reinterpret_cast<std::int64_t&>(rhs) - reinterpret_cast<std::int64_t&>(lhs) <= ulpDistance;
29
+ }
30
+
31
+ // Due to the static_assert above, this should not happen
32
+ return false;
33
+ }
34
+
35
+ // Template Instantations for float and double (required since definition is in .cpp file,
36
+ // also makes the static assert not strictly necessary)
37
+ template bool almostEqualUlps<float>(float lhs, float rhs, int ulpDistance);
38
+ template bool almostEqualUlps<double>(double lhs, double rhs, int ulpDistance);
39
+
40
+
41
+ template<typename FloatType>
42
+ bool almostEqualRelative(FloatType lhs, FloatType rhs, double epsilon) {
43
+ const FloatType diff = std::abs(rhs - lhs);
44
+ const FloatType largerValue = std::max(std::abs(rhs), std::abs(lhs));
45
+ return diff <= largerValue * epsilon;
46
+ }
47
+
48
+ template bool almostEqualRelative<float>(float lhs, float rhs, double epsilon);
49
+ template bool almostEqualRelative<double>(double lhs, double rhs, double epsilon);
50
+
51
+ }
@@ -0,0 +1,73 @@
1
+ #pragma once
2
+
3
+ #include <algorithm>
4
+ #include <cmath>
5
+ #include <cstdint>
6
+ #include <type_traits>
7
+
8
+ namespace polyhedralGravity::util {
9
+
10
+ /**
11
+ * The EPSILON used in the polyhedral gravity model to determine a radius around zero/ to use as slight offset.
12
+ * @related Used to determine if a floating point number is equal to zero as threshold for rounding errors
13
+ * @related Used for the sgn() function to determine the sign of a double value. Different compilers
14
+ * produce different results if no EPSILON is applied for the comparison!
15
+ */
16
+ constexpr double EPSILON_ZERO_OFFSET = 1e-14;
17
+
18
+ /**
19
+ * This relative EPSILON is utilized ONLY for testing purposes to compare intermediate values to
20
+ * Tsoulis' reference implementation Fortran.
21
+ * It is used in the {@link polyhedralGravity::util::almostEqualRelative} function.
22
+ *
23
+ * @note While in theory no difference at all is observed when compiling this program on Linux using GCC on x86_64,
24
+ * the intermediate values change when the program is compiled in different environments.
25
+ * Hence, this solves the flakiness of the tests when on different plattforms
26
+ */
27
+ constexpr double EPSILON_ALMOST_EQUAL = 1e-10;
28
+
29
+ /**
30
+ * The maximal allowed ULP distance utilized for FloatingPoint comparisons using the
31
+ * {@link polyhedralGravity::util::almostEqualUlps} function.
32
+ *
33
+ * @see https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
34
+ */
35
+ constexpr int MAX_ULP_DISTANCE = 4;
36
+
37
+
38
+ /**
39
+ * Function for comparing closeness of two floating point numbers using ULP (Units in the Last Place) method.
40
+ *
41
+ * @tparam FloatType must be either double or float (ensured by static assertion)
42
+ * @param lhs The left hand side floating point number to compare.
43
+ * @param rhs The right hand side floating point number to compare.
44
+ * @param ulpDistance The maximum acceptable ULP distance between the two floating points
45
+ * for which they would be considered near each other. This is optional and by default, it will be {@link MAX_ULP_DISTANCE}.
46
+ *
47
+ * @return true if the ULP distance between lhs and rhs is less than or equal to the provided ulpDistance value, otherwise, false.
48
+ * Returns true if both numbers are exactly the same. Returns false if the signs do not match.
49
+ * @example The ULP distance between 3.0 and std::nextafter(3.0, INFINITY) would be 1,
50
+ * the ULP distance of 3.0 and std::nextafter(std::nextafter(3.0, INFINITY), INFINITY) would be 2, etc.
51
+ * @see https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
52
+ */
53
+ template<typename FloatType>
54
+ bool almostEqualUlps(FloatType lhs, FloatType rhs, int ulpDistance = MAX_ULP_DISTANCE);
55
+
56
+ /**
57
+ * Function to check if two floating point numbers are relatively equal to each other within a given error range or tolerance.
58
+ *
59
+ * @tparam FloatType must be either double or float (ensured by static assertion)
60
+ * @param lhs The first floating-point number to be compared.
61
+ * @param rhs The second floating-point number to be compared.
62
+ * @param epsilon The tolerance for comparison. Two numbers that are less than epsilon apart are considered equal.
63
+ * The default value is {@link EPSILON_ALMOST_EQUAL}.
64
+ *
65
+ * @return boolean value - Returns `true` if the absolute difference between `lhs` and `rhs` is less than or equal to
66
+ * the relative error factored by the larger of the magnitude of `lhs` and `rhs`. Otherwise, `false`.
67
+ * @see https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
68
+ */
69
+ template<typename FloatType>
70
+ bool almostEqualRelative(FloatType lhs, FloatType rhs, double epsilon = EPSILON_ALMOST_EQUAL);
71
+
72
+
73
+ }
@@ -152,8 +152,8 @@ PYBIND11_MODULE(polyhedral_gravity, m) {
152
152
 
153
153
  * :code:`AUTOMATIC` (Default): Prints to stdout and throws ValueError if normal_orientation is wrong/ inconsisten
154
154
  * :code:`VERIFY`: Like :code:`AUTOMATIC`, but does not print to stdout
155
- * :code:`DISABLE`: Recommened, when you know the mesh to avoid to pay :math:`O(n^2)` runtime. Disables ALL checks
156
- * :code`HEAL`: Automatically fixes the normal_orientation and vertex ordering to the correct values
155
+ * :code:`DISABLE`: Recommened, when you are familiar with the mesh to avoid :math:`O(n^2)` runtime cost. Disables ALL checks
156
+ * :code:`HEAL`: Automatically fixes the normal_orientation and vertex ordering to the correct values
157
157
 
158
158
  Raises:
159
159
  ValueError: If the faces array does not contain a reference to vertex 0 indicating an index start at 1
@@ -182,7 +182,7 @@ PYBIND11_MODULE(polyhedral_gravity, m) {
182
182
  This utility is mainly for diagnostics and debugging purposes. If the polyhedron is constrcuted with `integrity_check`
183
183
  set to :code:`AUTOMATIC` or :code:`VERIFY`, the construction fails anyways.
184
184
  If set to :code:`HEAL`, this method should return an empty set (but maybe a different ordering than initially specified)
185
- Only if set to code:`DISABLE`, then this method might actually return a set with faulty indices.
185
+ Only if set to :code:`DISABLE`, then this method might actually return a set with faulty indices.
186
186
  Hence, if you want to know your mesh error. Construct the polyhedron with :code:`integrity_check=DISABLE` and call this method.
187
187
  )mydelimiter")
188
188
  .def("__getitem__", &Polyhedron::getResolvedFace, R"mydelimiter(