1// TR1 cmath -*- C++ -*-
2
3// Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file tr1/cmath
26 *  This is a TR1 C++ Library header. 
27 */
28
29#ifndef _GLIBCXX_TR1_CMATH
30#define _GLIBCXX_TR1_CMATH 1
31
32#pragma GCC system_header
33
34#if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
35#  error TR1 header cannot be included from C++0x header
36#endif
37
38#include <cmath>
39
40#if defined(_GLIBCXX_INCLUDE_AS_TR1)
41#  include <tr1_impl/cmath>
42#else
43#  define _GLIBCXX_INCLUDE_AS_TR1
44#  define _GLIBCXX_BEGIN_NAMESPACE_TR1 namespace tr1 {
45#  define _GLIBCXX_END_NAMESPACE_TR1 }
46#  define _GLIBCXX_TR1 tr1::
47#  include <tr1_impl/cmath>
48#  undef _GLIBCXX_TR1
49#  undef _GLIBCXX_END_NAMESPACE_TR1
50#  undef _GLIBCXX_BEGIN_NAMESPACE_TR1
51#  undef _GLIBCXX_INCLUDE_AS_TR1
52#endif
53
54namespace std
55{
56namespace tr1
57{
58  // DR 550. What should the return type of pow(float,int) be?
59  // NB: C++0x and TR1 != C++03.
60  inline double
61  pow(double __x, double __y)
62  { return std::pow(__x, __y); }
63
64  inline float
65  pow(float __x, float __y)
66  { return std::pow(__x, __y); }
67
68  inline long double
69  pow(long double __x, long double __y)
70  { return std::pow(__x, __y); }
71
72  template<typename _Tp, typename _Up>
73    inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
74    pow(_Tp __x, _Up __y)
75    {
76      typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
77      return std::pow(__type(__x), __type(__y));
78    }
79}
80}
81
82#include <bits/stl_algobase.h>
83#include <limits>
84#include <tr1/type_traits>
85
86#include <tr1/gamma.tcc>
87#include <tr1/bessel_function.tcc>
88#include <tr1/beta_function.tcc>
89#include <tr1/ell_integral.tcc>
90#include <tr1/exp_integral.tcc>
91#include <tr1/hypergeometric.tcc>
92#include <tr1/legendre_function.tcc>
93#include <tr1/modified_bessel_func.tcc>
94#include <tr1/poly_hermite.tcc>
95#include <tr1/poly_laguerre.tcc>
96#include <tr1/riemann_zeta.tcc>
97
98namespace std
99{
100namespace tr1
101{
102  /**
103   * @defgroup tr1_math_spec_func Mathematical Special Functions
104   * @ingroup numerics
105   *
106   * A collection of advanced mathematical special functions.
107   * @{
108   */
109
110  inline float
111  assoc_laguerref(unsigned int __n, unsigned int __m, float __x)
112  { return __detail::__assoc_laguerre<float>(__n, __m, __x); }
113
114  inline long double
115  assoc_laguerrel(unsigned int __n, unsigned int __m, long double __x)
116  {
117    return __detail::__assoc_laguerre<long double>(__n, __m, __x);
118  }
119
120  ///  5.2.1.1  Associated Laguerre polynomials.
121  template<typename _Tp>
122    inline typename __gnu_cxx::__promote<_Tp>::__type
123    assoc_laguerre(unsigned int __n, unsigned int __m, _Tp __x)
124    {
125      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
126      return __detail::__assoc_laguerre<__type>(__n, __m, __x);
127    }
128
129  inline float
130  assoc_legendref(unsigned int __l, unsigned int __m, float __x)
131  { return __detail::__assoc_legendre_p<float>(__l, __m, __x); }
132
133  inline long double
134  assoc_legendrel(unsigned int __l, unsigned int __m, long double __x)
135  { return __detail::__assoc_legendre_p<long double>(__l, __m, __x); }
136
137  ///  5.2.1.2  Associated Legendre functions.
138  template<typename _Tp>
139    inline typename __gnu_cxx::__promote<_Tp>::__type
140    assoc_legendre(unsigned int __l, unsigned int __m, _Tp __x)
141    {
142      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
143      return __detail::__assoc_legendre_p<__type>(__l, __m, __x);
144    }
145
146  inline float
147  betaf(float __x, float __y)
148  { return __detail::__beta<float>(__x, __y); }
149
150  inline long double
151  betal(long double __x, long double __y)
152  { return __detail::__beta<long double>(__x, __y); }
153
154  ///  5.2.1.3  Beta functions.
155  template<typename _Tpx, typename _Tpy>
156    inline typename __gnu_cxx::__promote_2<_Tpx, _Tpy>::__type
157    beta(_Tpx __x, _Tpy __y)
158    {
159      typedef typename __gnu_cxx::__promote_2<_Tpx, _Tpy>::__type __type;
160      return __detail::__beta<__type>(__x, __y);
161    }
162
163  inline float
164  comp_ellint_1f(float __k)
165  { return __detail::__comp_ellint_1<float>(__k); }
166
167  inline long double
168  comp_ellint_1l(long double __k)
169  { return __detail::__comp_ellint_1<long double>(__k); }
170
171  ///  5.2.1.4  Complete elliptic integrals of the first kind.
172  template<typename _Tp>
173    inline typename __gnu_cxx::__promote<_Tp>::__type
174    comp_ellint_1(_Tp __k)
175    {
176      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
177      return __detail::__comp_ellint_1<__type>(__k);
178    }
179
180  inline float
181  comp_ellint_2f(float __k)
182  { return __detail::__comp_ellint_2<float>(__k); }
183
184  inline long double
185  comp_ellint_2l(long double __k)
186  { return __detail::__comp_ellint_2<long double>(__k); }
187
188  ///  5.2.1.5  Complete elliptic integrals of the second kind.
189  template<typename _Tp>
190    inline typename __gnu_cxx::__promote<_Tp>::__type
191    comp_ellint_2(_Tp __k)
192    {
193      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
194      return __detail::__comp_ellint_2<__type>(__k);
195    }
196
197  inline float
198  comp_ellint_3f(float __k, float __nu)
199  { return __detail::__comp_ellint_3<float>(__k, __nu); }
200
201  inline long double
202  comp_ellint_3l(long double __k, long double __nu)
203  { return __detail::__comp_ellint_3<long double>(__k, __nu); }
204
205  ///  5.2.1.6  Complete elliptic integrals of the third kind.
206  template<typename _Tp, typename _Tpn>
207    inline typename __gnu_cxx::__promote_2<_Tp, _Tpn>::__type
208    comp_ellint_3(_Tp __k, _Tpn __nu)
209    {
210      typedef typename __gnu_cxx::__promote_2<_Tp, _Tpn>::__type __type;
211      return __detail::__comp_ellint_3<__type>(__k, __nu);
212    }
213
214  inline float
215  conf_hypergf(float __a, float __c, float __x)
216  { return __detail::__conf_hyperg<float>(__a, __c, __x); }
217
218  inline long double
219  conf_hypergl(long double __a, long double __c, long double __x)
220  { return __detail::__conf_hyperg<long double>(__a, __c, __x); }
221
222  ///  5.2.1.7  Confluent hypergeometric functions.
223  template<typename _Tpa, typename _Tpc, typename _Tp>
224    inline typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type
225    conf_hyperg(_Tpa __a, _Tpc __c, _Tp __x)
226    {
227      typedef typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type __type;
228      return __detail::__conf_hyperg<__type>(__a, __c, __x);
229    }
230
231  inline float
232  cyl_bessel_if(float __nu, float __x)
233  { return __detail::__cyl_bessel_i<float>(__nu, __x); }
234
235  inline long double
236  cyl_bessel_il(long double __nu, long double __x)
237  { return __detail::__cyl_bessel_i<long double>(__nu, __x); }
238
239  ///  5.2.1.8  Regular modified cylindrical Bessel functions.
240  template<typename _Tpnu, typename _Tp>
241    inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type
242    cyl_bessel_i(_Tpnu __nu, _Tp __x)
243    {
244      typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type;
245      return __detail::__cyl_bessel_i<__type>(__nu, __x);
246    }
247
248  inline float
249  cyl_bessel_jf(float __nu, float __x)
250  { return __detail::__cyl_bessel_j<float>(__nu, __x); }
251
252  inline long double
253  cyl_bessel_jl(long double __nu, long double __x)
254  { return __detail::__cyl_bessel_j<long double>(__nu, __x); }
255
256  ///  5.2.1.9  Cylindrical Bessel functions (of the first kind).
257  template<typename _Tpnu, typename _Tp>
258    inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type
259    cyl_bessel_j(_Tpnu __nu, _Tp __x)
260    {
261      typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type;
262      return __detail::__cyl_bessel_j<__type>(__nu, __x);
263    }
264
265  inline float
266  cyl_bessel_kf(float __nu, float __x)
267  { return __detail::__cyl_bessel_k<float>(__nu, __x); }
268
269  inline long double
270  cyl_bessel_kl(long double __nu, long double __x)
271  { return __detail::__cyl_bessel_k<long double>(__nu, __x); }
272
273  ///  5.2.1.10  Irregular modified cylindrical Bessel functions.
274  template<typename _Tpnu, typename _Tp>
275    inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type
276    cyl_bessel_k(_Tpnu __nu, _Tp __x)
277    {
278      typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type;
279      return __detail::__cyl_bessel_k<__type>(__nu, __x);
280    }
281
282  inline float
283  cyl_neumannf(float __nu, float __x)
284  { return __detail::__cyl_neumann_n<float>(__nu, __x); }
285
286  inline long double
287  cyl_neumannl(long double __nu, long double __x)
288  { return __detail::__cyl_neumann_n<long double>(__nu, __x); }
289
290  ///  5.2.1.11  Cylindrical Neumann functions.
291  template<typename _Tpnu, typename _Tp>
292    inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type
293    cyl_neumann(_Tpnu __nu, _Tp __x)
294    {
295      typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type;
296      return __detail::__cyl_neumann_n<__type>(__nu, __x);
297    }
298
299  inline float
300  ellint_1f(float __k, float __phi)
301  { return __detail::__ellint_1<float>(__k, __phi); }
302
303  inline long double
304  ellint_1l(long double __k, long double __phi)
305  { return __detail::__ellint_1<long double>(__k, __phi); }
306
307  ///  5.2.1.12  Incomplete elliptic integrals of the first kind.
308  template<typename _Tp, typename _Tpp>
309    inline typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type
310    ellint_1(_Tp __k, _Tpp __phi)
311    {
312      typedef typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type __type;
313      return __detail::__ellint_1<__type>(__k, __phi);
314    }
315
316  inline float
317  ellint_2f(float __k, float __phi)
318  { return __detail::__ellint_2<float>(__k, __phi); }
319
320  inline long double
321  ellint_2l(long double __k, long double __phi)
322  { return __detail::__ellint_2<long double>(__k, __phi); }
323
324  ///  5.2.1.13  Incomplete elliptic integrals of the second kind.
325  template<typename _Tp, typename _Tpp>
326    inline typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type
327    ellint_2(_Tp __k, _Tpp __phi)
328    {
329      typedef typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type __type;
330      return __detail::__ellint_2<__type>(__k, __phi);
331    }
332
333  inline float
334  ellint_3f(float __k, float __nu, float __phi)
335  { return __detail::__ellint_3<float>(__k, __nu, __phi); }
336
337  inline long double
338  ellint_3l(long double __k, long double __nu, long double __phi)
339  { return __detail::__ellint_3<long double>(__k, __nu, __phi); }
340
341  ///  5.2.1.14  Incomplete elliptic integrals of the third kind.
342  template<typename _Tp, typename _Tpn, typename _Tpp>
343    inline typename __gnu_cxx::__promote_3<_Tp, _Tpn, _Tpp>::__type
344    ellint_3(_Tp __k, _Tpn __nu, _Tpp __phi)
345    {
346      typedef typename __gnu_cxx::__promote_3<_Tp, _Tpn, _Tpp>::__type __type;
347      return __detail::__ellint_3<__type>(__k, __nu, __phi);
348    }
349
350  inline float
351  expintf(float __x)
352  { return __detail::__expint<float>(__x); }
353
354  inline long double
355  expintl(long double __x)
356  { return __detail::__expint<long double>(__x); }
357
358  ///  5.2.1.15  Exponential integrals.
359  template<typename _Tp>
360    inline typename __gnu_cxx::__promote<_Tp>::__type
361    expint(_Tp __x)
362    {
363      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
364      return __detail::__expint<__type>(__x);
365    }
366
367  inline float
368  hermitef(unsigned int __n, float __x)
369  { return __detail::__poly_hermite<float>(__n, __x); }
370
371  inline long double
372  hermitel(unsigned int __n, long double __x)
373  { return __detail::__poly_hermite<long double>(__n, __x); }
374
375  ///  5.2.1.16  Hermite polynomials.
376  template<typename _Tp>
377    inline typename __gnu_cxx::__promote<_Tp>::__type
378    hermite(unsigned int __n, _Tp __x)
379    {
380      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
381      return __detail::__poly_hermite<__type>(__n, __x);
382    }
383
384  inline float
385  hypergf(float __a, float __b, float __c, float __x)
386  { return __detail::__hyperg<float>(__a, __b, __c, __x); }
387
388  inline long double
389  hypergl(long double __a, long double __b, long double __c, long double __x)
390  { return __detail::__hyperg<long double>(__a, __b, __c, __x); }
391
392  ///  5.2.1.17  Hypergeometric functions.
393  template<typename _Tpa, typename _Tpb, typename _Tpc, typename _Tp>
394    inline typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type
395    hyperg(_Tpa __a, _Tpb __b, _Tpc __c, _Tp __x)
396    {
397      typedef typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type __type;
398      return __detail::__hyperg<__type>(__a, __b, __c, __x);
399    }
400
401  inline float
402  laguerref(unsigned int __n, float __x)
403  { return __detail::__laguerre<float>(__n, __x); }
404
405  inline long double
406  laguerrel(unsigned int __n, long double __x)
407  { return __detail::__laguerre<long double>(__n, __x); }
408
409  ///  5.2.1.18  Laguerre polynomials.
410  template<typename _Tp>
411    inline typename __gnu_cxx::__promote<_Tp>::__type
412    laguerre(unsigned int __n, _Tp __x)
413    {
414      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
415      return __detail::__laguerre<__type>(__n, __x);
416    }
417
418  inline float
419  legendref(unsigned int __n, float __x)
420  { return __detail::__poly_legendre_p<float>(__n, __x); }
421
422  inline long double
423  legendrel(unsigned int __n, long double __x)
424  { return __detail::__poly_legendre_p<long double>(__n, __x); }
425
426  ///  5.2.1.19  Legendre polynomials.
427  template<typename _Tp>
428    inline typename __gnu_cxx::__promote<_Tp>::__type
429    legendre(unsigned int __n, _Tp __x)
430    {
431      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
432      return __detail::__poly_legendre_p<__type>(__n, __x);
433    }
434
435  inline float
436  riemann_zetaf(float __x)
437  { return __detail::__riemann_zeta<float>(__x); }
438
439  inline long double
440  riemann_zetal(long double __x)
441  { return __detail::__riemann_zeta<long double>(__x); }
442
443  ///  5.2.1.20  Riemann zeta function.
444  template<typename _Tp>
445    inline typename __gnu_cxx::__promote<_Tp>::__type
446    riemann_zeta(_Tp __x)
447    {
448      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
449      return __detail::__riemann_zeta<__type>(__x);
450    }
451
452  inline float
453  sph_besself(unsigned int __n, float __x)
454  { return __detail::__sph_bessel<float>(__n, __x); }
455
456  inline long double
457  sph_bessell(unsigned int __n, long double __x)
458  { return __detail::__sph_bessel<long double>(__n, __x); }
459
460  ///  5.2.1.21  Spherical Bessel functions.
461  template<typename _Tp>
462    inline typename __gnu_cxx::__promote<_Tp>::__type
463    sph_bessel(unsigned int __n, _Tp __x)
464    {
465      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
466      return __detail::__sph_bessel<__type>(__n, __x);
467    }
468
469  inline float
470  sph_legendref(unsigned int __l, unsigned int __m, float __theta)
471  { return __detail::__sph_legendre<float>(__l, __m, __theta); }
472
473  inline long double
474  sph_legendrel(unsigned int __l, unsigned int __m, long double __theta)
475  { return __detail::__sph_legendre<long double>(__l, __m, __theta); }
476
477  ///  5.2.1.22  Spherical associated Legendre functions.
478  template<typename _Tp>
479    inline typename __gnu_cxx::__promote<_Tp>::__type
480    sph_legendre(unsigned int __l, unsigned int __m, _Tp __theta)
481    {
482      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
483      return __detail::__sph_legendre<__type>(__l, __m, __theta);
484    }
485
486  inline float
487  sph_neumannf(unsigned int __n, float __x)
488  { return __detail::__sph_neumann<float>(__n, __x); }
489
490  inline long double
491  sph_neumannl(unsigned int __n, long double __x)
492  { return __detail::__sph_neumann<long double>(__n, __x); }
493
494  ///  5.2.1.23  Spherical Neumann functions.
495  template<typename _Tp>
496    inline typename __gnu_cxx::__promote<_Tp>::__type
497    sph_neumann(unsigned int __n, _Tp __x)
498    {
499      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
500      return __detail::__sph_neumann<__type>(__n, __x);
501    }
502
503  /* @} */ // tr1_math_spec_func
504}
505}
506
507#endif // _GLIBCXX_TR1_CMATH
508