ISO/ IEC JTC1/SC22/WG14 N1023

Document: WG14 N1023
Date:     09-Sep-2003

PROPOSED ADDITION OF SPECIAL
MATH FUNCTIONS

P.J. Plauger
Dinkumware, Ltd.
pjp@dinkumware.com

The C++ committee is preparing a non-normative technical report
(TR-1) which includes, among many other things, a number of special
math functions, as described by Walter E. Brown in WG21/N1422.
Our experience so far is that these functions are implementable,
even though they are not easy to implement well in all precisions.
In the interest of maintaining future C/C++ compatibility, we are
proposing that the C committee undertake a similar project --
prepare a Type 2 Technical Report describing C versions of the
same functions. We also encourage close liaison with the C++
work so that the two TRs remain compatible.

Note that we have problems both with the choice of names used in
N1422 and the order of arguments to these functions. What we propose
here assumes the signatures will be changed as we desire; but in
any case we strongly favor reconciling signatures (and semantics)
between the two languages as needed over time. 

All the functions, or close brothers to them, are defined in
ISO-31:11 1992. They are also pretty precisely described in
N1422, and have even better descriptions in a revised version of
that document which will soon be available. This proposal makes no
attempt to replicate that precision. If adopted in spirit, however,
we will supply a revised document that reflects the latest version
adopted by WG21.

As with other math functions, these should be declared in math.h.
Versions with an f suffix should also be provided with double
parameters changed to float, and with an l suffix with double
parameters changed to long double. Generic versions should also
be added to tgmath.h. The signatures below are preceded by their
item numbers from ISO 31-11. Any definitions are merely intended
to show relationships to other functions:

11-14.4  double cyl_bessel_i(double x, double l);
11-14.1  double cyl_bessel_j(double x, double l);
11-14.4  double cyl_bessel_k(double x, double l);
11-14.5  double sph_bessel(double x, double l)
	{return sqrt(pi / (2 * x) * cyl_bessel(x, l + 0.5); }

11-14.2  double cyl_neumann(double x, double l);
11-14.6  double sph_neumann(double x, double l)
	{return sqrt(pi / (2 * x) * cyl_neumann(x, l + 0.5); }

11-14.20  double beta(double x, double y)
	{return tgamma(x) * tgamma(y) / tgamma(x + y); }

11-14.21  double expint(double x);

11-14.16  double ellint_1(double k, double phi);
11-14.16  double comp_ellint_1(double k)
	{return ellint_1(k, pi/2); }
11-14.17  double ellint_2(double k, double phi);
11-14.17  double comp_ellint_2(double k)
	{return ellint_2(k, pi/2); }
11-14.18  double ellint_3(double k, double n, double phi);
11-14.18  double comp_ellint_3(double k, double n)
	{return ellint_3(k, n, pi/2); }

11-14.14  double hyperg(double x, double a, double b, double c);
11-14.15  double conf_hyperg(double x, double a, double c);

11-14.11  double hermite(double x, unsigned int n);

11-14.13  double assoc_laguerre(double x, unsigned int n, unsigned int m);
11-14.12  double laguerre(double x, unsigned int n)
	{return assoc_laguerre(x, n, 0); }

11-14.9  double assoc_legendre(double x, unsigned int l, unsigned int m);
11-14.8  double legendre(double x, unsigned int l)
	{return assoc_legendre(x, l); }
11-14.10  double sph_legendre(double theta, unsigned int l, int m)
	{return f(l, m) * assoc_legendre(cos(theta), l, m); }

11-14.23  double riemann_zeta(double x);

Note that sph_legendre omits the azimuthal angle phi, but is otherwise
the same as the spherical harmonic defined in 11-14.10. One or two
other phase factors may be simplified as well.