Skip to content

Instantly share code, notes, and snippets.

@Psirus
Last active May 17, 2018 08:39
Show Gist options
  • Save Psirus/311512d4439f27e4abfcfdcc0665f029 to your computer and use it in GitHub Desktop.
Save Psirus/311512d4439f27e4abfcfdcc0665f029 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <array>
struct Point
{
constexpr Point(double x, double y)
: x(x)
, y(y){};
double x, y;
};
template <std::size_t N>
using Data = std::array<Point, N>;
template <std::size_t N>
constexpr double factor(const Data<N>& known_points, double n, int i, int j)
{
if (i == j)
return 1;
return (n - known_points[j].x) / (known_points[i].x - known_points[j].x);
}
template <std::size_t N, std::size_t... Ns>
constexpr double factors(const Data<N>& known_points, double n, int i, std::index_sequence<Ns...>)
{
return (factor(known_points, n, i, Ns) * ...);
}
template <std::size_t N, std::size_t... Ns>
constexpr double interpolate_impl(const Data<N>& known_points, double n, std::index_sequence<Ns...>)
{
return ((known_points[Ns].y * factors(known_points, n, Ns, std::index_sequence<Ns...>())) + ...);
}
template <std::size_t N>
constexpr double interpolate(const Data<N>& known_points, double n)
{
return interpolate_impl(known_points, n, std::make_index_sequence<N>());
}
int main()
{
constexpr Data<4> kp = {Point{0., 2.}, Point{1., 3.}, Point{2., 12.}, Point{5., 147.}};
constexpr auto r = interpolate(kp, 3.);
static_assert(r == 35.); // completely compile-time
double d;
std::cin >> d;
std::cout << interpolate(kp, d); // 35
}
@pmueller2
Copy link

This example uses C++17 features in factors and interpolate_impl. Can you rewrite it using c++14 (variadic templates things)?

@Psirus
Copy link
Author

Psirus commented May 17, 2018

Possibly…will try later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment