4 #ifndef SOPHUS_AVERAGE_HPP
5 #define SOPHUS_AVERAGE_HPP
23 template <
class SequenceContainer>
25 SequenceContainer
const& foo_Ts_bar,
int max_num_iterations) {
26 size_t N = foo_Ts_bar.size();
29 using Group =
typename SequenceContainer::value_type;
30 using Scalar =
typename Group::Scalar;
31 using Tangent =
typename Group::Tangent;
35 Group foo_T_average = foo_Ts_bar.front();
36 Scalar w = Scalar(1. / N);
37 for (
int i = 0; i < max_num_iterations; ++i) {
40 for (Group
const& foo_T_bar : foo_Ts_bar) {
41 average += w * (foo_T_average.inverse() * foo_T_bar).log();
43 Group foo_T_newaverage = foo_T_average * Group::exp(
average);
44 if (squaredNorm<Tangent>(
45 (foo_T_newaverage.inverse() * foo_T_average).log()) <
47 return foo_T_newaverage;
50 foo_T_average = foo_T_newaverage;
57 #ifdef DOXYGEN_SHOULD_SKIP_THIS
58 template <
class SequenceContainer,
class Scalar>
60 optional<typename SequenceContainer::value_type>
average(
61 SequenceContainer
const& foo_Ts_bar);
65 template <
class SequenceContainer,
66 class Scalar =
typename SequenceContainer::value_type::Scalar>
68 std::is_same<typename SequenceContainer::value_type, SO2<Scalar> >::value,
69 optional<typename SequenceContainer::value_type> >
70 average(SequenceContainer
const& foo_Ts_bar) {
73 size_t N = std::distance(std::begin(foo_Ts_bar), std::end(foo_Ts_bar));
76 Scalar w = Scalar(1. / N);
80 average += w * (foo_T_average.inverse() * foo_T_bar).log();
86 template <
class SequenceContainer,
87 class Scalar =
typename SequenceContainer::value_type::Scalar>
89 std::is_same<typename SequenceContainer::value_type, RxSO2<Scalar> >::value,
90 optional<typename SequenceContainer::value_type> >
91 average(SequenceContainer
const& foo_Ts_bar) {
92 size_t N = std::distance(std::begin(foo_Ts_bar), std::end(foo_Ts_bar));
95 Scalar w = Scalar(1. / N);
99 average += w * (foo_T_average.inverse() * foo_T_bar).log();
108 template <
class Scalar>
113 template <
class Scalar>
115 return sR.so3().unit_quaternion();
118 template <
class SequenceContainer,
119 class Scalar =
typename SequenceContainer::value_type::Scalar>
121 SequenceContainer
const& foo_Ts_bar) {
123 size_t N = std::distance(std::begin(foo_Ts_bar), std::end(foo_Ts_bar));
125 Eigen::Matrix<Scalar, 4, Eigen::Dynamic> Q(4, N);
127 Scalar w = Scalar(1. / N);
128 for (
auto const& foo_T_bar : foo_Ts_bar) {
133 Eigen::Matrix<Scalar, 4, 4> QQt = Q * Q.transpose();
135 Eigen::EigenSolver<Eigen::Matrix<Scalar, 4, 4> > es(QQt);
137 std::complex<Scalar> max_eigenvalue = es.eigenvalues()[0];
138 Eigen::Matrix<std::complex<Scalar>, 4, 1> max_eigenvector =
139 es.eigenvectors().col(0);
141 for (
int i = 1; i < 4; i++) {
142 if (std::norm(es.eigenvalues()[i]) > std::norm(max_eigenvalue)) {
143 max_eigenvalue = es.eigenvalues()[i];
144 max_eigenvector = es.eigenvectors().col(i);
147 Eigen::Quaternion<Scalar> quat;
149 max_eigenvector[0].real(),
150 max_eigenvector[1].real(),
151 max_eigenvector[2].real(),
152 max_eigenvector[3].real();
160 template <
class SequenceContainer,
161 class Scalar =
typename SequenceContainer::value_type::Scalar>
163 std::is_same<typename SequenceContainer::value_type, SO3<Scalar> >::value,
164 optional<typename SequenceContainer::value_type> >
165 average(SequenceContainer
const& foo_Ts_bar) {
170 template <
class SequenceContainer,
171 class Scalar =
typename SequenceContainer::value_type::Scalar>
173 std::is_same<typename SequenceContainer::value_type, RxSO3<Scalar> >::value,
174 optional<typename SequenceContainer::value_type> >
175 average(SequenceContainer
const& foo_Ts_bar) {
176 size_t N = std::distance(std::begin(foo_Ts_bar), std::end(foo_Ts_bar));
179 Scalar scale_sum = Scalar(0);
183 scale_sum += log(foo_T_bar.scale());
189 template <
class SequenceContainer,
190 class Scalar =
typename SequenceContainer::value_type::Scalar>
192 std::is_same<typename SequenceContainer::value_type, SE2<Scalar> >::value,
193 optional<typename SequenceContainer::value_type> >
194 average(SequenceContainer
const& foo_Ts_bar,
int max_num_iterations = 20) {
200 template <
class SequenceContainer,
201 class Scalar =
typename SequenceContainer::value_type::Scalar>
203 std::is_same<typename SequenceContainer::value_type, Sim2<Scalar> >::value,
204 optional<typename SequenceContainer::value_type> >
205 average(SequenceContainer
const& foo_Ts_bar,
int max_num_iterations = 20) {
209 template <
class SequenceContainer,
210 class Scalar =
typename SequenceContainer::value_type::Scalar>
212 std::is_same<typename SequenceContainer::value_type, SE3<Scalar> >::value,
213 optional<typename SequenceContainer::value_type> >
214 average(SequenceContainer
const& foo_Ts_bar,
int max_num_iterations = 20) {
218 template <
class SequenceContainer,
219 class Scalar =
typename SequenceContainer::value_type::Scalar>
221 std::is_same<typename SequenceContainer::value_type, Sim3<Scalar> >::value,
222 optional<typename SequenceContainer::value_type> >
223 average(SequenceContainer
const& foo_Ts_bar,
int max_num_iterations = 20) {
227 #endif // DOXYGEN_SHOULD_SKIP_THIS
231 #endif // SOPHUS_AVERAGE_HPP