16#ifndef dealii_polynomial_h
17#define dealii_polynomial_h
63 template <
typename number>
90 const unsigned int evaluation_point);
120 value(
const number x, std::vector<number> &values)
const;
140 template <
typename Number2>
143 const unsigned int n_derivatives,
144 Number2 * values)
const;
158 template <std::
size_t n_entries,
typename Number2>
161 const unsigned int n_derivatives,
162 std::array<Number2, n_entries> * values)
const;
180 scale(
const number factor);
197 template <
typename number2>
199 shift(
const number2 offset);
248 print(std::ostream &out)
const;
255 template <
class Archive>
275 template <
typename number2>
327 template <
typename number>
335 Monomial(
const unsigned int n,
const double coefficient = 1.);
343 static std::vector<Polynomial<number>>
350 static std::vector<number>
351 make_vector(
unsigned int n,
const double coefficient);
388 static std::vector<Polynomial<double>>
398 const unsigned int support_point,
399 std::vector<double> &a);
410 std::vector<Polynomial<double>>
442 static std::vector<Polynomial<double>>
472 Lobatto(
const unsigned int p = 0);
478 static std::vector<Polynomial<double>>
547 static std::vector<Polynomial<double>>
561 static const std::vector<double> &
572 static std::vector<std::unique_ptr<const std::vector<double>>>
619 static std::vector<Polynomial<double>>
734 const unsigned int index);
740 static std::vector<Polynomial<double>>
755 template <
typename Number>
775 template <
typename Number>
789 template <
typename number>
791 : in_lagrange_product_form(false)
792 , lagrange_weight(1.)
797 template <
typename number>
801 if (in_lagrange_product_form ==
true)
803 return lagrange_support_points.size();
808 return coefficients.size() - 1;
814 template <
typename number>
818 if (in_lagrange_product_form ==
false)
823 const unsigned int m = coefficients.size();
824 number value = coefficients.back();
825 for (
int k = m - 2; k >= 0; --k)
826 value = value * x + coefficients[k];
832 const unsigned int m = lagrange_support_points.size();
834 for (
unsigned int j = 0; j < m; ++j)
835 value *= x - lagrange_support_points[j];
836 value *= lagrange_weight;
843 template <
typename number>
844 template <
typename Number2>
847 const unsigned int n_derivatives,
848 Number2 * values)
const
850 values_of_array(std::array<Number2, 1ul>{{x}},
852 reinterpret_cast<std::array<Number2, 1ul> *
>(values));
857 template <
typename number>
858 template <std::
size_t n_entries,
typename Number2>
861 const std::array<Number2, n_entries> &x,
862 const unsigned int n_derivatives,
863 std::array<Number2, n_entries> * values)
const
866 if (in_lagrange_product_form ==
true)
871 const unsigned int n_supp = lagrange_support_points.size();
872 const number weight = lagrange_weight;
873 switch (n_derivatives)
876 for (
unsigned int e = 0; e < n_entries; ++e)
878 for (
unsigned int k = 1; k <= n_derivatives; ++k)
879 for (
unsigned int e = 0; e < n_entries; ++e)
881 for (
unsigned int i = 0; i < n_supp; ++i)
883 std::array<Number2, n_entries> v = x;
884 for (
unsigned int e = 0; e < n_entries; ++e)
885 v[e] -= lagrange_support_points[i];
893 for (
unsigned int k = n_derivatives; k > 0; --k)
894 for (
unsigned int e = 0; e < n_entries; ++e)
895 values[k][e] = (values[k][e] * v[e] + values[k - 1][e]);
896 for (
unsigned int e = 0; e < n_entries; ++e)
897 values[0][e] *= v[e];
908 number k_factorial = 1;
909 for (
unsigned int k = 0; k <= n_derivatives; ++k)
911 for (
unsigned int e = 0; e < n_entries; ++e)
912 values[k][e] *= k_factorial * weight;
913 k_factorial *=
static_cast<number
>(k + 1);
925 std::array<Number2, n_entries> value;
926 for (
unsigned int e = 0; e < n_entries; ++e)
928 for (
unsigned int i = 0; i < n_supp; ++i)
929 for (
unsigned int e = 0; e < n_entries; ++e)
930 value[e] *= (x[e] - lagrange_support_points[i]);
932 for (
unsigned int e = 0; e < n_entries; ++e)
933 values[0][e] = weight * value[e];
939 std::array<Number2, n_entries> value, derivative = {};
940 for (
unsigned int e = 0; e < n_entries; ++e)
942 for (
unsigned int i = 0; i < n_supp; ++i)
943 for (
unsigned int e = 0; e < n_entries; ++e)
945 const Number2 v = x[e] - lagrange_support_points[i];
946 derivative[e] = derivative[e] * v + value[e];
950 for (
unsigned int e = 0; e < n_entries; ++e)
952 values[0][e] = weight * value[e];
953 values[1][e] = weight * derivative[e];
960 std::array<Number2, n_entries> value, derivative = {},
962 for (
unsigned int e = 0; e < n_entries; ++e)
964 for (
unsigned int i = 0; i < n_supp; ++i)
965 for (
unsigned int e = 0; e < n_entries; ++e)
967 const Number2 v = x[e] - lagrange_support_points[i];
969 derivative[e] = derivative[e] * v + value[e];
973 for (
unsigned int e = 0; e < n_entries; ++e)
975 values[0][e] = weight * value[e];
976 values[1][e] = weight * derivative[e];
977 values[2][e] =
static_cast<number
>(2) * weight *
second[e];
989 const unsigned int m = coefficients.size();
990 std::vector<std::array<Number2, n_entries>> a(coefficients.size());
991 for (
unsigned int i = 0; i < coefficients.size(); ++i)
992 for (
unsigned int e = 0; e < n_entries; ++e)
993 a[i][e] = coefficients[i];
995 unsigned int j_factorial = 1;
1000 const unsigned int min_valuessize_m =
std::min(n_derivatives + 1, m);
1001 for (
unsigned int j = 0; j < min_valuessize_m; ++j)
1003 for (
int k = m - 2; k >=
static_cast<int>(j); --k)
1004 for (
unsigned int e = 0; e < n_entries; ++e)
1005 a[k][e] += x[e] * a[k + 1][e];
1006 for (
unsigned int e = 0; e < n_entries; ++e)
1007 values[j][e] =
static_cast<number
>(j_factorial) * a[j][e];
1009 j_factorial *= j + 1;
1013 for (
unsigned int j = min_valuessize_m; j <= n_derivatives; ++j)
1014 for (
unsigned int e = 0; e < n_entries; ++e)
1020 template <
typename number>
1021 template <
class Archive>
1028 ar &in_lagrange_product_form;
1029 ar &lagrange_support_points;
1030 ar &lagrange_weight;
1035 template <
typename Number>
1042 Assert(alpha >= 0 && beta >= 0,
1049 const Number xeval = Number(-1) + 2. * x;
1055 p1 = ((alpha + beta + 2) * xeval + (alpha - beta)) / 2;
1059 for (
unsigned int i = 1; i < degree; ++i)
1061 const Number v = 2 * i + (alpha + beta);
1062 const Number a1 = 2 * (i + 1) * (i + (alpha + beta + 1)) * v;
1063 const Number a2 = (v + 1) * (alpha * alpha - beta * beta);
1064 const Number a3 = v * (v + 1) * (v + 2);
1065 const Number a4 = 2 * (i + alpha) * (i + beta) * (v + 2);
1067 const Number pn = ((a2 + a3 * xeval) * p1 - a4 * p0) / a1;
1076 template <
typename Number>
1082 std::vector<Number> x(degree, 0.5);
1093 const Number tolerance =
1094 4 *
std::max(
static_cast<Number
>(std::numeric_limits<double>::epsilon()),
1095 std::numeric_limits<Number>::epsilon());
1103 const unsigned int n_points = (alpha == beta ? degree / 2 : degree);
1104 for (
unsigned int k = 0; k < n_points; ++k)
1108 Number r = 0.5 - 0.5 *
std::cos(
static_cast<Number
>(2 * k + 1) /
1111 r = (r + x[k - 1]) / 2;
1114 for (
unsigned int it = 1; it < 1000; ++it)
1117 for (
unsigned int i = 0; i < k; ++i)
1118 s += 1. / (r - x[i]);
1122 (alpha + beta + degree + 1) *
1127 const Number delta = f / (f * s - J_x);
1135 if (it == converged + 1)
1140 ExcMessage(
"Newton iteration for zero of Jacobi polynomial "
1141 "did not converge."));
1147 for (
unsigned int k = n_points; k < degree; ++k)
1148 x[k] = 1.0 - x[degree - k - 1];
static std::vector< Polynomial< double > > generate_complete_basis(const unsigned int p)
static std::vector< Polynomial< double > > generate_complete_basis(const unsigned int degree)
static std::vector< std::unique_ptr< const std::vector< double > > > recursive_coefficients
static void compute_coefficients(const unsigned int p)
static const std::vector< double > & get_coefficients(const unsigned int p)
static std::vector< Polynomial< double > > generate_complete_basis(const unsigned int degree)
static void compute_coefficients(const unsigned int n, const unsigned int support_point, std::vector< double > &a)
static std::vector< Polynomial< double > > generate_complete_basis(const unsigned int degree)
static std::vector< Polynomial< double > > generate_complete_basis(const unsigned int degree)
std::vector< double > compute_coefficients(const unsigned int p)
static std::vector< Polynomial< double > > generate_complete_basis(const unsigned int p)
static std::vector< Polynomial< number > > generate_complete_basis(const unsigned int degree)
static std::vector< number > make_vector(unsigned int n, const double coefficient)
number value(const number x) const
bool operator==(const Polynomial< number > &p) const
std::vector< number > coefficients
Polynomial< number > primitive() const
Polynomial< number > & operator+=(const Polynomial< number > &p)
void values_of_array(const std::array< Number2, n_entries > &points, const unsigned int n_derivatives, std::array< Number2, n_entries > *values) const
Polynomial< number > derivative() const
void transform_into_standard_form()
void scale(const number factor)
Polynomial< number > & operator-=(const Polynomial< number > &p)
std::vector< number > lagrange_support_points
void shift(const number2 offset)
void print(std::ostream &out) const
bool in_lagrange_product_form
void serialize(Archive &ar, const unsigned int version)
static void multiply(std::vector< number > &coefficients, const number factor)
void value(const Number2 x, const unsigned int n_derivatives, Number2 *values) const
Polynomial< number > & operator*=(const double s)
virtual std::size_t memory_consumption() const
unsigned int degree() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
static ::ExceptionBase & ExcNotImplemented()
static ::ExceptionBase & ExcEmptyObject()
#define Assert(cond, exc)
static ::ExceptionBase & ExcMessage(std::string arg1)
Number jacobi_polynomial_value(const unsigned int degree, const int alpha, const int beta, const Number x)
std::vector< Polynomial< double > > generate_complete_Lagrange_basis(const std::vector< Point< 1 > > &points)
std::vector< Number > jacobi_polynomial_roots(const unsigned int degree, const int alpha, const int beta)
static constexpr double PI
static const unsigned int invalid_unsigned_int
::VectorizedArray< Number, width > min(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > cos(const ::VectorizedArray< Number, width > &)
::VectorizedArray< Number, width > abs(const ::VectorizedArray< Number, width > &)