farm-ng-core
division_ring_prop_tests.h
Go to the documentation of this file.
1 // Copyright (c) 2011, Hauke Strasdat
2 // Copyright (c) 2012, Steven Lovegrove
3 // Copyright (c) 2021, farm-ng, inc.
4 //
5 // Use of this source code is governed by an MIT-style
6 // license that can be found in the LICENSE file or at
7 // https://opensource.org/licenses/MIT.
8 
9 #pragma once
10 
12 
13 namespace sophus {
14 namespace test {
15 
16 template <concepts::DivisionRingConcept TRing>
18  using Ring = TRing;
19  using Scalar = typename TRing::Scalar;
20  static int constexpr kNumParams = TRing::kNumParams;
21  static decltype(Ring::Impl::paramsExamples()) const kParamsExamples;
22 
23  using Params = Eigen::Vector<Scalar, kNumParams>;
24 
25  static void associativityTests(std::string ring_name) {
26  for (size_t params_id = 0; params_id < kParamsExamples.size();
27  ++params_id) {
28  Params params = SOPHUS_AT(kParamsExamples, params_id);
29  Ring g1 = Ring::fromParams(params);
30  for (size_t params_id2 = 0; params_id2 < kParamsExamples.size();
31  ++params_id2) {
32  Params params2 = SOPHUS_AT(kParamsExamples, params_id2);
33  Ring g2 = Ring::fromParams(params2);
34  for (size_t params_id3 = 0; params_id3 < kParamsExamples.size();
35  ++params_id3) {
36  Params params3 = SOPHUS_AT(kParamsExamples, params_id3);
37  Ring g3 = Ring::fromParams(params3);
38 
39  Ring left_hugging = (g1 * g2) * g3;
40  Ring right_hugging = g1 * (g2 * g3);
41 
43  left_hugging.params(),
44  right_hugging.params(),
45  10.0 * kEpsilonSqrt<Scalar>,
46  "`(g1*g2)*g3 == g1*(g2*g3)` Test for {}, #{}/#{}/#{}",
47  ring_name,
48  params_id,
49  params_id2,
50  params_id2);
51  }
52  }
53  }
54  }
55 
56  static void commutativityTests(std::string ring_name) {
57  if (Ring::Impl::kIsCommutative) {
58  for (size_t params_id = 0; params_id < kParamsExamples.size();
59  ++params_id) {
60  Params params = SOPHUS_AT(kParamsExamples, params_id);
61  Ring g1 = Ring::fromParams(params);
62  for (size_t params_id2 = 0; params_id2 < kParamsExamples.size();
63  ++params_id2) {
64  Params params2 = SOPHUS_AT(kParamsExamples, params_id2);
65  Ring g2 = Ring::fromParams(params2);
66 
67  Ring left_hugging = g1 * g2;
68  Ring right_hugging = g2 * g1;
69 
71  left_hugging.params(),
72  right_hugging.params(),
73  kEpsilonSqrt<Scalar>,
74  "`g1 * g2 == g2 * g3` Test for {}, #{}/#{}",
75  ring_name,
76  params_id,
77  params_id2);
78  }
79  }
80  } else {
81  size_t num_cases = 0;
82  size_t num_commutativity = 0;
83  for (size_t params_id = 0; params_id < kParamsExamples.size();
84  ++params_id) {
85  Params params = SOPHUS_AT(kParamsExamples, params_id);
86  Ring g1 = Ring::fromParams(params);
87  for (size_t params_id2 = 0; params_id2 < kParamsExamples.size();
88  ++params_id2) {
89  Params params2 = SOPHUS_AT(kParamsExamples, params_id2);
90  Ring g2 = Ring::fromParams(params2);
91  Ring left_hugging = g1 * g2;
92  Ring right_hugging = g2 * g1;
93  ++num_cases;
94  if ((left_hugging.params() - right_hugging.params()).norm() <
95  kEpsilonSqrt<Scalar>) {
96  ++num_commutativity;
97  }
98  }
99  }
100  if (num_cases > 0) {
101  Scalar commutativity_percentage =
102  Scalar(num_commutativity) / Scalar(num_cases);
103  SOPHUS_ASSERT_LE(commutativity_percentage, 0.75);
104  }
105  }
106  }
107 
108  static void additionTests(std::string ring_name) {
109  for (size_t params_id = 0; params_id < kParamsExamples.size();
110  ++params_id) {
111  Params params = SOPHUS_AT(kParamsExamples, params_id);
112  Ring g = Ring::fromParams(params);
113 
115  g.params(),
116  (g + Ring::zero()).params(),
117  kEpsilonSqrt<Scalar>,
118  "`g + 0 == g` Test for {}, #{}",
119  ring_name,
120  params_id);
121  }
122  }
123 
124  static void multiplicationTests(std::string ring_name) {
125  for (size_t params_id = 0; params_id < kParamsExamples.size();
126  ++params_id) {
127  Params params = SOPHUS_AT(kParamsExamples, params_id);
128  Ring g = Ring::fromParams(params);
129 
131  g.params(),
132  (g * Ring::one()).params(),
133  kEpsilonSqrt<Scalar>,
134  "`g * 1 == g` Test for {}, #{}",
135  ring_name,
136  params_id);
137 
139  (g * g.inverse()).params(),
140  Ring::one().params(),
141  kEpsilonSqrt<Scalar>,
142  "`g * 1 == g` Test for {}, #{}",
143  ring_name,
144  params_id);
145  }
146  }
147 
148  static void runAllTests(std::string ring_name) {
149  associativityTests(ring_name);
150  commutativityTests(ring_name);
151  additionTests(ring_name);
152  multiplicationTests(ring_name);
153  }
154 };
155 
156 template <concepts::DivisionRingConcept TRing>
157 decltype(TRing::Impl::paramsExamples())
158  const DivisionRingTestSuite<TRing>::kParamsExamples =
159  TRing::Impl::paramsExamples();
160 
161 } // namespace test
162 } // namespace sophus
sophus::test::DivisionRingTestSuite
Definition: division_ring_prop_tests.h:17
Eigen
Definition: params.h:72
sophus::test::DivisionRingTestSuite::additionTests
static void additionTests(std::string ring_name)
Definition: division_ring_prop_tests.h:108
sophus::test::DivisionRingTestSuite::kNumParams
static constexpr int kNumParams
Definition: division_ring_prop_tests.h:20
sophus
Image MutImage, owning images types.
Definition: num_diff.h:20
sophus::test::DivisionRingTestSuite::multiplicationTests
static void multiplicationTests(std::string ring_name)
Definition: division_ring_prop_tests.h:124
SOPHUS_ASSERT_NEAR
#define SOPHUS_ASSERT_NEAR(...)
Definition: common.h:47
sophus::test::DivisionRingTestSuite::Scalar
typename TRing::Scalar Scalar
Definition: division_ring_prop_tests.h:19
sophus::zero
auto zero() -> TPoint
Definition: vector_space.h:34
SOPHUS_ASSERT_LE
#define SOPHUS_ASSERT_LE(...)
Definition: common.h:44
sophus::test::DivisionRingTestSuite::runAllTests
static void runAllTests(std::string ring_name)
Definition: division_ring_prop_tests.h:148
sophus::test::DivisionRingTestSuite::commutativityTests
static void commutativityTests(std::string ring_name)
Definition: division_ring_prop_tests.h:56
sophus::test::DivisionRingTestSuite::Ring
TRing Ring
Definition: division_ring_prop_tests.h:18
sophus::test::DivisionRingTestSuite::Params
Eigen::Vector< Scalar, kNumParams > Params
Definition: division_ring_prop_tests.h:23
sophus::test::DivisionRingTestSuite::kParamsExamples
static decltype(Ring::Impl::paramsExamples()) const kParamsExamples
Definition: division_ring_prop_tests.h:21
division_ring.h
sophus::test::DivisionRingTestSuite::associativityTests
static void associativityTests(std::string ring_name)
Definition: division_ring_prop_tests.h:25
SOPHUS_AT
#define SOPHUS_AT(...)
Definition: common.h:48