1[/ 2 Copyright 2019, Nick Thompson 3 Distributed under the Boost Software License, Version 1.0. 4 (See accompanying file LICENSE_1_0.txt or copy at 5 http://www.boost.org/LICENSE_1_0.txt). 6] 7 8[section:gegenbauer Gegenbauer Polynomials] 9 10[h4 Synopsis] 11 12`` 13#include <boost/math/special_functions/gegenbauer.hpp> 14`` 15 16 namespace boost{ namespace math{ 17 18 template<typename Real> 19 Real gegenbauer(unsigned n, Real lambda, Real x); 20 21 template<typename Real> 22 Real gegenbauer_prime(unsigned n, Real lambda, Real x); 23 24 template<typename Real> 25 Real gegenbauer_derivative(unsigned n, Real lambda, Real x, unsigned k); 26 27 }} // namespaces 28 29Gegenbauer polynomials are a family of orthogonal polynomials. 30 31A basic usage is as follows: 32 33 using boost::math::gegenbauer; 34 double x = 0.5; 35 double lambda = 0.5; 36 unsigned n = 3; 37 double y = gegenbauer(n, lambda, x); 38 39All derivatives of the Gegenbauer polynomials are available. 40The /k/-th derivative of the /n/-th Gegenbauer polynomial is given by 41 42 using boost::math::gegenbauer_derivative; 43 double x = 0.5; 44 double lambda = 0.5; 45 unsigned n = 3; 46 unsigned k = 2; 47 double y = gegenbauer_derivative(n, lambda, x, k); 48 49For consistency with the rest of the library, `gegenbauer_prime` is provided which simply returns `gegenbauer_derivative(n, lambda, x,1 )`. 50 51[$../graphs/gegenbauer.svg] 52 53[h3 Implementation] 54 55The implementation uses the 3-term recurrence for the Gegenbauer polynomials, rising. 56 57[h3 Performance] 58 59Double precision timing on a consumer x86 laptop is shown below. 60Included is the time to generate a random number argument in the interval \[-1, 1\] (which takes 11.5ns). 61 62`` 63Run on (16 X 4300 MHz CPU s) 64CPU Caches: 65 L1 Data 32K (x8) 66 L1 Instruction 32K (x8) 67 L2 Unified 1024K (x8) 68 L3 Unified 11264K (x1) 69Load Average: 0.21, 0.33, 0.29 70----------------------------------------- 71Benchmark Time 72----------------------------------------- 73Gegenbauer<double>/1 12.5 ns 74Gegenbauer<double>/2 13.5 ns 75Gegenbauer<double>/3 14.6 ns 76Gegenbauer<double>/4 16.0 ns 77Gegenbauer<double>/5 17.5 ns 78Gegenbauer<double>/6 19.2 ns 79Gegenbauer<double>/7 20.7 ns 80Gegenbauer<double>/8 22.2 ns 81Gegenbauer<double>/9 23.6 ns 82Gegenbauer<double>/10 25.2 ns 83Gegenbauer<double>/11 26.9 ns 84Gegenbauer<double>/12 28.7 ns 85Gegenbauer<double>/13 30.5 ns 86Gegenbauer<double>/14 32.5 ns 87Gegenbauer<double>/15 34.3 ns 88Gegenbauer<double>/16 36.3 ns 89Gegenbauer<double>/17 38.0 ns 90Gegenbauer<double>/18 39.9 ns 91Gegenbauer<double>/19 41.8 ns 92Gegenbauer<double>/20 43.8 ns 93UniformReal<double> 11.5 ns 94`` 95 96[h3 Accuracy] 97 98Some representative ULP plots are shown below. 99The relative accuracy cannot be controlled at the roots of the polynomial, as is to be expected. 100 101[$../graphs/gegenbauer_ulp_3.svg] 102[$../graphs/gegenbauer_ulp_5.svg] 103[$../graphs/gegenbauer_ulp_9.svg] 104 105[h3 Caveats] 106 107Some programs define the Gegenbauer polynomial with \u03BB = 0 via renormalization (which makes them Chebyshev polynomials). 108We do not follow this convention: In this case, only the zeroth Gegenbauer polynomial is nonzero. 109 110 111[endsect] 112