Initial commit.

parents
cmake_minimum_required(VERSION 3.9)
project(cexpr_tschebyscheff)
set(CMAKE_CXX_STANDARD 17)
add_executable(cexpr_tschebyscheff main.cpp)
\ No newline at end of file
#include <iostream>
#include <array>
#include <experimental/iterator>
template<typename... Ts>
constexpr auto make_array(Ts &&... values) noexcept
{
return std::array<std::common_type_t<Ts...>, sizeof...(Ts)>{std::forward<Ts>(values)...};
}
template<typename T, std::size_t N>
constexpr auto make_array() noexcept
{
return std::array<T, N>{ };
}
namespace detail {
template<int R1, int R2, typename T, std::size_t... Idx>
constexpr auto _make_range_impl(std::integer_sequence<std::size_t, Idx...>) noexcept
{
constexpr auto N = sizeof...(Idx);
return std::array<T, N>{(R1 + Idx * (static_cast<double>(R2 - R1) / (N - 1)))...};
}
template<typename T, std::size_t... Idx>
constexpr auto _make_array_filled_impl(T val,
std::integer_sequence<std::size_t, Idx...>) noexcept
{
constexpr auto N = sizeof...(Idx);
return std::array<T, N>{(val * static_cast<T>((Idx + 1) / (Idx + 1)))...};
}
template<typename T1, typename T2, std::size_t N, std::size_t... Idx>
constexpr auto _mul_impl(const std::array<T1, N> &lhs, const std::array<T2, N> &rhs,
std::integer_sequence<std::size_t, Idx...>) noexcept
{
return make_array((lhs[Idx] * rhs[Idx])...);
}
template<typename T1, typename T2, std::size_t N, std::size_t... Idx>
constexpr auto _mul_impl(T1 s, const std::array<T2, N> &rhs,
std::integer_sequence<std::size_t, Idx...>) noexcept
{
return make_array(s * rhs[Idx]...);
}
template<typename T1, typename T2, std::size_t N, std::size_t... Idx>
constexpr auto _sub_impl(const std::array<T1, N> &lhs, const std::array<T2, N> &rhs,
std::integer_sequence<std::size_t, Idx...>) noexcept
{
return make_array((lhs[Idx] - rhs[Idx])...);
}
}
template<int R1, int R2, std::size_t N, typename T>
constexpr auto make_range() noexcept
{
return detail::_make_range_impl<R1, R2, T>(std::make_index_sequence<N>{ });
}
template<std::size_t N, typename T>
constexpr auto make_array_filled(T val) noexcept
{
return detail::_make_array_filled_impl<T>(val, std::make_index_sequence<N>{ });
}
template<typename T1, typename T2, std::size_t N>
std::array<decltype(std::declval<T1>() * std::declval<T2>()), N>
constexpr operator*(const std::array<T1, N> &lhs, const std::array<T2, N> &rhs) noexcept
{
return detail::_mul_impl(lhs, rhs, std::make_index_sequence<N>());
}
template<typename T1, typename T2, std::size_t N>
std::array<decltype(std::declval<T1>() * std::declval<T2>()), N>
constexpr operator*(T1 s, const std::array<T2, N> &rhs) noexcept
{
return detail::_mul_impl(s, rhs, std::make_index_sequence<N>());
}
template<typename T1, typename T2, std::size_t N>
std::array<decltype(std::declval<T1>() * std::declval<T2>()), N>
constexpr operator-(const std::array<T1, N> &lhs, const std::array<T2, N> &rhs) noexcept
{
return detail::_sub_impl(lhs, rhs, std::make_index_sequence<N>());
}
template<std::size_t K, typename T, std::size_t N>
constexpr decltype(auto) tschebyscheff(const std::array<T, N> &x) noexcept
{
if constexpr (K == 0)
return make_array_filled<N>(1);
else if constexpr (K == 1)
return x;
else
return 2 * x * tschebyscheff<K - 1>(x) - tschebyscheff<K - 2>(x);
}
int main()
{
// Calculation of the Tschebyscheff-Polynom for k = 5 at compiletime.
constexpr auto x = make_range<-1, 1, 101, double>();
constexpr auto y = tschebyscheff<5>(x);
std::copy(std::begin(y), std::end(y),
std::experimental::make_ostream_joiner(std::cout, ", "));
std::cout << std::endl;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment