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