| // This file is part of Eigen, a lightweight C++ template library |
| // for linear algebra. |
| // |
| // Copyright (C) 2007 Julien Pommier |
| // Copyright (C) 2009-2019 Gael Guennebaud <gael.guennebaud@inria.fr> |
| // |
| // This Source Code Form is subject to the terms of the Mozilla |
| // Public License v. 2.0. If a copy of the MPL was not distributed |
| // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| |
| #ifndef EIGEN_ARCH_GENERIC_PACKET_MATH_POLYNOMIALS_H |
| #define EIGEN_ARCH_GENERIC_PACKET_MATH_POLYNOMIALS_H |
| |
| // IWYU pragma: private |
| #include "../../InternalHeaderCheck.h" |
| |
| namespace Eigen { |
| namespace internal { |
| |
| /* polevl (modified for Eigen) |
| * |
| * Evaluate polynomial |
| * |
| * |
| * |
| * SYNOPSIS: |
| * |
| * int N; |
| * Scalar x, y, coef[N+1]; |
| * |
| * y = polevl<decltype(x), N>( x, coef); |
| * |
| * |
| * |
| * DESCRIPTION: |
| * |
| * Evaluates polynomial of degree N: |
| * |
| * 2 N |
| * y = C + C x + C x +...+ C x |
| * 0 1 2 N |
| * |
| * Coefficients are stored in reverse order: |
| * |
| * coef[0] = C , ..., coef[N] = C . |
| * N 0 |
| * |
| * The function p1evl() assumes that coef[N] = 1.0 and is |
| * omitted from the array. Its calling arguments are |
| * otherwise the same as polevl(). |
| * |
| * |
| * The Eigen implementation is templatized. For best speed, store |
| * coef as a const array (constexpr), e.g. |
| * |
| * const double coef[] = {1.0, 2.0, 3.0, ...}; |
| * |
| */ |
| template <typename Packet, int N> |
| struct ppolevl { |
| static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& x, |
| const typename unpacket_traits<Packet>::type coeff[]) { |
| EIGEN_STATIC_ASSERT((N > 0), YOU_MADE_A_PROGRAMMING_MISTAKE); |
| return pmadd(ppolevl<Packet, N - 1>::run(x, coeff), x, pset1<Packet>(coeff[N])); |
| } |
| }; |
| |
| template <typename Packet> |
| struct ppolevl<Packet, 0> { |
| static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet run(const Packet& x, |
| const typename unpacket_traits<Packet>::type coeff[]) { |
| EIGEN_UNUSED_VARIABLE(x); |
| return pset1<Packet>(coeff[0]); |
| } |
| }; |
| |
| /* chbevl (modified for Eigen) |
| * |
| * Evaluate Chebyshev series |
| * |
| * |
| * |
| * SYNOPSIS: |
| * |
| * int N; |
| * Scalar x, y, coef[N], chebevl(); |
| * |
| * y = chbevl( x, coef, N ); |
| * |
| * |
| * |
| * DESCRIPTION: |
| * |
| * Evaluates the series |
| * |
| * N-1 |
| * - ' |
| * y = > coef[i] T (x/2) |
| * - i |
| * i=0 |
| * |
| * of Chebyshev polynomials Ti at argument x/2. |
| * |
| * Coefficients are stored in reverse order, i.e. the zero |
| * order term is last in the array. Note N is the number of |
| * coefficients, not the order. |
| * |
| * If coefficients are for the interval a to b, x must |
| * have been transformed to x -> 2(2x - b - a)/(b-a) before |
| * entering the routine. This maps x from (a, b) to (-1, 1), |
| * over which the Chebyshev polynomials are defined. |
| * |
| * If the coefficients are for the inverted interval, in |
| * which (a, b) is mapped to (1/b, 1/a), the transformation |
| * required is x -> 2(2ab/x - b - a)/(b-a). If b is infinity, |
| * this becomes x -> 4a/x - 1. |
| * |
| * |
| * |
| * SPEED: |
| * |
| * Taking advantage of the recurrence properties of the |
| * Chebyshev polynomials, the routine requires one more |
| * addition per loop than evaluating a nested polynomial of |
| * the same degree. |
| * |
| */ |
| |
| template <typename Packet, int N> |
| struct pchebevl { |
| EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE Packet run(Packet x, |
| const typename unpacket_traits<Packet>::type coef[]) { |
| typedef typename unpacket_traits<Packet>::type Scalar; |
| Packet b0 = pset1<Packet>(coef[0]); |
| Packet b1 = pset1<Packet>(static_cast<Scalar>(0.f)); |
| Packet b2; |
| |
| for (int i = 1; i < N; i++) { |
| b2 = b1; |
| b1 = b0; |
| b0 = psub(pmadd(x, b1, pset1<Packet>(coef[i])), b2); |
| } |
| |
| return pmul(pset1<Packet>(static_cast<Scalar>(0.5f)), psub(b0, b2)); |
| } |
| }; |
| |
| } // end namespace internal |
| } // end namespace Eigen |
| |
| #endif // EIGEN_ARCH_GENERIC_PACKET_MATH_POLYNOMIALS_H |