Skip to content

Instantly share code, notes, and snippets.

@telishev
Created January 3, 2016 11:37
Show Gist options
  • Save telishev/deea7eaab660e1ea885b to your computer and use it in GitHub Desktop.
Save telishev/deea7eaab660e1ea885b to your computer and use it in GitHub Desktop.
#include <tuple>
#include <initializer_list>
#include <math.h>
#include <utility>
using namespace std;
#define USE_RECURSION 1
#if USE_RECURSION
template <int I>
struct helper {
template <typename Tup1, typename Tup2>
static double sum_squared_deltas(Tup1 const& tup1, Tup2 const& tup2) {
double sd = static_cast<double>(std::get<I>(tup1) - std::get<I>(tup2));
return sd*sd + helper<I-1>::sum_squared_deltas(tup1, tup2);
}
};
template <>
struct helper<-1> {
template <typename Tup1, typename Tup2>
static double sum_squared_deltas(Tup1 const& tup1, Tup2 const& tup2) {
return 0.0;
}
};
template <typename Tup1, typename Tup2>
auto euclidean_distance(Tup1 const &tup1, Tup2 const &tup2) {
static_assert(std::tuple_size<Tup1>::value == std::tuple_size<Tup2>::value,
"tuples must have the same size");
double ssd = helper<std::tuple_size<Tup1>::value-1>::sum_squared_deltas(tup1, tup2);
return sqrt(ssd);
}
#else
template <typename Tup1, typename Tup2, size_t...s>
double euclidean_distance_impl (Tup1 const &tup1, Tup2 const &tup2, index_sequence<s...>)
{
double res = 0.0;
auto x = {res += ((std::get<s> (tup2) - std::get<s> (tup1))*(std::get<s> (tup2) - std::get<s> (tup1)))...};
(void)x;
return sqrt (res);
}
template <typename Tup1, typename Tup2>
double euclidean_distance(Tup1 const &tup1, Tup2 const &tup2)
{
static_assert(tuple_size<Tup1>::value == tuple_size<Tup2>::value, "tuples must be of the same size");
return euclidean_distance_impl (tup1, tup2, make_index_sequence<tuple_size<Tup1>::value> ());
}
#endif
template<size_t...s>
auto create_tuple_impl (double value, index_sequence<s...> ) { return make_tuple ((s, value)...); }
template<size_t s>
auto create_tuple (double value) { return create_tuple_impl (value, make_index_sequence<s> ()); }
int main ()
{
auto x = euclidean_distance (create_tuple<16> (0), create_tuple<16> (1));
return x;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment