faunus
legendre.h
1 #pragma once
2 #include <array>
3 
4 namespace Faunus {
24 template <std::floating_point T, std::size_t max_order, bool use_table = false> class Legendre
25 {
26  private:
27  std::array<T, max_order + 1> y;
28  std::array<T, max_order + 1> P;
29  public:
30  Legendre()
31  {
32  P[0] = 1.0;
33  if constexpr (use_table) {
34  for (std::size_t i = 1; i < max_order; ++i) {
35  y[i] = 1.0 + 1.0 / T(i);
36  }
37  }
38  }
39 
41  const auto& eval(T x)
42  {
43  if constexpr (max_order > 0) {
44  P[1] = x;
45  for (std::size_t i = 1; i < max_order; ++i) {
46  if constexpr (use_table) {
47  P[i + 1] = ((y[i] + 1.0) * x * P[i] - P[i - 1]) / y[i];
48  }
49  else {
50  P[i + 1] = ((2.0 + 1.0 / T(i)) * x * P[i] - P[i - 1]) / (1.0 + 1.0 / T(i));
51  }
52  }
53  }
54  return P;
55  }
56 };
57 #ifdef DOCTEST_LIBRARY_INCLUDED__
58 TEST_CASE_TEMPLATE("[Faunus] Legendre", LegendreType, Legendre<double, 3, false>,
60 {
61  using doctest::Approx;
62  LegendreType l;
63  double x = 2.2;
64  auto P = l.eval(x);
65  CHECK_EQ(P[0], Approx(1));
66  CHECK_EQ(P[1], Approx(x));
67  CHECK_EQ(P[2], Approx(0.5 * (3 * x * x - 1)));
68  CHECK_EQ(P[3], Approx(0.5 * (5 * x * x * x - 3 * x)));
69 }
70 #endif
71 
72 } // namespace Faunus
double T
floating point size
Definition: units.h:73
const auto & eval(T x)
Evaluate polynomials at x.
Definition: legendre.h:41
Cell list class templates.
Definition: actions.cpp:11
Evaluate n&#39;th degree Legendre polynomial.
Definition: legendre.h:24