testSO4.cpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
18 #include <gtsam/base/Manifold.h>
19 #include <gtsam/base/Testable.h>
20 #include <gtsam/base/lieProxies.h>
22 #include <gtsam/geometry/SO4.h>
23 #include <gtsam/geometry/SO3.h>
24 
26 
27 #include <iostream>
28 #include <random>
29 
30 using namespace std;
31 using namespace gtsam;
32 
33 //******************************************************************************
34 TEST(SO4, Identity) {
35  const SO4 R;
36  EXPECT_LONGS_EQUAL(4, R.rows());
37  EXPECT_LONGS_EQUAL(6, SO4::dimension);
38  EXPECT_LONGS_EQUAL(6, SO4::Dim());
39  EXPECT_LONGS_EQUAL(6, R.dim());
41 }
42 
43 //******************************************************************************
44 TEST(SO4, Concept) {
46  GTSAM_CONCEPT_ASSERT(IsManifold<SO4>);
48 }
49 
50 //******************************************************************************
51 TEST(SO4, Random) {
52  std::mt19937 rng(42);
53  auto Q = SO4::Random(rng);
55 }
56 
57 //******************************************************************************
58 namespace {
59 SO4 id;
60 Vector6 v1 = (Vector(6) << 0, 0, 0, 0.1, 0, 0).finished();
61 SO4 Q1 = SO4::Expmap(v1);
62 Vector6 v2 = (Vector(6) << 0.00, 0.00, 0.00, 0.01, 0.02, 0.03).finished();
63 SO4 Q2 = SO4::Expmap(v2);
64 Vector6 v3 = (Vector(6) << 1, 2, 3, 4, 5, 6).finished();
65 SO4 Q3 = SO4::Expmap(v3);
66 } // namespace
67 
68 //******************************************************************************
70  // If we do exponential map in SO(3) subgroup, topleft should be equal to R1.
71  auto R1 = SO3::Expmap(v1.tail<3>()).matrix();
72  EXPECT((Q1.matrix().topLeftCorner<3, 3>().isApprox(R1)));
73 
74  // Same here
75  auto R2 = SO3::Expmap(v2.tail<3>()).matrix();
76  EXPECT((Q2.matrix().topLeftCorner<3, 3>().isApprox(R2)));
77 
78  // Check commutative subgroups
79  for (size_t i = 0; i < 6; i++) {
80  Vector6 xi = Vector6::Zero();
81  xi[i] = 2;
82  SO4 Q1 = SO4::Expmap(xi);
83  xi[i] = 3;
84  SO4 Q2 = SO4::Expmap(xi);
85  EXPECT(assert_equal(Q1 * Q2, Q2 * Q1));
86  }
87 }
88 
89 //******************************************************************************
90 // Check that Hat specialization is equal to dynamic version
91 TEST(SO4, Hat) {
92  EXPECT(assert_equal(SO4::Hat(v1), SOn::Hat(v1)));
93  EXPECT(assert_equal(SO4::Hat(v2), SOn::Hat(v2)));
94  EXPECT(assert_equal(SO4::Hat(v3), SOn::Hat(v3)));
95 }
96 
97 //******************************************************************************
98 // Check that Hat specialization is equal to dynamic version
99 TEST(SO4, Vee) {
100  auto X1 = SOn::Hat(v1), X2 = SOn::Hat(v2), X3 = SOn::Hat(v3);
101  EXPECT(assert_equal(SO4::Vee(X1), SOn::Vee(X1)));
102  EXPECT(assert_equal(SO4::Vee(X2), SOn::Vee(X2)));
103  EXPECT(assert_equal(SO4::Vee(X3), SOn::Vee(X3)));
104 }
105 
106 //******************************************************************************
107 TEST(SO4, Retract) {
108  // Check that Cayley yields the same as Expmap for small values
109  EXPECT(assert_equal(id.retract(v1 / 100), SO4::Expmap(v1 / 100)));
110  EXPECT(assert_equal(id.retract(v2 / 100), SO4::Expmap(v2 / 100)));
111 
112  // Check that Cayley is identical to dynamic version
113  EXPECT(assert_equal(SOn(id.retract(v1 / 100)), SOn(4).retract(v1 / 100)));
114  EXPECT(assert_equal(SOn(id.retract(v2 / 100)), SOn(4).retract(v2 / 100)));
115 
116  auto v = Vector6::Zero();
117  SO4 actual = traits<SO4>::Retract(id, v);
118  EXPECT(assert_equal(id, actual));
119 }
120 
121 //******************************************************************************
122 // Check that Cayley is identical to dynamic version
123 TEST(SO4, Local) {
124  EXPECT(
125  assert_equal(id.localCoordinates(Q1), SOn(4).localCoordinates(SOn(Q1))));
126  EXPECT(
127  assert_equal(id.localCoordinates(Q2), SOn(4).localCoordinates(SOn(Q2))));
128 
129  auto v0 = Vector6::Zero();
130  Vector6 actual = traits<SO4>::Local(id, id);
131  EXPECT(assert_equal((Vector)v0, actual));
132 }
133 
134 //******************************************************************************
135 TEST(SO4, Invariants) {
136  EXPECT(check_group_invariants(id, id));
137  EXPECT(check_group_invariants(id, Q1));
138  EXPECT(check_group_invariants(Q2, id));
139  EXPECT(check_group_invariants(Q2, Q1));
140  EXPECT(check_group_invariants(Q1, Q2));
141 
142  EXPECT(check_manifold_invariants(id, id));
143  EXPECT(check_manifold_invariants(id, Q1));
144  EXPECT(check_manifold_invariants(Q2, id));
145  EXPECT(check_manifold_invariants(Q2, Q1));
146  EXPECT(check_manifold_invariants(Q1, Q2));
147 }
148 
149 //******************************************************************************
151  SO4 expected = Q1 * Q2;
152  Matrix actualH1, actualH2;
153  SO4 actual = Q1.compose(Q2, actualH1, actualH2);
154  EXPECT(assert_equal(expected, actual));
155 
156  Matrix numericalH1 =
157  numericalDerivative21(testing::compose<SO4>, Q1, Q2, 1e-2);
158  EXPECT(assert_equal(numericalH1, actualH1));
159 
160  Matrix numericalH2 =
161  numericalDerivative22(testing::compose<SO4>, Q1, Q2, 1e-2);
162  EXPECT(assert_equal(numericalH2, actualH2));
163 }
164 
165 //******************************************************************************
166 TEST(SO4, vec) {
167  using Vector16 = SO4::VectorN2;
168  const Vector16 expected = Eigen::Map<const Vector16>(Q2.matrix().data());
169  Matrix actualH;
170  const Vector16 actual = Q2.vec(actualH);
171  EXPECT(assert_equal(expected, actual));
172  std::function<Vector16(const SO4&)> f = [](const SO4& Q) { return Q.vec(); };
173  const Matrix numericalH = numericalDerivative11(f, Q2, 1e-5);
174  EXPECT(assert_equal(numericalH, actualH));
175 }
176 
177 //******************************************************************************
179  const Matrix3 expected = Q3.matrix().topLeftCorner<3, 3>();
180  Matrix actualH;
181  const Matrix3 actual = topLeft(Q3, actualH);
182  EXPECT(assert_equal(expected, actual));
183  std::function<Matrix3(const SO4&)> f = [](const SO4& Q3) {
184  return topLeft(Q3);
185  };
186  const Matrix numericalH = numericalDerivative11(f, Q3, 1e-5);
187  EXPECT(assert_equal(numericalH, actualH));
188 }
189 
190 //******************************************************************************
192  const Matrix43 expected = Q3.matrix().leftCols<3>();
193  Matrix actualH;
194  const Matrix43 actual = stiefel(Q3, actualH);
195  EXPECT(assert_equal(expected, actual));
196  std::function<Matrix43(const SO4&)> f = [](const SO4& Q3) {
197  return stiefel(Q3);
198  };
199  const Matrix numericalH = numericalDerivative11(f, Q3, 1e-5);
200  EXPECT(assert_equal(numericalH, actualH));
201 }
202 
203 //******************************************************************************
204 int main() {
205  TestResult tr;
206  return TestRegistry::runAllTests(tr);
207 }
208 //******************************************************************************
Quaternion Q
#define GTSAM_CONCEPT_ASSERT(concept)
Definition: base/concepts.h:22
Vector v2
Concept check for values that can be used in unit tests.
Provides convenient mappings of common member functions for testing.
static int runAllTests(TestResult &result)
Vector v1
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar * data() const
EIGEN_DEVICE_FUNC const VectorBlock< const Coefficients, 3 > vec() const
Matrix expected
Definition: testMatrix.cpp:971
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:94
static std::mt19937 rng
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
Definition: Matrix.cpp:40
Eigen::MatrixXd Matrix
Definition: base/Matrix.h:39
Rot2 R(Rot2::fromAngle(0.1))
4*4 matrix representation of SO(4)
Pose2_ Expmap(const Vector3_ &xi)
Definition: BFloat16.h:88
Some functions to compute numerical derivatives.
TEST(SO4, Identity)
Definition: testSO4.cpp:34
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
3*3 matrix representation of SO(3)
Definition: SOn.h:54
static const Similarity3 id
internal::FixedSizeMatrix< Y, X >::type numericalDerivative11(std::function< Y(const X &)> h, const X &x, double delta=1e-5)
New-style numerical derivatives using manifold_traits.
T compose(const T &t1, const T &t2)
Definition: lieProxies.h:39
internal::FixedSizeMatrix< Y, X1 >::type numericalDerivative21(const std::function< Y(const X1 &, const X2 &)> &h, const X1 &x1, const X2 &x2, double delta=1e-5)
Vector v3
Eigen::VectorXd Vector
Definition: Vector.h:38
Base class and basic functions for Manifold types.
GTSAM_EXPORT Matrix43 stiefel(const SO4 &Q, OptionalJacobian< 12, 6 > H)
Definition: SO4.cpp:220
const MatrixNN & matrix() const
Return matrix.
Definition: SOn.h:157
#define EXPECT(condition)
Definition: Test.h:150
Array< int, Dynamic, 1 > v
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Class compose(const Class &g) const
Definition: Lie.h:48
GTSAM_EXPORT Matrix3 topLeft(const SO4 &Q, OptionalJacobian< 9, 6 > H)
Definition: SO4.cpp:206
size_t dim() const
Definition: SOn.h:216
Vector xi
Definition: testPose2.cpp:148
traits
Definition: chartTesting.h:28
int main()
Definition: testSO4.cpp:204
#define EXPECT_LONGS_EQUAL(expected, actual)
Definition: Test.h:154
The quaternion class used to represent 3D orientations and rotations.
static const double v0
internal::FixedSizeMatrix< Y, X2 >::type numericalDerivative22(std::function< Y(const X1 &, const X2 &)> h, const X1 &x1, const X2 &x2, double delta=1e-5)
size_t rows() const
Definition: SOn.h:159
SO< Eigen::Dynamic > SOn
Definition: SOn.h:342
The matrix class, also used for vectors and row-vectors.
EIGEN_DEVICE_FUNC bool isApprox(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
Eigen::Matrix< double, Eigen::Dynamic, 1 > Vector
EIGEN_DEVICE_FUNC RotationMatrixType matrix() const
Definition: RotationBase.h:50
VectorN2 vec(OptionalJacobian< internal::NSquaredSO(N), dimension > H={}) const
Definition: SOn-inl.h:88


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:39:41