cc [ flags ] -I/usr/local/include file(s) -L/usr/local/lib -lmcw [ ... ] #include <mathcw.h> extern float echebf (float x, int n, const float c[/* n */]); extern double echeb (double x, int n, const double c[/* n */]); extern long double echebl (long double x, int n, const long double c[/* n */]); extern __float80 echebw (__float80 x, int n, const __float80 c[/* n */]); extern __float128 echebq (__float128 x, int n, const __float128 c[/* n */]); extern long_long_double echebll (long_long_double x, int n, const long_long_double c[/* n */]); extern decimal_float echebdf (decimal_float x, int n, const decimal_float c[/* n */]); extern decimal_double echebd (decimal_double x, int n, const decimal_double c[/* n */]); extern decimal_long_double echebdl (decimal_long_double x, int n, const decimal_long_double c[/* n */]); extern decimal_long_long_double echebdll (decimal_long_long_double x, int n, const decimal_long_long_double c[/* n */]);
NB: Functions with prototypes containing underscores in type names may be available only with certain extended compilers.
P(x) = sum(k = 0 to n-1) c[k] * T(k,x)where T(k,x) is the order-k Chebyshev polynomial of the first kind, and x is normally restricted to the interval [-1,+1], although that condition is intentionally not checked for.
The number of floating-point operations required is n multiplies and 2*n adds, about 50% more than required for evaluation of a conventional order-n polynomial in Horner form.
Caution: Some authors implicitly halve the coefficient c[0], conventionally indicated by a prime on the summation symbol; the functions described here do not.
The output takes only a few seconds to generate, and after some simple reformatting, looks something like this:with(numapprox): interface(prettyprint=0, quiet=true, screenwidth=infinity): Digits := 20: c := chebyshev(tan(x), x = 0 .. Pi, 1.0e-16);
If those coefficients are stored in an array, c[], then a call echeb((8.0 / M_PI) * x - 1.0, sizeof(c)/sizeof(c[0]), c) should return a value of tan(x) that is accurate to about 16 decimal digits.c := 0.45565217041349203532 * T(0, (8/Pi) * x - 1) + 0.48946864364506139170 * T(1, (8/Pi) * x - 1) + 0.42848348909108677383e-1 * T(2, (8/Pi) * x - 1) + 0.10244343354792446844e-1 * T(3, (8/Pi) * x - 1) ... + 0.87981510697734638763e-15 * T(20, (8/Pi) * x - 1) + 0.15095587991023089012e-15 * T(21, (8/Pi) * x - 1) + 0.25899583833164263991e-16 * T(22, (8/Pi) * x - 1)
In most cases, the Chebyshev coefficients fall with increasing order, and since the Chebyshev polynomials lie in [-1,+1] for x in [-1,+1], the series can be truncated. The sum of the absolute values of the omitted coefficients is then an upper bound on the truncation error. The first omitted coefficients is often a reasonable estimate of that error. As a result, a single table of Chebyshev coefficients makes it possible to compute a polynomial expansion to variable accuracy. This can be used, for example, to speed up intermediate steps of a calculation when less accuracy may be acceptable, and it can also be used to provide single function approximations that are easily tailored to differing native floating-point precisions.
NB: It is often possible to achieve the same accuracy with a minimax fit using a rational polynomial of lower total degree, and that may be faster to evaluate than the Chebyshev expansion, unless the single required division is exceptionally slow.