Eigen  5.0.1
 
Loading...
Searching...
No Matches
GenericPacketMathPolynomials.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2007 Julien Pommier
5// Copyright (C) 2009-2019 Gael Guennebaud <gael.guennebaud@inria.fr>
6//
7// This Source Code Form is subject to the terms of the Mozilla
8// Public License v. 2.0. If a copy of the MPL was not distributed
9// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10// SPDX-License-Identifier: MPL-2.0
11
12#ifndef EIGEN_ARCH_GENERIC_PACKET_MATH_POLYNOMIALS_H
13#define EIGEN_ARCH_GENERIC_PACKET_MATH_POLYNOMIALS_H
14
15// IWYU pragma: private
16#include "../../InternalHeaderCheck.h"
17
18namespace Eigen {
19namespace internal {
20
21/* polevl (modified for Eigen)
22 *
23 * Evaluate polynomial
24 *
25 *
26 *
27 * SYNOPSIS:
28 *
29 * int N;
30 * Scalar x, y, coef[N+1];
31 *
32 * y = polevl<decltype(x), N>( x, coef);
33 *
34 *
35 *
36 * DESCRIPTION:
37 *
38 * Evaluates polynomial of degree N:
39 *
40 * 2 N
41 * y = C + C x + C x +...+ C x
42 * 0 1 2 N
43 *
44 * Coefficients are stored in reverse order:
45 *
46 * coef[0] = C , ..., coef[N] = C .
47 * N 0
48 *
49 * The function p1evl() assumes that coef[N] = 1.0 and is
50 * omitted from the array. Its calling arguments are
51 * otherwise the same as polevl().
52 *
53 *
54 * The Eigen implementation is templatized. For best speed, store
55 * coef as a const array (constexpr), e.g.
56 *
57 * const double coef[] = {1.0, 2.0, 3.0, ...};
58 *
59 */
60template <typename Packet, int N>
61struct ppolevl {
62 template <int... Indices>
63 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run_impl(const Packet& x,
64 const typename unpacket_traits<Packet>::type coeff[],
65 std::integer_sequence<int, Indices...>) {
66 Packet result = pset1<Packet>(coeff[0]);
67 int unused[] = {0, (result = pmadd(result, x, pset1<Packet>(coeff[Indices + 1])), 0)...};
68 EIGEN_UNUSED_VARIABLE(unused);
69 return result;
70 }
71
72 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& x,
73 const typename unpacket_traits<Packet>::type coeff[]) {
74 EIGEN_STATIC_ASSERT((N >= 0), YOU_MADE_A_PROGRAMMING_MISTAKE);
75 return run_impl(x, coeff, std::make_integer_sequence<int, (N > 0 ? N : 0)>{});
76 }
77};
78
79/* chbevl (modified for Eigen)
80 *
81 * Evaluate Chebyshev series
82 *
83 *
84 *
85 * SYNOPSIS:
86 *
87 * int N;
88 * Scalar x, y, coef[N], chebevl();
89 *
90 * y = chbevl( x, coef, N );
91 *
92 *
93 *
94 * DESCRIPTION:
95 *
96 * Evaluates the series
97 *
98 * N-1
99 * - '
100 * y = > coef[i] T (x/2)
101 * - i
102 * i=0
103 *
104 * of Chebyshev polynomials Ti at argument x/2.
105 *
106 * Coefficients are stored in reverse order, i.e. the zero
107 * order term is last in the array. Note N is the number of
108 * coefficients, not the order.
109 *
110 * If coefficients are for the interval a to b, x must
111 * have been transformed to x -> 2(2x - b - a)/(b-a) before
112 * entering the routine. This maps x from (a, b) to (-1, 1),
113 * over which the Chebyshev polynomials are defined.
114 *
115 * If the coefficients are for the inverted interval, in
116 * which (a, b) is mapped to (1/b, 1/a), the transformation
117 * required is x -> 2(2ab/x - b - a)/(b-a). If b is infinity,
118 * this becomes x -> 4a/x - 1.
119 *
120 *
121 *
122 * SPEED:
123 *
124 * Taking advantage of the recurrence properties of the
125 * Chebyshev polynomials, the routine requires one more
126 * addition per loop than evaluating a nested polynomial of
127 * the same degree.
128 *
129 */
130
131template <typename Packet, int N>
132struct pchebevl {
133 EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Packet run(const Packet& x,
134 const typename unpacket_traits<Packet>::type coef[]) {
135 using Scalar = typename unpacket_traits<Packet>::type;
136 Packet b0 = pset1<Packet>(coef[0]);
137 Packet b1 = pset1<Packet>(static_cast<Scalar>(0.f));
138 Packet b2;
139
140 for (int i = 1; i < N; i++) {
141 b2 = b1;
142 b1 = b0;
143 b0 = psub(pmadd(x, b1, pset1<Packet>(coef[i])), b2);
144 }
145
146 return pmul(pset1<Packet>(static_cast<Scalar>(0.5f)), psub(b0, b2));
147 }
148};
149
150} // end namespace internal
151} // end namespace Eigen
152
153#endif // EIGEN_ARCH_GENERIC_PACKET_MATH_POLYNOMIALS_H