Created
January 3, 2016 11:37
-
-
Save telishev/deea7eaab660e1ea885b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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