TR1 Special Math

Ed Smith-Rowland 3dw4rd@verizon.net
Sat Nov 14 20:30:00 GMT 2015


On 11/13/2015 11:20 AM, Ed Smith-Rowland wrote:
> On 11/13/2015 10:32 AM, Jonathan Wakely wrote:
>> On 25 October 2015 at 20:48, Jonathan Wakely <jwakely.gcc@gmail.com> 
>> wrote:
>>> On 25 October 2015 at 17:46, Ed Smith-Rowland <3dw4rd@verizon.net> 
>>> wrote:
>>>> On 10/24/2015 11:38 PM, Jonathan Wakely wrote:
>>>>> On 8 May 2015 at 15:05, Ed Smith-Rowland <3dw4rd@verizon.net> wrote:
>>>>>> On 05/07/2015 12:06 PM, Jonathan Wakely wrote:
>>>>>>> Hi Ed,
>>>>>>>
>>>>>>> The C++ committee is considering the
>>>>>>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4437.pdf
>>>>>>> proposal to make C++17 include the contents of ISO 29124:2010 (the
>>>>>>> special math functions from TR1 that went into a separate standard,
>>>>>>> not into C++11).
>>>>>>>
>>>>>>> What is the status of our TR1 implementation? Is it complete? Good
>>>>>>> enough quality to move out of the tr1 sub-dir?
>>>>>>>
>>>>>>> Even if N4437 isn't accepted for C++17 we could move things 
>>>>>>> around to
>>>>>>> turn the TR1 code into an iso29124 implementation, do you think 
>>>>>>> that
>>>>>>> would make sense?
>>>>>>>
>>>>>> That would make absolute sense.
>>>>>> I actually have a tree where I've done that.
>>>>>> All the functions are in there (29124 removed the hypergeometric
>>>>>> functions.
>>>>>> I'd like to keep those as extensions.
>>>>>> I have some bugfixes also.
>>>>>>
>>>>>> I have a better version of the Carlson elliptic functions (which 
>>>>>> are used
>>>>>> in
>>>>>> the 29124 elliptic functions).
>>>>>>
>>>>>> Ed
>>>>>>
>>>>> Hi Ed, Florian,
>>>>>
>>>>> Here's a patch to re-use the TR1 math functions to implement IS 
>>>>> 29124,
>>>>> what do you think of this approach? Ed, were you just going to copy
>>>>> the files and have duplicated code?
>>>>>
>>>>> We should probably uglify the names of the hypergeometric 
>>>>> functions if
>>>>> they are not in the final standard.
>>>>>
>>>>> This doesn't include Florian's patch, which should be applied.
>>>>>
>>>>> (I want to get this done before stage 1 ends in a couple of weeks, so
>>>>> am posting this for review now, but I'll be unavailable for the next
>>>>> week or two and might not be able to actually commit anything until
>>>>> stage 3).
>>>> Hi all!
>>>>
>>>> I am actually very aware of the stage 1 deadline and am working 
>>>> furiously!
>>>>
>>>> This patch adds the hypergeometric and confluent hypergeometric 
>>>> functions
>>>> that were actually stricken fromTR29124.
>>>> I actually had a mind to add those back especially since the 
>>>> confluent one
>>>> is actually pretty stable in it's realm and is used in some statistics
>>>> tests.
>>>> I expect that some people have ventures to use both and so TR29129 
>>>> would not
>>>> be a full replacement for TR1 without them.
>>>>
>>>> I intend to post within the next few days.  I have to realize that 
>>>> some of
>>>> my hopes and dreams would be better done with these in tree! ;-)
>>>>
>>>> Thank you for lighting a fire Jonathan!
>>> Excellent, glad to hear you're on this, as you know the code and the
>>> specs, whereas I'm poking around blindly :-)
>> Hi Ed,
>>
>> Have you been able to find enough time to work on this?
>>
>> Will you be able to make the stage 1 deadline tomorrow, and if not, do
>> you think I should apply my patch to re-use the TR1 stuff?  (We can
>> apply Florian's bug fix to that as well).
>>
> I'm going to post something in a few hours.
>
>
OK,

this is still testing but I wanted to get it in under the deadline.
It is basically a combination of Jonathan's approach using TR1 (which I 
do for C++03)
Plus the start of a new impl in bits.
Plus patches from Florian.

Ed


-------------- next part --------------
Index: include/Makefile.in
===================================================================
--- include/Makefile.in	(revision 230377)
+++ include/Makefile.in	(working copy)
@@ -435,12 +435,31 @@
 	${bits_srcdir}/regex_compiler.tcc \
 	${bits_srcdir}/regex_executor.h \
 	${bits_srcdir}/regex_executor.tcc \
-	${bits_srcdir}/stream_iterator.h \
-	${bits_srcdir}/streambuf_iterator.h \
+	${bits_srcdir}/sf_bessel.tcc \
+	${bits_srcdir}/sf_beta.tcc \
+	${bits_srcdir}/sf_chebyshev.tcc \
+	${bits_srcdir}/sf_dawson.tcc \
+	${bits_srcdir}/sf_ellint.tcc \
+	${bits_srcdir}/sf_expint.tcc \
+	${bits_srcdir}/sf_fresnel.tcc \
+	${bits_srcdir}/sf_gamma.tcc \
+	${bits_srcdir}/sf_gegenbauer.tcc \
+	${bits_srcdir}/sf_hermite.tcc \
+	${bits_srcdir}/sf_hyperg.tcc \
+	${bits_srcdir}/sf_hypint.tcc \
+	${bits_srcdir}/sf_jacobi.tcc \
+	${bits_srcdir}/sf_laguerre.tcc \
+	${bits_srcdir}/sf_legendre.tcc \
+	${bits_srcdir}/sf_mod_bessel.tcc \
+	${bits_srcdir}/sf_theta.tcc \
+	${bits_srcdir}/sf_trigint.tcc \
+	${bits_srcdir}/sf_zeta.tcc \
 	${bits_srcdir}/shared_ptr.h \
 	${bits_srcdir}/shared_ptr_atomic.h \
 	${bits_srcdir}/shared_ptr_base.h \
 	${bits_srcdir}/slice_array.h \
+	${bits_srcdir}/specfun.h \
+	${bits_srcdir}/specfun_util.h \
 	${bits_srcdir}/sstream.tcc \
 	${bits_srcdir}/stl_algo.h \
 	${bits_srcdir}/stl_algobase.h \
@@ -467,6 +486,8 @@
 	${bits_srcdir}/stl_tree.h \
 	${bits_srcdir}/stl_uninitialized.h \
 	${bits_srcdir}/stl_vector.h \
+	${bits_srcdir}/stream_iterator.h \
+	${bits_srcdir}/streambuf_iterator.h \
 	${bits_srcdir}/streambuf.tcc \
 	${bits_srcdir}/stringfwd.h \
 	${bits_srcdir}/unique_ptr.h \
@@ -879,9 +900,9 @@
 	${tr1_srcdir}/functional \
 	${tr1_srcdir}/functional_hash.h \
 	${tr1_srcdir}/gamma.tcc \
-	${tr1_srcdir}/hypergeometric.tcc \
 	${tr1_srcdir}/hashtable.h \
 	${tr1_srcdir}/hashtable_policy.h \
+	${tr1_srcdir}/hypergeometric.tcc \
 	${tr1_srcdir}/inttypes.h \
 	${tr1_srcdir}/limits.h \
 	${tr1_srcdir}/math.h \
Index: include/Makefile.am
===================================================================
--- include/Makefile.am	(revision 230377)
+++ include/Makefile.am	(working copy)
@@ -145,12 +145,31 @@
 	${bits_srcdir}/regex_compiler.tcc \
 	${bits_srcdir}/regex_executor.h \
 	${bits_srcdir}/regex_executor.tcc \
-	${bits_srcdir}/stream_iterator.h \
-	${bits_srcdir}/streambuf_iterator.h \
+	${bits_srcdir}/sf_bessel.tcc \
+	${bits_srcdir}/sf_beta.tcc \
+	${bits_srcdir}/sf_chebyshev.tcc \
+	${bits_srcdir}/sf_dawson.tcc \
+	${bits_srcdir}/sf_ellint.tcc \
+	${bits_srcdir}/sf_expint.tcc \
+	${bits_srcdir}/sf_fresnel.tcc \
+	${bits_srcdir}/sf_gamma.tcc \
+	${bits_srcdir}/sf_gegenbauer.tcc \
+	${bits_srcdir}/sf_hermite.tcc \
+	${bits_srcdir}/sf_hyperg.tcc \
+	${bits_srcdir}/sf_hypint.tcc \
+	${bits_srcdir}/sf_jacobi.tcc \
+	${bits_srcdir}/sf_laguerre.tcc \
+	${bits_srcdir}/sf_legendre.tcc \
+	${bits_srcdir}/sf_mod_bessel.tcc \
+	${bits_srcdir}/sf_theta.tcc \
+	${bits_srcdir}/sf_trigint.tcc \
+	${bits_srcdir}/sf_zeta.tcc \
 	${bits_srcdir}/shared_ptr.h \
 	${bits_srcdir}/shared_ptr_atomic.h \
 	${bits_srcdir}/shared_ptr_base.h \
 	${bits_srcdir}/slice_array.h \
+	${bits_srcdir}/specfun.h \
+	${bits_srcdir}/specfun_util.h \
 	${bits_srcdir}/sstream.tcc \
 	${bits_srcdir}/stl_algo.h \
 	${bits_srcdir}/stl_algobase.h \
@@ -177,6 +196,8 @@
 	${bits_srcdir}/stl_tree.h \
 	${bits_srcdir}/stl_uninitialized.h \
 	${bits_srcdir}/stl_vector.h \
+	${bits_srcdir}/stream_iterator.h \
+	${bits_srcdir}/streambuf_iterator.h \
 	${bits_srcdir}/streambuf.tcc \
 	${bits_srcdir}/stringfwd.h \
 	${bits_srcdir}/unique_ptr.h \
@@ -591,9 +612,9 @@
 	${tr1_srcdir}/functional \
 	${tr1_srcdir}/functional_hash.h \
 	${tr1_srcdir}/gamma.tcc \
-	${tr1_srcdir}/hypergeometric.tcc \
 	${tr1_srcdir}/hashtable.h \
 	${tr1_srcdir}/hashtable_policy.h \
+	${tr1_srcdir}/hypergeometric.tcc \
 	${tr1_srcdir}/inttypes.h \
 	${tr1_srcdir}/limits.h \
 	${tr1_srcdir}/math.h \
Index: include/bits/specfun.h
===================================================================
--- include/bits/specfun.h	(revision 0)
+++ include/bits/specfun.h	(working copy)
@@ -0,0 +1,1238 @@
+// math special functions -*- C++ -*-
+
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/specfun.h
+ *  This is an internal header file, included by other library headers.
+ *  You should not attempt to use it directly.
+ */
+
+#ifndef _GLIBCXX_BITS_SPECFUN_H
+#define _GLIBCXX_BITS_SPECFUN_H 1
+
+#define __STDCPP_MATH_SPEC_FUNCS__ 201003L
+
+#pragma GCC visibility push(default)
+
+#include <bits/c++config.h>
+
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__ == 0
+# error include <cmath> and define __STDCPP_WANT_MATH_SPEC_FUNCS__
+#endif
+
+#pragma GCC system_header
+
+#include <bits/stl_algobase.h>
+#include <limits>
+
+#if __cplusplus >= 201103L
+#  include <complex>
+#  include <type_traits>
+#  include <bits/sf_gamma.tcc>
+#  include <bits/sf_bessel.tcc>
+#  include <bits/sf_beta.tcc>
+#  include <bits/sf_chebyshev.tcc>
+#  include <bits/sf_dawson.tcc>
+#  include <bits/sf_ellint.tcc>
+#  include <bits/sf_expint.tcc>
+#  include <bits/sf_fresnel.tcc>
+#  include <bits/sf_gegenbauer.tcc>
+#  include <bits/sf_hermite.tcc>
+#  include <bits/sf_hyperg.tcc>
+#  include <bits/sf_hypint.tcc>
+#  include <bits/sf_jacobi.tcc>
+#  include <bits/sf_laguerre.tcc>
+#  include <bits/sf_legendre.tcc>
+#  include <bits/sf_mod_bessel.tcc>
+#  include <bits/sf_theta.tcc>
+#  include <bits/sf_trigint.tcc>
+#  include <bits/sf_zeta.tcc>
+#else
+#  include <tr1/type_traits>
+#  include <tr1/cmath>
+#  define _GLIBCXX_MATH_NS ::std::tr1::
+#  include <tr1/gamma.tcc>
+#  include <tr1/bessel_function.tcc>
+#  include <tr1/beta_function.tcc>
+#  include <tr1/ell_integral.tcc>
+#  include <tr1/exp_integral.tcc>
+#  include <tr1/hypergeometric.tcc>
+#  include <tr1/legendre_function.tcc>
+#  include <tr1/modified_bessel_func.tcc>
+#  include <tr1/poly_hermite.tcc>
+#  include <tr1/poly_laguerre.tcc>
+#  include <tr1/riemann_zeta.tcc>
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   * @defgroup tr29124_math_spec_func Mathematical Special Functions
+   * @ingroup numerics
+   *
+   * A collection of advanced mathematical special functions.
+   * @{
+   */
+
+  //  Associated Laguerre polynomials
+
+  inline float
+  assoc_laguerref(unsigned int __n, unsigned int __m, float __x)
+  { return __detail::__assoc_laguerre<float>(__n, __m, __x); }
+
+  inline long double
+  assoc_laguerrel(unsigned int __n, unsigned int __m, long double __x)
+  { return __detail::__assoc_laguerre<long double>(__n, __m, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    assoc_laguerre(unsigned int __n, unsigned int __m, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__assoc_laguerre<__type>(__n, __m, __x);
+    }
+
+  //  Associated Legendre functions
+
+  inline float
+  assoc_legendref(unsigned int __l, unsigned int __m, float __x)
+  { return __detail::__assoc_legendre_p<float>(__l, __m, __x); }
+
+  inline long double
+  assoc_legendrel(unsigned int __l, unsigned int __m, long double __x)
+  { return __detail::__assoc_legendre_p<long double>(__l, __m, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    assoc_legendre(unsigned int __l, unsigned int __m, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__assoc_legendre_p<__type>(__l, __m, __x);
+    }
+
+  //  Beta functions
+
+  inline float
+  betaf(float __x, float __y)
+  { return __detail::__beta<float>(__x, __y); }
+
+  inline long double
+  betal(long double __x, long double __y)
+  { return __detail::__beta<long double>(__x, __y); }
+
+  template<typename _Tpx, typename _Tpy>
+    inline typename __gnu_cxx::__promote_2<_Tpx, _Tpy>::__type
+    beta(_Tpx __x, _Tpy __y)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tpx, _Tpy>::__type __type;
+      return __detail::__beta<__type>(__x, __y);
+    }
+
+  //  Complete elliptic integrals of the first kind
+
+  inline float
+  comp_ellint_1f(float __k)
+  { return __detail::__comp_ellint_1<float>(__k); }
+
+  inline long double
+  comp_ellint_1l(long double __k)
+  { return __detail::__comp_ellint_1<long double>(__k); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    comp_ellint_1(_Tp __k)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__comp_ellint_1<__type>(__k);
+    }
+
+  //  Complete elliptic integrals of the second kind
+
+  inline float
+  comp_ellint_2f(float __k)
+  { return __detail::__comp_ellint_2<float>(__k); }
+
+  inline long double
+  comp_ellint_2l(long double __k)
+  { return __detail::__comp_ellint_2<long double>(__k); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    comp_ellint_2(_Tp __k)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__comp_ellint_2<__type>(__k);
+    }
+
+  //  Complete elliptic integrals of the third kind
+
+  inline float
+  comp_ellint_3f(float __k, float __nu)
+  { return __detail::__comp_ellint_3<float>(__k, __nu); }
+
+  inline long double
+  comp_ellint_3l(long double __k, long double __nu)
+  { return __detail::__comp_ellint_3<long double>(__k, __nu); }
+
+  template<typename _Tp, typename _Tpn>
+    inline typename __gnu_cxx::__promote_2<_Tp, _Tpn>::__type
+    comp_ellint_3(_Tp __k, _Tpn __nu)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tp, _Tpn>::__type __type;
+      return __detail::__comp_ellint_3<__type>(__k, __nu);
+    }
+
+  //  Regular modified cylindrical Bessel functions
+
+  inline float
+  cyl_bessel_if(float __nu, float __x)
+  { return __detail::__cyl_bessel_i<float>(__nu, __x); }
+
+  inline long double
+  cyl_bessel_il(long double __nu, long double __x)
+  { return __detail::__cyl_bessel_i<long double>(__nu, __x); }
+
+  template<typename _Tpnu, typename _Tp>
+    inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type
+    cyl_bessel_i(_Tpnu __nu, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type;
+      return __detail::__cyl_bessel_i<__type>(__nu, __x);
+    }
+
+  //  Cylindrical Bessel functions (of the first kind)
+
+  inline float
+  cyl_bessel_jf(float __nu, float __x)
+  { return __detail::__cyl_bessel_j<float>(__nu, __x); }
+
+  inline long double
+  cyl_bessel_jl(long double __nu, long double __x)
+  { return __detail::__cyl_bessel_j<long double>(__nu, __x); }
+
+  template<typename _Tpnu, typename _Tp>
+    inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type
+    cyl_bessel_j(_Tpnu __nu, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type;
+      return __detail::__cyl_bessel_j<__type>(__nu, __x);
+    }
+
+  //  Irregular modified cylindrical Bessel functions
+
+  inline float
+  cyl_bessel_kf(float __nu, float __x)
+  { return __detail::__cyl_bessel_k<float>(__nu, __x); }
+
+  inline long double
+  cyl_bessel_kl(long double __nu, long double __x)
+  { return __detail::__cyl_bessel_k<long double>(__nu, __x); }
+
+  template<typename _Tpnu, typename _Tp>
+    inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type
+    cyl_bessel_k(_Tpnu __nu, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type;
+      return __detail::__cyl_bessel_k<__type>(__nu, __x);
+    }
+
+  //  Cylindrical Neumann functions
+
+  inline float
+  cyl_neumannf(float __nu, float __x)
+  { return __detail::__cyl_neumann_n<float>(__nu, __x); }
+
+  inline long double
+  cyl_neumannl(long double __nu, long double __x)
+  { return __detail::__cyl_neumann_n<long double>(__nu, __x); }
+
+  template<typename _Tpnu, typename _Tp>
+    inline typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type
+    cyl_neumann(_Tpnu __nu, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type __type;
+      return __detail::__cyl_neumann_n<__type>(__nu, __x);
+    }
+
+  //  Incomplete elliptic integrals of the first kind
+
+  inline float
+  ellint_1f(float __k, float __phi)
+  { return __detail::__ellint_1<float>(__k, __phi); }
+
+  inline long double
+  ellint_1l(long double __k, long double __phi)
+  { return __detail::__ellint_1<long double>(__k, __phi); }
+
+  template<typename _Tp, typename _Tpp>
+    inline typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type
+    ellint_1(_Tp __k, _Tpp __phi)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type __type;
+      return __detail::__ellint_1<__type>(__k, __phi);
+    }
+
+  //  Incomplete elliptic integrals of the second kind
+
+  inline float
+  ellint_2f(float __k, float __phi)
+  { return __detail::__ellint_2<float>(__k, __phi); }
+
+  inline long double
+  ellint_2l(long double __k, long double __phi)
+  { return __detail::__ellint_2<long double>(__k, __phi); }
+
+  template<typename _Tp, typename _Tpp>
+    inline typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type
+    ellint_2(_Tp __k, _Tpp __phi)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tp, _Tpp>::__type __type;
+      return __detail::__ellint_2<__type>(__k, __phi);
+    }
+
+  //  Incomplete elliptic integrals of the third kind
+
+  inline float
+  ellint_3f(float __k, float __nu, float __phi)
+  { return __detail::__ellint_3<float>(__k, __nu, __phi); }
+
+  inline long double
+  ellint_3l(long double __k, long double __nu, long double __phi)
+  { return __detail::__ellint_3<long double>(__k, __nu, __phi); }
+
+  template<typename _Tp, typename _Tpn, typename _Tpp>
+    inline typename __gnu_cxx::__promote_3<_Tp, _Tpn, _Tpp>::__type
+    ellint_3(_Tp __k, _Tpn __nu, _Tpp __phi)
+    {
+      typedef typename __gnu_cxx::__promote_3<_Tp, _Tpn, _Tpp>::__type __type;
+      return __detail::__ellint_3<__type>(__k, __nu, __phi);
+    }
+
+  //  Exponential integrals
+
+  inline float
+  expintf(float __x)
+  { return __detail::__expint<float>(__x); }
+
+  inline long double
+  expintl(long double __x)
+  { return __detail::__expint<long double>(__x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    expint(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__expint<__type>(__x);
+    }
+
+  //  Hermite polynomials
+
+  inline float
+  hermitef(unsigned int __n, float __x)
+  { return __detail::__poly_hermite<float>(__n, __x); }
+
+  inline long double
+  hermitel(unsigned int __n, long double __x)
+  { return __detail::__poly_hermite<long double>(__n, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    hermite(unsigned int __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__poly_hermite<__type>(__n, __x);
+    }
+
+  //  Laguerre polynomials
+
+  inline float
+  laguerref(unsigned int __n, float __x)
+  { return __detail::__laguerre<float>(__n, __x); }
+
+  inline long double
+  laguerrel(unsigned int __n, long double __x)
+  { return __detail::__laguerre<long double>(__n, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    laguerre(unsigned int __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__laguerre<__type>(__n, __x);
+    }
+
+  //  Legendre polynomials
+
+  inline float
+  legendref(unsigned int __n, float __x)
+  { return __detail::__poly_legendre_p<float>(__n, __x); }
+
+  inline long double
+  legendrel(unsigned int __n, long double __x)
+  { return __detail::__poly_legendre_p<long double>(__n, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    legendre(unsigned int __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__poly_legendre_p<__type>(__n, __x);
+    }
+
+  //  Riemann zeta functions
+
+  inline float
+  riemann_zetaf(float __x)
+  { return __detail::__riemann_zeta<float>(__x); }
+
+  inline long double
+  riemann_zetal(long double __x)
+  { return __detail::__riemann_zeta<long double>(__x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    riemann_zeta(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__riemann_zeta<__type>(__x);
+    }
+
+  //  Spherical Bessel functions
+
+  inline float
+  sph_besself(unsigned int __n, float __x)
+  { return __detail::__sph_bessel<float>(__n, __x); }
+
+  inline long double
+  sph_bessell(unsigned int __n, long double __x)
+  { return __detail::__sph_bessel<long double>(__n, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    sph_bessel(unsigned int __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__sph_bessel<__type>(__n, __x);
+    }
+
+  //  Spherical associated Legendre functions
+
+  inline float
+  sph_legendref(unsigned int __l, unsigned int __m, float __theta)
+  { return __detail::__sph_legendre<float>(__l, __m, __theta); }
+
+  inline long double
+  sph_legendrel(unsigned int __l, unsigned int __m, long double __theta)
+  { return __detail::__sph_legendre<long double>(__l, __m, __theta); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    sph_legendre(unsigned int __l, unsigned int __m, _Tp __theta)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__sph_legendre<__type>(__l, __m, __theta);
+    }
+
+  //  Spherical Neumann functions
+
+  inline float
+  sph_neumannf(unsigned int __n, float __x)
+  { return __detail::__sph_neumann<float>(__n, __x); }
+
+  inline long double
+  sph_neumannl(unsigned int __n, long double __x)
+  { return __detail::__sph_neumann<long double>(__n, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    sph_neumann(unsigned int __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return __detail::__sph_neumann<__type>(__n, __x);
+    }
+
+  /* @} */ // tr29124_math_spec_func
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
+{
+
+  //  Confluent hypergeometric functions
+
+  inline float
+  conf_hypergf(float __a, float __c, float __x)
+  { return std::__detail::__conf_hyperg<float>(__a, __c, __x); }
+
+  inline long double
+  conf_hypergl(long double __a, long double __c, long double __x)
+  { return std::__detail::__conf_hyperg<long double>(__a, __c, __x); }
+
+  template<typename _Tpa, typename _Tpc, typename _Tp>
+    inline typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type
+    conf_hyperg(_Tpa __a, _Tpc __c, _Tp __x)
+    {
+      using __type = typename __gnu_cxx::__promote_3<_Tpa, _Tpc, _Tp>::__type;
+      return std::__detail::__conf_hyperg<__type>(__a, __c, __x);
+    }
+
+  //  Hypergeometric functions
+
+  inline float
+  hypergf(float __a, float __b, float __c, float __x)
+  { return std::__detail::__hyperg<float>(__a, __b, __c, __x); }
+
+  inline long double
+  hypergl(long double __a, long double __b, long double __c, long double __x)
+  { return std::__detail::__hyperg<long double>(__a, __b, __c, __x); }
+
+  template<typename _Tpa, typename _Tpb, typename _Tpc, typename _Tp>
+    inline typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type
+    hyperg(_Tpa __a, _Tpb __b, _Tpc __c, _Tp __x)
+    {
+      using __type = typename __gnu_cxx::__promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type;
+      return std::__detail::__hyperg<__type>(__a, __b, __c, __x);
+    }
+
+#if __cplusplus >= 201103L
+
+  // Sinus cardinal functions
+
+  inline float
+  sincf(float __x)
+  {
+    if (__isnan(__x))
+      return std::numeric_limits<float>::quiet_NaN();
+    else
+      return __x == 0.0F ? 1.0F : std::sin/*f*/(__x) / __x;
+  }
+
+  inline long double
+  sincl(long double __x)
+  {
+    if (__isnan(__x))
+      return std::numeric_limits<long double>::quiet_NaN();
+    else
+      return __x == 0.0L ? 1.0L : std::sin/*l*/(__x) / __x;
+  }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    sinc(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      if (__isnan(__x))
+        return std::numeric_limits<__type>::quiet_NaN();
+      else
+        return __type(__x) == __type(0)
+             ? __type(1)
+             : std::sin(__type(__x)) / __type(__x);
+    }
+
+  //  Logarithmic integrals
+
+  inline float
+  logintf(float __x)
+  { return std::__detail::__logint<float>(__x); }
+
+  inline long double
+  logintl(long double __x)
+  { return std::__detail::__logint<long double>(__x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    logint(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__logint<__type>(__x);
+    }
+
+  //  Sine integrals
+
+  inline float
+  sinintf(float __x)
+  { return std::__detail::__csint<float>(__x).second; }
+
+  inline long double
+  sinintl(long double __x)
+  { return std::__detail::__csint<long double>(__x).second; }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    sinint(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__csint<__type>(__x).second;
+    }
+
+  //  Cosine integrals
+
+  inline float
+  cosintf(float __x)
+  { return std::__detail::__csint<float>(__x).first; }
+
+  inline long double
+  cosintl(long double __x)
+  { return std::__detail::__csint<long double>(__x).first; }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    cosint(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__csint<__type>(__x).first;
+    }
+
+  //  Hyperbolic sine integrals
+
+  inline float
+  sinhintf(float __x)
+  { return std::__detail::__sinhint<float>(__x); }
+
+  inline long double
+  sinhintl(long double __x)
+  { return std::__detail::__sinhint<long double>(__x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    sinhint(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__sinhint<__type>(__x);
+    }
+
+  //  Hyperbolic cosine integrals
+
+  inline float
+  coshintf(float __x)
+  { return std::__detail::__coshint<float>(__x); }
+
+  inline long double
+  coshintl(long double __x)
+  { return std::__detail::__coshint<long double>(__x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    coshint(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__coshint<__type>(__x);
+    }
+
+  //  Chebyshev polynomials of the first kind
+
+  inline float
+  chebyshev_tf(unsigned int __n, float __x)
+  { return std::__detail::__chebyshev_t<float>(__n, __x); }
+
+  inline long double
+  chebyshev_tl(unsigned int __n, long double __x)
+  { return std::__detail::__chebyshev_t<long double>(__n, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    chebyshev_t(unsigned int __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__chebyshev_t<__type>(__n, __x);
+    }
+
+  //  Chebyshev polynomials of the second kind
+
+  inline float
+  chebyshev_uf(unsigned int __n, float __x)
+  { return std::__detail::__chebyshev_u<float>(__n, __x); }
+
+  inline long double
+  chebyshev_ul(unsigned int __n, long double __x)
+  { return std::__detail::__chebyshev_u<long double>(__n, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    chebyshev_u(unsigned int __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__chebyshev_u<__type>(__n, __x);
+    }
+
+  //  Chebyshev polynomials of the third kind
+
+  inline float
+  chebyshev_vf(unsigned int __n, float __x)
+  { return std::__detail::__chebyshev_v<float>(__n, __x); }
+
+  inline long double
+  chebyshev_vl(unsigned int __n, long double __x)
+  { return std::__detail::__chebyshev_v<long double>(__n, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    chebyshev_v(unsigned int __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__chebyshev_v<__type>(__n, __x);
+    }
+
+  //  Chebyshev polynomials of the fourth kind
+
+  inline float
+  chebyshev_wf(unsigned int __n, float __x)
+  { return std::__detail::__chebyshev_w<float>(__n, __x); }
+
+  inline long double
+  chebyshev_wl(unsigned int __n, long double __x)
+  { return std::__detail::__chebyshev_w<long double>(__n, __x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    chebyshev_w(unsigned int __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__chebyshev_w<__type>(__n, __x);
+    }
+
+  //  Jacobi polynomials
+
+  inline float
+  jacobif(unsigned __n, float __alpha, float __beta, float __x)
+  { return std::__detail::__poly_jacobi<float>(__n, __alpha, __beta, __x); }
+
+  inline long double
+  jacobil(unsigned __n, long double __alpha, long double __beta, long double __x)
+  { return std::__detail::__poly_jacobi<long double>(__n, __alpha, __beta, __x); }
+
+  template<typename _Talpha, typename _Tbeta, typename _Tp>
+    inline typename __gnu_cxx::__promote_3<_Talpha, _Tbeta, _Tp>::__type
+    jacobi(unsigned __n, _Talpha __alpha, _Tbeta __beta, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote_3<_Talpha, _Tbeta, _Tp>::__type __type;
+      return std::__detail::__poly_jacobi<__type>(__n, __alpha, __beta, __x);
+    }
+
+  //  Gegenbauer polynomials
+
+  inline float
+  gegenbauerf(unsigned int __n, float __alpha, float __x)
+  { return std::__detail::__gegenbauer_poly<float>(__n, __alpha, __x); }
+
+  inline long double
+  gegenbauerl(unsigned int __n, long double __alpha, long double __x)
+  { return std::__detail::__gegenbauer_poly<long double>(__n, __alpha, __x); }
+
+  template<typename _Talpha, typename _Tp>
+    inline typename __gnu_cxx::__promote_2<_Talpha, _Tp>::__type
+    gegenbauer(unsigned int __n, _Talpha __alpha, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Talpha, _Tp>::__type __type;
+      return std::__detail::__gegenbauer_poly<__type>(__n, __alpha, __x);
+    }
+
+  //  Zernike polynomials
+
+  inline float
+  zernikef(unsigned int __n, int __m, float __rho, float __phi)
+  { return std::__detail::__poly_radial_jacobi(__n, std::abs(__m), __rho)
+         * (__m >= 0 ? std::cos(__m * __phi) : std::sin(__m * __phi)); }
+
+  inline long double
+  zernikel(unsigned int __n, int __m, long double __rho, long double __phi)
+  { return std::__detail::__poly_radial_jacobi(__n, std::abs(__m), __rho)
+         * (__m >= 0 ? std::cos(__m * __phi) : std::sin(__m * __phi)); }
+
+  template<typename _Trho, typename _Tphi>
+    inline typename __gnu_cxx::__promote_2<_Trho, _Tphi>::__type
+    zernike(unsigned int __n, int __m, _Trho __rho, _Tphi __phi)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Trho, _Tphi>::__type __type;
+      return std::__detail::__poly_radial_jacobi<__type>(__n, std::abs(__m), __rho)
+           * (__m >= 0 ? std::cos(__m * __phi) : std::sin(__m * __phi));
+    }
+
+  //  Radial polynomials
+
+  inline float
+  radpolyf(unsigned int __n, unsigned int __m, float __rho)
+  { return std::__detail::__poly_radial_jacobi(__n, __m, __rho); }
+
+  inline long double
+  radpolyl(unsigned int __n, unsigned int __m, long double __rho)
+  { return std::__detail::__poly_radial_jacobi(__n, __m, __rho); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    radpoly(unsigned int __n, unsigned int __m, double __rho)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__poly_radial_jacobi<__type>(__n, __m, __rho);
+    }
+
+  //  Hyperbolic sinus cardinal functions
+
+  inline float
+  sinhcf(float __x)
+  {
+    if (__isnan(__x))
+      return std::numeric_limits<float>::quiet_NaN();
+    else
+      return __x == 0.0F ? 1.0F : std::sinh/*f*/(__x) / __x;
+  }
+
+  inline long double
+  sinchl(long double __x)
+  {
+    if (__isnan(__x))
+      return std::numeric_limits<long double>::quiet_NaN();
+    else
+      return __x == 0.0L ? 1.0L : std::sinh/*l*/(__x) / __x;
+  }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    sinch(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      if (__isnan(__x))
+        return std::numeric_limits<__type>::quiet_NaN();
+      else
+        return __type(__x) == __type(0)
+             ? __type(1)
+             : std::sinh(__type(__x)) / __type(__x);
+    }
+
+  //  Dawson's integrals
+
+  inline float
+  dawsonintf(float __x)
+  { return std::__detail::__dawson<float>(__x); }
+
+  inline long double
+  dawsonintl(long double __x)
+  { return std::__detail::__dawson<long double>(__x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    dawsonint(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__dawson<__type>(__x);
+    }
+
+  //  Cylindrical Hankel functions of the first kind
+
+  inline std::complex<float>
+  cyl_hankel_h1f(float __nu, float __z)
+  { return std::__detail::__cyl_hankel_h1<float>(__nu, __z); }
+
+  inline std::complex<long double>
+  cyl_hankel_h1l(long double __nu, long double __z)
+  { return std::__detail::__cyl_hankel_h1<long double>(__nu, __z); }
+
+  template<typename _Tpnu, typename _Tp>
+    inline std::complex<typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type>
+    cyl_hankel_h1(_Tpnu __nu, _Tp __z)
+    {
+      using __type = typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type;
+      return std::__detail::__cyl_hankel_h1<__type>(__nu, __z);
+    }
+
+  //  Cylindrical Hankel functions of the second kind
+
+  inline std::complex<float>
+  cyl_hankel_h2f(float __nu, float __z)
+  { return std::__detail::__cyl_hankel_h2<float>(__nu, __z); }
+
+  inline std::complex<long double>
+  cyl_hankel_h2l(long double __nu, long double __z)
+  { return std::__detail::__cyl_hankel_h2<long double>(__nu, __z); }
+
+  template<typename _Tpnu, typename _Tp>
+    inline std::complex<typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type>
+    cyl_hankel_h2(_Tpnu __nu, _Tp __z)
+    {
+      using __type = typename __gnu_cxx::__promote_2<_Tpnu, _Tp>::__type;
+      return std::__detail::__cyl_hankel_h2<__type>(__nu, __z);
+    }
+
+  //  Spherical Hankel functions of the first kind
+
+  inline std::complex<float>
+  sph_hankel_h1f(unsigned int __n, float __z)
+  { return std::__detail::__sph_hankel_h1<float>(__n, __z); }
+
+  inline std::complex<long double>
+  sph_hankel_h1l(unsigned int __n, long double __z)
+  { return std::__detail::__sph_hankel_h1<long double>(__n, __z); }
+
+  template<typename _Tp>
+    inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
+    sph_hankel_h1(unsigned int __n, _Tp __z)
+    {
+      using __type = typename __gnu_cxx::__promote<_Tp>::__type;
+      return std::__detail::__sph_hankel_h1<__type>(__n, __z);
+    }
+
+  //  Spherical Hankel functions of the second kind
+
+  inline std::complex<float>
+  sph_hankel_h2f(unsigned int __n, float __z)
+  { return std::__detail::__sph_hankel_h2<float>(__n, __z); }
+
+  inline std::complex<long double>
+  sph_hankel_h2l(unsigned int __n, long double __z)
+  { return std::__detail::__sph_hankel_h2<long double>(__n, __z); }
+
+  template<typename _Tp>
+    inline std::complex<typename __gnu_cxx::__promote<_Tp>::__type>
+    sph_hankel_h2(unsigned int __n, _Tp __z)
+    {
+      using __type = typename __gnu_cxx::__promote<_Tp>::__type;
+      return std::__detail::__sph_hankel_h2<__type>(__n, __z);
+    }
+
+  //  Modified spherical Bessel functions of the first kind
+
+  inline float
+  sph_bessel_if(unsigned int __n, float __x)
+  {
+    float __i_n, __k_n, __ip_n, __kp_n;
+    std::__detail::__sph_bessel_ik<float>(__n, __x,
+        			     __i_n, __k_n, __ip_n, __kp_n);
+    return __i_n;
+  }
+
+  inline long double
+  sph_bessel_il(unsigned int __n, long double __x)
+  {
+    long double __i_n, __k_n, __ip_n, __kp_n;
+    std::__detail::__sph_bessel_ik<long double>(__n, __x,
+        				__i_n, __k_n, __ip_n, __kp_n);
+    return __i_n;
+  }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    sph_bessel_i(unsigned int __n, double __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      __type __i_n, __k_n, __ip_n, __kp_n;
+      std::__detail::__sph_bessel_ik<__type>(__n, __x,
+        				__i_n, __k_n, __ip_n, __kp_n);
+      return __i_n;
+    }
+
+  //  Modified spherical Bessel functions of the second kind
+
+  inline float
+  sph_bessel_kf(unsigned int __n, float __x)
+  {
+    float __i_n, __k_n, __ip_n, __kp_n;
+    std::__detail::__sph_bessel_ik<float>(__n, __x,
+        			     __i_n, __k_n, __ip_n, __kp_n);
+    return __k_n;
+  }
+
+  inline long double
+  sph_bessel_kl(unsigned int __n, long double __x)
+  {
+    long double __i_n, __k_n, __ip_n, __kp_n;
+    std::__detail::__sph_bessel_ik<long double>(__n, __x,
+        				__i_n, __k_n, __ip_n, __kp_n);
+    return __k_n;
+  }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    sph_bessel_k(unsigned int __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      __type __i_n, __k_n, __ip_n, __kp_n;
+      std::__detail::__sph_bessel_ik<__type>(__n, __x,
+        				__i_n, __k_n, __ip_n, __kp_n);
+      return __k_n;
+    }
+
+  //  Airy functions of the first kind
+
+  inline float
+  airy_aif(float __x)
+  {
+    float __Ai, __Bi, __Aip, __Bip;
+    std::__detail::__airy<float>(__x, __Ai, __Bi, __Aip, __Bip);
+    return __Ai;
+  }
+
+  inline long double
+  airy_ail(long double __x)
+  {
+    long double __Ai, __Bi, __Aip, __Bip;
+    std::__detail::__airy<long double>(__x, __Ai, __Bi, __Aip, __Bip);
+    return __Ai;
+  }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    airy_ai(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      __type __Ai, __Bi, __Aip, __Bip;
+      std::__detail::__airy<__type>(__x, __Ai, __Bi, __Aip, __Bip);
+      return __Ai;
+    }
+
+  //  Airy functions of the second kind
+
+  inline float
+  airy_bif(float __x)
+  {
+    float __Ai, __Bi, __Aip, __Bip;
+    std::__detail::__airy<float>(__x, __Ai, __Bi, __Aip, __Bip);
+    return __Bi;
+  }
+
+  inline long double
+  airy_bil(long double __x)
+  {
+    long double __Ai, __Bi, __Aip, __Bip;
+    std::__detail::__airy<long double>(__x, __Ai, __Bi, __Aip, __Bip);
+    return __Bi;
+  }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    airy_bi(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      __type __Ai, __Bi, __Aip, __Bip;
+      std::__detail::__airy<__type>(__x, __Ai, __Bi, __Aip, __Bip);
+      return __Bi;
+    }
+
+  //  Upper incomplete gamma functions
+
+  inline float
+  gamma_uf(float __n, float __x)
+  { return std::__detail::__gamma_u<float>(__n, __x); }
+
+  inline long double
+  gamma_ul(long double __n, long double __x)
+  { return std::__detail::__gamma_u<long double>(__n, __x); }
+
+  template<typename _Tn, typename _Tp>
+    inline typename __gnu_cxx::__promote_2<_Tn, _Tp>::__type
+    gamma_u(_Tn __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tn, _Tp>::__type __type;
+      return std::__detail::__gamma_u<__type>(__n, __x);
+    }
+
+  //  Lower incomplete gamma functions
+
+  inline float
+  gamma_lf(float __n, float __x)
+  { return std::__detail::__gamma_l<float>(__n, __x); }
+
+  inline long double
+  gamma_ll(long double __n, long double __x)
+  { return std::__detail::__gamma_l<long double>(__n, __x); }
+
+  template<typename _Tn, typename _Tp>
+    inline typename __gnu_cxx::__promote_2<_Tn, _Tp>::__type
+    gamma_l(_Tn __n, _Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tn, _Tp>::__type __type;
+      return std::__detail::__gamma_l<__type>(__n, __x);
+    }
+
+  //  Digamma functions
+
+  inline float
+  digammaf(float __z)
+  { return std::__detail::__psi<float>(__z); }
+
+  inline long double
+  digammal(long double __z)
+  { return std::__detail::__psi<long double>(__z); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    digamma(_Tp __z)
+    {
+      using __type = typename __gnu_cxx::__promote<_Tp>::__type;
+      return std::__detail::__psi<__type>(__z);
+    }
+
+  //  Dilogarithm functions
+
+  inline float
+  dilogf(float __x)
+  { return std::__detail::__dilog<float>(__x); }
+
+  inline long double
+  dilogl(long double __x)
+  { return std::__detail::__dilog<long double>(__x); }
+
+  template<typename _Tp>
+    inline typename __gnu_cxx::__promote<_Tp>::__type
+    dilog(_Tp __x)
+    {
+      typedef typename __gnu_cxx::__promote<_Tp>::__type __type;
+      return std::__detail::__dilog<__type>(__x);
+    }
+
+  //  Complete Carlson elliptic R_F functions
+
+  inline float
+  comp_ellint_rf(float __x, float __y)
+  { return std::__detail::__comp_ellint_rf<float>(__x, __y); }
+
+  inline long double
+  comp_ellint_rf(long double __x, long double __y)
+  { return std::__detail::__comp_ellint_rf<long double>(__x, __y); }
+
+  template<typename _Tx, typename _Ty>
+    inline typename __gnu_cxx::__promote_2<_Tx, _Ty>::__type
+    comp_ellint_rf(_Tx __x, _Ty __y)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tx, _Ty>::__type __type;
+      return std::__detail::__comp_ellint_rf<__type>(__x, __y);
+    }
+
+  //  Carlson elliptic R_F functions
+
+  inline float
+  ellint_rff(float __x, float __y, float __z)
+  { return std::__detail::__ellint_rf<float>(__x, __y, __z); }
+
+  inline long double
+  ellint_rfl(long double __x, long double __y, long double __z)
+  { return std::__detail::__ellint_rf<long double>(__x, __y, __z); }
+
+  template<typename _Tp, typename _Up, typename _Vp>
+    inline typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type
+    ellint_rf(_Tp __x, _Up __y, _Vp __z)
+    {
+      typedef typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type __type;
+      return std::__detail::__ellint_rf<__type>(__x, __y, __z);
+    }
+
+  //  Carlson elliptic R_C functions
+
+  inline float
+  ellint_rcf(float __x, float __y)
+  { return std::__detail::__ellint_rc<float>(__x, __y); }
+
+  inline long double
+  ellint_rcl(long double __x, long double __y)
+  { return std::__detail::__ellint_rc<long double>(__x, __y); }
+
+  template<typename _Tp, typename _Up>
+    inline typename __gnu_cxx::__promote_2<_Tp, _Up>::__type
+    ellint_rc(_Tp __x, _Up __y)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tp, _Up>::__type __type;
+      return std::__detail::__ellint_rc<__type>(__x, __y);
+    }
+
+  //  Carlson elliptic R_J functions
+
+  inline float
+  ellint_rjf(float __x, float __y, float __z, float __p)
+  { return std::__detail::__ellint_rj<float>(__x, __y, __z, __p); }
+
+  inline long double
+  ellint_rjl(long double __x, long double __y, long double __z, long double __p)
+  { return std::__detail::__ellint_rj<long double>(__x, __y, __z, __p); }
+
+  template<typename _Tp, typename _Up, typename _Vp, typename _Wp>
+    inline typename __gnu_cxx::__promote_4<_Tp, _Up, _Vp, _Wp>::__type
+    ellint_rj(_Tp __x, _Up __y, _Vp __z, _Wp __p)
+    {
+      typedef typename __gnu_cxx::__promote_4<_Tp, _Up, _Vp, _Wp>::__type __type;
+      return std::__detail::__ellint_rj<__type>(__x, __y, __z, __p);
+    }
+
+  //  Carlson elliptic R_D functions
+
+  inline float
+  ellint_rdf(float __x, float __y, float __z)
+  { return std::__detail::__ellint_rd<float>(__x, __y, __z); }
+
+  inline long double
+  ellint_rdl(long double __x, long double __y, long double __z)
+  { return std::__detail::__ellint_rd<long double>(__x, __y, __z); }
+
+  template<typename _Tp, typename _Up, typename _Vp>
+    inline typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type
+    ellint_rd(_Tp __x, _Up __y, _Vp __z)
+    {
+      typedef typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type __type;
+      return std::__detail::__ellint_rd<__type>(__x, __y, __z);
+    }
+
+  //  Complete Carlson elliptic R_G functions
+
+  inline float
+  comp_ellint_rg(float __x, float __y)
+  { return std::__detail::__comp_ellint_rg<float>(__x, __y); }
+
+  inline long double
+  comp_ellint_rg(long double __x, long double __y)
+  { return std::__detail::__comp_ellint_rg<long double>(__x, __y); }
+
+  template<typename _Tx, typename _Ty>
+    inline typename __gnu_cxx::__promote_2<_Tx, _Ty>::__type
+    comp_ellint_rg(_Tx __x, _Ty __y)
+    {
+      typedef typename __gnu_cxx::__promote_2<_Tx, _Ty>::__type __type;
+      return std::__detail::__comp_ellint_rg<__type>(__x, __y);
+    }
+
+  //  Carlson elliptic R_G functions
+
+  inline float
+  ellint_rgf(float __x, float __y, float __z)
+  { return std::__detail::__ellint_rg<float>(__x, __y, __z); }
+
+  inline long double
+  ellint_rgl(long double __x, long double __y, long double __z)
+  { return std::__detail::__ellint_rg<long double>(__x, __y, __z); }
+
+  template<typename _Tp, typename _Up, typename _Vp>
+    inline typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type
+    ellint_rg(_Tp __x, _Up __y, _Vp __z)
+    {
+      typedef typename __gnu_cxx::__promote_3<_Tp, _Up, _Vp>::__type __type;
+      return std::__detail::__ellint_rg<__type>(__x, __y, __z);
+    }
+
+#endif // __cplusplus >= 201103L
+
+} // namespace __gnu_cxx
+
+#pragma GCC visibility pop
+
+#endif // _GLIBCXX_BITS_SPECFUN_H
Index: include/bits/specfun_util.h
===================================================================
--- include/bits/specfun_util.h	(revision 175789)
+++ include/bits/specfun_util.h	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,122 +22,164 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/special_function_util.h
+/** @file bits/specfun_util.h
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
 // Written by Edward Smith-Rowland based on numerous mathematics books.
 
-#ifndef _GLIBCXX_TR1_SPECIAL_FUNCTION_UTIL_H
-#define _GLIBCXX_TR1_SPECIAL_FUNCTION_UTIL_H 1
+#ifndef _GLIBCXX_BITS_SPECFUN_UTIL_H
+#define _GLIBCXX_BITS_SPECFUN_UTIL_H 1
 
+#include <complex>
+
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+namespace __detail
 {
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-    /// A class to encapsulate type dependent floating point
-    /// constants.  Not everything will be able to be expressed as
-    /// type logic.
-    template<typename _Tp>
+  /// A class to encapsulate type dependent floating point
+  /// constants.  Not everything will be able to be expressed as
+  /// type logic.
+  template<typename _Tp>
     struct __floating_point_constant
     {
       static const _Tp __value;
     };
 
+  template<typename _Tp>
+    struct __num_traits
+    {
+      using __value_type = _Tp;
+    };
 
-    /// A structure for numeric constants.
+  template<>
     template<typename _Tp>
-      struct __numeric_constants
+      struct __num_traits<std::complex<_Tp>>
       {
-        ///  Constant @f$ \pi @f$.
-        static _Tp __pi() throw()
-        { return static_cast<_Tp>(3.1415926535897932384626433832795029L); }
-        ///  Constant @f$ \pi / 2 @f$.
-        static _Tp __pi_2() throw()
-        { return static_cast<_Tp>(1.5707963267948966192313216916397514L); }
-        ///  Constant @f$ \pi / 3 @f$.
-        static _Tp __pi_3() throw()
-        { return static_cast<_Tp>(1.0471975511965977461542144610931676L); }
-        ///  Constant @f$ \pi / 4 @f$.
-        static _Tp __pi_4() throw()
-        { return static_cast<_Tp>(0.7853981633974483096156608458198757L); }
-        ///  Constant @f$ 1 / \pi @f$.
-        static _Tp __1_pi() throw()
-        { return static_cast<_Tp>(0.3183098861837906715377675267450287L); }
-        ///  Constant @f$ 2 / \sqrt(\pi) @f$.
-        static _Tp __2_sqrtpi() throw()
-        { return static_cast<_Tp>(1.1283791670955125738961589031215452L); }
-        ///  Constant @f$ \sqrt(2) @f$.
-        static _Tp __sqrt2() throw()
-        { return static_cast<_Tp>(1.4142135623730950488016887242096981L); }
-        ///  Constant @f$ \sqrt(3) @f$.
-        static _Tp __sqrt3() throw()
-        { return static_cast<_Tp>(1.7320508075688772935274463415058723L); }
-        ///  Constant @f$ \sqrt(\pi/2) @f$.
-        static _Tp __sqrtpio2() throw()
-        { return static_cast<_Tp>(1.2533141373155002512078826424055226L); }
-        ///  Constant @f$ 1 / sqrt(2) @f$.
-        static _Tp __sqrt1_2() throw()
-        { return static_cast<_Tp>(0.7071067811865475244008443621048490L); }
-        ///  Constant @f$ \log(\pi) @f$.
-        static _Tp __lnpi() throw()
-        { return static_cast<_Tp>(1.1447298858494001741434273513530587L); }
-        ///  Constant Euler's constant @f$ \gamma_E @f$.
-        static _Tp __gamma_e() throw()
-        { return static_cast<_Tp>(0.5772156649015328606065120900824024L); }
-        ///  Constant Euler-Mascheroni @f$ e @f$
-        static _Tp __euler() throw()
-        { return static_cast<_Tp>(2.7182818284590452353602874713526625L); }
+	using __value_type = typename std::complex<_Tp>::value_type;
       };
 
+  template<typename _Tp>
+    using __num_traits_t = typename __num_traits<_Tp>::__value_type;
 
+  /// A structure for numeric constants.
+  template<typename _Tp>
+    struct __numeric_constants
+    {
+      ///  Constant @f$ \pi @f$.
+      static constexpr _Tp __pi() noexcept
+      { return static_cast<_Tp>(3.1415926535897932384626433832795029L); }
+      ///  Constant @f$ \pi / 2 @f$.
+      static constexpr _Tp __pi_2() noexcept
+      { return static_cast<_Tp>(1.5707963267948966192313216916397514L); }
+      ///  Constant @f$ \pi / 3 @f$.
+      static constexpr _Tp __pi_3() noexcept
+      { return static_cast<_Tp>(1.0471975511965977461542144610931676L); }
+      ///  Constant @f$ \pi / 4 @f$.
+      static constexpr _Tp __pi_4() noexcept
+      { return static_cast<_Tp>(0.7853981633974483096156608458198757L); }
+      ///  Constant @f$ 1 / \pi @f$.
+      static constexpr _Tp __1_pi() noexcept
+      { return static_cast<_Tp>(0.3183098861837906715377675267450287L); }
+      ///  Constant @f$ 2 / \sqrt(\pi) @f$.
+      static constexpr _Tp __2_sqrtpi() noexcept
+      { return static_cast<_Tp>(1.1283791670955125738961589031215452L); }
+      ///  Constant @f$ \sqrt(2) @f$.
+      static constexpr _Tp __sqrt2() noexcept
+      { return static_cast<_Tp>(1.4142135623730950488016887242096981L); }
+      ///  Constant @f$ \sqrt(3) @f$.
+      static constexpr _Tp __sqrt3() noexcept
+      { return static_cast<_Tp>(1.7320508075688772935274463415058723L); }
+      ///  Constant @f$ \sqrt(\pi/2) @f$.
+      static constexpr _Tp __sqrtpio2() noexcept
+      { return static_cast<_Tp>(1.2533141373155002512078826424055226L); }
+      ///  Constant @f$ 1 / sqrt(2) @f$.
+      static constexpr _Tp __sqrt1_2() noexcept
+      { return static_cast<_Tp>(0.7071067811865475244008443621048490L); }
+      ///  Constant @f$ \log(\pi) @f$.
+      static constexpr _Tp __lnpi() noexcept
+      { return static_cast<_Tp>(1.1447298858494001741434273513530587L); }
+      ///  Constant Euler's constant @f$ \gamma_E @f$.
+      static constexpr _Tp __gamma_e() noexcept
+      { return static_cast<_Tp>(0.5772156649015328606065120900824024L); }
+      ///  Constant Euler-Mascheroni @f$ e @f$
+      static constexpr _Tp __euler() noexcept
+      { return static_cast<_Tp>(2.7182818284590452353602874713526625L); }
+    };
+
 #if _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
 
-    /// This is a wrapper for the isnan function. Otherwise, for NaN,
-    /// all comparisons result in false. If/when we build a std::isnan
-    /// out of intrinsics, this will disappear completely in favor of
-    /// std::isnan.
-    template<typename _Tp>
-    inline bool __isnan(const _Tp __x)
-    {
-      return std::isnan(__x);
-    }
+  /// This is a wrapper for the isnan function. Otherwise, for NaN,
+  /// all comparisons result in false. If/when we build a std::isnan
+  /// out of intrinsics, this will disappear completely in favor of
+  /// std::isnan.
+  template<typename _Tp>
+    inline bool
+    __isnan(_Tp __x)
+    { return std::isnan(__x); }
 
 #else
 
-    template<typename _Tp>
-    inline bool __isnan(const _Tp __x)
-    {
-      return __builtin_isnan(__x);
-    }
+  template<typename _Tp>
+    inline bool
+    __isnan(_Tp __x)
+    { return __builtin_isnan(__x); }
 
-    template<>
-    inline bool __isnan<float>(const float __x)
+  template<>
+    inline bool
+    __isnan<float>(float __x)
+    { return __builtin_isnanf(__x); }
+
+  template<>
+    inline bool
+    __isnan<long double>(long double __x)
+    { return __builtin_isnanl(__x); }
+
+#endif
+
+  template<typename _Tp>
+    inline bool
+    __isnan(const std::complex<_Tp>& __x)
+    { return __isnan(std::real(__x)) || __isnan(std::imag(__x)); }
+
+
+  template<typename _Tp>
+    inline _Tp
+    __quiet_NaN(_Tp)
+    { return std::numeric_limits<_Tp>::quiet_NaN(); }
+
+  template<typename _Tp>
+    inline std::complex<_Tp>
+    __quiet_NaN(std::complex<_Tp>)
     {
-      return __builtin_isnanf(__x);
+      auto __nan = std::numeric_limits<_Tp>::quiet_NaN();
+      return std::complex<_Tp>(__nan, __nan);
     }
 
-    template<>
-    inline bool __isnan<long double>(const long double __x)
+
+  template<typename _Tp>
+    inline _Tp
+    __infinity(_Tp)
+    { return std::numeric_limits<_Tp>::infinity(); }
+
+  template<typename _Tp>
+    inline std::complex<_Tp>
+    __infinity(std::complex<_Tp>)
     {
-      return __builtin_isnanl(__x);
+      auto __inf = std::numeric_limits<_Tp>::infinity();
+      return std::complex<_Tp>(__inf, __inf);
     }
 
-#endif
-
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace __detail
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
 }
-}
 
-#endif // _GLIBCXX_TR1_SPECIAL_FUNCTION_UTIL_H
+#endif // _GLIBCXX_BITS_SPECFUN_UTIL_H
 
Index: include/bits/sf_beta.tcc
===================================================================
--- include/bits/sf_beta.tcc	(revision 175789)
+++ include/bits/sf_beta.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,16 +22,18 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/beta_function.tcc
+/** @file bits/sf_beta.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
-// Written by Edward Smith-Rowland based on:
+// Written by Edward Smith-Rowland.
+//
+// References:
 //   (1) Handbook of Mathematical Functions,
 //       ed. Milton Abramowitz and Irene A. Stegun,
 //       Dover Publications,
@@ -44,112 +45,87 @@
 //   (4) Gamma, Exploring Euler's Constant, Julian Havil,
 //       Princeton, 2003.
 
-#ifndef _GLIBCXX_TR1_BETA_FUNCTION_TCC
-#define _GLIBCXX_TR1_BETA_FUNCTION_TCC 1
+#ifndef _GLIBCXX_BITS_SF_BETA_TCC
+#define _GLIBCXX_BITS_SF_BETA_TCC 1
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // [5.2] Special functions
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-    /**
-     *   @brief  Return the beta function: \f$B(x,y)\f$.
-     * 
-     *   The beta function is defined by
-     *   @f[
-     *     B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
-     *   @f]
-     *
-     *   @param __x The first argument of the beta function.
-     *   @param __y The second argument of the beta function.
-     *   @return  The beta function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the beta function: \f$B(x,y)\f$.
+   *
+   *   The beta function is defined by
+   *   @f[
+   *     B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
+   *   @f]
+   *
+   *   @param __x The first argument of the beta function.
+   *   @param __y The second argument of the beta function.
+   *   @return  The beta function.
+   */
+  template<typename _Tp>
     _Tp
     __beta_gamma(_Tp __x, _Tp __y)
     {
 
       _Tp __bet;
-#if _GLIBCXX_USE_C99_MATH_TR1
       if (__x > __y)
-        {
-          __bet = std::tr1::tgamma(__x)
-                / std::tr1::tgamma(__x + __y);
-          __bet *= std::tr1::tgamma(__y);
-        }
+	{
+	  __bet = __gamma(__x) / __gamma(__x + __y);
+	  __bet *= __gamma(__y);
+	}
       else
-        {
-          __bet = std::tr1::tgamma(__y)
-                / std::tr1::tgamma(__x + __y);
-          __bet *= std::tr1::tgamma(__x);
-        }
-#else
-      if (__x > __y)
-        {
-          __bet = __gamma(__x) / __gamma(__x + __y);
-          __bet *= __gamma(__y);
-        }
-      else
-        {
-          __bet = __gamma(__y) / __gamma(__x + __y);
-          __bet *= __gamma(__x);
-        }
-#endif
+	{
+	  __bet = __gamma(__y) / __gamma(__x + __y);
+	  __bet *= __gamma(__x);
+	}
 
       return __bet;
     }
 
-    /**
-     *   @brief  Return the beta function \f$B(x,y)\f$ using
-     *           the log gamma functions.
-     * 
-     *   The beta function is defined by
-     *   @f[
-     *     B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
-     *   @f]
-     *
-     *   @param __x The first argument of the beta function.
-     *   @param __y The second argument of the beta function.
-     *   @return  The beta function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the beta function \f$B(x,y)\f$ using
+   *           the log gamma functions.
+   *
+   *   The beta function is defined by
+   *   @f[
+   *     B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
+   *   @f]
+   *
+   *   @param __x The first argument of the beta function.
+   *   @param __y The second argument of the beta function.
+   *   @return  The beta function.
+   */
+  template<typename _Tp>
     _Tp
     __beta_lgamma(_Tp __x, _Tp __y)
     {
-#if _GLIBCXX_USE_C99_MATH_TR1
-      _Tp __bet = std::tr1::lgamma(__x)
-                + std::tr1::lgamma(__y)
-                - std::tr1::lgamma(__x + __y);
-#else
       _Tp __bet = __log_gamma(__x)
-                + __log_gamma(__y)
-                - __log_gamma(__x + __y);
-#endif
+		+ __log_gamma(__y)
+		- __log_gamma(__x + __y);
       __bet = std::exp(__bet);
       return __bet;
     }
 
 
-    /**
-     *   @brief  Return the beta function \f$B(x,y)\f$ using
-     *           the product form.
-     * 
-     *   The beta function is defined by
-     *   @f[
-     *     B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
-     *   @f]
-     *
-     *   @param __x The first argument of the beta function.
-     *   @param __y The second argument of the beta function.
-     *   @return  The beta function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the beta function \f$B(x,y)\f$ using
+   *           the product form.
+   *
+   *   The beta function is defined by
+   *   @f[
+   *     B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
+   *   @f]
+   *
+   *   @param __x The first argument of the beta function.
+   *   @param __y The second argument of the beta function.
+   *   @return  The beta function.
+   */
+  template<typename _Tp>
     _Tp
     __beta_product(_Tp __x, _Tp __y)
     {
@@ -156,43 +132,119 @@
 
       _Tp __bet = (__x + __y) / (__x * __y);
 
-      unsigned int __max_iter = 1000000;
+      const unsigned int __max_iter = 1000000;
+
       for (unsigned int __k = 1; __k < __max_iter; ++__k)
-        {
-          _Tp __term = (_Tp(1) + (__x + __y) / __k)
-                     / ((_Tp(1) + __x / __k) * (_Tp(1) + __y / __k));
-          __bet *= __term;
-        }
+	{
+	  _Tp __term = (_Tp(1) + (__x + __y) / __k)
+		     / ((_Tp(1) + __x / __k) * (_Tp(1) + __y / __k));
+	  __bet *= __term;
+	}
 
       return __bet;
     }
 
 
-    /**
-     *   @brief  Return the beta function \f$ B(x,y) \f$.
-     * 
-     *   The beta function is defined by
-     *   @f[
-     *     B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
-     *   @f]
-     *
-     *   @param __x The first argument of the beta function.
-     *   @param __y The second argument of the beta function.
-     *   @return  The beta function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the beta function \f$ B(x,y) \f$.
+   *
+   *   The beta function is defined by
+   *   @f[
+   *     B(x,y) = \frac{\Gamma(x)\Gamma(y)}{\Gamma(x+y)}
+   *   @f]
+   *
+   *   @param __x The first argument of the beta function.
+   *   @param __y The second argument of the beta function.
+   *   @return  The beta function.
+   */
+  template<typename _Tp>
     inline _Tp
     __beta(_Tp __x, _Tp __y)
     {
       if (__isnan(__x) || __isnan(__y))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else
-        return __beta_lgamma(__x, __y);
+	return __beta_lgamma(__x, __y);
     }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
 
-#endif // __GLIBCXX_TR1_BETA_FUNCTION_TCC
+  template<typename _Tp>
+    _Tp
+    __beta_inc_cont_frac(_Tp __a, _Tp __b, _Tp __x)
+    {
+      static constexpr unsigned int _S_itmax = 100;
+      static constexpr _Tp _S_eps = std::numeric_limits<_Tp>::epsilon();
+
+      _Tp __apb = __a + __b;
+      _Tp __ap1 = __a + _Tp(1);
+      _Tp __am1 = __a - _Tp(1);
+      _Tp __c = _Tp(1);
+      _Tp __d = _Tp(1) - __apb * __x / __ap1;
+      if (std::abs(__d) < _S_eps)
+	__d = _S_eps;
+      __d = _Tp(1) / __d;
+      _Tp __h = __d;
+      for (unsigned int __m = 1; __m <= _S_itmax; ++__m)
+	{
+          _Tp __m2(2 * __m);
+
+          _Tp __aa = _Tp(__m) * (__b - _Tp(__m)) * __x
+                   / ((__am1 + __m2) * (__a + __m2));
+          __d = _Tp(1) + __aa * __d;
+          if (std::abs(__d) < _S_eps)
+            __d = _S_eps;
+          __c = _Tp(1) + __aa / __c;
+          if (std::abs(__c) < _S_eps)
+            __c = _S_eps;
+          __d = _Tp(1) / __d;
+          __h *= __d * __c;
+
+          __aa = -(__a + _Tp(__m)) * (__apb + __m) * __x
+               / ((__a + __m2) * (__ap1 + __m2));
+          __d = _Tp(1) + __aa * __d;
+          if (std::abs(__d) < _S_eps)
+            __d = _S_eps;
+          __c = _Tp(1) + __aa / __c;
+          if (std::abs(__c) < _S_eps)
+            __c = _S_eps;
+          __d = _Tp(1) / __d;
+          _Tp __del = __d * __c;
+          __h *= __del;
+
+          if (std::abs(__del - _Tp(1)) < _S_eps)
+            return __h;
+	}
+      throw std::runtime_error("__beta_inc_cont_frac: "
+			       "continued fractions failed to converge");
+    }
+
+
+  template<typename _Tp>
+    _Tp
+    __beta_inc(_Tp __a, _Tp __b, _Tp __x)
+    {
+      if (__isnan(__x) || __isnan(__a) || __isnan(__b))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+
+      if (__x < _Tp(0) || __x > _Tp(1))
+	throw std::domain_error("__beta_inc: x out of range");
+
+      _Tp __fact;
+      if (__x == _Tp(0) || __x == _Tp(1))
+	__fact = _Tp(0);
+      else
+	__fact = std::exp(std::lgamma(__a + __b)
+                	- std::lgamma(__a) - std::lgamma(__b)
+                	+ __a * std::log(__x) + __b * std::log(_Tp(1) - __x));
+
+      if (__x < (__a + _Tp(1)) / (__a + __b + _Tp(2)))
+	return __fact * __beta_inc_cont_frac(__a, __b, __x) / __a;
+      else
+	return _Tp(1) - __fact * __beta_inc_cont_frac(__b, __a, _Tp(1) - __x) / __b;
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#endif // __GLIBCXX_BITS_SF_BETA_TCC
Index: include/bits/sf_bessel.tcc
===================================================================
--- include/bits/sf_bessel.tcc	(revision 175789)
+++ include/bits/sf_bessel.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,13 +22,13 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/bessel_function.tcc
+/** @file bits/sf_bessel.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
 // Written by Edward Smith-Rowland.
@@ -44,64 +43,55 @@
 //       W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
 //       2nd ed, pp. 240-245
 
-#ifndef _GLIBCXX_TR1_BESSEL_FUNCTION_TCC
-#define _GLIBCXX_TR1_BESSEL_FUNCTION_TCC 1
+#ifndef _GLIBCXX_BITS_SF_BESSEL_TCC
+#define _GLIBCXX_BITS_SF_BESSEL_TCC 1
 
-#include "special_function_util.h"
+#include <bits/specfun_util.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // [5.2] Special functions
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-    /**
-     *   @brief Compute the gamma functions required by the Temme series
-     *          expansions of @f$ N_\nu(x) @f$ and @f$ K_\nu(x) @f$.
-     *   @f[
-     *     \Gamma_1 = \frac{1}{2\mu}
-     *                [\frac{1}{\Gamma(1 - \mu)} - \frac{1}{\Gamma(1 + \mu)}]
-     *   @f]
-     *   and
-     *   @f[
-     *     \Gamma_2 = \frac{1}{2}
-     *                [\frac{1}{\Gamma(1 - \mu)} + \frac{1}{\Gamma(1 + \mu)}]
-     *   @f]
-     *   where @f$ -1/2 <= \mu <= 1/2 @f$ is @f$ \mu = \nu - N @f$ and @f$ N @f$.
-     *   is the nearest integer to @f$ \nu @f$.
-     *   The values of \f$ \Gamma(1 + \mu) \f$ and \f$ \Gamma(1 - \mu) \f$
-     *   are returned as well.
-     * 
-     *   The accuracy requirements on this are exquisite.
-     *
-     *   @param __mu     The input parameter of the gamma functions.
-     *   @param __gam1   The output function \f$ \Gamma_1(\mu) \f$
-     *   @param __gam2   The output function \f$ \Gamma_2(\mu) \f$
-     *   @param __gampl  The output function \f$ \Gamma(1 + \mu) \f$
-     *   @param __gammi  The output function \f$ \Gamma(1 - \mu) \f$
-     */
-    template <typename _Tp>
+  /**
+   *   @brief Compute the gamma functions required by the Temme series
+   *          expansions of @f$ N_\nu(x) @f$ and @f$ K_\nu(x) @f$.
+   *   @f[
+   *     \Gamma_1 = \frac{1}{2\mu}
+   *                [\frac{1}{\Gamma(1 - \mu)} - \frac{1}{\Gamma(1 + \mu)}]
+   *   @f]
+   *   and
+   *   @f[
+   *     \Gamma_2 = \frac{1}{2}
+   *                [\frac{1}{\Gamma(1 - \mu)} + \frac{1}{\Gamma(1 + \mu)}]
+   *   @f]
+   *   where @f$ -1/2 <= \mu <= 1/2 @f$ is @f$ \mu = \nu - N @f$ and @f$ N @f$.
+   *   is the nearest integer to @f$ \nu @f$.
+   *   The values of \f$ \Gamma(1 + \mu) \f$ and \f$ \Gamma(1 - \mu) \f$
+   *   are returned as well.
+   *
+   *   The accuracy requirements on this are exquisite.
+   *
+   *   @param __mu     The input parameter of the gamma functions.
+   *   @param __gam1   The output function \f$ \Gamma_1(\mu) \f$
+   *   @param __gam2   The output function \f$ \Gamma_2(\mu) \f$
+   *   @param __gampl  The output function \f$ \Gamma(1 + \mu) \f$
+   *   @param __gammi  The output function \f$ \Gamma(1 - \mu) \f$
+   */
+  template<typename _Tp>
     void
-    __gamma_temme(const _Tp __mu,
-                   _Tp & __gam1, _Tp & __gam2, _Tp & __gampl, _Tp & __gammi)
+    __gamma_temme(_Tp __mu,
+		  _Tp & __gam1, _Tp & __gam2, _Tp & __gampl, _Tp & __gammi)
     {
-#if _GLIBCXX_USE_C99_MATH_TR1
-      __gampl = _Tp(1) / std::tr1::tgamma(_Tp(1) + __mu);
-      __gammi = _Tp(1) / std::tr1::tgamma(_Tp(1) - __mu);
-#else
       __gampl = _Tp(1) / __gamma(_Tp(1) + __mu);
       __gammi = _Tp(1) / __gamma(_Tp(1) - __mu);
-#endif
 
       if (std::abs(__mu) < std::numeric_limits<_Tp>::epsilon())
-        __gam1 = -_Tp(__numeric_constants<_Tp>::__gamma_e());
+	__gam1 = -_Tp(__numeric_constants<_Tp>::__gamma_e());
       else
-        __gam1 = (__gammi - __gampl) / (_Tp(2) * __mu);
+	__gam1 = (__gammi - __gampl) / (_Tp(2) * __mu);
 
       __gam2 = (__gammi + __gampl) / (_Tp(2));
 
@@ -109,46 +99,46 @@
     }
 
 
-    /**
-     *   @brief  Compute the Bessel @f$ J_\nu(x) @f$ and Neumann
-     *           @f$ N_\nu(x) @f$ functions and their first derivatives
-     *           @f$ J'_\nu(x) @f$ and @f$ N'_\nu(x) @f$ respectively.
-     *           These four functions are computed together for numerical
-     *           stability.
-     *
-     *   @param  __nu  The order of the Bessel functions.
-     *   @param  __x   The argument of the Bessel functions.
-     *   @param  __Jnu  The output Bessel function of the first kind.
-     *   @param  __Nnu  The output Neumann function (Bessel function of the second kind).
-     *   @param  __Jpnu  The output derivative of the Bessel function of the first kind.
-     *   @param  __Npnu  The output derivative of the Neumann function.
-     */
-    template <typename _Tp>
+  /**
+   *   @brief  Compute the Bessel @f$ J_\nu(x) @f$ and Neumann
+   *           @f$ N_\nu(x) @f$ functions and their first derivatives
+   *           @f$ J'_\nu(x) @f$ and @f$ N'_\nu(x) @f$ respectively.
+   *           These four functions are computed together for numerical
+   *           stability.
+   *
+   *   @param  __nu  The order of the Bessel functions.
+   *   @param  __x   The argument of the Bessel functions.
+   *   @param  __Jnu  The output Bessel function of the first kind.
+   *   @param  __Nnu  The output Neumann function (Bessel function of the second kind).
+   *   @param  __Jpnu  The output derivative of the Bessel function of the first kind.
+   *   @param  __Npnu  The output derivative of the Neumann function.
+   */
+  template<typename _Tp>
     void
-    __bessel_jn(const _Tp __nu, const _Tp __x,
-                _Tp & __Jnu, _Tp & __Nnu, _Tp & __Jpnu, _Tp & __Npnu)
+    __bessel_jn(_Tp __nu, _Tp __x,
+		_Tp & __Jnu, _Tp & __Nnu, _Tp & __Jpnu, _Tp & __Npnu)
     {
       if (__x == _Tp(0))
-        {
-          if (__nu == _Tp(0))
-            {
-              __Jnu = _Tp(1);
-              __Jpnu = _Tp(0);
-            }
-          else if (__nu == _Tp(1))
-            {
-              __Jnu = _Tp(0);
-              __Jpnu = _Tp(0.5L);
-            }
-          else
-            {
-              __Jnu = _Tp(0);
-              __Jpnu = _Tp(0);
-            }
-          __Nnu = -std::numeric_limits<_Tp>::infinity();
-          __Npnu = std::numeric_limits<_Tp>::infinity();
-          return;
-        }
+	{
+	  if (__nu == _Tp(0))
+	    {
+	      __Jnu = _Tp(1);
+	      __Jpnu = _Tp(0);
+	    }
+	  else if (__nu == _Tp(1))
+	    {
+	      __Jnu = _Tp(0);
+	      __Jpnu = _Tp(0.5L);
+	    }
+	  else
+	    {
+	      __Jnu = _Tp(0);
+	      __Jpnu = _Tp(0);
+	    }
+	  __Nnu = -std::numeric_limits<_Tp>::infinity();
+	  __Npnu = std::numeric_limits<_Tp>::infinity();
+	  return;
+	}
 
       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
       //  When the multiplier is N i.e.
@@ -160,8 +150,8 @@
       const _Tp __x_min = _Tp(2);
 
       const int __nl = (__x < __x_min
-                    ? static_cast<int>(__nu + _Tp(0.5L))
-                    : std::max(0, static_cast<int>(__nu - __x + _Tp(1.5L))));
+		    ? static_cast<int>(__nu + _Tp(0.5L))
+		    : std::max(0, static_cast<int>(__nu - __x + _Tp(1.5L))));
 
       const _Tp __mu = __nu - __nl;
       const _Tp __mu2 = __mu * __mu;
@@ -171,31 +161,31 @@
       int __isign = 1;
       _Tp __h = __nu * __xi;
       if (__h < __fp_min)
-        __h = __fp_min;
+	__h = __fp_min;
       _Tp __b = __xi2 * __nu;
       _Tp __d = _Tp(0);
       _Tp __c = __h;
       int __i;
       for (__i = 1; __i <= __max_iter; ++__i)
-        {
-          __b += __xi2;
-          __d = __b - __d;
-          if (std::abs(__d) < __fp_min)
-            __d = __fp_min;
-          __c = __b - _Tp(1) / __c;
-          if (std::abs(__c) < __fp_min)
-            __c = __fp_min;
-          __d = _Tp(1) / __d;
-          const _Tp __del = __c * __d;
-          __h *= __del;
-          if (__d < _Tp(0))
-            __isign = -__isign;
-          if (std::abs(__del - _Tp(1)) < __eps)
-            break;
-        }
+	{
+	  __b += __xi2;
+	  __d = __b - __d;
+	  if (std::abs(__d) < __fp_min)
+	    __d = __fp_min;
+	  __c = __b - _Tp(1) / __c;
+	  if (std::abs(__c) < __fp_min)
+	    __c = __fp_min;
+	  __d = _Tp(1) / __d;
+	  const _Tp __del = __c * __d;
+	  __h *= __del;
+	  if (__d < _Tp(0))
+	    __isign = -__isign;
+	  if (std::abs(__del - _Tp(1)) < __eps)
+	    break;
+	}
       if (__i > __max_iter)
-        std::__throw_runtime_error(__N("Argument x too large in __bessel_jn; "
-                                       "try asymptotic expansion."));
+	std::__throw_runtime_error(__N("__bessel_jn: argument x too large;"
+				       " try asymptotic expansion"));
       _Tp __Jnul = __isign * __fp_min;
       _Tp __Jpnul = __h * __Jnul;
       _Tp __Jnul1 = __Jnul;
@@ -202,129 +192,124 @@
       _Tp __Jpnu1 = __Jpnul;
       _Tp __fact = __nu * __xi;
       for ( int __l = __nl; __l >= 1; --__l )
-        {
-          const _Tp __Jnutemp = __fact * __Jnul + __Jpnul;
-          __fact -= __xi;
-          __Jpnul = __fact * __Jnutemp - __Jnul;
-          __Jnul = __Jnutemp;
-        }
+	{
+	  const _Tp __Jnutemp = __fact * __Jnul + __Jpnul;
+	  __fact -= __xi;
+	  __Jpnul = __fact * __Jnutemp - __Jnul;
+	  __Jnul = __Jnutemp;
+	}
       if (__Jnul == _Tp(0))
-        __Jnul = __eps;
+	__Jnul = __eps;
       _Tp __f= __Jpnul / __Jnul;
       _Tp __Nmu, __Nnu1, __Npmu, __Jmu;
       if (__x < __x_min)
-        {
-          const _Tp __x2 = __x / _Tp(2);
-          const _Tp __pimu = __numeric_constants<_Tp>::__pi() * __mu;
-          _Tp __fact = (std::abs(__pimu) < __eps
-                      ? _Tp(1) : __pimu / std::sin(__pimu));
-          _Tp __d = -std::log(__x2);
-          _Tp __e = __mu * __d;
-          _Tp __fact2 = (std::abs(__e) < __eps
-                       ? _Tp(1) : std::sinh(__e) / __e);
-          _Tp __gam1, __gam2, __gampl, __gammi;
-          __gamma_temme(__mu, __gam1, __gam2, __gampl, __gammi);
-          _Tp __ff = (_Tp(2) / __numeric_constants<_Tp>::__pi())
-                   * __fact * (__gam1 * std::cosh(__e) + __gam2 * __fact2 * __d);
-          __e = std::exp(__e);
-          _Tp __p = __e / (__numeric_constants<_Tp>::__pi() * __gampl);
-          _Tp __q = _Tp(1) / (__e * __numeric_constants<_Tp>::__pi() * __gammi);
-          const _Tp __pimu2 = __pimu / _Tp(2);
-          _Tp __fact3 = (std::abs(__pimu2) < __eps
-                       ? _Tp(1) : std::sin(__pimu2) / __pimu2 );
-          _Tp __r = __numeric_constants<_Tp>::__pi() * __pimu2 * __fact3 * __fact3;
-          _Tp __c = _Tp(1);
-          __d = -__x2 * __x2;
-          _Tp __sum = __ff + __r * __q;
-          _Tp __sum1 = __p;
-          for (__i = 1; __i <= __max_iter; ++__i)
-            {
-              __ff = (__i * __ff + __p + __q) / (__i * __i - __mu2);
-              __c *= __d / _Tp(__i);
-              __p /= _Tp(__i) - __mu;
-              __q /= _Tp(__i) + __mu;
-              const _Tp __del = __c * (__ff + __r * __q);
-              __sum += __del; 
-              const _Tp __del1 = __c * __p - __i * __del;
-              __sum1 += __del1;
-              if ( std::abs(__del) < __eps * (_Tp(1) + std::abs(__sum)) )
-                break;
-            }
-          if ( __i > __max_iter )
-            std::__throw_runtime_error(__N("Bessel y series failed to converge "
-                                           "in __bessel_jn."));
-          __Nmu = -__sum;
-          __Nnu1 = -__sum1 * __xi2;
-          __Npmu = __mu * __xi * __Nmu - __Nnu1;
-          __Jmu = __w / (__Npmu - __f * __Nmu);
-        }
+	{
+	  const _Tp __x2 = __x / _Tp(2);
+	  const _Tp __pimu = __numeric_constants<_Tp>::__pi() * __mu;
+	  _Tp __fact = (std::abs(__pimu) < __eps
+		      ? _Tp(1) : __pimu / std::sin(__pimu));
+	  _Tp __d = -std::log(__x2);
+	  _Tp __e = __mu * __d;
+	  _Tp __fact2 = (std::abs(__e) < __eps
+		       ? _Tp(1) : std::sinh(__e) / __e);
+	  _Tp __gam1, __gam2, __gampl, __gammi;
+	  __gamma_temme(__mu, __gam1, __gam2, __gampl, __gammi);
+	  _Tp __ff = (_Tp(2) / __numeric_constants<_Tp>::__pi())
+		   * __fact * (__gam1 * std::cosh(__e) + __gam2 * __fact2 * __d);
+	  __e = std::exp(__e);
+	  _Tp __p = __e / (__numeric_constants<_Tp>::__pi() * __gampl);
+	  _Tp __q = _Tp(1) / (__e * __numeric_constants<_Tp>::__pi() * __gammi);
+	  const _Tp __pimu2 = __pimu / _Tp(2);
+	  _Tp __fact3 = (std::abs(__pimu2) < __eps
+		       ? _Tp(1) : std::sin(__pimu2) / __pimu2 );
+	  _Tp __r = __numeric_constants<_Tp>::__pi() * __pimu2 * __fact3 * __fact3;
+	  _Tp __c = _Tp(1);
+	  __d = -__x2 * __x2;
+	  _Tp __sum = __ff + __r * __q;
+	  _Tp __sum1 = __p;
+	  for (__i = 1; __i <= __max_iter; ++__i)
+	    {
+	      __ff = (__i * __ff + __p + __q) / (__i * __i - __mu2);
+	      __c *= __d / _Tp(__i);
+	      __p /= _Tp(__i) - __mu;
+	      __q /= _Tp(__i) + __mu;
+	      const _Tp __del = __c * (__ff + __r * __q);
+	      __sum += __del;
+	      const _Tp __del1 = __c * __p - __i * __del;
+	      __sum1 += __del1;
+	      if ( std::abs(__del) < __eps * (_Tp(1) + std::abs(__sum)) )
+		break;
+	    }
+	  if ( __i > __max_iter )
+	    std::__throw_runtime_error(__N("__bessel_jn: "
+					   "Y-series failed to converge"));
+	  __Nmu = -__sum;
+	  __Nnu1 = -__sum1 * __xi2;
+	  __Npmu = __mu * __xi * __Nmu - __Nnu1;
+	  __Jmu = __w / (__Npmu - __f * __Nmu);
+	}
       else
-        {
-          _Tp __a = _Tp(0.25L) - __mu2;
-          _Tp __q = _Tp(1);
-          _Tp __p = -__xi / _Tp(2);
-          _Tp __br = _Tp(2) * __x;
-          _Tp __bi = _Tp(2);
-          _Tp __fact = __a * __xi / (__p * __p + __q * __q);
-          _Tp __cr = __br + __q * __fact;
-          _Tp __ci = __bi + __p * __fact;
-          _Tp __den = __br * __br + __bi * __bi;
-          _Tp __dr = __br / __den;
-          _Tp __di = -__bi / __den;
-          _Tp __dlr = __cr * __dr - __ci * __di;
-          _Tp __dli = __cr * __di + __ci * __dr;
-          _Tp __temp = __p * __dlr - __q * __dli;
-          __q = __p * __dli + __q * __dlr;
-          __p = __temp;
-          int __i;
-          for (__i = 2; __i <= __max_iter; ++__i)
-            {
-              __a += _Tp(2 * (__i - 1));
-              __bi += _Tp(2);
-              __dr = __a * __dr + __br;
-              __di = __a * __di + __bi;
-              if (std::abs(__dr) + std::abs(__di) < __fp_min)
-                __dr = __fp_min;
-              __fact = __a / (__cr * __cr + __ci * __ci);
-              __cr = __br + __cr * __fact;
-              __ci = __bi - __ci * __fact;
-              if (std::abs(__cr) + std::abs(__ci) < __fp_min)
-                __cr = __fp_min;
-              __den = __dr * __dr + __di * __di;
-              __dr /= __den;
-              __di /= -__den;
-              __dlr = __cr * __dr - __ci * __di;
-              __dli = __cr * __di + __ci * __dr;
-              __temp = __p * __dlr - __q * __dli;
-              __q = __p * __dli + __q * __dlr;
-              __p = __temp;
-              if (std::abs(__dlr - _Tp(1)) + std::abs(__dli) < __eps)
-                break;
-          }
-          if (__i > __max_iter)
-            std::__throw_runtime_error(__N("Lentz's method failed "
-                                           "in __bessel_jn."));
-          const _Tp __gam = (__p - __f) / __q;
-          __Jmu = std::sqrt(__w / ((__p - __f) * __gam + __q));
-#if _GLIBCXX_USE_C99_MATH_TR1
-          __Jmu = std::tr1::copysign(__Jmu, __Jnul);
-#else
-          if (__Jmu * __Jnul < _Tp(0))
-            __Jmu = -__Jmu;
-#endif
-          __Nmu = __gam * __Jmu;
-          __Npmu = (__p + __q / __gam) * __Nmu;
-          __Nnu1 = __mu * __xi * __Nmu - __Npmu;
+	{
+	  _Tp __a = _Tp(0.25L) - __mu2;
+	  _Tp __q = _Tp(1);
+	  _Tp __p = -__xi / _Tp(2);
+	  _Tp __br = _Tp(2) * __x;
+	  _Tp __bi = _Tp(2);
+	  _Tp __fact = __a * __xi / (__p * __p + __q * __q);
+	  _Tp __cr = __br + __q * __fact;
+	  _Tp __ci = __bi + __p * __fact;
+	  _Tp __den = __br * __br + __bi * __bi;
+	  _Tp __dr = __br / __den;
+	  _Tp __di = -__bi / __den;
+	  _Tp __dlr = __cr * __dr - __ci * __di;
+	  _Tp __dli = __cr * __di + __ci * __dr;
+	  _Tp __temp = __p * __dlr - __q * __dli;
+	  __q = __p * __dli + __q * __dlr;
+	  __p = __temp;
+	  int __i;
+	  for (__i = 2; __i <= __max_iter; ++__i)
+	    {
+	      __a += _Tp(2 * (__i - 1));
+	      __bi += _Tp(2);
+	      __dr = __a * __dr + __br;
+	      __di = __a * __di + __bi;
+	      if (std::abs(__dr) + std::abs(__di) < __fp_min)
+		__dr = __fp_min;
+	      __fact = __a / (__cr * __cr + __ci * __ci);
+	      __cr = __br + __cr * __fact;
+	      __ci = __bi - __ci * __fact;
+	      if (std::abs(__cr) + std::abs(__ci) < __fp_min)
+		__cr = __fp_min;
+	      __den = __dr * __dr + __di * __di;
+	      __dr /= __den;
+	      __di /= -__den;
+	      __dlr = __cr * __dr - __ci * __di;
+	      __dli = __cr * __di + __ci * __dr;
+	      __temp = __p * __dlr - __q * __dli;
+	      __q = __p * __dli + __q * __dlr;
+	      __p = __temp;
+	      if (std::abs(__dlr - _Tp(1)) + std::abs(__dli) < __eps)
+		break;
+	    }
+	  if (__i > __max_iter)
+	    std::__throw_runtime_error(__N("__bessel_jn: "
+					   "Lentz's method failed"));
+	  const _Tp __gam = (__p - __f) / __q;
+	  __Jmu = std::sqrt(__w / ((__p - __f) * __gam + __q));
+	  __Jmu = std::copysign(__Jmu, __Jnul);
+	  __Nmu = __gam * __Jmu;
+	  __Npmu = (__p + __q / __gam) * __Nmu;
+	  __Nnu1 = __mu * __xi * __Nmu - __Npmu;
       }
       __fact = __Jmu / __Jnul;
       __Jnu = __fact * __Jnul1;
       __Jpnu = __fact * __Jpnu1;
       for (__i = 1; __i <= __nl; ++__i)
-        {
-          const _Tp __Nnutemp = (__mu + __i) * __xi2 * __Nnu1 - __Nmu;
-          __Nmu = __Nnu1;
-          __Nnu1 = __Nnutemp;
-        }
+	{
+	  const _Tp __Nnutemp = (__mu + __i) * __xi2 * __Nnu1 - __Nmu;
+	  __Nmu = __Nnu1;
+	  __Nnu1 = __Nnutemp;
+	}
       __Nnu = __Nmu;
       __Npnu = __nu * __xi * __Nmu - __Nnu1;
 
@@ -332,45 +317,62 @@
     }
 
 
-    /**
-     *   @brief This routine computes the asymptotic cylindrical Bessel
-     *          and Neumann functions of order nu: \f$ J_{\nu} \f$,
-     *          \f$ N_{\nu} \f$.
-     *
-     *   References:
-     *    (1) Handbook of Mathematical Functions,
-     *        ed. Milton Abramowitz and Irene A. Stegun,
-     *        Dover Publications,
-     *        Section 9 p. 364, Equations 9.2.5-9.2.10
-     *
-     *   @param  __nu  The order of the Bessel functions.
-     *   @param  __x   The argument of the Bessel functions.
-     *   @param  __Jnu  The output Bessel function of the first kind.
-     *   @param  __Nnu  The output Neumann function (Bessel function of the second kind).
-     */
-    template <typename _Tp>
+  /**
+   *   @brief This routine computes the asymptotic cylindrical Bessel
+   *          and Neumann functions of order nu: \f$ J_{\nu}(x) \f$,
+   *          \f$ N_{\nu}(x) \f$.  Use this for \f$ x >> nu^2 + 1 \f$.
+   *
+   *   References:
+   *    (1) Handbook of Mathematical Functions,
+   *        ed. Milton Abramowitz and Irene A. Stegun,
+   *        Dover Publications,
+   *        Section 9 p. 364, Equations 9.2.5-9.2.10
+   *
+   *   @param  __nu  The order of the Bessel functions.
+   *   @param  __x   The argument of the Bessel functions.
+   *   @param  __Jnu  The output Bessel function of the first kind.
+   *   @param  __Nnu  The output Neumann function (Bessel function of the second kind).
+   */
+  template<typename _Tp>
     void
-    __cyl_bessel_jn_asymp(const _Tp __nu, const _Tp __x,
-                          _Tp & __Jnu, _Tp & __Nnu)
+    __cyl_bessel_jn_asymp( _Tp __nu, _Tp __x,
+			  _Tp & __Jnu, _Tp & __Nnu)
     {
-      const _Tp __coef = std::sqrt(_Tp(2)
-                             / (__numeric_constants<_Tp>::__pi() * __x));
-      const _Tp __mu   = _Tp(4) * __nu * __nu;
-      const _Tp __mum1 = __mu - _Tp(1);
-      const _Tp __mum9 = __mu - _Tp(9);
-      const _Tp __mum25 = __mu - _Tp(25);
-      const _Tp __mum49 = __mu - _Tp(49);
-      const _Tp __xx = _Tp(64) * __x * __x;
-      const _Tp __P = _Tp(1) - __mum1 * __mum9 / (_Tp(2) * __xx)
-                    * (_Tp(1) - __mum25 * __mum49 / (_Tp(12) * __xx));
-      const _Tp __Q = __mum1 / (_Tp(8) * __x)
-                    * (_Tp(1) - __mum9 * __mum25 / (_Tp(6) * __xx));
+      const auto __2nu = 2 * __nu;
+      const auto __x8 = 8 * __x;
+      auto __k = 1;
+      auto __k2m1 = 1;
+      auto __P = _Tp(1);
+      auto __Q = (__2nu - __k2m1) * (__2nu + __k2m1) / __x8;
+      ++__k;
+      const auto __eps = std::numeric_limits<_Tp>::epsilon();
+      auto __t = _Tp(1);
+      do
+	{
+	  __k2m1 += 2;
+	  __t *= -(__2nu - __k2m1) * (__2nu + __k2m1) / (__k * __x8);
+	  auto __convP = std::abs(__t) < __eps * std::abs(__P);
+	  __P += __t;
+	  ++__k;
 
-      const _Tp __chi = __x - (__nu + _Tp(0.5L))
-                            * __numeric_constants<_Tp>::__pi_2();
-      const _Tp __c = std::cos(__chi);
-      const _Tp __s = std::sin(__chi);
+	  __k2m1 += 2;
+	  __t *= (__2nu - __k2m1) * (__2nu + __k2m1) / (__k * __x8);
+	  auto __convQ = std::abs(__t) < __eps * std::abs(__Q);
+	  __Q += __t;
+	  ++__k;
 
+	  if (__convP && __convQ && __k > (__nu / _Tp(2)))
+	    break;
+	}
+      while (__k < 10 * __nu);
+
+      auto __chi = __x - (__nu + _Tp(0.5L))
+		       * __numeric_constants<_Tp>::__pi_2();
+      auto __c = std::cos(__chi);
+      auto __s = std::sin(__chi);
+
+      auto __coef = std::sqrt(_Tp(2)
+		  / (__numeric_constants<_Tp>::__pi() * __x));
       __Jnu = __coef * (__c * __P - __s * __Q);
       __Nnu = __coef * (__s * __P + __c * __Q);
 
@@ -378,46 +380,41 @@
     }
 
 
-    /**
-     *   @brief This routine returns the cylindrical Bessel functions
-     *          of order \f$ \nu \f$: \f$ J_{\nu} \f$ or \f$ I_{\nu} \f$
-     *          by series expansion.
-     *
-     *   The modified cylindrical Bessel function is:
-     *   @f[
-     *    Z_{\nu}(x) = \sum_{k=0}^{\infty}
-     *              \frac{\sigma^k (x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)}
-     *   @f]
-     *   where \f$ \sigma = +1 \f$ or\f$  -1 \f$ for
-     *   \f$ Z = I \f$ or \f$ J \f$ respectively.
-     * 
-     *   See Abramowitz & Stegun, 9.1.10
-     *       Abramowitz & Stegun, 9.6.7
-     *    (1) Handbook of Mathematical Functions,
-     *        ed. Milton Abramowitz and Irene A. Stegun,
-     *        Dover Publications,
-     *        Equation 9.1.10 p. 360 and Equation 9.6.10 p. 375
-     *
-     *   @param  __nu  The order of the Bessel function.
-     *   @param  __x   The argument of the Bessel function.
-     *   @param  __sgn  The sign of the alternate terms
-     *                  -1 for the Bessel function of the first kind.
-     *                  +1 for the modified Bessel function of the first kind.
-     *   @return  The output Bessel function.
-     */
-    template <typename _Tp>
+  /**
+   *   @brief This routine returns the cylindrical Bessel functions
+   *          of order \f$ \nu \f$: \f$ J_{\nu} \f$ or \f$ I_{\nu} \f$
+   *          by series expansion.
+   *
+   *   The modified cylindrical Bessel function is:
+   *   @f[
+   *    Z_{\nu}(x) = \sum_{k=0}^{\infty}
+   *              \frac{\sigma^k (x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)}
+   *   @f]
+   *   where \f$ \sigma = +1 \f$ or\f$  -1 \f$ for
+   *   \f$ Z = I \f$ or \f$ J \f$ respectively.
+   *
+   *   See Abramowitz & Stegun, 9.1.10
+   *       Abramowitz & Stegun, 9.6.7
+   *    (1) Handbook of Mathematical Functions,
+   *        ed. Milton Abramowitz and Irene A. Stegun,
+   *        Dover Publications,
+   *        Equation 9.1.10 p. 360 and Equation 9.6.10 p. 375
+   *
+   *   @param  __nu  The order of the Bessel function.
+   *   @param  __x   The argument of the Bessel function.
+   *   @param  __sgn  The sign of the alternate terms
+   *                  -1 for the Bessel function of the first kind.
+   *                  +1 for the modified Bessel function of the first kind.
+   *   @return  The output Bessel function.
+   */
+  template<typename _Tp>
     _Tp
-    __cyl_bessel_ij_series(const _Tp __nu, const _Tp __x, const _Tp __sgn,
-                           const unsigned int __max_iter)
+    __cyl_bessel_ij_series(_Tp __nu, _Tp __x, _Tp __sgn,
+			   unsigned int __max_iter)
     {
-
       const _Tp __x2 = __x / _Tp(2);
       _Tp __fact = __nu * std::log(__x2);
-#if _GLIBCXX_USE_C99_MATH_TR1
-      __fact -= std::tr1::lgamma(__nu + _Tp(1));
-#else
       __fact -= __log_gamma(__nu + _Tp(1));
-#endif
       __fact = std::exp(__fact);
       const _Tp __xx4 = __sgn * __x2 * __x2;
       _Tp __Jn = _Tp(1);
@@ -424,205 +421,332 @@
       _Tp __term = _Tp(1);
 
       for (unsigned int __i = 1; __i < __max_iter; ++__i)
-        {
-          __term *= __xx4 / (_Tp(__i) * (__nu + _Tp(__i)));
-          __Jn += __term;
-          if (std::abs(__term / __Jn) < std::numeric_limits<_Tp>::epsilon())
-            break;
-        }
+	{
+	  __term *= __xx4 / (_Tp(__i) * (__nu + _Tp(__i)));
+	  __Jn += __term;
+	  if (std::abs(__term / __Jn) < std::numeric_limits<_Tp>::epsilon())
+	    break;
+	}
 
       return __fact * __Jn;
     }
 
 
-    /**
-     *   @brief  Return the Bessel function of order \f$ \nu \f$:
-     *           \f$ J_{\nu}(x) \f$.
-     *
-     *   The cylindrical Bessel function is:
-     *   @f[
-     *    J_{\nu}(x) = \sum_{k=0}^{\infty}
-     *              \frac{(-1)^k (x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)}
-     *   @f]
-     *
-     *   @param  __nu  The order of the Bessel function.
-     *   @param  __x   The argument of the Bessel function.
-     *   @return  The output Bessel function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the Bessel function of order \f$ \nu \f$:
+   *           \f$ J_{\nu}(x) \f$.
+   *
+   *   The cylindrical Bessel function is:
+   *   @f[
+   *    J_{\nu}(x) = \sum_{k=0}^{\infty}
+   *              \frac{(-1)^k (x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)}
+   *   @f]
+   *
+   *   @param  __nu  The order of the Bessel function.
+   *   @param  __x   The argument of the Bessel function.
+   *   @return  The output Bessel function.
+   */
+  template<typename _Tp>
     _Tp
-    __cyl_bessel_j(const _Tp __nu, const _Tp __x)
+    __cyl_bessel_j(_Tp __nu, _Tp __x)
     {
       if (__nu < _Tp(0) || __x < _Tp(0))
-        std::__throw_domain_error(__N("Bad argument "
-                                      "in __cyl_bessel_j."));
+	std::__throw_domain_error(__N("__cyl_bessel_j: bad argument"));
       else if (__isnan(__nu) || __isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__x * __x < _Tp(10) * (__nu + _Tp(1)))
-        return __cyl_bessel_ij_series(__nu, __x, -_Tp(1), 200);
+	return __cyl_bessel_ij_series(__nu, __x, -_Tp(1), 200);
       else if (__x > _Tp(1000))
-        {
-          _Tp __J_nu, __N_nu;
-          __cyl_bessel_jn_asymp(__nu, __x, __J_nu, __N_nu);
-          return __J_nu;
-        }
+	{
+	  _Tp _J_nu, _N_nu;
+	  __cyl_bessel_jn_asymp(__nu, __x, _J_nu, _N_nu);
+	  return _J_nu;
+	}
       else
-        {
-          _Tp __J_nu, __N_nu, __Jp_nu, __Np_nu;
-          __bessel_jn(__nu, __x, __J_nu, __N_nu, __Jp_nu, __Np_nu);
-          return __J_nu;
-        }
+	{
+	  _Tp _J_nu, _N_nu, _Jp_nu, _Np_nu;
+	  __bessel_jn(__nu, __x, _J_nu, _N_nu, _Jp_nu, _Np_nu);
+	  return _J_nu;
+	}
     }
 
 
-    /**
-     *   @brief  Return the Neumann function of order \f$ \nu \f$:
-     *           \f$ N_{\nu}(x) \f$.
-     *
-     *   The Neumann function is defined by:
-     *   @f[
-     *      N_{\nu}(x) = \frac{J_{\nu}(x) \cos \nu\pi - J_{-\nu}(x)}
-     *                        {\sin \nu\pi}
-     *   @f]
-     *   where for integral \f$ \nu = n \f$ a limit is taken:
-     *   \f$ lim_{\nu \to n} \f$.
-     *
-     *   @param  __nu  The order of the Neumann function.
-     *   @param  __x   The argument of the Neumann function.
-     *   @return  The output Neumann function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the Neumann function of order \f$ \nu \f$:
+   *           \f$ N_{\nu}(x) \f$.
+   *
+   *   The Neumann function is defined by:
+   *   @f[
+   *      N_{\nu}(x) = \frac{J_{\nu}(x) \cos \nu\pi - J_{-\nu}(x)}
+   *                        {\sin \nu\pi}
+   *   @f]
+   *   where for integral \f$ \nu = n \f$ a limit is taken:
+   *   \f$ lim_{\nu \to n} \f$.
+   *
+   *   @param  __nu  The order of the Neumann function.
+   *   @param  __x   The argument of the Neumann function.
+   *   @return  The output Neumann function.
+   */
+  template<typename _Tp>
     _Tp
-    __cyl_neumann_n(const _Tp __nu, const _Tp __x)
+    __cyl_neumann_n(_Tp __nu, _Tp __x)
     {
       if (__nu < _Tp(0) || __x < _Tp(0))
-        std::__throw_domain_error(__N("Bad argument "
-                                      "in __cyl_neumann_n."));
+	std::__throw_domain_error(__N("__cyl_neumann_n: bad argument"));
       else if (__isnan(__nu) || __isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__x > _Tp(1000))
-        {
-          _Tp __J_nu, __N_nu;
-          __cyl_bessel_jn_asymp(__nu, __x, __J_nu, __N_nu);
-          return __N_nu;
-        }
+	{
+	  _Tp _J_nu, _N_nu;
+	  __cyl_bessel_jn_asymp(__nu, __x, _J_nu, _N_nu);
+	  return _N_nu;
+	}
       else
-        {
-          _Tp __J_nu, __N_nu, __Jp_nu, __Np_nu;
-          __bessel_jn(__nu, __x, __J_nu, __N_nu, __Jp_nu, __Np_nu);
-          return __N_nu;
-        }
+	{
+	  _Tp _J_nu, _N_nu, _Jp_nu, _Np_nu;
+	  __bessel_jn(__nu, __x, _J_nu, _N_nu, _Jp_nu, _Np_nu);
+	  return _N_nu;
+	}
     }
 
 
-    /**
-     *   @brief  Compute the spherical Bessel @f$ j_n(x) @f$
-     *           and Neumann @f$ n_n(x) @f$ functions and their first
-     *           derivatives @f$ j'_n(x) @f$ and @f$ n'_n(x) @f$
-     *           respectively.
-     *
-     *   @param  __n  The order of the spherical Bessel function.
-     *   @param  __x  The argument of the spherical Bessel function.
-     *   @param  __j_n  The output spherical Bessel function.
-     *   @param  __n_n  The output spherical Neumann function.
-     *   @param  __jp_n The output derivative of the spherical Bessel function.
-     *   @param  __np_n The output derivative of the spherical Neumann function.
-     */
-    template <typename _Tp>
+  /**
+   *   @brief  Return the cylindrical Hankel function of the first kind
+   *           @f$ h^{(1)}_n(x) @f$.
+   *
+   *   The cylindrical Hankel function of the first kind is defined by:
+   *   @f[
+   *     H^{(1)}_n(x) = J_n(x) + i N_n(x)
+   *   @f]
+   *
+   *   @param  __n  The order of the spherical Neumann function.
+   *   @param  __x  The argument of the spherical Neumann function.
+   *   @return  The output spherical Neumann function.
+   */
+  template<typename _Tp>
+    std::complex<_Tp>
+    __cyl_hankel_h1(_Tp __nu, _Tp __x)
+    {
+      if (__x < _Tp(0))
+	std::__throw_domain_error(__N("__cyl_hankel_h1: bad argument"));
+      else if (__isnan(__x))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (__x == _Tp(0))
+	return -std::numeric_limits<_Tp>::infinity();
+      else
+	{
+	  std::complex<_Tp> _S_j(0, 1);
+	  _Tp _J_n, _N_n, __jp_n, __np_n;
+	  __bessel_jn(__nu, __x, _J_n, _N_n, __jp_n, __np_n);
+	  return (_J_n + _S_j * _N_n);
+	}
+    }
+
+
+  /**
+   *   @brief  Return the cylindrical Hankel function of the second kind
+   *           @f$ h^{(1)}_n(x) @f$.
+   *
+   *   The cylindrical Hankel function of the second kind is defined by:
+   *   @f[
+   *     H^{(2)}_n(x) = J_n(x) - i N_n(x)
+   *   @f]
+   *
+   *   @param  __n  The order of the spherical Neumann function.
+   *   @param  __x  The argument of the spherical Neumann function.
+   *   @return  The output spherical Neumann function.
+   */
+  template<typename _Tp>
+    std::complex<_Tp>
+    __cyl_hankel_h2(_Tp __nu, _Tp __x)
+    {
+      if (__x < _Tp(0))
+	std::__throw_domain_error(__N("__cyl_hankel_h2: bad argument"));
+      else if (__isnan(__x))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (__x == _Tp(0))
+	return -std::numeric_limits<_Tp>::infinity();
+      else
+	{
+	  std::complex<_Tp> _S_j(0, 1);
+	  _Tp _J_n, _N_n, __jp_n, __np_n;
+	  __bessel_jn(__nu, __x, _J_n, _N_n, __jp_n, __np_n);
+	  return (_J_n + _S_j * _N_n);
+	}
+    }
+
+
+  /**
+   *   @brief  Compute the spherical Bessel @f$ j_n(x) @f$
+   *           and Neumann @f$ n_n(x) @f$ functions and their first
+   *           derivatives @f$ j'_n(x) @f$ and @f$ n'_n(x) @f$
+   *           respectively.
+   *
+   *   @param  __n  The order of the spherical Bessel function.
+   *   @param  __x  The argument of the spherical Bessel function.
+   *   @param  __j_n  The output spherical Bessel function.
+   *   @param  __n_n  The output spherical Neumann function.
+   *   @param  __jp_n The output derivative of the spherical Bessel function.
+   *   @param  __np_n The output derivative of the spherical Neumann function.
+   */
+  template<typename _Tp>
     void
-    __sph_bessel_jn(const unsigned int __n, const _Tp __x,
-                    _Tp & __j_n, _Tp & __n_n, _Tp & __jp_n, _Tp & __np_n)
+    __sph_bessel_jn(unsigned int __n, _Tp __x,
+		    _Tp & __j_n, _Tp & __n_n, _Tp & __jp_n, _Tp & __np_n)
     {
       const _Tp __nu = _Tp(__n) + _Tp(0.5L);
 
-      _Tp __J_nu, __N_nu, __Jp_nu, __Np_nu;
-      __bessel_jn(__nu, __x, __J_nu, __N_nu, __Jp_nu, __Np_nu);
+      _Tp _J_nu, _N_nu, _Jp_nu, _Np_nu;
+      __bessel_jn(__nu, __x, _J_nu, _N_nu, _Jp_nu, _Np_nu);
 
       const _Tp __factor = __numeric_constants<_Tp>::__sqrtpio2()
-                         / std::sqrt(__x);
+			 / std::sqrt(__x);
 
-      __j_n = __factor * __J_nu;
-      __n_n = __factor * __N_nu;
-      __jp_n = __factor * __Jp_nu - __j_n / (_Tp(2) * __x);
-      __np_n = __factor * __Np_nu - __n_n / (_Tp(2) * __x);
+      __j_n = __factor * _J_nu;
+      __n_n = __factor * _N_nu;
+      __jp_n = __factor * _Jp_nu - __j_n / (_Tp(2) * __x);
+      __np_n = __factor * _Np_nu - __n_n / (_Tp(2) * __x);
 
       return;
     }
 
 
-    /**
-     *   @brief  Return the spherical Bessel function
-     *           @f$ j_n(x) @f$ of order n.
-     *
-     *   The spherical Bessel function is defined by:
-     *   @f[
-     *    j_n(x) = \left( \frac{\pi}{2x} \right) ^{1/2} J_{n+1/2}(x)
-     *   @f]
-     *
-     *   @param  __n  The order of the spherical Bessel function.
-     *   @param  __x  The argument of the spherical Bessel function.
-     *   @return  The output spherical Bessel function.
-     */
-    template <typename _Tp>
+  /**
+   *   @brief  Return the spherical Bessel function
+   *           @f$ j_n(x) @f$ of order n.
+   *
+   *   The spherical Bessel function is defined by:
+   *   @f[
+   *    j_n(x) = \left( \frac{\pi}{2x} \right) ^{1/2} J_{n+1/2}(x)
+   *   @f]
+   *
+   *   @param  __n  The order of the spherical Bessel function.
+   *   @param  __x  The argument of the spherical Bessel function.
+   *   @return  The output spherical Bessel function.
+   */
+  template<typename _Tp>
     _Tp
-    __sph_bessel(const unsigned int __n, const _Tp __x)
+    __sph_bessel(unsigned int __n, _Tp __x)
     {
       if (__x < _Tp(0))
-        std::__throw_domain_error(__N("Bad argument "
-                                      "in __sph_bessel."));
+	std::__throw_domain_error(__N("__sph_bessel: bad argument"));
       else if (__isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__x == _Tp(0))
-        {
-          if (__n == 0)
-            return _Tp(1);
-          else
-            return _Tp(0);
-        }
+	{
+	  if (__n == 0)
+	    return _Tp(1);
+	  else
+	    return _Tp(0);
+	}
       else
-        {
-          _Tp __j_n, __n_n, __jp_n, __np_n;
-          __sph_bessel_jn(__n, __x, __j_n, __n_n, __jp_n, __np_n);
-          return __j_n;
-        }
+	{
+	  _Tp __j_n, __n_n, __jp_n, __np_n;
+	  __sph_bessel_jn(__n, __x, __j_n, __n_n, __jp_n, __np_n);
+	  return __j_n;
+	}
     }
 
 
-    /**
-     *   @brief  Return the spherical Neumann function
-     *           @f$ n_n(x) @f$.
-     *
-     *   The spherical Neumann function is defined by:
-     *   @f[
-     *    n_n(x) = \left( \frac{\pi}{2x} \right) ^{1/2} N_{n+1/2}(x)
-     *   @f]
-     *
-     *   @param  __n  The order of the spherical Neumann function.
-     *   @param  __x  The argument of the spherical Neumann function.
-     *   @return  The output spherical Neumann function.
-     */
-    template <typename _Tp>
+  /**
+   *   @brief  Return the spherical Neumann function
+   *           @f$ n_n(x) @f$.
+   *
+   *   The spherical Neumann function is defined by:
+   *   @f[
+   *    n_n(x) = \left( \frac{\pi}{2x} \right) ^{1/2} N_{n+1/2}(x)
+   *   @f]
+   *
+   *   @param  __n  The order of the spherical Neumann function.
+   *   @param  __x  The argument of the spherical Neumann function.
+   *   @return  The output spherical Neumann function.
+   */
+  template<typename _Tp>
     _Tp
-    __sph_neumann(const unsigned int __n, const _Tp __x)
+    __sph_neumann(unsigned int __n, _Tp __x)
     {
       if (__x < _Tp(0))
-        std::__throw_domain_error(__N("Bad argument "
-                                      "in __sph_neumann."));
+	std::__throw_domain_error(__N("__sph_neumann: bad argument"));
       else if (__isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__x == _Tp(0))
-        return -std::numeric_limits<_Tp>::infinity();
+	return -std::numeric_limits<_Tp>::infinity();
       else
-        {
-          _Tp __j_n, __n_n, __jp_n, __np_n;
-          __sph_bessel_jn(__n, __x, __j_n, __n_n, __jp_n, __np_n);
-          return __n_n;
-        }
+	{
+	  _Tp __j_n, __n_n, __jp_n, __np_n;
+	  __sph_bessel_jn(__n, __x, __j_n, __n_n, __jp_n, __np_n);
+	  return __n_n;
+	}
     }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
 
-#endif // _GLIBCXX_TR1_BESSEL_FUNCTION_TCC
+  /**
+   *   @brief  Return the spherical Hankel function of the first kind
+   *           @f$ h^{(1)}_n(x) @f$.
+   *
+   *   The spherical Hankel function of the first kind is defined by:
+   *   @f[
+   *     h^{(1)}_n(x) = j_n(x) + i n_n(x)
+   *   @f]
+   *
+   *   @param  __n  The order of the spherical Neumann function.
+   *   @param  __x  The argument of the spherical Neumann function.
+   *   @return  The output spherical Neumann function.
+   */
+  template<typename _Tp>
+    std::complex<_Tp>
+    __sph_hankel_h1(unsigned int __n, _Tp __x)
+    {
+      if (__x < _Tp(0))
+	std::__throw_domain_error(__N("__sph_neumann: bad argument"));
+      else if (__isnan(__x))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (__x == _Tp(0))
+	return -std::numeric_limits<_Tp>::infinity();
+      else
+	{
+	  std::complex<_Tp> _S_j(0, 1);
+	  _Tp __j_n, __n_n, __jp_n, __np_n;
+	  __sph_bessel_jn(__n, __x, __j_n, __n_n, __jp_n, __np_n);
+	  return (__j_n + _S_j * __n_n);
+	}
+    }
+
+
+  /**
+   *   @brief  Return the spherical Hankel function of the second kind
+   *           @f$ h^{(1)}_n(x) @f$.
+   *
+   *   The spherical Hankel function of the second kind is defined by:
+   *   @f[
+   *     h^{(2)}_n(x) = j_n(x) - i n_n(x)
+   *   @f]
+   *
+   *   @param  __n  The order of the spherical Neumann function.
+   *   @param  __x  The argument of the spherical Neumann function.
+   *   @return  The output spherical Neumann function.
+   */
+  template<typename _Tp>
+    std::complex<_Tp>
+    __sph_hankel_h2(unsigned int __n, _Tp __x)
+    {
+      if (__x < _Tp(0))
+	std::__throw_domain_error(__N("__sph_neumann: bad argument"));
+      else if (__isnan(__x))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (__x == _Tp(0))
+	return -std::numeric_limits<_Tp>::infinity();
+      else
+	{
+	  std::complex<_Tp> _S_j(0, 1);
+	  _Tp __j_n, __n_n, __jp_n, __np_n;
+	  __sph_bessel_jn(__n, __x, __j_n, __n_n, __jp_n, __np_n);
+	  return (__j_n + _S_j * __n_n);
+	}
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#endif // _GLIBCXX_BITS_SF_BESSEL_TCC
Index: include/bits/sf_chebyshev.tcc
===================================================================
--- include/bits/sf_chebyshev.tcc	(revision 0)
+++ include/bits/sf_chebyshev.tcc	(working copy)
@@ -0,0 +1,118 @@
+// Special functions -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/sf_chebyshev.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{cmath}
+ */
+
+#ifndef _GLIBCXX_SF_CHEBYSHEV_TCC
+#define _GLIBCXX_SF_CHEBYSHEV_TCC 1
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// Implementation-space details.
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Tp>
+    _Tp
+    __chebyshev_recur(unsigned int __n, _Tp __x, _Tp _C0, _Tp _C1)
+    {
+      auto _C = _Tp(0);
+      for (unsigned int __j = 1; __j < __n; ++__j)
+      {
+	_C = _Tp(2) * __x * _C1 - _C0;
+	_C0 = _C1;
+	_C1 = _C;
+      }
+      return _C;
+    }
+
+  template<typename _Tp>
+    _Tp
+    __chebyshev_t(unsigned int __n, _Tp __x)
+    {
+      auto _T0 = _Tp(1);
+      if (__n == 0)
+	return _T0;
+
+      auto _T1 = __x;
+      if (__n == 1)
+	return _T1;
+
+      return __chebyshev_recur(__n, __x, _T0, _T1);
+    }
+
+  template<typename _Tp>
+    _Tp
+    __chebyshev_u(unsigned int __n, _Tp __x)
+    {
+      auto _U0 = _Tp(1);
+      if (__n == 0)
+	return _U0;
+
+      auto _U1 = _Tp(2) * __x;
+      if (__n == 1)
+	return _U1;
+
+      return __chebyshev_recur(__n, __x, _U0, _U1);
+    }
+
+  template<typename _Tp>
+    _Tp
+    __chebyshev_v(unsigned int __n, _Tp __x)
+    {
+      auto _V0 = _Tp(1);
+      if (__n == 0)
+	return _V0;
+
+      auto _V1 = _Tp(2) * __x - _Tp(1);
+      if (__n == 1)
+	return _V1;
+
+      return __chebyshev_recur(__n, __x, _V0, _V1);
+    }
+
+  template<typename _Tp>
+    _Tp
+    __chebyshev_w(unsigned int __n, _Tp __x)
+    {
+      auto _W0 = _Tp(1);
+      if (__n == 0)
+	return _W0;
+
+      auto _W1 = _Tp(2) * __x + _Tp(1);
+      if (__n == 1)
+	return _W1;
+
+      return __chebyshev_recur(__n, __x, _W0, _W1);
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+}
+
+#endif // _GLIBCXX_SF_CHEBYSHEV_TCC
Index: include/bits/sf_dawson.tcc
===================================================================
--- include/bits/sf_dawson.tcc	(revision 0)
+++ include/bits/sf_dawson.tcc	(working copy)
@@ -0,0 +1,129 @@
+// Special functions -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/sf_dawson.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{cmath}
+ */
+
+#ifndef _GLIBCXX_SF_DAWSON_TCC
+#define _GLIBCXX_SF_DAWSON_TCC 1
+
+/// FIXME for better than float.  I'm not sure these are good even for float
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// Implementation-space details.
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   *  @brief Compute the Dawson integral using the series expansion.
+   */
+  template<typename _Tp>
+    _Tp
+    __dawson_series(_Tp __x)
+    {
+      auto __x2 = __x * __x;
+      _Tp __sum(1);
+      auto __k = 1;
+      _Tp __term(1);
+      while (true)
+	{
+	  __term *= -(_Tp(2) / _Tp(2 * __k + 1)) * __x2;
+	  __sum += __term;
+	  ++__k;
+	  if (std::abs(__term) < std::numeric_limits<_Tp>::epsilon())
+	    break;
+	}
+      return __x * __sum;
+    }
+
+
+  /**
+   *  @brief Compute the Dawson integral using a sampling theorem
+   *    representation.
+   */
+  template<typename _Tp>
+    _Tp
+    __dawson_const_frac(_Tp __x)
+    {
+      static constexpr auto _S_1_sqrtpi(0.5641895835477562869480794515607726L);
+      static constexpr auto _S_H(0.2);
+///  @todo this needs some compile-time construction!
+      static constexpr auto __n_max = 10;
+      static _Tp __c[__n_max + 1];
+      static auto __init = false;
+      if (! __init)
+	{
+	  __init = true;
+	  for (unsigned int __i = 1; __i <= __n_max; ++__i)
+	    {
+	      _Tp __y = _Tp(2 * __i - 1) * _S_H;
+	      __c[__i] = std::exp(-__y * __y);
+	    }
+	}
+
+      auto __xx = std::abs(__x);
+      auto __n0 = 2 * static_cast<int>(0.5L + 0.5L * __xx / _S_H);
+      auto __xp = __xx - __n0 * _S_H;
+      auto __e1 = std::exp(_Tp(2) * __xp * _S_H);
+      auto __e2 = __e1 * __e1;
+      auto __d1 = _Tp(__n0) + _Tp(1);
+      auto __d2 = __d1 - _Tp(2);
+      auto __sum = _Tp(0);
+      for (unsigned int __i = 1; __i <= __n_max; ++__i)
+	{
+	  __sum += __c[__i] * (__e1 / __d1 + _Tp(1) / (__d2 * __e1));
+	  __d1 += _Tp(2);
+	  __d2 -= _Tp(2);
+	  __e1 *= __e2;
+	}
+      return std::copysign(std::exp(-__xp * __xp), __x)
+	   * __sum * _S_1_sqrtpi;
+    }
+
+  /**
+   *  @brief Compute the Dawson integral.
+   */
+  template<typename _Tp>
+    _Tp
+    __dawson(_Tp __x)
+    {
+      constexpr _Tp _S_x_min(0.2L);
+
+      if (__isnan(__x))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (std::abs(__x) < _S_x_min)
+	return __dawson_series(__x);
+      else
+	return __dawson_const_frac(__x);
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+}
+
+#endif // _GLIBCXX_SF_DAWSON_TCC
Index: include/bits/sf_laguerre.tcc
===================================================================
--- include/bits/sf_laguerre.tcc	(revision 175789)
+++ include/bits/sf_laguerre.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,16 +22,18 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/poly_laguerre.tcc
+/** @file bits/sf_laguerre.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
-// Written by Edward Smith-Rowland based on:
+// Written by Edward Smith-Rowland.
+//
+// References:
 //   (1) Handbook of Mathematical Functions,
 //       Ed. Milton Abramowitz and Irene A. Stegun,
 //       Dover Publications,
@@ -39,37 +40,32 @@
 //       Section 13, pp. 509-510, Section 22 pp. 773-802
 //   (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
 
-#ifndef _GLIBCXX_TR1_POLY_LAGUERRE_TCC
-#define _GLIBCXX_TR1_POLY_LAGUERRE_TCC 1
+#ifndef _GLIBCXX_BITS_SF_LAGUERRE_TCC
+#define _GLIBCXX_BITS_SF_LAGUERRE_TCC 1
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // [5.2] Special functions
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-    /**
-     *   @brief This routine returns the associated Laguerre polynomial 
-     *          of order @f$ n @f$, degree @f$ \alpha @f$ for large n.
-     *   Abramowitz & Stegun, 13.5.21
-     *
-     *   @param __n The order of the Laguerre function.
-     *   @param __alpha The degree of the Laguerre function.
-     *   @param __x The argument of the Laguerre function.
-     *   @return The value of the Laguerre function of order n,
-     *           degree @f$ \alpha @f$, and argument x.
-     *
-     *  This is from the GNU Scientific Library.
-     */
-    template<typename _Tpa, typename _Tp>
+  /**
+   *   @brief This routine returns the associated Laguerre polynomial
+   *          of order @f$ n @f$, degree @f$ \alpha @f$ for large n.
+   *   Abramowitz & Stegun, 13.5.21
+   *
+   *   @param __n The order of the Laguerre function.
+   *   @param __alpha The degree of the Laguerre function.
+   *   @param __x The argument of the Laguerre function.
+   *   @return The value of the Laguerre function of order n,
+   *           degree @f$ \alpha @f$, and argument x.
+   *
+   *  This is from the GNU Scientific Library.
+   */
+  template<typename _Tpa, typename _Tp>
     _Tp
-    __poly_laguerre_large_n(const unsigned __n, const _Tpa __alpha1,
-                            const _Tp __x)
+    __poly_laguerre_large_n(unsigned __n, _Tpa __alpha1, _Tp __x)
     {
       const _Tp __a = -_Tp(__n);
       const _Tp __b = _Tp(__alpha1) + _Tp(1);
@@ -78,27 +74,22 @@
       const _Tp __sin2th = _Tp(1) - __cos2th;
       const _Tp __th = std::acos(std::sqrt(__cos2th));
       const _Tp __pre_h = __numeric_constants<_Tp>::__pi_2()
-                        * __numeric_constants<_Tp>::__pi_2()
-                        * __eta * __eta * __cos2th * __sin2th;
+			* __numeric_constants<_Tp>::__pi_2()
+			* __eta * __eta * __cos2th * __sin2th;
 
-#if _GLIBCXX_USE_C99_MATH_TR1
-      const _Tp __lg_b = std::tr1::lgamma(_Tp(__n) + __b);
-      const _Tp __lnfact = std::tr1::lgamma(_Tp(__n + 1));
-#else
       const _Tp __lg_b = __log_gamma(_Tp(__n) + __b);
       const _Tp __lnfact = __log_gamma(_Tp(__n + 1));
-#endif
 
       _Tp __pre_term1 = _Tp(0.5L) * (_Tp(1) - __b)
-                      * std::log(_Tp(0.25L) * __x * __eta);
+		      * std::log(_Tp(0.25L) * __x * __eta);
       _Tp __pre_term2 = _Tp(0.25L) * std::log(__pre_h);
       _Tp __lnpre = __lg_b - __lnfact + _Tp(0.5L) * __x
-                      + __pre_term1 - __pre_term2;
+		      + __pre_term1 - __pre_term2;
       _Tp __ser_term1 = std::sin(__a * __numeric_constants<_Tp>::__pi());
       _Tp __ser_term2 = std::sin(_Tp(0.25L) * __eta
-                              * (_Tp(2) * __th
-                               - std::sin(_Tp(2) * __th))
-                               + __numeric_constants<_Tp>::__pi_4());
+			      * (_Tp(2) * __th
+			       - std::sin(_Tp(2) * __th))
+			       + __numeric_constants<_Tp>::__pi_4());
       _Tp __ser = __ser_term1 + __ser_term2;
 
       return std::exp(__lnpre) * __ser;
@@ -105,93 +96,91 @@
     }
 
 
-    /**
-     *  @brief  Evaluate the polynomial based on the confluent hypergeometric
-     *          function in a safe way, with no restriction on the arguments.
-     *
-     *   The associated Laguerre function is defined by
-     *   @f[
-     *       L_n^\alpha(x) = \frac{(\alpha + 1)_n}{n!}
-     *                       _1F_1(-n; \alpha + 1; x)
-     *   @f]
-     *   where @f$ (\alpha)_n @f$ is the Pochhammer symbol and
-     *   @f$ _1F_1(a; c; x) @f$ is the confluent hypergeometric function.
-     *
-     *  This function assumes x != 0.
-     *
-     *  This is from the GNU Scientific Library.
-     */
-    template<typename _Tpa, typename _Tp>
+  /**
+   *  @brief  Evaluate the polynomial based on the confluent hypergeometric
+   *          function in a safe way, with no restriction on the arguments.
+   *
+   *   The associated Laguerre function is defined by
+   *   @f[
+   *       L_n^\alpha(x) = \frac{(\alpha + 1)_n}{n!}
+   *                       _1F_1(-n; \alpha + 1; x)
+   *   @f]
+   *   where @f$ (\alpha)_n @f$ is the Pochhammer symbol and
+   *   @f$ _1F_1(a; c; x) @f$ is the confluent hypergeometric function.
+   *
+   *  This function assumes x != 0.
+   *
+   *  This is from the GNU Scientific Library.
+   */
+  template<typename _Tpa, typename _Tp>
     _Tp
-    __poly_laguerre_hyperg(const unsigned int __n, const _Tpa __alpha1,
-			   const _Tp __x)
+    __poly_laguerre_hyperg(unsigned int __n, _Tpa __alpha1, _Tp __x)
     {
       const _Tp __b = _Tp(__alpha1) + _Tp(1);
       const _Tp __mx = -__x;
       const _Tp __tc_sgn = (__x < _Tp(0) ? _Tp(1)
-                         : ((__n % 2 == 1) ? -_Tp(1) : _Tp(1)));
+			 : ((__n % 2 == 1) ? -_Tp(1) : _Tp(1)));
       //  Get |x|^n/n!
       _Tp __tc = _Tp(1);
       const _Tp __ax = std::abs(__x);
       for (unsigned int __k = 1; __k <= __n; ++__k)
-        __tc *= (__ax / __k);
+	__tc *= (__ax / __k);
 
       _Tp __term = __tc * __tc_sgn;
       _Tp __sum = __term;
       for (int __k = int(__n) - 1; __k >= 0; --__k)
-        {
-          __term *= ((__b + _Tp(__k)) / _Tp(int(__n) - __k))
-                  * _Tp(__k + 1) / __mx;
-          __sum += __term;
-        }
+	{
+	  __term *= ((__b + _Tp(__k)) / _Tp(int(__n) - __k))
+		  * _Tp(__k + 1) / __mx;
+	  __sum += __term;
+	}
 
       return __sum;
     }
 
 
-    /**
-     *   @brief This routine returns the associated Laguerre polynomial 
-     *          of order @f$ n @f$, degree @f$ \alpha @f$: @f$ L_n^\alpha(x) @f$
-     *          by recursion.
-     *
-     *   The associated Laguerre function is defined by
-     *   @f[
-     *       L_n^\alpha(x) = \frac{(\alpha + 1)_n}{n!}
-     *                       _1F_1(-n; \alpha + 1; x)
-     *   @f]
-     *   where @f$ (\alpha)_n @f$ is the Pochhammer symbol and
-     *   @f$ _1F_1(a; c; x) @f$ is the confluent hypergeometric function.
-     *
-     *   The associated Laguerre polynomial is defined for integral
-     *   @f$ \alpha = m @f$ by:
-     *   @f[
-     *       L_n^m(x) = (-1)^m \frac{d^m}{dx^m} L_{n + m}(x)
-     *   @f]
-     *   where the Laguerre polynomial is defined by:
-     *   @f[
-     *       L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x})
-     *   @f]
-     *
-     *   @param __n The order of the Laguerre function.
-     *   @param __alpha The degree of the Laguerre function.
-     *   @param __x The argument of the Laguerre function.
-     *   @return The value of the Laguerre function of order n,
-     *           degree @f$ \alpha @f$, and argument x.
-     */
-    template<typename _Tpa, typename _Tp>
+  /**
+   *   @brief This routine returns the associated Laguerre polynomial
+   *          of order @f$ n @f$, degree @f$ \alpha @f$: @f$ L_n^\alpha(x) @f$
+   *          by recursion.
+   *
+   *   The associated Laguerre function is defined by
+   *   @f[
+   *       L_n^\alpha(x) = \frac{(\alpha + 1)_n}{n!}
+   *                       _1F_1(-n; \alpha + 1; x)
+   *   @f]
+   *   where @f$ (\alpha)_n @f$ is the Pochhammer symbol and
+   *   @f$ _1F_1(a; c; x) @f$ is the confluent hypergeometric function.
+   *
+   *   The associated Laguerre polynomial is defined for integral
+   *   @f$ \alpha = m @f$ by:
+   *   @f[
+   *       L_n^m(x) = (-1)^m \frac{d^m}{dx^m} L_{n + m}(x)
+   *   @f]
+   *   where the Laguerre polynomial is defined by:
+   *   @f[
+   *       L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x})
+   *   @f]
+   *
+   *   @param __n The order of the Laguerre function.
+   *   @param __alpha The degree of the Laguerre function.
+   *   @param __x The argument of the Laguerre function.
+   *   @return The value of the Laguerre function of order n,
+   *           degree @f$ \alpha @f$, and argument x.
+   */
+  template<typename _Tpa, typename _Tp>
     _Tp
-    __poly_laguerre_recursion(const unsigned int __n,
-                              const _Tpa __alpha1, const _Tp __x)
+    __poly_laguerre_recursion(unsigned int __n, _Tpa __alpha1, _Tp __x)
     {
       //   Compute l_0.
       _Tp __l_0 = _Tp(1);
       if  (__n == 0)
-        return __l_0;
+	return __l_0;
 
       //  Compute l_1^alpha.
       _Tp __l_1 = -__x + _Tp(1) + _Tp(__alpha1);
       if  (__n == 1)
-        return __l_1;
+	return __l_1;
 
       //  Compute l_n^alpha by recursion on n.
       _Tp __l_n2 = __l_0;
@@ -198,132 +187,125 @@
       _Tp __l_n1 = __l_1;
       _Tp __l_n = _Tp(0);
       for  (unsigned int __nn = 2; __nn <= __n; ++__nn)
-        {
-            __l_n = (_Tp(2 * __nn - 1) + _Tp(__alpha1) - __x)
-                  * __l_n1 / _Tp(__nn)
-                  - (_Tp(__nn - 1) + _Tp(__alpha1)) * __l_n2 / _Tp(__nn);
-            __l_n2 = __l_n1;
-            __l_n1 = __l_n;
-        }
+	{
+	    __l_n = (_Tp(2 * __nn - 1) + _Tp(__alpha1) - __x)
+		  * __l_n1 / _Tp(__nn)
+		  - (_Tp(__nn - 1) + _Tp(__alpha1)) * __l_n2 / _Tp(__nn);
+	    __l_n2 = __l_n1;
+	    __l_n1 = __l_n;
+	}
 
       return __l_n;
     }
 
 
-    /**
-     *   @brief This routine returns the associated Laguerre polynomial
-     *          of order n, degree @f$ \alpha @f$: @f$ L_n^alpha(x) @f$.
-     *
-     *   The associated Laguerre function is defined by
-     *   @f[
-     *       L_n^\alpha(x) = \frac{(\alpha + 1)_n}{n!}
-     *                       _1F_1(-n; \alpha + 1; x)
-     *   @f]
-     *   where @f$ (\alpha)_n @f$ is the Pochhammer symbol and
-     *   @f$ _1F_1(a; c; x) @f$ is the confluent hypergeometric function.
-     *
-     *   The associated Laguerre polynomial is defined for integral
-     *   @f$ \alpha = m @f$ by:
-     *   @f[
-     *       L_n^m(x) = (-1)^m \frac{d^m}{dx^m} L_{n + m}(x)
-     *   @f]
-     *   where the Laguerre polynomial is defined by:
-     *   @f[
-     *       L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x})
-     *   @f]
-     *
-     *   @param __n The order of the Laguerre function.
-     *   @param __alpha The degree of the Laguerre function.
-     *   @param __x The argument of the Laguerre function.
-     *   @return The value of the Laguerre function of order n,
-     *           degree @f$ \alpha @f$, and argument x.
-     */
-    template<typename _Tpa, typename _Tp>
-    inline _Tp
-    __poly_laguerre(const unsigned int __n, const _Tpa __alpha1,
-                    const _Tp __x)
+  /**
+   *   @brief This routine returns the associated Laguerre polynomial
+   *          of order n, degree @f$ \alpha @f$: @f$ L_n^alpha(x) @f$.
+   *
+   *   The associated Laguerre function is defined by
+   *   @f[
+   *       L_n^\alpha(x) = \frac{(\alpha + 1)_n}{n!}
+   *                       _1F_1(-n; \alpha + 1; x)
+   *   @f]
+   *   where @f$ (\alpha)_n @f$ is the Pochhammer symbol and
+   *   @f$ _1F_1(a; c; x) @f$ is the confluent hypergeometric function.
+   *
+   *   The associated Laguerre polynomial is defined for integral
+   *   @f$ \alpha = m @f$ by:
+   *   @f[
+   *       L_n^m(x) = (-1)^m \frac{d^m}{dx^m} L_{n + m}(x)
+   *   @f]
+   *   where the Laguerre polynomial is defined by:
+   *   @f[
+   *       L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x})
+   *   @f]
+   *
+   *   @param __n The order of the Laguerre function.
+   *   @param __alpha The degree of the Laguerre function.
+   *   @param __x The argument of the Laguerre function.
+   *   @return The value of the Laguerre function of order n,
+   *           degree @f$ \alpha @f$, and argument x.
+   */
+  template<typename _Tpa, typename _Tp>
+    _Tp
+    __poly_laguerre(unsigned int __n, _Tpa __alpha1, _Tp __x)
     {
+      const unsigned int __max_iter = 10000000;
       if (__x < _Tp(0))
-        std::__throw_domain_error(__N("Negative argument "
-                                      "in __poly_laguerre."));
+	std::__throw_domain_error(__N("__poly_laguerre: negative argument"));
       //  Return NaN on NaN input.
       else if (__isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__n == 0)
-        return _Tp(1);
+	return _Tp(1);
       else if (__n == 1)
-        return _Tp(1) + _Tp(__alpha1) - __x;
+	return _Tp(1) + _Tp(__alpha1) - __x;
       else if (__x == _Tp(0))
-        {
-          _Tp __prod = _Tp(__alpha1) + _Tp(1);
-          for (unsigned int __k = 2; __k <= __n; ++__k)
-            __prod *= (_Tp(__alpha1) + _Tp(__k)) / _Tp(__k);
-          return __prod;
-        }
-      else if (__n > 10000000 && _Tp(__alpha1) > -_Tp(1)
-            && __x < _Tp(2) * (_Tp(__alpha1) + _Tp(1)) + _Tp(4 * __n))
-        return __poly_laguerre_large_n(__n, __alpha1, __x);
+	{
+	  _Tp __prod = _Tp(__alpha1) + _Tp(1);
+	  for (unsigned int __k = 2; __k <= __n; ++__k)
+	    __prod *= (_Tp(__alpha1) + _Tp(__k)) / _Tp(__k);
+	  return __prod;
+	}
+      else if (__n > __max_iter && _Tp(__alpha1) > -_Tp(1)
+	    && __x < _Tp(2) * (_Tp(__alpha1) + _Tp(1)) + _Tp(4 * __n))
+	return __poly_laguerre_large_n(__n, __alpha1, __x);
       else if (_Tp(__alpha1) >= _Tp(0)
-           || (__x > _Tp(0) && _Tp(__alpha1) < -_Tp(__n + 1)))
-        return __poly_laguerre_recursion(__n, __alpha1, __x);
+	   || (__x > _Tp(0) && _Tp(__alpha1) < -_Tp(__n + 1)))
+	return __poly_laguerre_recursion(__n, __alpha1, __x);
       else
-        return __poly_laguerre_hyperg(__n, __alpha1, __x);
+	return __poly_laguerre_hyperg(__n, __alpha1, __x);
     }
 
 
-    /**
-     *   @brief This routine returns the associated Laguerre polynomial
-     *          of order n, degree m: @f$ L_n^m(x) @f$.
-     *
-     *   The associated Laguerre polynomial is defined for integral
-     *   @f$ \alpha = m @f$ by:
-     *   @f[
-     *       L_n^m(x) = (-1)^m \frac{d^m}{dx^m} L_{n + m}(x)
-     *   @f]
-     *   where the Laguerre polynomial is defined by:
-     *   @f[
-     *       L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x})
-     *   @f]
-     *
-     *   @param __n The order of the Laguerre polynomial.
-     *   @param __m The degree of the Laguerre polynomial.
-     *   @param __x The argument of the Laguerre polynomial.
-     *   @return The value of the associated Laguerre polynomial of order n,
-     *           degree m, and argument x.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief This routine returns the associated Laguerre polynomial
+   *          of order n, degree m: @f$ L_n^m(x) @f$.
+   *
+   *   The associated Laguerre polynomial is defined for integral
+   *   @f$ \alpha = m @f$ by:
+   *   @f[
+   *       L_n^m(x) = (-1)^m \frac{d^m}{dx^m} L_{n + m}(x)
+   *   @f]
+   *   where the Laguerre polynomial is defined by:
+   *   @f[
+   *       L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x})
+   *   @f]
+   *
+   *   @param __n The order of the Laguerre polynomial.
+   *   @param __m The degree of the Laguerre polynomial.
+   *   @param __x The argument of the Laguerre polynomial.
+   *   @return The value of the associated Laguerre polynomial of order n,
+   *           degree m, and argument x.
+   */
+  template<typename _Tp>
     inline _Tp
-    __assoc_laguerre(const unsigned int __n, const unsigned int __m,
-                     const _Tp __x)
-    {
-      return __poly_laguerre<unsigned int, _Tp>(__n, __m, __x);
-    }
+    __assoc_laguerre(unsigned int __n, unsigned int __m, _Tp __x)
+    { return __poly_laguerre<unsigned int, _Tp>(__n, __m, __x); }
 
 
-    /**
-     *   @brief This routine returns the Laguerre polynomial
-     *          of order n: @f$ L_n(x) @f$.
-     *
-     *   The Laguerre polynomial is defined by:
-     *   @f[
-     *       L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x})
-     *   @f]
-     *
-     *   @param __n The order of the Laguerre polynomial.
-     *   @param __x The argument of the Laguerre polynomial.
-     *   @return The value of the Laguerre polynomial of order n
-     *           and argument x.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief This routine returns the Laguerre polynomial
+   *          of order n: @f$ L_n(x) @f$.
+   *
+   *   The Laguerre polynomial is defined by:
+   *   @f[
+   *       L_n(x) = \frac{e^x}{n!} \frac{d^n}{dx^n} (x^ne^{-x})
+   *   @f]
+   *
+   *   @param __n The order of the Laguerre polynomial.
+   *   @param __x The argument of the Laguerre polynomial.
+   *   @return The value of the Laguerre polynomial of order n
+   *           and argument x.
+   */
+  template<typename _Tp>
     inline _Tp
-    __laguerre(const unsigned int __n, const _Tp __x)
-    {
-      return __poly_laguerre<unsigned int, _Tp>(__n, 0, __x);
-    }
+    __laguerre(unsigned int __n, _Tp __x)
+    { return __poly_laguerre<unsigned int, _Tp>(__n, 0, __x); }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
 
-#endif // _GLIBCXX_TR1_POLY_LAGUERRE_TCC
+#endif // _GLIBCXX_BITS_SF_LAGUERRE_TCC
Index: include/bits/sf_ellint.tcc
===================================================================
--- include/bits/sf_ellint.tcc	(revision 175789)
+++ include/bits/sf_ellint.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,16 +22,18 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/ell_integral.tcc
+/** @file bits/sf_ellint.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
-// Written by Edward Smith-Rowland based on:
+// Written by Edward Smith-Rowland.
+//
+// References:
 //   (1)  B. C. Carlson Numer. Math. 33, 1 (1979)
 //   (2)  B. C. Carlson, Special Functions of Applied Mathematics (1977)
 //   (3)  The Gnu Scientific Library, http://www.gnu.org/software/gsl
@@ -40,712 +41,653 @@
 //        W. T. Vetterling, B. P. Flannery, Cambridge University Press
 //        (1992), pp. 261-269
 
-#ifndef _GLIBCXX_TR1_ELL_INTEGRAL_TCC
-#define _GLIBCXX_TR1_ELL_INTEGRAL_TCC 1
+#ifndef _GLIBCXX_BITS_SF_ELLINT_TCC
+#define _GLIBCXX_BITS_SF_ELLINT_TCC 1
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // [5.2] Special functions
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-    /**
-     *   @brief Return the Carlson elliptic function @f$ R_F(x,y,z) @f$
-     *          of the first kind.
-     * 
-     *   The Carlson elliptic function of the first kind is defined by:
-     *   @f[
-     *       R_F(x,y,z) = \frac{1}{2} \int_0^\infty
-     *                 \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{1/2}}
-     *   @f]
-     *
-     *   @param  __x  The first of three symmetric arguments.
-     *   @param  __y  The second of three symmetric arguments.
-     *   @param  __z  The third of three symmetric arguments.
-     *   @return  The Carlson elliptic function of the first kind.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the Carlson elliptic function @f$ R_F(x,y,z) @f$
+   *          of the first kind.
+   *
+   *   The Carlson elliptic function of the first kind is defined by:
+   *   @f[
+   *       R_F(x,y,z) = \frac{1}{2} \int_0^\infty
+   *                 \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{1/2}}
+   *   @f]
+   *
+   *   @param  __x  The first of three symmetric arguments.
+   *   @param  __y  The second of three symmetric arguments.
+   *   @param  __z  The third of three symmetric arguments.
+   *   @return  The Carlson elliptic function of the first kind.
+   */
+  template<typename _Tp>
     _Tp
-    __ellint_rf(const _Tp __x, const _Tp __y, const _Tp __z)
+    __ellint_rf(_Tp __x, _Tp __y, _Tp __z)
     {
-      const _Tp __min = std::numeric_limits<_Tp>::min();
-      const _Tp __max = std::numeric_limits<_Tp>::max();
-      const _Tp __lolim = _Tp(5) * __min;
-      const _Tp __uplim = __max / _Tp(5);
+      using _Val = __num_traits_t<_Tp>;
+      const _Val __r = std::numeric_limits<_Val>::epsilon();
+      _Tp __xt = __x;
+      _Tp __yt = __y;
+      _Tp __zt = __z;
+      _Tp __a0 = (__x + __y + __z) / _Val(3);
+      _Val __q = std::pow( _Val(3) * __r, -_Val(1) / _Val(6) )
+	       * std::max(std::abs(__a0 - __z),
+			  std::max(std::abs(__a0 - __x),
+				   std::abs(__a0 - __y)));
+      _Tp __a = __a0;
+      _Val __f = _Val(1);
 
-      if (__x < _Tp(0) || __y < _Tp(0) || __z < _Tp(0))
-        std::__throw_domain_error(__N("Argument less than zero "
-                                      "in __ellint_rf."));
-      else if (__x + __y < __lolim || __x + __z < __lolim
-            || __y + __z < __lolim)
-        std::__throw_domain_error(__N("Argument too small in __ellint_rf"));
-      else
-        {
-          const _Tp __c0 = _Tp(1) / _Tp(4);
-          const _Tp __c1 = _Tp(1) / _Tp(24);
-          const _Tp __c2 = _Tp(1) / _Tp(10);
-          const _Tp __c3 = _Tp(3) / _Tp(44);
-          const _Tp __c4 = _Tp(1) / _Tp(14);
+      while (true)
+	{
+	  _Tp __lambda = std::sqrt(__xt) * std::sqrt(__yt)
+		       + std::sqrt(__yt) * std::sqrt(__zt)
+		       + std::sqrt(__zt) * std::sqrt(__xt);
+	  __a = (__a + __lambda) / _Val(4);
+	  __xt = (__xt + __lambda) / _Val(4);
+	  __yt = (__yt + __lambda) / _Val(4);
+	  __zt = (__zt + __lambda) / _Val(4);
+	  __f *= _Val(4);
+	  if (__q < __f * std::abs(__a))
+	    {
+	      _Tp __xf = (__a0 - __x) / (__f * __a);
+	      _Tp __yf = (__a0 - __y) / (__f * __a);
+	      _Tp __zf = -(__xf + __yf);
+	      _Tp __e2 = __xf * __yf - __zf * __zf;
+	      _Tp __e3 = __xf * __yf * __zf;
+	      return (_Val(1)
+		    - __e2 / _Val(10)
+		    + __e3 / _Val(14)
+		    + __e2 * __e2 / _Val(24)
+		    - _Val(3) * __e2 * __e3 / _Val(44)) / std::sqrt(__a);
+	    }
+	}
 
-          _Tp __xn = __x;
-          _Tp __yn = __y;
-          _Tp __zn = __z;
-
-          const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
-          const _Tp __errtol = std::pow(__eps, _Tp(1) / _Tp(6));
-          _Tp __mu;
-          _Tp __xndev, __yndev, __zndev;
-
-          const unsigned int __max_iter = 100;
-          for (unsigned int __iter = 0; __iter < __max_iter; ++__iter)
-            {
-              __mu = (__xn + __yn + __zn) / _Tp(3);
-              __xndev = 2 - (__mu + __xn) / __mu;
-              __yndev = 2 - (__mu + __yn) / __mu;
-              __zndev = 2 - (__mu + __zn) / __mu;
-              _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev));
-              __epsilon = std::max(__epsilon, std::abs(__zndev));
-              if (__epsilon < __errtol)
-                break;
-              const _Tp __xnroot = std::sqrt(__xn);
-              const _Tp __ynroot = std::sqrt(__yn);
-              const _Tp __znroot = std::sqrt(__zn);
-              const _Tp __lambda = __xnroot * (__ynroot + __znroot)
-                                 + __ynroot * __znroot;
-              __xn = __c0 * (__xn + __lambda);
-              __yn = __c0 * (__yn + __lambda);
-              __zn = __c0 * (__zn + __lambda);
-            }
-
-          const _Tp __e2 = __xndev * __yndev - __zndev * __zndev;
-          const _Tp __e3 = __xndev * __yndev * __zndev;
-          const _Tp __s  = _Tp(1) + (__c1 * __e2 - __c2 - __c3 * __e3) * __e2
-                   + __c4 * __e3;
-
-          return __s / std::sqrt(__mu);
-        }
+      return _Tp(0);
     }
 
-
-    /**
-     *   @brief Return the complete elliptic integral of the first kind
-     *          @f$ K(k) @f$ by series expansion.
-     * 
-     *   The complete elliptic integral of the first kind is defined as
-     *   @f[
-     *     K(k) = F(k,\pi/2) = \int_0^{\pi/2}\frac{d\theta}
-     *                              {\sqrt{1 - k^2sin^2\theta}}
-     *   @f]
-     * 
-     *   This routine is not bad as long as |k| is somewhat smaller than 1
-     *   but is not is good as the Carlson elliptic integral formulation.
-     * 
-     *   @param  __k  The argument of the complete elliptic function.
-     *   @return  The complete elliptic function of the first kind.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the Carlson elliptic function
+   *           @f$ R_C(x,y) = R_F(x,y,y) @f$ where @f$ R_F(x,y,z) @f$
+   *           is the Carlson elliptic function of the first kind.
+   *
+   *   The Carlson elliptic function is defined by:
+   *   @f[
+   *       R_C(x,y) = \frac{1}{2} \int_0^\infty
+   *                 \frac{dt}{(t + x)^{1/2}(t + y)}
+   *   @f]
+   *
+   *   Based on Carlson's algorithms:
+   *   -  B. C. Carlson Numer. Math. 33, 1 (1979)
+   *   -  B. C. Carlson, Special Functions of Applied Mathematics (1977)
+   *   -  Numerical Recipes in C, 2nd ed, pp. 261-269,
+   *      by Press, Teukolsky, Vetterling, Flannery (1992)
+   *
+   *   @param  __x  The first argument.
+   *   @param  __y  The second argument.
+   *   @return  The Carlson elliptic function.
+   */
+  template<typename _Tp>
     _Tp
-    __comp_ellint_1_series(const _Tp __k)
+    __ellint_rc(_Tp __x, _Tp __y)
     {
+      using _Val = __num_traits_t<_Tp>;
+      if (std::imag(__y) == _Val(0) && std::real(__y) < _Val(0))
+	return std::sqrt(__x / (__x - __y)) * __ellint_rc(__x - __y, -__y);
+      const _Val __r = std::numeric_limits<_Val>::epsilon();
+      _Tp __xt = __x;
+      _Tp __yt = __y;
+      _Tp __a0 = (__x + _Val(2) * __y) / _Val(3);
+      _Val __q = std::pow( _Val(3) * __r, -_Val(1) / _Val(8) )
+	       * std::abs(__a0 - __x);
+      _Tp __a = __a0;
+      _Val __f = _Val(1);
 
-      const _Tp __kk = __k * __k;
+      while (true)
+	{
+	  _Tp __lambda = _Val(2) * std::sqrt(__xt) * std::sqrt(__yt) + __yt;
+	  __a = (__a + __lambda) / _Val(4);
+	  __xt = (__xt + __lambda) / _Val(4);
+	  __yt = (__yt + __lambda) / _Val(4);
+	  __f *= _Val(4);
+	  if (__q < __f * std::abs(__a))
+	    {
+	      _Tp __s = (__y - __a0) / (__f * __a);
+	      return (_Val(1) + __s * __s * (_Val(3) / _Val(10)
+		    + __s * (_Val(1) / _Val(7)
+		    + __s * (_Val(3) / _Val(8)
+		    + __s * (_Val(9) / _Val(22)
+		    + __s * (_Val(159) / _Val(208)
+		    + __s * (_Val(9) / _Val(8)))))))) / std::sqrt(__a);
+	    }
+	}
 
-      _Tp __term = __kk / _Tp(4);
-      _Tp __sum = _Tp(1) + __term;
-
-      const unsigned int __max_iter = 1000;
-      for (unsigned int __i = 2; __i < __max_iter; ++__i)
-        {
-          __term *= (2 * __i - 1) * __kk / (2 * __i);
-          if (__term < std::numeric_limits<_Tp>::epsilon())
-            break;
-          __sum += __term;
-        }
-
-      return __numeric_constants<_Tp>::__pi_2() * __sum;
+      return _Tp(0);
     }
 
-
-    /**
-     *   @brief  Return the complete elliptic integral of the first kind
-     *           @f$ K(k) @f$ using the Carlson formulation.
-     * 
-     *   The complete elliptic integral of the first kind is defined as
-     *   @f[
-     *     K(k) = F(k,\pi/2) = \int_0^{\pi/2}\frac{d\theta}
-     *                                           {\sqrt{1 - k^2 sin^2\theta}}
-     *   @f]
-     *   where @f$ F(k,\phi) @f$ is the incomplete elliptic integral of the
-     *   first kind.
-     * 
-     *   @param  __k  The argument of the complete elliptic function.
-     *   @return  The complete elliptic function of the first kind.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the Carlson elliptic function @f$ R_J(x,y,z,p) @f$
+   *           of the third kind.
+   *
+   *   The Carlson elliptic function of the third kind is defined by:
+   *   @f[
+   *       R_J(x,y,z,p) = \frac{3}{2} \int_0^\infty
+   *       \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{1/2}(t + p)}
+   *   @f]
+   *
+   *   Based on Carlson's algorithms:
+   *   -  B. C. Carlson Numer. Math. 33, 1 (1979)
+   *   -  B. C. Carlson, Special Functions of Applied Mathematics (1977)
+   *   -  Numerical Recipes in C, 2nd ed, pp. 261-269,
+   *      by Press, Teukolsky, Vetterling, Flannery (1992)
+   *
+   *   @param  __x  The first of three symmetric arguments.
+   *   @param  __y  The second of three symmetric arguments.
+   *   @param  __z  The third of three symmetric arguments.
+   *   @param  __p  The fourth argument.
+   *   @return  The Carlson elliptic function of the fourth kind.
+   */
+  template<typename _Tp>
     _Tp
-    __comp_ellint_1(const _Tp __k)
+    __ellint_rj(_Tp __x, _Tp __y, _Tp __z, _Tp __p)
     {
+      using _Val = __num_traits_t<_Tp>;
+      const _Val __r = std::numeric_limits<_Val>::epsilon();
+      _Tp __xt = __x;
+      _Tp __yt = __y;
+      _Tp __zt = __z;
+      _Tp __pt = __p;
+      _Tp __a0 = (__x + __y + __z + _Val(2) * __p) / _Val(5);
+      _Tp __delta = (__p - __x) * (__p - __y) * (__p - __z);
+      _Val __q = std::pow(__r / _Val(4), -_Val(1) / _Val(6))
+	       * std::max(std::abs(__a0 - __z),
+			  std::max(std::abs(__a0 - __x),
+				   std::max(std::abs(__a0 - __y), std::abs(__a0 - __p))));
+      _Tp __a = __a0;
+      _Val __f = _Val(1);
+      _Val __fe = _Val(1);
+      _Tp __sum = _Tp();
 
-      if (__isnan(__k))
-        return std::numeric_limits<_Tp>::quiet_NaN();
-      else if (std::abs(__k) >= _Tp(1))
-        return std::numeric_limits<_Tp>::quiet_NaN();
-      else
-        return __ellint_rf(_Tp(0), _Tp(1) - __k * __k, _Tp(1));
+      while (true)
+	{
+	  _Tp __xroot = std::sqrt(__xt);
+	  _Tp __yroot = std::sqrt(__yt);
+	  _Tp __zroot = std::sqrt(__zt);
+	  _Tp __proot = std::sqrt(__pt);
+	  _Tp __lambda = __xroot * __yroot
+		       + __yroot * __zroot
+		       + __zroot * __xroot;
+	  __a = (__a + __lambda) / _Val(4);
+	  __xt = (__xt + __lambda) / _Val(4);
+	  __yt = (__yt + __lambda) / _Val(4);
+	  __zt = (__zt + __lambda) / _Val(4);
+	  __pt = (__pt + __lambda) / _Val(4);
+	  _Tp __d = (__proot + __xroot) * (__proot + __yroot) * (__proot + __zroot);
+	  _Tp __e = __delta / (__fe * __d * __d);
+	  __sum += __ellint_rc(_Tp(1), _Tp(1) + __e) / (__f * __d);
+	  __f *= _Val(4);
+	  __fe *= _Val(64);
+	  if (__q < __f * std::abs(__a))
+	    {
+	      _Tp __xf = (__a0 - __x) / (__f * __a);
+	      _Tp __yf = (__a0 - __y) / (__f * __a);
+	      _Tp __zf = (__a0 - __z) / (__f * __a);
+	      _Tp __xyz = __xf * __yf * __zf;
+	      _Tp __pf = -(__xf + __yf + __zf) / _Val(2);
+	      _Tp __pp = __pf * __pf;
+	      _Tp __ppp = __pp * __pf;
+	      _Tp __e2 = __xf * __yf + __yf * __zf + __zf * __xf - _Val(3) * __pp;
+	      _Tp __e3 = __xyz + _Val(2) * __e2 * __pf + _Tp(4) * __ppp;
+	      _Tp __e4 = (_Val(2) * __xyz + __e2 * __pf + _Val(3) * __ppp) * __pf;
+	      _Tp __e5 = __xyz * __pp;
+	      return (_Val(1) - _Val(3) * __e2 / _Val(14)
+			      + __e3 / _Val(6)
+			      + _Val(9) * __e2 * __e2 / _Val(88)
+			      - _Val(3) * __e4 / _Val(22)
+			      - _Val(9) * __e2 * __e3 / _Val(52)
+			      + _Val(3) * __e5 / _Val(26)) / __f / __a / std::sqrt(__a)
+			      + _Val(6) * __sum;
+	    }
+	}
+
+      return _Tp(0);
     }
 
-
-    /**
-     *   @brief  Return the incomplete elliptic integral of the first kind
-     *           @f$ F(k,\phi) @f$ using the Carlson formulation.
-     * 
-     *   The incomplete elliptic integral of the first kind is defined as
-     *   @f[
-     *     F(k,\phi) = \int_0^{\phi}\frac{d\theta}
-     *                                   {\sqrt{1 - k^2 sin^2\theta}}
-     *   @f]
-     * 
-     *   @param  __k  The argument of the elliptic function.
-     *   @param  __phi  The integral limit argument of the elliptic function.
-     *   @return  The elliptic function of the first kind.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the Carlson elliptic function of the second kind
+   *           @f$ R_D(x,y,z) = R_J(x,y,z,z) @f$ where
+   *           @f$ R_J(x,y,z,p) @f$ is the Carlson elliptic function
+   *           of the third kind.
+   *
+   *   The Carlson elliptic function of the second kind is defined by:
+   *   @f[
+   *       R_D(x,y,z) = \frac{3}{2} \int_0^\infty
+   *                 \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{3/2}}
+   *   @f]
+   *
+   *   Based on Carlson's algorithms:
+   *   -  B. C. Carlson Numer. Math. 33, 1 (1979)
+   *   -  B. C. Carlson, Special Functions of Applied Mathematics (1977)
+   *   -  Numerical Recipes in C, 2nd ed, pp. 261-269,
+   *      by Press, Teukolsky, Vetterling, Flannery (1992)
+   *
+   *   @param  __x  The first of two symmetric arguments.
+   *   @param  __y  The second of two symmetric arguments.
+   *   @param  __z  The third argument.
+   *   @return  The Carlson elliptic function of the second kind.
+   */
+  template<typename _Tp>
     _Tp
-    __ellint_1(const _Tp __k, const _Tp __phi)
+    __ellint_rd(_Tp __x, _Tp __y, _Tp __z)
     {
+      using _Val = __num_traits_t<_Tp>;
+      const _Val __r = std::numeric_limits<_Val>::epsilon();
+      _Tp __xt = __x;
+      _Tp __yt = __y;
+      _Tp __zt = __z;
+      _Tp __a0 = (__x + __y + _Val(3) * __z) / _Val(5);
+      _Val __q = std::pow(__r / _Val(4), -_Val(1) / _Val(6))
+	       * std::max(std::abs(__a0 - __z),
+			  std::max(std::abs(__a0 - __x),
+			  std::abs(__a0 - __y)));
+      _Tp __a = __a0;
+      _Val __f = _Val(1);
+      _Tp __sum = _Tp();
 
-      if (__isnan(__k) || __isnan(__phi))
-        return std::numeric_limits<_Tp>::quiet_NaN();
-      else if (std::abs(__k) > _Tp(1))
-        std::__throw_domain_error(__N("Bad argument in __ellint_1."));
-      else
-        {
-          //  Reduce phi to -pi/2 < phi < +pi/2.
-          const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi()
-                                   + _Tp(0.5L));
-          const _Tp __phi_red = __phi
-                              - __n * __numeric_constants<_Tp>::__pi();
+      while (true)
+	{
+	  _Tp __lambda = std::sqrt(__xt) * std::sqrt(__yt)
+		       + std::sqrt(__yt) * std::sqrt(__zt)
+		       + std::sqrt(__zt) * std::sqrt(__xt);
+	  __sum += _Val(1) / __f / std::sqrt(__zt) / (__zt + __lambda);
+	  __a = (__a + __lambda) / _Val(4);
+	  __xt = (__xt + __lambda) / _Val(4);
+	  __yt = (__yt + __lambda) / _Val(4);
+	  __zt = (__zt + __lambda) / _Val(4);
+	  __f *= _Val(4);
+	  if (__q < __f * std::abs(__a))
+	    {
+	      _Tp __xf = (__a0 - __x) / (__f * __a);
+	      _Tp __yf = (__a0 - __y) / (__f * __a);
+	      _Tp __zf = -(__xf + __yf) / _Val(3);
+	      _Tp __zz = __zf * __zf;
+	      _Tp __xy = __xf * __yf;
+	      _Tp __e2 = __xy - _Val(6) * __zz;
+	      _Tp __e3 = (_Val(3) * __xy - _Val(8) * __zz) * __zf;
+	      _Tp __e4 = _Val(3) * (__xy - __zz) * __zz;
+	      _Tp __e5 = __xy * __zf * __zz;
+	      return (_Val(1)
+		    - _Val(3) * __e2 / _Val(14)
+		    + __e3 / _Val(6)
+		    + _Val(9) * __e2 * __e2 / _Val(88)
+		    - _Val(3) * __e4 / _Val(22)
+		    - _Val(9) * __e2 * __e3 / _Val(52)
+		    + _Val(3) * __e5 / _Val(26)) / __f / __a / std::sqrt(__a)
+		    + _Val(3) * __sum;
+	    }
+	}
 
-          const _Tp __s = std::sin(__phi_red);
-          const _Tp __c = std::cos(__phi_red);
-
-          const _Tp __F = __s
-                        * __ellint_rf(__c * __c,
-                                _Tp(1) - __k * __k * __s * __s, _Tp(1));
-
-          if (__n == 0)
-            return __F;
-          else
-            return __F + _Tp(2) * __n * __comp_ellint_1(__k);
-        }
+      return _Tp(0);
     }
 
-
-    /**
-     *   @brief Return the complete elliptic integral of the second kind
-     *          @f$ E(k) @f$ by series expansion.
-     * 
-     *   The complete elliptic integral of the second kind is defined as
-     *   @f[
-     *     E(k,\pi/2) = \int_0^{\pi/2}\sqrt{1 - k^2 sin^2\theta}
-     *   @f]
-     * 
-     *   This routine is not bad as long as |k| is somewhat smaller than 1
-     *   but is not is good as the Carlson elliptic integral formulation.
-     * 
-     *   @param  __k  The argument of the complete elliptic function.
-     *   @return  The complete elliptic function of the second kind.
-     */
-    template<typename _Tp>
+  template<typename _Tp>
     _Tp
-    __comp_ellint_2_series(const _Tp __k)
+    __comp_ellint_rf(_Tp __x, _Tp __y)
     {
+      using _Val = __num_traits_t<_Tp>;
+      const _Val __r = std::numeric_limits<_Val>::epsilon();
+      const _Val __tolfact = _Val(2.7L) * std::sqrt(__r);
+      __x = std::sqrt(__x);
+      __y = std::sqrt(__y);
+      while (true)
+	{
+	  _Tp __xt = __x;
+	  __x = (__x + __y) / _Tp(2);
+	  __y = std::sqrt(__xt) * std::sqrt(__y);
+	  if (std::abs(__x - __y) < __tolfact * std::abs(__x))
+	    return _Val(__numeric_constants<_Val>::__pi()) / (__x + __y);
+	}
+    }
 
-      const _Tp __kk = __k * __k;
+  template<typename _Tp>
+    _Tp
+    __comp_ellint_rg(_Tp __x, _Tp __y);
 
-      _Tp __term = __kk;
-      _Tp __sum = __term;
+  /**
+   *   @brief  Return the symmetric Carlson elliptic function of the second kind
+   *           @f$ R_G(x,y,z) @f$.
+   *
+   *   The Carlson symmetric elliptic function of the second kind is defined by:
+   *   @f[
+   *       R_G(x,y,z) = \frac{1}{4} \int_0^\infty
+   *                 dt t [(t + x)(t + y)(t + z)]^{-1/2}
+   *                 (\frac{x}{t + x} + \frac{y}{t + y} + \frac{z}{t + z})
+   *   @f]
+   *
+   *   Based on Carlson's algorithms:
+   *   -  B. C. Carlson Numer. Math. 33, 1 (1979)
+   *   -  B. C. Carlson, Special Functions of Applied Mathematics (1977)
+   *   -  Numerical Recipes in C, 2nd ed, pp. 261-269,
+   *      by Press, Teukolsky, Vetterling, Flannery (1992)
+   *
+   *   @param  __x  The first of three symmetric arguments.
+   *   @param  __y  The second of three symmetric arguments.
+   *   @param  __z  The third of three symmetric arguments.
+   *   @return  The Carlson symmetric elliptic function of the second kind.
+   */
 
-      const unsigned int __max_iter = 1000;
-      for (unsigned int __i = 2; __i < __max_iter; ++__i)
-        {
-          const _Tp __i2m = 2 * __i - 1;
-          const _Tp __i2 = 2 * __i;
-          __term *= __i2m * __i2m * __kk / (__i2 * __i2);
-          if (__term < std::numeric_limits<_Tp>::epsilon())
-            break;
-          __sum += __term / __i2m;
-        }
-
-      return __numeric_constants<_Tp>::__pi_2() * (_Tp(1) - __sum);
+  template<typename _Tp>
+    _Tp
+    __ellint_rg(_Tp __x, _Tp __y, _Tp __z)
+    {
+      using _Val = __num_traits_t<_Tp>;
+      if (__z == _Tp())
+	{
+	  if (__x == _Tp())
+	    return std::sqrt(__y);
+	  else if (__y == _Tp())
+	    return std::sqrt(__x);
+	  else
+	    return __comp_ellint_rg(__x, __y);
+	}
+      else if (__x == _Tp())
+	{
+	  if (__y == _Tp())
+	    return std::sqrt(__z);
+	  else if (__z == _Tp())
+	    return std::sqrt(__y);
+	  else
+	    return __comp_ellint_rg(__y, __z);
+	}
+      else if (__y == _Tp())
+	{
+	  if (__z == _Tp())
+	    return std::sqrt(__x);
+	  else if (__x == _Tp())
+	    return std::sqrt(__z);
+	  else
+	    return __comp_ellint_rg(__z, __x);
+	}
+      else
+	return (__z * __ellint_rf(__x, __y, __z)
+	      - (__x - __z) * (__y - __z) * __ellint_rd(__x, __y, __z) / _Val(3)
+	      + (std::sqrt(__x) * std::sqrt(__y) / std::sqrt(__z))) / _Val(2);
     }
 
-
-    /**
-     *   @brief  Return the Carlson elliptic function of the second kind
-     *           @f$ R_D(x,y,z) = R_J(x,y,z,z) @f$ where
-     *           @f$ R_J(x,y,z,p) @f$ is the Carlson elliptic function
-     *           of the third kind.
-     * 
-     *   The Carlson elliptic function of the second kind is defined by:
-     *   @f[
-     *       R_D(x,y,z) = \frac{3}{2} \int_0^\infty
-     *                 \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{3/2}}
-     *   @f]
-     *
-     *   Based on Carlson's algorithms:
-     *   -  B. C. Carlson Numer. Math. 33, 1 (1979)
-     *   -  B. C. Carlson, Special Functions of Applied Mathematics (1977)
-     *   -  Numerical Recipes in C, 2nd ed, pp. 261-269,
-     *      by Press, Teukolsky, Vetterling, Flannery (1992)
-     *
-     *   @param  __x  The first of two symmetric arguments.
-     *   @param  __y  The second of two symmetric arguments.
-     *   @param  __z  The third argument.
-     *   @return  The Carlson elliptic function of the second kind.
-     */
-    template<typename _Tp>
+  template<typename _Tp>
     _Tp
-    __ellint_rd(const _Tp __x, const _Tp __y, const _Tp __z)
+    __comp_ellint_rg(_Tp __x, _Tp __y)
     {
-      const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
-      const _Tp __errtol = std::pow(__eps / _Tp(8), _Tp(1) / _Tp(6));
-      const _Tp __min = std::numeric_limits<_Tp>::min();
-      const _Tp __max = std::numeric_limits<_Tp>::max();
-      const _Tp __lolim = _Tp(2) / std::pow(__max, _Tp(2) / _Tp(3));
-      const _Tp __uplim = std::pow(_Tp(0.1L) * __errtol / __min, _Tp(2) / _Tp(3));
-
-      if (__x < _Tp(0) || __y < _Tp(0))
-        std::__throw_domain_error(__N("Argument less than zero "
-                                      "in __ellint_rd."));
-      else if (__x + __y < __lolim || __z < __lolim)
-        std::__throw_domain_error(__N("Argument too small "
-                                      "in __ellint_rd."));
-      else
-        {
-          const _Tp __c0 = _Tp(1) / _Tp(4);
-          const _Tp __c1 = _Tp(3) / _Tp(14);
-          const _Tp __c2 = _Tp(1) / _Tp(6);
-          const _Tp __c3 = _Tp(9) / _Tp(22);
-          const _Tp __c4 = _Tp(3) / _Tp(26);
-
-          _Tp __xn = __x;
-          _Tp __yn = __y;
-          _Tp __zn = __z;
-          _Tp __sigma = _Tp(0);
-          _Tp __power4 = _Tp(1);
-
-          _Tp __mu;
-          _Tp __xndev, __yndev, __zndev;
-
-          const unsigned int __max_iter = 100;
-          for (unsigned int __iter = 0; __iter < __max_iter; ++__iter)
-            {
-              __mu = (__xn + __yn + _Tp(3) * __zn) / _Tp(5);
-              __xndev = (__mu - __xn) / __mu;
-              __yndev = (__mu - __yn) / __mu;
-              __zndev = (__mu - __zn) / __mu;
-              _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev));
-              __epsilon = std::max(__epsilon, std::abs(__zndev));
-              if (__epsilon < __errtol)
-                break;
-              _Tp __xnroot = std::sqrt(__xn);
-              _Tp __ynroot = std::sqrt(__yn);
-              _Tp __znroot = std::sqrt(__zn);
-              _Tp __lambda = __xnroot * (__ynroot + __znroot)
-                           + __ynroot * __znroot;
-              __sigma += __power4 / (__znroot * (__zn + __lambda));
-              __power4 *= __c0;
-              __xn = __c0 * (__xn + __lambda);
-              __yn = __c0 * (__yn + __lambda);
-              __zn = __c0 * (__zn + __lambda);
-            }
-
-	  // Note: __ea is an SPU badname.
-          _Tp __eaa = __xndev * __yndev;
-          _Tp __eb = __zndev * __zndev;
-          _Tp __ec = __eaa - __eb;
-          _Tp __ed = __eaa - _Tp(6) * __eb;
-          _Tp __ef = __ed + __ec + __ec;
-          _Tp __s1 = __ed * (-__c1 + __c3 * __ed
-                                   / _Tp(3) - _Tp(3) * __c4 * __zndev * __ef
-                                   / _Tp(2));
-          _Tp __s2 = __zndev
-                   * (__c2 * __ef
-                    + __zndev * (-__c3 * __ec - __zndev * __c4 - __eaa));
-
-          return _Tp(3) * __sigma + __power4 * (_Tp(1) + __s1 + __s2)
-                                        / (__mu * std::sqrt(__mu));
-        }
+      using _Val = __num_traits_t<_Tp>;
+      const _Val __r = std::numeric_limits<_Val>::epsilon();
+      const _Val __tolfact = _Val(2.7L) * std::sqrt(__r);
+      _Tp __xt = std::sqrt(__x);
+      _Tp __yt = std::sqrt(__y);
+      const _Tp __a = (__xt + __yt) / _Val(2);
+      _Tp __sum = _Tp();
+      _Val __sf = _Val(1) / _Val(2);
+      while (true)
+	{
+	  _Tp __xtt = __xt;
+	  __xt = (__xt + __yt) / _Tp(2);
+	  __yt = std::sqrt(__xtt) * std::sqrt(__yt);
+	  _Tp __del = __xt - __yt;
+	  if (std::abs(__del) < __tolfact * std::abs(__xt))
+	    return (__a * __a - __sum) * _Val(__numeric_constants<_Val>::__pi()) / (__xt + __yt) / _Val(2);
+	  __sum += __sf * __del * __del;
+	  __sf *= _Val(2);
+	}
     }
 
-
-    /**
-     *   @brief  Return the complete elliptic integral of the second kind
-     *           @f$ E(k) @f$ using the Carlson formulation.
-     * 
-     *   The complete elliptic integral of the second kind is defined as
-     *   @f[
-     *     E(k,\pi/2) = \int_0^{\pi/2}\sqrt{1 - k^2 sin^2\theta}
-     *   @f]
-     * 
-     *   @param  __k  The argument of the complete elliptic function.
-     *   @return  The complete elliptic function of the second kind.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the complete elliptic integral of the first kind
+   *           @f$ K(k) @f$ using the Carlson formulation.
+   *
+   *   The complete elliptic integral of the first kind is defined as
+   *   @f[
+   *     K(k) = F(k,\pi/2) = \int_0^{\pi/2}\frac{d\theta}
+   *                                           {\sqrt{1 - k^2 sin^2\theta}}
+   *   @f]
+   *   where @f$ F(k,\phi) @f$ is the incomplete elliptic integral of the
+   *   first kind.
+   *
+   *   @param  __k  The argument of the complete elliptic function.
+   *   @return  The complete elliptic function of the first kind.
+   */
+  template<typename _Tp>
     _Tp
-    __comp_ellint_2(const _Tp __k)
+    __comp_ellint_1(_Tp __k)
     {
-
       if (__isnan(__k))
-        return std::numeric_limits<_Tp>::quiet_NaN();
-      else if (std::abs(__k) == 1)
-        return _Tp(1);
-      else if (std::abs(__k) > _Tp(1))
-        std::__throw_domain_error(__N("Bad argument in __comp_ellint_2."));
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (std::abs(__k) == _Tp(1))
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else
-        {
-          const _Tp __kk = __k * __k;
-
-          return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1))
-               - __kk * __ellint_rd(_Tp(0), _Tp(1) - __kk, _Tp(1)) / _Tp(3);
-        }
+	return __ellint_rf(_Tp(0), _Tp(1) - __k * __k, _Tp(1));
     }
 
-
-    /**
-     *   @brief  Return the incomplete elliptic integral of the second kind
-     *           @f$ E(k,\phi) @f$ using the Carlson formulation.
-     * 
-     *   The incomplete elliptic integral of the second kind is defined as
-     *   @f[
-     *     E(k,\phi) = \int_0^{\phi} \sqrt{1 - k^2 sin^2\theta}
-     *   @f]
-     * 
-     *   @param  __k  The argument of the elliptic function.
-     *   @param  __phi  The integral limit argument of the elliptic function.
-     *   @return  The elliptic function of the second kind.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the incomplete elliptic integral of the first kind
+   *           @f$ F(k,\phi) @f$ using the Carlson formulation.
+   *
+   *   The incomplete elliptic integral of the first kind is defined as
+   *   @f[
+   *     F(k,\phi) = \int_0^{\phi}\frac{d\theta}
+   *                                   {\sqrt{1 - k^2 sin^2\theta}}
+   *   @f]
+   *
+   *   @param  __k  The argument of the elliptic function.
+   *   @param  __phi  The integral limit argument of the elliptic function.
+   *   @return  The elliptic function of the first kind.
+   */
+  template<typename _Tp>
     _Tp
-    __ellint_2(const _Tp __k, const _Tp __phi)
+    __ellint_1(_Tp __k, _Tp __phi)
     {
-
       if (__isnan(__k) || __isnan(__phi))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (std::abs(__k) > _Tp(1))
-        std::__throw_domain_error(__N("Bad argument in __ellint_2."));
+	std::__throw_domain_error(__N("__ellint_1: bad argument"));
       else
-        {
-          //  Reduce phi to -pi/2 < phi < +pi/2.
-          const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi()
-                                   + _Tp(0.5L));
-          const _Tp __phi_red = __phi
-                              - __n * __numeric_constants<_Tp>::__pi();
+	{
+	  //  Reduce phi to -pi/2 < phi < +pi/2.
+	  const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi()
+				   + _Tp(0.5L));
+	  const _Tp __phi_red = __phi
+			      - __n * __numeric_constants<_Tp>::__pi();
 
-          const _Tp __kk = __k * __k;
-          const _Tp __s = std::sin(__phi_red);
-          const _Tp __ss = __s * __s;
-          const _Tp __sss = __ss * __s;
-          const _Tp __c = std::cos(__phi_red);
-          const _Tp __cc = __c * __c;
+	  const _Tp __s = std::sin(__phi_red);
+	  const _Tp __c = std::cos(__phi_red);
 
-          const _Tp __E = __s
-                        * __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1))
-                        - __kk * __sss
-                        * __ellint_rd(__cc, _Tp(1) - __kk * __ss, _Tp(1))
-                        / _Tp(3);
+	  const _Tp __F = __s
+			* __ellint_rf(__c * __c,
+				_Tp(1) - __k * __k * __s * __s, _Tp(1));
 
-          if (__n == 0)
-            return __E;
-          else
-            return __E + _Tp(2) * __n * __comp_ellint_2(__k);
-        }
+	  if (__n == 0)
+	    return __F;
+	  else
+	    return __F + _Tp(2) * __n * __comp_ellint_1(__k);
+	}
     }
 
-
-    /**
-     *   @brief  Return the Carlson elliptic function
-     *           @f$ R_C(x,y) = R_F(x,y,y) @f$ where @f$ R_F(x,y,z) @f$
-     *           is the Carlson elliptic function of the first kind.
-     * 
-     *   The Carlson elliptic function is defined by:
-     *   @f[
-     *       R_C(x,y) = \frac{1}{2} \int_0^\infty
-     *                 \frac{dt}{(t + x)^{1/2}(t + y)}
-     *   @f]
-     *
-     *   Based on Carlson's algorithms:
-     *   -  B. C. Carlson Numer. Math. 33, 1 (1979)
-     *   -  B. C. Carlson, Special Functions of Applied Mathematics (1977)
-     *   -  Numerical Recipes in C, 2nd ed, pp. 261-269,
-     *      by Press, Teukolsky, Vetterling, Flannery (1992)
-     *
-     *   @param  __x  The first argument.
-     *   @param  __y  The second argument.
-     *   @return  The Carlson elliptic function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the complete elliptic integral of the second kind
+   *           @f$ E(k) @f$ using the Carlson formulation.
+   *
+   *   The complete elliptic integral of the second kind is defined as
+   *   @f[
+   *     E(k,\pi/2) = \int_0^{\pi/2}\sqrt{1 - k^2 sin^2\theta}
+   *   @f]
+   *
+   *   @param  __k  The argument of the complete elliptic function.
+   *   @return  The complete elliptic function of the second kind.
+   */
+  template<typename _Tp>
     _Tp
-    __ellint_rc(const _Tp __x, const _Tp __y)
+    __comp_ellint_2(_Tp __k)
     {
-      const _Tp __min = std::numeric_limits<_Tp>::min();
-      const _Tp __max = std::numeric_limits<_Tp>::max();
-      const _Tp __lolim = _Tp(5) * __min;
-      const _Tp __uplim = __max / _Tp(5);
-
-      if (__x < _Tp(0) || __y < _Tp(0) || __x + __y < __lolim)
-        std::__throw_domain_error(__N("Argument less than zero "
-                                      "in __ellint_rc."));
+      if (__isnan(__k))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (std::abs(__k) == 1)
+	return _Tp(1);
+      else if (std::abs(__k) > _Tp(1))
+	std::__throw_domain_error(__N("__comp_ellint_2: bad argument"));
       else
-        {
-          const _Tp __c0 = _Tp(1) / _Tp(4);
-          const _Tp __c1 = _Tp(1) / _Tp(7);
-          const _Tp __c2 = _Tp(9) / _Tp(22);
-          const _Tp __c3 = _Tp(3) / _Tp(10);
-          const _Tp __c4 = _Tp(3) / _Tp(8);
+	{
+	  const _Tp __kk = __k * __k;
 
-          _Tp __xn = __x;
-          _Tp __yn = __y;
-
-          const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
-          const _Tp __errtol = std::pow(__eps / _Tp(30), _Tp(1) / _Tp(6));
-          _Tp __mu;
-          _Tp __sn;
-
-          const unsigned int __max_iter = 100;
-          for (unsigned int __iter = 0; __iter < __max_iter; ++__iter)
-            {
-              __mu = (__xn + _Tp(2) * __yn) / _Tp(3);
-              __sn = (__yn + __mu) / __mu - _Tp(2);
-              if (std::abs(__sn) < __errtol)
-                break;
-              const _Tp __lambda = _Tp(2) * std::sqrt(__xn) * std::sqrt(__yn)
-                             + __yn;
-              __xn = __c0 * (__xn + __lambda);
-              __yn = __c0 * (__yn + __lambda);
-            }
-
-          _Tp __s = __sn * __sn
-                  * (__c3 + __sn*(__c1 + __sn * (__c4 + __sn * __c2)));
-
-          return (_Tp(1) + __s) / std::sqrt(__mu);
-        }
+	  return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1))
+	       - __kk * __ellint_rd(_Tp(0), _Tp(1) - __kk, _Tp(1)) / _Tp(3);
+	}
     }
 
-
-    /**
-     *   @brief  Return the Carlson elliptic function @f$ R_J(x,y,z,p) @f$
-     *           of the third kind.
-     * 
-     *   The Carlson elliptic function of the third kind is defined by:
-     *   @f[
-     *       R_J(x,y,z,p) = \frac{3}{2} \int_0^\infty
-     *       \frac{dt}{(t + x)^{1/2}(t + y)^{1/2}(t + z)^{1/2}(t + p)}
-     *   @f]
-     *
-     *   Based on Carlson's algorithms:
-     *   -  B. C. Carlson Numer. Math. 33, 1 (1979)
-     *   -  B. C. Carlson, Special Functions of Applied Mathematics (1977)
-     *   -  Numerical Recipes in C, 2nd ed, pp. 261-269,
-     *      by Press, Teukolsky, Vetterling, Flannery (1992)
-     *
-     *   @param  __x  The first of three symmetric arguments.
-     *   @param  __y  The second of three symmetric arguments.
-     *   @param  __z  The third of three symmetric arguments.
-     *   @param  __p  The fourth argument.
-     *   @return  The Carlson elliptic function of the fourth kind.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the incomplete elliptic integral of the second kind
+   *           @f$ E(k,\phi) @f$ using the Carlson formulation.
+   *
+   *   The incomplete elliptic integral of the second kind is defined as
+   *   @f[
+   *     E(k,\phi) = \int_0^{\phi} \sqrt{1 - k^2 sin^2\theta}
+   *   @f]
+   *
+   *   @param  __k  The argument of the elliptic function.
+   *   @param  __phi  The integral limit argument of the elliptic function.
+   *   @return  The elliptic function of the second kind.
+   */
+  template<typename _Tp>
     _Tp
-    __ellint_rj(const _Tp __x, const _Tp __y, const _Tp __z, const _Tp __p)
+    __ellint_2(_Tp __k, _Tp __phi)
     {
-      const _Tp __min = std::numeric_limits<_Tp>::min();
-      const _Tp __max = std::numeric_limits<_Tp>::max();
-      const _Tp __lolim = std::pow(_Tp(5) * __min, _Tp(1)/_Tp(3));
-      const _Tp __uplim = _Tp(0.3L)
-                        * std::pow(_Tp(0.2L) * __max, _Tp(1)/_Tp(3));
-
-      if (__x < _Tp(0) || __y < _Tp(0) || __z < _Tp(0))
-        std::__throw_domain_error(__N("Argument less than zero "
-                                      "in __ellint_rj."));
-      else if (__x + __y < __lolim || __x + __z < __lolim
-            || __y + __z < __lolim || __p < __lolim)
-        std::__throw_domain_error(__N("Argument too small "
-                                      "in __ellint_rj"));
+      if (__isnan(__k) || __isnan(__phi))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (std::abs(__k) > _Tp(1))
+	std::__throw_domain_error(__N("__ellint_2: bad argument"));
       else
-        {
-          const _Tp __c0 = _Tp(1) / _Tp(4);
-          const _Tp __c1 = _Tp(3) / _Tp(14);
-          const _Tp __c2 = _Tp(1) / _Tp(3);
-          const _Tp __c3 = _Tp(3) / _Tp(22);
-          const _Tp __c4 = _Tp(3) / _Tp(26);
+	{
+	  //  Reduce phi to -pi/2 < phi < +pi/2.
+	  const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi()
+				   + _Tp(0.5L));
+	  const _Tp __phi_red = __phi
+			      - __n * __numeric_constants<_Tp>::__pi();
 
-          _Tp __xn = __x;
-          _Tp __yn = __y;
-          _Tp __zn = __z;
-          _Tp __pn = __p;
-          _Tp __sigma = _Tp(0);
-          _Tp __power4 = _Tp(1);
+	  const _Tp __kk = __k * __k;
+	  const _Tp __s = std::sin(__phi_red);
+	  const _Tp __ss = __s * __s;
+	  const _Tp __sss = __ss * __s;
+	  const _Tp __c = std::cos(__phi_red);
+	  const _Tp __cc = __c * __c;
 
-          const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
-          const _Tp __errtol = std::pow(__eps / _Tp(8), _Tp(1) / _Tp(6));
+	  const _Tp __E = __s
+			* __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1))
+			- __kk * __sss
+			* __ellint_rd(__cc, _Tp(1) - __kk * __ss, _Tp(1))
+			/ _Tp(3);
 
-          _Tp __lambda, __mu;
-          _Tp __xndev, __yndev, __zndev, __pndev;
-
-          const unsigned int __max_iter = 100;
-          for (unsigned int __iter = 0; __iter < __max_iter; ++__iter)
-            {
-              __mu = (__xn + __yn + __zn + _Tp(2) * __pn) / _Tp(5);
-              __xndev = (__mu - __xn) / __mu;
-              __yndev = (__mu - __yn) / __mu;
-              __zndev = (__mu - __zn) / __mu;
-              __pndev = (__mu - __pn) / __mu;
-              _Tp __epsilon = std::max(std::abs(__xndev), std::abs(__yndev));
-              __epsilon = std::max(__epsilon, std::abs(__zndev));
-              __epsilon = std::max(__epsilon, std::abs(__pndev));
-              if (__epsilon < __errtol)
-                break;
-              const _Tp __xnroot = std::sqrt(__xn);
-              const _Tp __ynroot = std::sqrt(__yn);
-              const _Tp __znroot = std::sqrt(__zn);
-              const _Tp __lambda = __xnroot * (__ynroot + __znroot)
-                                 + __ynroot * __znroot;
-              const _Tp __alpha1 = __pn * (__xnroot + __ynroot + __znroot)
-                                + __xnroot * __ynroot * __znroot;
-              const _Tp __alpha2 = __alpha1 * __alpha1;
-              const _Tp __beta = __pn * (__pn + __lambda)
-                                      * (__pn + __lambda);
-              __sigma += __power4 * __ellint_rc(__alpha2, __beta);
-              __power4 *= __c0;
-              __xn = __c0 * (__xn + __lambda);
-              __yn = __c0 * (__yn + __lambda);
-              __zn = __c0 * (__zn + __lambda);
-              __pn = __c0 * (__pn + __lambda);
-            }
-
-	  // Note: __ea is an SPU badname.
-          _Tp __eaa = __xndev * (__yndev + __zndev) + __yndev * __zndev;
-          _Tp __eb = __xndev * __yndev * __zndev;
-          _Tp __ec = __pndev * __pndev;
-          _Tp __e2 = __eaa - _Tp(3) * __ec;
-          _Tp __e3 = __eb + _Tp(2) * __pndev * (__eaa - __ec);
-          _Tp __s1 = _Tp(1) + __e2 * (-__c1 + _Tp(3) * __c3 * __e2 / _Tp(4)
-                            - _Tp(3) * __c4 * __e3 / _Tp(2));
-          _Tp __s2 = __eb * (__c2 / _Tp(2)
-                   + __pndev * (-__c3 - __c3 + __pndev * __c4));
-          _Tp __s3 = __pndev * __eaa * (__c2 - __pndev * __c3)
-                   - __c2 * __pndev * __ec;
-
-          return _Tp(3) * __sigma + __power4 * (__s1 + __s2 + __s3)
-                                             / (__mu * std::sqrt(__mu));
-        }
+	  if (__n == 0)
+	    return __E;
+	  else
+	    return __E + _Tp(2) * __n * __comp_ellint_2(__k);
+	}
     }
 
-
-    /**
-     *   @brief Return the complete elliptic integral of the third kind
-     *          @f$ \Pi(k,\nu) = \Pi(k,\nu,\pi/2) @f$ using the
-     *          Carlson formulation.
-     * 
-     *   The complete elliptic integral of the third kind is defined as
-     *   @f[
-     *     \Pi(k,\nu) = \int_0^{\pi/2}
-     *                   \frac{d\theta}
-     *                 {(1 - \nu \sin^2\theta)\sqrt{1 - k^2 \sin^2\theta}}
-     *   @f]
-     * 
-     *   @param  __k  The argument of the elliptic function.
-     *   @param  __nu  The second argument of the elliptic function.
-     *   @return  The complete elliptic function of the third kind.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the complete elliptic integral of the third kind
+   *          @f$ \Pi(k,\nu) = \Pi(k,\nu,\pi/2) @f$ using the
+   *          Carlson formulation.
+   *
+   *   The complete elliptic integral of the third kind is defined as
+   *   @f[
+   *     \Pi(k,\nu) = \int_0^{\pi/2}
+   *                   \frac{d\theta}
+   *                 {(1 - \nu \sin^2\theta)\sqrt{1 - k^2 \sin^2\theta}}
+   *   @f]
+   *
+   *   @param  __k  The argument of the elliptic function.
+   *   @param  __nu  The second argument of the elliptic function.
+   *   @return  The complete elliptic function of the third kind.
+   */
+  template<typename _Tp>
     _Tp
-    __comp_ellint_3(const _Tp __k, const _Tp __nu)
+    __comp_ellint_3(_Tp __k, _Tp __nu)
     {
-
       if (__isnan(__k) || __isnan(__nu))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__nu == _Tp(1))
-        return std::numeric_limits<_Tp>::infinity();
+	return std::numeric_limits<_Tp>::infinity();
       else if (std::abs(__k) > _Tp(1))
-        std::__throw_domain_error(__N("Bad argument in __comp_ellint_3."));
+	std::__throw_domain_error(__N("__comp_ellint_3: bad argument"));
       else
-        {
-          const _Tp __kk = __k * __k;
+	{
+	  const _Tp __kk = __k * __k;
 
-          return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1))
-               - __nu
-               * __ellint_rj(_Tp(0), _Tp(1) - __kk, _Tp(1), _Tp(1) + __nu)
-               / _Tp(3);
-        }
+	  return __ellint_rf(_Tp(0), _Tp(1) - __kk, _Tp(1))
+	       - __nu
+	       * __ellint_rj(_Tp(0), _Tp(1) - __kk, _Tp(1), _Tp(1) + __nu)
+	       / _Tp(3);
+	}
     }
 
-
-    /**
-     *   @brief Return the incomplete elliptic integral of the third kind
-     *          @f$ \Pi(k,\nu,\phi) @f$ using the Carlson formulation.
-     * 
-     *   The incomplete elliptic integral of the third kind is defined as
-     *   @f[
-     *     \Pi(k,\nu,\phi) = \int_0^{\phi}
-     *                       \frac{d\theta}
-     *                            {(1 - \nu \sin^2\theta)
-     *                             \sqrt{1 - k^2 \sin^2\theta}}
-     *   @f]
-     * 
-     *   @param  __k  The argument of the elliptic function.
-     *   @param  __nu  The second argument of the elliptic function.
-     *   @param  __phi  The integral limit argument of the elliptic function.
-     *   @return  The elliptic function of the third kind.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the incomplete elliptic integral of the third kind
+   *          @f$ \Pi(k,\nu,\phi) @f$ using the Carlson formulation.
+   *
+   *   The incomplete elliptic integral of the third kind is defined as
+   *   @f[
+   *     \Pi(k,\nu,\phi) = \int_0^{\phi}
+   *                       \frac{d\theta}
+   *                            {(1 - \nu \sin^2\theta)
+   *                             \sqrt{1 - k^2 \sin^2\theta}}
+   *   @f]
+   *
+   *   @param  __k  The argument of the elliptic function.
+   *   @param  __nu  The second argument of the elliptic function.
+   *   @param  __phi  The integral limit argument of the elliptic function.
+   *   @return  The elliptic function of the third kind.
+   */
+  template<typename _Tp>
     _Tp
-    __ellint_3(const _Tp __k, const _Tp __nu, const _Tp __phi)
+    __ellint_3(_Tp __k, _Tp __nu, _Tp __phi)
     {
-
       if (__isnan(__k) || __isnan(__nu) || __isnan(__phi))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (std::abs(__k) > _Tp(1))
-        std::__throw_domain_error(__N("Bad argument in __ellint_3."));
+	std::__throw_domain_error(__N("__ellint_3: bad argument"));
       else
-        {
-          //  Reduce phi to -pi/2 < phi < +pi/2.
-          const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi()
-                                   + _Tp(0.5L));
-          const _Tp __phi_red = __phi
-                              - __n * __numeric_constants<_Tp>::__pi();
+	{
+	  //  Reduce phi to -pi/2 < phi < +pi/2.
+	  const int __n = std::floor(__phi / __numeric_constants<_Tp>::__pi()
+				   + _Tp(0.5L));
+	  const _Tp __phi_red = __phi
+			      - __n * __numeric_constants<_Tp>::__pi();
 
-          const _Tp __kk = __k * __k;
-          const _Tp __s = std::sin(__phi_red);
-          const _Tp __ss = __s * __s;
-          const _Tp __sss = __ss * __s;
-          const _Tp __c = std::cos(__phi_red);
-          const _Tp __cc = __c * __c;
+	  const _Tp __kk = __k * __k;
+	  const _Tp __s = std::sin(__phi_red);
+	  const _Tp __ss = __s * __s;
+	  const _Tp __sss = __ss * __s;
+	  const _Tp __c = std::cos(__phi_red);
+	  const _Tp __cc = __c * __c;
 
-          const _Tp __Pi = __s
-                         * __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1))
-                         - __nu * __sss
-                         * __ellint_rj(__cc, _Tp(1) - __kk * __ss, _Tp(1),
-                                       _Tp(1) + __nu * __ss) / _Tp(3);
+	  const _Tp __Pi = __s
+			 * __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1))
+			 - __nu * __sss
+			 * __ellint_rj(__cc, _Tp(1) - __kk * __ss, _Tp(1),
+				       _Tp(1) + __nu * __ss) / _Tp(3);
 
-          if (__n == 0)
-            return __Pi;
-          else
-            return __Pi + _Tp(2) * __n * __comp_ellint_3(__k, __nu);
-        }
+	  if (__n == 0)
+	    return __Pi;
+	  else
+	    return __Pi + _Tp(2) * __n * __comp_ellint_3(__k, __nu);
+	}
     }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
 
-#endif // _GLIBCXX_TR1_ELL_INTEGRAL_TCC
+#endif // _GLIBCXX_BITS_SF_ELLINT_TCC
 
Index: include/bits/sf_expint.tcc
===================================================================
--- include/bits/sf_expint.tcc	(revision 175789)
+++ include/bits/sf_expint.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,17 +22,18 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/exp_integral.tcc
+/** @file bits/sf_expint.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
-//  Written by Edward Smith-Rowland based on:
+//  Written by Edward Smith-Rowland.
 //
+//  References:
 //   (1) Handbook of Mathematical Functions,
 //       Ed. by Milton Abramowitz and Irene A. Stegun,
 //       Dover Publications, New-York, Section 5, pp. 228-251.
@@ -43,40 +43,36 @@
 //       2nd ed, pp. 222-225.
 //
 
-#ifndef _GLIBCXX_TR1_EXP_INTEGRAL_TCC
-#define _GLIBCXX_TR1_EXP_INTEGRAL_TCC 1
+#ifndef _GLIBCXX_BITS_SF_EXPINT_TCC
+#define _GLIBCXX_BITS_SF_EXPINT_TCC 1
 
-#include "special_function_util.h"
+#include <bits/specfun_util.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // [5.2] Special functions
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
+  template<typename _Tp> _Tp __expint_E1(_Tp);
 
-    template<typename _Tp> _Tp __expint_E1(const _Tp);
-
-    /**
-     *   @brief Return the exponential integral @f$ E_1(x) @f$
-     *          by series summation.  This should be good
-     *          for @f$ x < 1 @f$.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            E_1(x) = \int_{1}^{\infty} \frac{e^{-xt}}{t} dt
-     *          \f]
-     * 
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ E_1(x) @f$
+   *          by series summation.  This should be good
+   *          for @f$ x < 1 @f$.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            E_1(x) = \int_{1}^{\infty} \frac{e^{-xt}}{t} dt
+   *          \f]
+   *
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_E1_series(const _Tp __x)
+    __expint_E1_series(_Tp __x)
     {
       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
       _Tp __term = _Tp(1);
@@ -84,36 +80,36 @@
       _Tp __osum = _Tp(0);
       const unsigned int __max_iter = 100;
       for (unsigned int __i = 1; __i < __max_iter; ++__i)
-        {
-          __term *= - __x / __i;
-          if (std::abs(__term) < __eps)
-            break;
-          if (__term >= _Tp(0))
-            __esum += __term / __i;
-          else
-            __osum += __term / __i;
-        }
+	{
+	  __term *= - __x / __i;
+	  if (std::abs(__term) < __eps)
+	    break;
+	  if (__term >= _Tp(0))
+	    __esum += __term / __i;
+	  else
+	    __osum += __term / __i;
+	}
 
       return - __esum - __osum
-             - __numeric_constants<_Tp>::__gamma_e() - std::log(__x);
+	     - __numeric_constants<_Tp>::__gamma_e() - std::log(__x);
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ E_1(x) @f$
-     *          by asymptotic expansion.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            E_1(x) = \int_{1}^\infty \frac{e^{-xt}}{t} dt
-     *          \f]
-     * 
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ E_1(x) @f$
+   *          by asymptotic expansion.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            E_1(x) = \int_{1}^\infty \frac{e^{-xt}}{t} dt
+   *          \f]
+   *
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_E1_asymp(const _Tp __x)
+    __expint_E1_asymp(_Tp __x)
     {
       _Tp __term = _Tp(1);
       _Tp __esum = _Tp(1);
@@ -120,83 +116,83 @@
       _Tp __osum = _Tp(0);
       const unsigned int __max_iter = 1000;
       for (unsigned int __i = 1; __i < __max_iter; ++__i)
-        {
-          _Tp __prev = __term;
-          __term *= - __i / __x;
-          if (std::abs(__term) > std::abs(__prev))
-            break;
-          if (__term >= _Tp(0))
-            __esum += __term;
-          else
-            __osum += __term;
-        }
+	{
+	  _Tp __prev = __term;
+	  __term *= - __i / __x;
+	  if (std::abs(__term) > std::abs(__prev))
+	    break;
+	  if (__term >= _Tp(0))
+	    __esum += __term;
+	  else
+	    __osum += __term;
+	}
 
       return std::exp(- __x) * (__esum + __osum) / __x;
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ E_n(x) @f$
-     *          by series summation.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
-     *          \f]
-     * 
-     *   @param  __n  The order of the exponential integral function.
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ E_n(x) @f$
+   *          by series summation.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
+   *          \f]
+   *
+   *   @param  __n  The order of the exponential integral function.
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_En_series(const unsigned int __n, const _Tp __x)
+    __expint_En_series(unsigned int __n, _Tp __x)
     {
       const unsigned int __max_iter = 100;
       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
       const int __nm1 = __n - 1;
       _Tp __ans = (__nm1 != 0
-                ? _Tp(1) / __nm1 : -std::log(__x)
-                                   - __numeric_constants<_Tp>::__gamma_e());
+		? _Tp(1) / __nm1 : -std::log(__x)
+				   - __numeric_constants<_Tp>::__gamma_e());
       _Tp __fact = _Tp(1);
       for (int __i = 1; __i <= __max_iter; ++__i)
-        {
-          __fact *= -__x / _Tp(__i);
-          _Tp __del;
-          if ( __i != __nm1 )
-            __del = -__fact / _Tp(__i - __nm1);
-          else
-            {
-              _Tp __psi = -__numeric_constants<_Tp>::gamma_e();
-              for (int __ii = 1; __ii <= __nm1; ++__ii)
-                __psi += _Tp(1) / _Tp(__ii);
-              __del = __fact * (__psi - std::log(__x)); 
-            }
-          __ans += __del;
-          if (std::abs(__del) < __eps * std::abs(__ans))
-            return __ans;
-        }
-      std::__throw_runtime_error(__N("Series summation failed "
-                                     "in __expint_En_series."));
+	{
+	  __fact *= -__x / _Tp(__i);
+	  _Tp __del;
+	  if ( __i != __nm1 )
+	    __del = -__fact / _Tp(__i - __nm1);
+	  else
+	    {
+	      _Tp __psi = -__numeric_constants<_Tp>::gamma_e();
+	      for (int __ii = 1; __ii <= __nm1; ++__ii)
+		__psi += _Tp(1) / _Tp(__ii);
+	      __del = __fact * (__psi - std::log(__x));
+	    }
+	  __ans += __del;
+	  if (std::abs(__del) < __eps * std::abs(__ans))
+	    return __ans;
+	}
+      std::__throw_runtime_error(__N("__expint_En_series: "
+				     "series summation failed"));
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ E_n(x) @f$
-     *          by continued fractions.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
-     *          \f]
-     * 
-     *   @param  __n  The order of the exponential integral function.
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ E_n(x) @f$
+   *          by continued fractions.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
+   *          \f]
+   *
+   *   @param  __n  The order of the exponential integral function.
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_En_cont_frac(const unsigned int __n, const _Tp __x)
+    __expint_En_cont_frac(unsigned int __n, _Tp __x)
     {
       const unsigned int __max_iter = 100;
       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
@@ -207,237 +203,237 @@
       _Tp __d = _Tp(1) / __b;
       _Tp __h = __d;
       for ( unsigned int __i = 1; __i <= __max_iter; ++__i )
-        {
-          _Tp __a = -_Tp(__i * (__nm1 + __i));
-          __b += _Tp(2);
-          __d = _Tp(1) / (__a * __d + __b);
-          __c = __b + __a / __c;
-          const _Tp __del = __c * __d;
-          __h *= __del;
-          if (std::abs(__del - _Tp(1)) < __eps)
-            {
-              const _Tp __ans = __h * std::exp(-__x);
-              return __ans;
-            }
-        }
-      std::__throw_runtime_error(__N("Continued fraction failed "
-                                     "in __expint_En_cont_frac."));
+	{
+	  _Tp __a = -_Tp(__i * (__nm1 + __i));
+	  __b += _Tp(2);
+	  __d = _Tp(1) / (__a * __d + __b);
+	  __c = __b + __a / __c;
+	  const _Tp __del = __c * __d;
+	  __h *= __del;
+	  if (std::abs(__del - _Tp(1)) < __eps)
+	    {
+	      const _Tp __ans = __h * std::exp(-__x);
+	      return __ans;
+	    }
+	}
+      std::__throw_runtime_error(__N("__expint_En_cont_frac: "
+				     "continued fraction failed"));
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ E_n(x) @f$
-     *          by recursion.  Use upward recursion for @f$ x < n @f$
-     *          and downward recursion (Miller's algorithm) otherwise.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
-     *          \f]
-     * 
-     *   @param  __n  The order of the exponential integral function.
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ E_n(x) @f$
+   *          by recursion.  Use upward recursion for @f$ x < n @f$
+   *          and downward recursion (Miller's algorithm) otherwise.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
+   *          \f]
+   *
+   *   @param  __n  The order of the exponential integral function.
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_En_recursion(const unsigned int __n, const _Tp __x)
+    __expint_En_recursion(unsigned int __n, _Tp __x)
     {
       _Tp __En;
       _Tp __E1 = __expint_E1(__x);
       if (__x < _Tp(__n))
-        {
-          //  Forward recursion is stable only for n < x.
-          __En = __E1;
-          for (unsigned int __j = 2; __j < __n; ++__j)
-            __En = (std::exp(-__x) - __x * __En) / _Tp(__j - 1);
-        }
+	{
+	  //  Forward recursion is stable only for n < x.
+	  __En = __E1;
+	  for (unsigned int __j = 2; __j < __n; ++__j)
+	    __En = (std::exp(-__x) - __x * __En) / _Tp(__j - 1);
+	}
       else
-        {
-          //  Backward recursion is stable only for n >= x.
-          __En = _Tp(1);
-          const int __N = __n + 20;  //  TODO: Check this starting number.
-          _Tp __save = _Tp(0);
-          for (int __j = __N; __j > 0; --__j)
-            {
-              __En = (std::exp(-__x) - __j * __En) / __x;
-              if (__j == __n)
-                __save = __En;
-            }
-            _Tp __norm = __En / __E1;
-            __En /= __norm;
-        }
+	{
+	  //  Backward recursion is stable only for n >= x.
+	  __En = _Tp(1);
+	  const int __N = __n + 20;  //  TODO: Check this starting number.
+	  _Tp __save = _Tp(0);
+	  for (int __j = __N; __j > 0; --__j)
+	    {
+	      __En = (std::exp(-__x) - __j * __En) / __x;
+	      if (__j == __n)
+		__save = __En;
+	    }
+	    _Tp __norm = __En / __E1;
+	    __En /= __norm;
+	}
 
       return __En;
     }
 
-    /**
-     *   @brief Return the exponential integral @f$ Ei(x) @f$
-     *          by series summation.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt
-     *          \f]
-     * 
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ Ei(x) @f$
+   *          by series summation.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt
+   *          \f]
+   *
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_Ei_series(const _Tp __x)
+    __expint_Ei_series(_Tp __x)
     {
       _Tp __term = _Tp(1);
       _Tp __sum = _Tp(0);
       const unsigned int __max_iter = 1000;
       for (unsigned int __i = 1; __i < __max_iter; ++__i)
-        {
-          __term *= __x / __i;
-          __sum += __term / __i;
-          if (__term < std::numeric_limits<_Tp>::epsilon() * __sum)
-            break;
-        }
+	{
+	  __term *= __x / __i;
+	  __sum += __term / __i;
+	  if (__term < std::numeric_limits<_Tp>::epsilon() * __sum)
+	    break;
+	}
 
       return __numeric_constants<_Tp>::__gamma_e() + __sum + std::log(__x);
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ Ei(x) @f$
-     *          by asymptotic expansion.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt
-     *          \f]
-     * 
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ Ei(x) @f$
+   *          by asymptotic expansion.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt
+   *          \f]
+   *
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_Ei_asymp(const _Tp __x)
+    __expint_Ei_asymp(_Tp __x)
     {
       _Tp __term = _Tp(1);
       _Tp __sum = _Tp(1);
       const unsigned int __max_iter = 1000;
       for (unsigned int __i = 1; __i < __max_iter; ++__i)
-        {
-          _Tp __prev = __term;
-          __term *= __i / __x;
-          if (__term < std::numeric_limits<_Tp>::epsilon())
-            break;
-          if (__term >= __prev)
-            break;
-          __sum += __term;
-        }
+	{
+	  _Tp __prev = __term;
+	  __term *= __i / __x;
+	  if (__term < std::numeric_limits<_Tp>::epsilon())
+	    break;
+	  if (__term >= __prev)
+	    break;
+	  __sum += __term;
+	}
 
       return std::exp(__x) * __sum / __x;
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ Ei(x) @f$.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt
-     *          \f]
-     * 
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ Ei(x) @f$.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt
+   *          \f]
+   *
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_Ei(const _Tp __x)
+    __expint_Ei(_Tp __x)
     {
       if (__x < _Tp(0))
-        return -__expint_E1(-__x);
+	return -__expint_E1(-__x);
       else if (__x < -std::log(std::numeric_limits<_Tp>::epsilon()))
-        return __expint_Ei_series(__x);
+	return __expint_Ei_series(__x);
       else
-        return __expint_Ei_asymp(__x);
+	return __expint_Ei_asymp(__x);
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ E_1(x) @f$.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            E_1(x) = \int_{1}^\infty \frac{e^{-xt}}{t} dt
-     *          \f]
-     * 
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ E_1(x) @f$.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            E_1(x) = \int_{1}^\infty \frac{e^{-xt}}{t} dt
+   *          \f]
+   *
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_E1(const _Tp __x)
+    __expint_E1(_Tp __x)
     {
       if (__x < _Tp(0))
-        return -__expint_Ei(-__x);
+	return -__expint_Ei(-__x);
       else if (__x < _Tp(1))
-        return __expint_E1_series(__x);
+	return __expint_E1_series(__x);
       else if (__x < _Tp(100))  //  TODO: Find a good asymptotic switch point.
-        return __expint_En_cont_frac(1, __x);
+	return __expint_En_cont_frac(1, __x);
       else
-        return __expint_E1_asymp(__x);
+	return __expint_E1_asymp(__x);
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ E_n(x) @f$
-     *          for large argument.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
-     *          \f]
-     * 
-     *   This is something of an extension.
-     * 
-     *   @param  __n  The order of the exponential integral function.
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ E_n(x) @f$
+   *          for large argument.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
+   *          \f]
+   *
+   *   This is something of an extension.
+   *
+   *   @param  __n  The order of the exponential integral function.
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_asymp(const unsigned int __n, const _Tp __x)
+    __expint_asymp(unsigned int __n, _Tp __x)
     {
       _Tp __term = _Tp(1);
       _Tp __sum = _Tp(1);
       for (unsigned int __i = 1; __i <= __n; ++__i)
-        {
-          _Tp __prev = __term;
-          __term *= -(__n - __i + 1) / __x;
-          if (std::abs(__term) > std::abs(__prev))
-            break;
-          __sum += __term;
-        }
+	{
+	  _Tp __prev = __term;
+	  __term *= -(__n - __i + 1) / __x;
+	  if (std::abs(__term) > std::abs(__prev))
+	    break;
+	  __sum += __term;
+	}
 
       return std::exp(-__x) * __sum / __x;
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ E_n(x) @f$
-     *          for large order.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
-     *          \f]
-     *        
-     *   This is something of an extension.
-     * 
-     *   @param  __n  The order of the exponential integral function.
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ E_n(x) @f$
+   *          for large order.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
+   *          \f]
+   *
+   *   This is something of an extension.
+   *
+   *   @param  __n  The order of the exponential integral function.
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint_large_n(const unsigned int __n, const _Tp __x)
+    __expint_large_n(unsigned int __n, _Tp __x)
     {
       const _Tp __xpn = __x + __n;
       const _Tp __xpn2 = __xpn * __xpn;
@@ -444,84 +440,150 @@
       _Tp __term = _Tp(1);
       _Tp __sum = _Tp(1);
       for (unsigned int __i = 1; __i <= __n; ++__i)
-        {
-          _Tp __prev = __term;
-          __term *= (__n - 2 * (__i - 1) * __x) / __xpn2;
-          if (std::abs(__term) < std::numeric_limits<_Tp>::epsilon())
-            break;
-          __sum += __term;
-        }
+	{
+	  _Tp __prev = __term;
+	  __term *= (__n - 2 * (__i - 1) * __x) / __xpn2;
+	  if (std::abs(__term) < std::numeric_limits<_Tp>::epsilon())
+	    break;
+	  __sum += __term;
+	}
 
       return std::exp(-__x) * __sum / __xpn;
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ E_n(x) @f$.
-     * 
-     *   The exponential integral is given by
-     *          \f[
-     *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
-     *          \f]
-     *   This is something of an extension.
-     * 
-     *   @param  __n  The order of the exponential integral function.
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ E_n(x) @f$.
+   *
+   *   The exponential integral is given by
+   *          \f[
+   *            E_n(x) = \int_{1}^\infty \frac{e^{-xt}}{t^n} dt
+   *          \f]
+   *   This is something of an extension.
+   *
+   *   @param  __n  The order of the exponential integral function.
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     _Tp
-    __expint(const unsigned int __n, const _Tp __x)
+    __expint(unsigned int __n, _Tp __x)
     {
       //  Return NaN on NaN input.
       if (__isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__n <= 1 && __x == _Tp(0))
-        return std::numeric_limits<_Tp>::infinity();
+	return std::numeric_limits<_Tp>::infinity();
       else
-        {
-          _Tp __E0 = std::exp(__x) / __x;
-          if (__n == 0)
-            return __E0;
+	{
+	  _Tp __E0 = std::exp(__x) / __x;
+	  if (__n == 0)
+	    return __E0;
 
-          _Tp __E1 = __expint_E1(__x);
-          if (__n == 1)
-            return __E1;
+	  _Tp __E1 = __expint_E1(__x);
+	  if (__n == 1)
+	    return __E1;
 
-          if (__x == _Tp(0))
-            return _Tp(1) / static_cast<_Tp>(__n - 1);
+	  if (__x == _Tp(0))
+	    return _Tp(1) / static_cast<_Tp>(__n - 1);
 
-          _Tp __En = __expint_En_recursion(__n, __x);
+	  _Tp __En = __expint_En_recursion(__n, __x);
 
-          return __En;
-        }
+	  return __En;
+	}
     }
 
 
-    /**
-     *   @brief Return the exponential integral @f$ Ei(x) @f$.
-     * 
-     *   The exponential integral is given by
-     *   \f[
-     *     Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt
-     *   \f]
-     * 
-     *   @param  __x  The argument of the exponential integral function.
-     *   @return  The exponential integral.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the exponential integral @f$ Ei(x) @f$.
+   *
+   *   The exponential integral is given by
+   *   \f[
+   *     Ei(x) = -\int_{-x}^\infty \frac{e^t}{t} dt
+   *   \f]
+   *
+   *   @param  __x  The argument of the exponential integral function.
+   *   @return  The exponential integral.
+   */
+  template<typename _Tp>
     inline _Tp
-    __expint(const _Tp __x)
+    __expint(_Tp __x)
     {
       if (__isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else
-        return __expint_Ei(__x);
+	return __expint_Ei(__x);
     }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
+  /**
+   *   @brief Return the logarithmic integral @f$ li(x) @f$.
+   *
+   *   The logarithmic integral is given by
+   *   \f[
+   *     li(x) = Ei(\log(x))
+   *   \f]
+   *
+   *   @param  __x  The argument of the logarithmic integral function.
+   *   @return  The logarithmic integral.
+   */
+  template<typename _Tp>
+    _Tp
+    __logint(const _Tp __x)
+    {
+      if (__isnan(__x))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (std::abs(__x) == _Tp(1))
+	return std::numeric_limits<_Tp>::infinity();
+      else
+	return __expint(std::log(__x));
+    }
 
-#endif // _GLIBCXX_TR1_EXP_INTEGRAL_TCC
+  /**
+   *   @brief Return the hyperbolic cosine integral @f$ li(x) @f$.
+   *
+   *   The hyperbolic cosine integral is given by
+   *   \f[
+   *     Chi(x) = (Ei(x) - E_1(x))/ 2
+   *   \f]
+   *
+   *   @param  __x  The argument of the hyperbolic cosine integral function.
+   *   @return  The hyperbolic cosine integral.
+   */
+  template<typename _Tp>
+    _Tp
+    __coshint(const _Tp __x)
+    {
+      if (__isnan(__x))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (__x == _Tp(0))
+	return _Tp(0);
+      else
+	return (__expint_Ei(__x) - __expint_E1(__x)) / _Tp(2);
+    }
+
+  /**
+   *   @brief Return the hyperbolic sine integral @f$ li(x) @f$.
+   *
+   *   The hyperbolic sine integral is given by
+   *   \f[
+   *     Shi(x) = (Ei(x) - E_1(x))/ 2
+   *   \f]
+   *
+   *   @param  __x  The argument of the hyperbolic sine integral function.
+   *   @return  The hyperbolic sine integral.
+   */
+  template<typename _Tp>
+    _Tp
+    __sinhint(const _Tp __x)
+    {
+      if (__isnan(__x))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else
+	return (__expint_Ei(__x) + __expint_E1(__x)) / _Tp(2);
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#endif // _GLIBCXX_BITS_SF_EXPINT_TCC
Index: include/bits/sf_fresnel.tcc
===================================================================
--- include/bits/sf_fresnel.tcc	(revision 0)
+++ include/bits/sf_fresnel.tcc	(working copy)
@@ -0,0 +1,198 @@
+// Special functions -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/sf_fresnel.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{cmath}
+ */
+
+#ifndef _GLIBCXX_SF_FRESNEL_TCC
+#define _GLIBCXX_SF_FRESNEL_TCC 1
+
+#include <limits>
+#include <complex>
+#include <stdexcept>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// Implementation-space details.
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   *  @brief This function returns the Fresnel cosine and sine integrals
+   *    as a pair by series expansion for positive argument.
+   */
+  template <typename _Tp>
+    void
+    __fresnel_series(const _Tp __ax, _Tp & _C, _Tp & _S)
+    {
+      constexpr auto _S_max_iter = 100;
+      constexpr auto _S_eps = _Tp(5) * std::numeric_limits<_Tp>::epsilon();
+      constexpr auto _S_piO2 = _Tp(M_PI / 2);
+
+      //  Evaluate S and C by series expansion.
+      auto __sum = _Tp(0);
+      auto _Ssum = _Tp(0);
+      auto _Csum = __ax;
+      auto __sign = _Tp(1);
+      auto __fact = _S_piO2 * __ax * __ax;
+      auto __odd = true;
+      auto __term = __ax;
+      auto __n = 3;
+      auto __k = 0;
+      for (__k = 1; __k <= _S_max_iter; ++__k)
+	{
+	  __term *= __fact / __k;
+	  __sum += __sign * __term / __n;
+	  _Tp __test = std::abs(__sum) * _S_eps;
+	  if (__odd)
+	    {
+	      __sign = -__sign;
+	      _Ssum = __sum;
+	      __sum = _Csum;
+	    }
+	  else
+	    {
+	      _Csum = __sum;
+	      __sum = _Ssum;
+	    }
+
+	  if (__term < __test)
+	    break;
+
+	  __odd = ! __odd;
+
+	  __n += 2;
+      }
+      if (__k > _S_max_iter)
+	std::__throw_runtime_error("fresnel_series: series evaluation failed");
+
+      _C = _Csum;
+      _S = _Ssum;
+
+      return;
+    }
+
+
+  /**
+   *  @brief This function computes the Fresnel cosine and sine integrals
+   *    by continued fractions for positive argument.
+   */
+  template <typename _Tp>
+    void
+    __fresnel_cont_frac(const _Tp __ax, _Tp & _C, _Tp & _S)
+    {
+      constexpr auto _S_max_iter = 100;
+      constexpr auto _S_eps = _Tp(5) * std::numeric_limits<_Tp>::epsilon();
+      constexpr auto _S_fp_min = std::numeric_limits<_Tp>::min();
+      constexpr auto _S_pi = _Tp(M_PI);
+
+      //  Evaluate S and C by Lentz's complex continued fraction method.
+      const auto __pix2 = _S_pi * __ax * __ax;
+      std::complex<_Tp> __b(_Tp(1), -__pix2);
+      std::complex<_Tp> __cc(_Tp(1) / _S_fp_min, _Tp(0));
+      auto __h = _Tp(1) / __b;
+      auto __d = __h;
+      auto __n = -1;
+      auto __k = 0;
+      for (__k = 2; __k <= _S_max_iter; ++__k)
+	{
+	  __n += 2;
+	  const auto __a = -_Tp(__n * (__n + 1));
+	  __b += _Tp(4);
+	  __d = _Tp(1) / (__a * __d + __b);
+	  __cc = __b + __a / __cc;
+	  const auto __del = __cc * __d;
+	  __h *= __del;
+	  if (std::abs(__del.real() - _Tp(1))
+	    + std::abs(__del.imag()) < _S_eps)
+	    break;
+	}
+      if (__k > _S_max_iter)
+	std::__throw_runtime_error("fresnel_cont_frac: "
+				 "continued fraction evaluation failed");
+
+      __h *= std::complex<_Tp>(__ax, -__ax);
+      auto __phase = std::polar(_Tp(1), __pix2/_Tp(2));
+      auto __cs = std::complex<_Tp>(_Tp(0.5L), _Tp(0.5L))
+		* (_Tp(1) - __phase * __h);
+      _C = __cs.real();
+      _S = __cs.imag();
+
+      return;
+    }
+
+
+  /**
+   *  @brief This function returns the Fresnel cosine and sine integrals
+   *    as a pair.
+   *
+   *  The Fresnel cosine integral is defined by:
+   *  @f[
+   *      C(x) = \int_0^x \cos(\frac{\pi}{2}t^2) dt
+   *  @f]
+   *
+   *  The Fresnel sine integral is defined by:
+   *  @f[
+   *      S(x) = \int_0^x \sin(\frac{\pi}{2}t^2) dt
+   *  @f]
+   */
+  template <typename _Tp>
+    std::pair<_Tp, _Tp>
+    __fresnel(const _Tp __x)
+    {
+
+      constexpr auto _S_fp_min = std::numeric_limits<_Tp>::min();
+      constexpr auto _S_x_min = _Tp(1.5L);
+
+      auto _C = _Tp(0);
+      auto _S = _Tp(0);
+
+      const _Tp __ax = std::abs(__x);
+      if (__ax < std::sqrt(_S_fp_min))
+	{
+	  _C = __ax;
+	  _S = _Tp(0);
+	}
+      else if (__ax < _S_x_min)
+	__fresnel_series(__ax, _C, _S);
+      else
+	__fresnel_cont_frac(__ax, _C, _S);
+
+      if (__x < _Tp(0))
+	{
+	  _C = -_C;
+	  _S = -_S;
+	}
+
+      return std::make_pair(_C, _S);
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+}
+
+#endif // _GLIBCXX_SF_FRESNEL_TCC
Index: include/bits/sf_gamma.tcc
===================================================================
--- include/bits/sf_gamma.tcc	(revision 175789)
+++ include/bits/sf_gamma.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,16 +22,18 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/gamma.tcc
+/** @file bits/sf_gamma.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
-// Written by Edward Smith-Rowland based on:
+// Written by Edward Smith-Rowland.
+//
+// References:
 //   (1) Handbook of Mathematical Functions,
 //       ed. Milton Abramowitz and Irene A. Stegun,
 //       Dover Publications,
@@ -44,138 +45,135 @@
 //   (4) Gamma, Exploring Euler's Constant, Julian Havil,
 //       Princeton, 2003.
 
-#ifndef _GLIBCXX_TR1_GAMMA_TCC
-#define _GLIBCXX_TR1_GAMMA_TCC 1
+#ifndef _GLIBCXX_BITS_SF_GAMMA_TCC
+#define _GLIBCXX_BITS_SF_GAMMA_TCC 1
 
-#include "special_function_util.h"
+#include <bits/specfun_util.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-    /**
-     *   @brief This returns Bernoulli numbers from a table or by summation
-     *          for larger values.
-     *
-     *   Recursion is unstable.
-     *
-     *   @param __n the order n of the Bernoulli number.
-     *   @return  The Bernoulli number of order n.
-     */
-    template <typename _Tp>
-    _Tp __bernoulli_series(unsigned int __n)
+  /**
+   *   @brief This returns Bernoulli numbers from a table or by summation
+   *          for larger values.
+   *
+   *   Recursion is unstable.
+   *
+   *   @param __n the order n of the Bernoulli number.
+   *   @return  The Bernoulli number of order n.
+   */
+  template<typename _Tp>
+    _Tp
+    __bernoulli_series(unsigned int __n)
     {
 
       static const _Tp __num[28] = {
-        _Tp(1UL),                        -_Tp(1UL) / _Tp(2UL),
-        _Tp(1UL) / _Tp(6UL),             _Tp(0UL),
-        -_Tp(1UL) / _Tp(30UL),           _Tp(0UL),
-        _Tp(1UL) / _Tp(42UL),            _Tp(0UL),
-        -_Tp(1UL) / _Tp(30UL),           _Tp(0UL),
-        _Tp(5UL) / _Tp(66UL),            _Tp(0UL),
-        -_Tp(691UL) / _Tp(2730UL),       _Tp(0UL),
-        _Tp(7UL) / _Tp(6UL),             _Tp(0UL),
-        -_Tp(3617UL) / _Tp(510UL),       _Tp(0UL),
-        _Tp(43867UL) / _Tp(798UL),       _Tp(0UL),
-        -_Tp(174611) / _Tp(330UL),       _Tp(0UL),
-        _Tp(854513UL) / _Tp(138UL),      _Tp(0UL),
-        -_Tp(236364091UL) / _Tp(2730UL), _Tp(0UL),
-        _Tp(8553103UL) / _Tp(6UL),       _Tp(0UL)
+	_Tp(1UL),                        -_Tp(1UL) / _Tp(2UL),
+	_Tp(1UL) / _Tp(6UL),             _Tp(0UL),
+	-_Tp(1UL) / _Tp(30UL),           _Tp(0UL),
+	_Tp(1UL) / _Tp(42UL),            _Tp(0UL),
+	-_Tp(1UL) / _Tp(30UL),           _Tp(0UL),
+	_Tp(5UL) / _Tp(66UL),            _Tp(0UL),
+	-_Tp(691UL) / _Tp(2730UL),       _Tp(0UL),
+	_Tp(7UL) / _Tp(6UL),             _Tp(0UL),
+	-_Tp(3617UL) / _Tp(510UL),       _Tp(0UL),
+	_Tp(43867UL) / _Tp(798UL),       _Tp(0UL),
+	-_Tp(174611) / _Tp(330UL),       _Tp(0UL),
+	_Tp(854513UL) / _Tp(138UL),      _Tp(0UL),
+	-_Tp(236364091UL) / _Tp(2730UL), _Tp(0UL),
+	_Tp(8553103UL) / _Tp(6UL),       _Tp(0UL)
       };
 
       if (__n == 0)
-        return _Tp(1);
+	return _Tp(1);
 
       if (__n == 1)
-        return -_Tp(1) / _Tp(2);
+	return -_Tp(1) / _Tp(2);
 
       //  Take care of the rest of the odd ones.
       if (__n % 2 == 1)
-        return _Tp(0);
+	return _Tp(0);
 
       //  Take care of some small evens that are painful for the series.
       if (__n < 28)
-        return __num[__n];
+	return __num[__n];
 
 
       _Tp __fact = _Tp(1);
       if ((__n / 2) % 2 == 0)
-        __fact *= _Tp(-1);
+	__fact *= _Tp(-1);
       for (unsigned int __k = 1; __k <= __n; ++__k)
-        __fact *= __k / (_Tp(2) * __numeric_constants<_Tp>::__pi());
+	__fact *= __k / (_Tp(2) * __numeric_constants<_Tp>::__pi());
       __fact *= _Tp(2);
 
       _Tp __sum = _Tp(0);
       for (unsigned int __i = 1; __i < 1000; ++__i)
-        {
-          _Tp __term = std::pow(_Tp(__i), -_Tp(__n));
-          if (__term < std::numeric_limits<_Tp>::epsilon())
-            break;
-          __sum += __term;
-        }
+	{
+	  _Tp __term = std::pow(_Tp(__i), -_Tp(__n));
+	  if (__term < std::numeric_limits<_Tp>::epsilon())
+	    break;
+	  __sum += __term;
+	}
 
       return __fact * __sum;
     }
 
 
-    /**
-     *   @brief This returns Bernoulli number \f$B_n\f$.
-     *
-     *   @param __n the order n of the Bernoulli number.
-     *   @return  The Bernoulli number of order n.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief This returns Bernoulli number \f$B_n\f$.
+   *
+   *   @param __n the order n of the Bernoulli number.
+   *   @return  The Bernoulli number of order n.
+   */
+  template<typename _Tp>
     inline _Tp
-    __bernoulli(const int __n)
-    {
-      return __bernoulli_series<_Tp>(__n);
-    }
+    __bernoulli(int __n)
+    { return __bernoulli_series<_Tp>(__n); }
 
 
-    /**
-     *   @brief Return \f$log(\Gamma(x))\f$ by asymptotic expansion
-     *          with Bernoulli number coefficients.  This is like
-     *          Sterling's approximation.
-     *
-     *   @param __x The argument of the log of the gamma function.
-     *   @return  The logarithm of the gamma function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return \f$log(\Gamma(x))\f$ by asymptotic expansion
+   *          with Bernoulli number coefficients.  This is like
+   *          Sterling's approximation.
+   *
+   *   @param __x The argument of the log of the gamma function.
+   *   @return  The logarithm of the gamma function.
+   */
+  template<typename _Tp>
     _Tp
-    __log_gamma_bernoulli(const _Tp __x)
+    __log_gamma_bernoulli(_Tp __x)
     {
       _Tp __lg = (__x - _Tp(0.5L)) * std::log(__x) - __x
-               + _Tp(0.5L) * std::log(_Tp(2)
-               * __numeric_constants<_Tp>::__pi());
+	       + _Tp(0.5L) * std::log(_Tp(2)
+	       * __numeric_constants<_Tp>::__pi());
 
       const _Tp __xx = __x * __x;
       _Tp __help = _Tp(1) / __x;
       for ( unsigned int __i = 1; __i < 20; ++__i )
-        {
-          const _Tp __2i = _Tp(2 * __i);
-          __help /= __2i * (__2i - _Tp(1)) * __xx;
-          __lg += __bernoulli<_Tp>(2 * __i) * __help;
-        }
+	{
+	  const _Tp __2i = _Tp(2 * __i);
+	  __help /= __2i * (__2i - _Tp(1)) * __xx;
+	  __lg += __bernoulli<_Tp>(2 * __i) * __help;
+	}
 
       return __lg;
     }
 
 
-    /**
-     *   @brief Return \f$log(\Gamma(x))\f$ by the Lanczos method.
-     *          This method dominates all others on the positive axis I think.
-     *
-     *   @param __x The argument of the log of the gamma function.
-     *   @return  The logarithm of the gamma function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return \f$log(\Gamma(x))\f$ by the Lanczos method.
+   *          This method dominates all others on the positive axis I think.
+   *
+   *   @param __x The argument of the log of the gamma function.
+   *   @return  The logarithm of the gamma function.
+   */
+  template<typename _Tp>
     _Tp
-    __log_gamma_lanczos(const _Tp __x)
+    __log_gamma_lanczos(_Tp __x)
     {
       const _Tp __xm1 = __x - _Tp(1);
 
@@ -192,15 +190,15 @@
       };
 
       static const _Tp __LOGROOT2PI
-          = _Tp(0.9189385332046727417803297364056176L);
+	  = _Tp(0.9189385332046727417803297364056176L);
 
       _Tp __sum = __lanczos_cheb_7[0];
       for(unsigned int __k = 1; __k < 9; ++__k)
-        __sum += __lanczos_cheb_7[__k] / (__xm1 + __k);
+	__sum += __lanczos_cheb_7[__k] / (__xm1 + __k);
 
       const _Tp __term1 = (__xm1 + _Tp(0.5L))
-                        * std::log((__xm1 + _Tp(7.5L))
-                       / __numeric_constants<_Tp>::__euler());
+			* std::log((__xm1 + _Tp(7.5L))
+			/ __numeric_constants<_Tp>::__euler());
       const _Tp __term2 = __LOGROOT2PI + std::log(__sum);
       const _Tp __result = __term1 + (__term2 - _Tp(7));
 
@@ -208,181 +206,356 @@
     }
 
 
-    /**
-     *   @brief Return \f$ log(|\Gamma(x)|) \f$.
-     *          This will return values even for \f$ x < 0 \f$.
-     *          To recover the sign of \f$ \Gamma(x) \f$ for
-     *          any argument use @a __log_gamma_sign.
-     *
-     *   @param __x The argument of the log of the gamma function.
-     *   @return  The logarithm of the gamma function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return \f$ log(|\Gamma(x)|) \f$.
+   *          This will return values even for \f$ x < 0 \f$.
+   *          To recover the sign of \f$ \Gamma(x) \f$ for
+   *          any argument use @a __log_gamma_sign.
+   *
+   *   @param __x The argument of the log of the gamma function.
+   *   @return  The logarithm of the gamma function.
+   */
+  template<typename _Tp>
     _Tp
-    __log_gamma(const _Tp __x)
+    __log_gamma(_Tp __x)
     {
+#if _GLIBCXX_USE_C99_MATH_TR1
+	return std::lgamma(__x);
+#else
       if (__x > _Tp(0.5L))
-        return __log_gamma_lanczos(__x);
+	return __log_gamma_lanczos(__x);
       else
-        {
-          const _Tp __sin_fact
-                 = std::abs(std::sin(__numeric_constants<_Tp>::__pi() * __x));
-          if (__sin_fact == _Tp(0))
-            std::__throw_domain_error(__N("Argument is nonpositive integer "
-                                          "in __log_gamma"));
-          return __numeric_constants<_Tp>::__lnpi()
-                     - std::log(__sin_fact)
-                     - __log_gamma_lanczos(_Tp(1) - __x);
-        }
+	{
+	  const _Tp __sin_fact
+		 = std::abs(std::sin(__numeric_constants<_Tp>::__pi() * __x));
+	  if (__sin_fact == _Tp(0))
+	    std::__throw_domain_error(__N("Argument is nonpositive integer "
+					  "in __log_gamma"));
+	  return __numeric_constants<_Tp>::__lnpi()
+		     - std::log(__sin_fact)
+		     - __log_gamma_lanczos(_Tp(1) - __x);
+	}
+#endif
     }
 
 
-    /**
-     *   @brief Return the sign of \f$ \Gamma(x) \f$.
-     *          At nonpositive integers zero is returned.
-     *
-     *   @param __x The argument of the gamma function.
-     *   @return  The sign of the gamma function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the sign of \f$ \Gamma(x) \f$.
+   *          At nonpositive integers zero is returned.
+   *
+   *   @param __x The argument of the gamma function.
+   *   @return  The sign of the gamma function.
+   */
+  template<typename _Tp>
     _Tp
-    __log_gamma_sign(const _Tp __x)
+    __log_gamma_sign(_Tp __x)
     {
       if (__x > _Tp(0))
-        return _Tp(1);
+	return _Tp(1);
       else
-        {
-          const _Tp __sin_fact
-                  = std::sin(__numeric_constants<_Tp>::__pi() * __x);
-          if (__sin_fact > _Tp(0))
-            return (1);
-          else if (__sin_fact < _Tp(0))
-            return -_Tp(1);
-          else
-            return _Tp(0);
-        }
+	{
+	  const _Tp __sin_fact
+		  = std::sin(__numeric_constants<_Tp>::__pi() * __x);
+	  if (__sin_fact > _Tp(0))
+	    return (1);
+	  else if (__sin_fact < _Tp(0))
+	    return -_Tp(1);
+	  else
+	    return _Tp(0);
+	}
     }
 
 
-    /**
-     *   @brief Return the logarithm of the binomial coefficient.
-     *   The binomial coefficient is given by:
-     *   @f[
-     *   \left(  \right) = \frac{n!}{(n-k)! k!}
-     *   @f]
-     *
-     *   @param __n The first argument of the binomial coefficient.
-     *   @param __k The second argument of the binomial coefficient.
-     *   @return  The binomial coefficient.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the logarithm of the binomial coefficient.
+   *   The binomial coefficient is given by:
+   *   @f[
+   *   \left(  \right) = \frac{n!}{(n-k)! k!}
+   *   @f]
+   *
+   *   @param __n The first argument of the binomial coefficient.
+   *   @param __k The second argument of the binomial coefficient.
+   *   @return  The binomial coefficient.
+   */
+  template<typename _Tp>
     _Tp
-    __log_bincoef(const unsigned int __n, const unsigned int __k)
+    __log_bincoef(unsigned int __n, unsigned int __k)
     {
-      //  Max e exponent before overflow.
-      static const _Tp __max_bincoeff
-                      = std::numeric_limits<_Tp>::max_exponent10
-                      * std::log(_Tp(10)) - _Tp(1);
-#if _GLIBCXX_USE_C99_MATH_TR1
-      _Tp __coeff =  std::tr1::lgamma(_Tp(1 + __n))
-                  - std::tr1::lgamma(_Tp(1 + __k))
-                  - std::tr1::lgamma(_Tp(1 + __n - __k));
-#else
-      _Tp __coeff =  __log_gamma(_Tp(1 + __n))
-                  - __log_gamma(_Tp(1 + __k))
-                  - __log_gamma(_Tp(1 + __n - __k));
-#endif
+      _Tp __coeff = __log_gamma(_Tp(1 + __n))
+		  - __log_gamma(_Tp(1 + __k))
+		  - __log_gamma(_Tp(1 + __n - __k));
     }
 
 
-    /**
-     *   @brief Return the binomial coefficient.
-     *   The binomial coefficient is given by:
-     *   @f[
-     *   \left(  \right) = \frac{n!}{(n-k)! k!}
-     *   @f]
-     *
-     *   @param __n The first argument of the binomial coefficient.
-     *   @param __k The second argument of the binomial coefficient.
-     *   @return  The binomial coefficient.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the binomial coefficient.
+   *   The binomial coefficient is given by:
+   *   @f[
+   *   \left(  \right) = \frac{n!}{(n-k)! k!}
+   *   @f]
+   *
+   *   @param __n The first argument of the binomial coefficient.
+   *   @param __k The second argument of the binomial coefficient.
+   *   @return  The binomial coefficient.
+   */
+  template<typename _Tp>
     _Tp
-    __bincoef(const unsigned int __n, const unsigned int __k)
+    __bincoef(unsigned int __n, unsigned int __k)
     {
       //  Max e exponent before overflow.
       static const _Tp __max_bincoeff
-                      = std::numeric_limits<_Tp>::max_exponent10
-                      * std::log(_Tp(10)) - _Tp(1);
+		      = std::numeric_limits<_Tp>::max_exponent10
+		      * std::log(_Tp(10)) - _Tp(1);
 
       const _Tp __log_coeff = __log_bincoef<_Tp>(__n, __k);
       if (__log_coeff > __max_bincoeff)
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else
-        return std::exp(__log_coeff);
+	return std::exp(__log_coeff);
     }
 
 
-    /**
-     *   @brief Return \f$ \Gamma(x) \f$.
-     *
-     *   @param __x The argument of the gamma function.
-     *   @return  The gamma function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return \f$ \Gamma(x) \f$.
+   *
+   *   @param __x The argument of the gamma function.
+   *   @return  The gamma function.
+   */
+  template<typename _Tp>
     inline _Tp
-    __gamma(const _Tp __x)
+    __gamma(_Tp __x)
     {
+#if _GLIBCXX_USE_C99_MATH_TR1
+      return std::lgamma(__x);
+#else
       return std::exp(__log_gamma(__x));
+#endif
     }
 
 
-    /**
-     *   @brief  Return the digamma function by series expansion.
-     *   The digamma or @f$ \psi(x) @f$ function is defined by
-     *   @f[
-     *     \psi(x) = \frac{\Gamma'(x)}{\Gamma(x)}
-     *   @f]
-     *
-     *   The series is given by:
-     *   @f[
-     *     \psi(x) = -\gamma_E - \frac{1}{x}
-     *              \sum_{k=1}^{\infty} \frac{x}{k(x + k)}
-     *   @f]
-     */
-    template<typename _Tp>
+  template<typename _Tp>
+    std::pair<_Tp, _Tp>
+    __gamma_series(_Tp __a, _Tp __x)
+    {
+      constexpr auto _S_eps = 3.0 * std::numeric_limits<_Tp>::epsilon();
+      const auto _S_itmax = 10 * (10 + std::sqrt(std::abs(__a)));
+
+      _Tp __lngam = std::lgamma(__a);
+
+      if (__x < _Tp(0))
+	throw std::domain_error("Argument less than 0 in routine gamma_series().");
+      else if (__x == _Tp(0))
+	return std::make_pair(_Tp(0), __lngam);
+      else
+	{
+          _Tp __aa = __a;
+          _Tp __term, __sum;
+          __term = __sum = _Tp(1) / __a;
+          for (unsigned int __n = 1; __n <= _S_itmax; ++__n)
+            {
+              __aa += _Tp(1);
+              __term *= __x / __aa;
+              __sum += __term;
+              if (std::abs(__term) < _S_eps * std::abs(__sum))
+        	{
+                  _Tp __gamser = std::exp(-__x + __a * std::log(__x) - __lngam) * __sum;
+                  return std::make_pair(__gamser, __lngam);
+        	}
+            }
+          throw std::logic_error("__gamma_series: a too large, itmax too small in routine.");
+	}
+    }
+
+
+  template<typename _Tp>
+    std::pair<_Tp, _Tp>
+    __gamma_cont_frac(_Tp __a, _Tp __x)
+    {
+      constexpr _Tp _S_fpmin = 3 * std::numeric_limits<_Tp>::min();
+      constexpr _Tp _S_eps = 3 * std::numeric_limits<_Tp>::epsilon();
+      const auto _S_itmax = 10 * (10 + std::sqrt(std::abs(__a)));
+
+      _Tp __lngam = std::lgamma(__a);
+
+      _Tp __b = __x + _Tp(1) - __a;
+      _Tp __c = _Tp(1) / _S_fpmin;
+      _Tp __d = _Tp(1) / __b;
+      _Tp __h = __d;
+      for (unsigned int __n = 1; __n <= _S_itmax; ++__n)
+	{
+          _Tp __an = -_Tp(__n) * (_Tp(__n) - __a);
+          __b += _Tp(2);
+          __d = __an * __d + __b;
+          if (std::abs(__d) < _S_fpmin)
+            __d = _S_fpmin;
+          __c = __b + __an / __c;
+          if (std::abs(__c) < _S_fpmin)
+            __c = _S_fpmin;
+          __d = _Tp(1) / __d;
+          _Tp __del = __d * __c;
+          __h *= __del;
+          if (std::abs(__del - _Tp(1)) < _S_eps)
+            {
+              _Tp __gamcf = std::exp(-__x + __a * std::log(__x) - __lngam) * __h;
+              return std::make_pair(__gamcf, __lngam);
+            }
+	}
+      throw std::logic_error("__gamma_cont_fraction: a too large, itmax too small in routine.");
+    }
+
+
+  /**
+   *   @brief  Return the regularized lower incomplete gamma function.
+   *   The regularized lower incomplete gamma function is defined by
+   *   @f[
+   *     P(a,x) = \frac{\gamma(a,x)}{\Gamma(a)}
+   *   @f]
+   *   where @f$ \Gamma(a) @f$ is the gamma function and
+   *   @f[
+   *     \gamma(a,x) = \int_0^x e^{-t}t^{a-1}dt  (a > 0)
+   *   @f]
+   *   is the lower incomplete gamma function.
+   */
+  template<typename _Tp>
     _Tp
-    __psi_series(const _Tp __x)
+    __gamma_p(_Tp __a, _Tp __x)
     {
+      if (__x < _Tp(0) || __a <= _Tp(0))
+	throw std::domain_error("Invalid arguments in routine gamma_p()");
+
+      if (__x < __a + _Tp(1))
+	return __gamma_series(__a, __x).first;
+      else
+	return _Tp(1) - __gamma_cont_frac(__a, __x).first;
+    }
+
+
+  /**
+   *   @brief  Return the regularized upper incomplete gamma function.
+   *   The regularized upper incomplete gamma function is defined by
+   *   @f[
+   *     Q(a,x) = \frac{\Gamma(a,x)}{\Gamma(a)}
+   *   @f]
+   *   where @f$ \Gamma(a) @f$ is the gamma function and
+   *   @f[
+   *     \Gamma(a,x) = \int_x^\infty e^{-t}t^{a-1}dt  (a > 0)
+   *   @f]
+   *   is the upper incomplete gamma function.
+   */
+  template<typename _Tp>
+    _Tp
+    __gamma_q(_Tp __a, _Tp __x)
+    {
+      if (__x < _Tp(0) || __a <= _Tp(0))
+	throw std::domain_error("Invalid arguments in routine gamma_q().");
+
+      if (__x < __a + _Tp(1))
+	return _Tp(1) - __gamma_series(__a, __x).first;
+      else
+	return __gamma_cont_frac(__a, __x).first;
+    }
+
+
+  /**
+   *   @brief  Return the lower incomplete gamma function.
+   *   The lower incomplete gamma function is defined by
+   *   @f[
+   *     \gamma(a,x) = \int_0^x e^{-t}t^{a-1}dt  (a > 0)
+   *   @f]
+   */
+  template<typename _Tp>
+    _Tp
+    __gamma_l(_Tp __a, _Tp __x)
+    {
+      if (__x < _Tp(0) || __a <= _Tp(0))
+	throw std::domain_error("gamma_l: invalid arguments in routine");
+
+      if (__x < __a + _Tp(1))
+      {
+	std::pair<_Tp, _Tp> __gp = __gamma_series(__a, __x);
+	return std::exp(__gp.second) * __gp.first;
+      }
+      else
+      {
+	std::pair<_Tp, _Tp> __gp = __gamma_cont_frac(__a, __x);
+	return std::exp(__gp.second) * (_Tp(1) - __gp.first);
+      }
+    }
+
+
+  /**
+   *   @brief  Return the upper incomplete gamma function.
+   *   The lower incomplete gamma function is defined by
+   *   @f[
+   *     \Gamma(a,x) = \int_x^\infty e^{-t}t^{a-1}dt  (a > 0)
+   *   @f]
+   */
+  template<typename _Tp>
+    _Tp
+    __gamma_u(_Tp __a, _Tp __x)
+    {
+      if (__x < 0.0 || __a <= 0.0)
+	throw std::domain_error("gamma_u: invalid arguments in routine");
+
+      if (__x < __a + _Tp(1))
+      {
+          std::pair<_Tp, _Tp> __gp = __gamma_series(__a, __x);
+          return std::exp(__gp.second) * (_Tp(1) - __gp.first);
+      }
+      else
+      {
+          std::pair<_Tp, _Tp> __gp = __gamma_cont_frac(__a, __x);
+          return std::exp(__gp.second) * __gp.first;
+      }
+    }
+
+
+  /**
+   *   @brief  Return the digamma function by series expansion.
+   *   The digamma or @f$ \psi(x) @f$ function is defined by
+   *   @f[
+   *     \psi(x) = \frac{\Gamma'(x)}{\Gamma(x)}
+   *   @f]
+   *
+   *   The series is given by:
+   *   @f[
+   *     \psi(x) = -\gamma_E - \frac{1}{x}
+   *              \sum_{k=1}^{\infty} \frac{x}{k(x + k)}
+   *   @f]
+   */
+  template<typename _Tp>
+    _Tp
+    __psi_series(_Tp __x)
+    {
       _Tp __sum = -__numeric_constants<_Tp>::__gamma_e() - _Tp(1) / __x;
       const unsigned int __max_iter = 100000;
       for (unsigned int __k = 1; __k < __max_iter; ++__k)
-        {
-          const _Tp __term = __x / (__k * (__k + __x));
-          __sum += __term;
-          if (std::abs(__term / __sum) < std::numeric_limits<_Tp>::epsilon())
-            break;
-        }
+	{
+	  const _Tp __term = __x / (__k * (__k + __x));
+	  __sum += __term;
+	  if (std::abs(__term / __sum) < std::numeric_limits<_Tp>::epsilon())
+	    break;
+	}
       return __sum;
     }
 
 
-    /**
-     *   @brief  Return the digamma function for large argument.
-     *   The digamma or @f$ \psi(x) @f$ function is defined by
-     *   @f[
-     *     \psi(x) = \frac{\Gamma'(x)}{\Gamma(x)}
-     *   @f]
-     *
-     *   The asymptotic series is given by:
-     *   @f[
-     *     \psi(x) = \ln(x) - \frac{1}{2x}
-     *             - \sum_{n=1}^{\infty} \frac{B_{2n}}{2 n x^{2n}}
-     *   @f]
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the digamma function for large argument.
+   *   The digamma or @f$ \psi(x) @f$ function is defined by
+   *   @f[
+   *     \psi(x) = \frac{\Gamma'(x)}{\Gamma(x)}
+   *   @f]
+   *
+   *   The asymptotic series is given by:
+   *   @f[
+   *     \psi(x) = \ln(x) - \frac{1}{2x}
+   *             - \sum_{n=1}^{\infty} \frac{B_{2n}}{2 n x^{2n}}
+   *   @f]
+   */
+  template<typename _Tp>
     _Tp
-    __psi_asymp(const _Tp __x)
+    __psi_asymp(_Tp __x)
     {
       _Tp __sum = std::log(__x) - _Tp(0.5L) / __x;
       const _Tp __xx = __x * __x;
@@ -389,85 +562,79 @@
       _Tp __xp = __xx;
       const unsigned int __max_iter = 100;
       for (unsigned int __k = 1; __k < __max_iter; ++__k)
-        {
-          const _Tp __term = __bernoulli<_Tp>(2 * __k) / (2 * __k * __xp);
-          __sum -= __term;
-          if (std::abs(__term / __sum) < std::numeric_limits<_Tp>::epsilon())
-            break;
-          __xp *= __xx;
-        }
+	{
+	  const _Tp __term = __bernoulli<_Tp>(2 * __k) / (2 * __k * __xp);
+	  __sum -= __term;
+	  if (std::abs(__term / __sum) < std::numeric_limits<_Tp>::epsilon())
+	    break;
+	  __xp *= __xx;
+	}
       return __sum;
     }
 
 
-    /**
-     *   @brief  Return the digamma function.
-     *   The digamma or @f$ \psi(x) @f$ function is defined by
-     *   @f[
-     *     \psi(x) = \frac{\Gamma'(x)}{\Gamma(x)}
-     *   @f]
-     *   For negative argument the reflection formula is used:
-     *   @f[
-     *     \psi(x) = \psi(1-x) - \pi \cot(\pi x)
-     *   @f]
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the digamma function.
+   *   The digamma or @f$ \psi(x) @f$ function is defined by
+   *   @f[
+   *     \psi(x) = \frac{\Gamma'(x)}{\Gamma(x)}
+   *   @f]
+   *   For negative argument the reflection formula is used:
+   *   @f[
+   *     \psi(x) = \psi(1-x) - \pi \cot(\pi x)
+   *   @f]
+   */
+  template<typename _Tp>
     _Tp
-    __psi(const _Tp __x)
+    __psi(_Tp __x)
     {
       const int __n = static_cast<int>(__x + 0.5L);
-      const _Tp __eps = _Tp(4) * std::numeric_limits<_Tp>::epsilon();
-      if (__n <= 0 && std::abs(__x - _Tp(__n)) < __eps)
-        return std::numeric_limits<_Tp>::quiet_NaN();
+      constexpr _Tp _S_eps = _Tp(4) * std::numeric_limits<_Tp>::epsilon();
+      if (__n <= 0 && std::abs(__x - _Tp(__n)) < _S_eps)
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__x < _Tp(0))
-        {
-          const _Tp __pi = __numeric_constants<_Tp>::__pi();
-          return __psi(_Tp(1) - __x)
-               - __pi * std::cos(__pi * __x) / std::sin(__pi * __x);
-        }
+	{
+	  const _Tp __pi = __numeric_constants<_Tp>::__pi();
+	  return __psi(_Tp(1) - __x)
+	       - __pi * std::cos(__pi * __x) / std::sin(__pi * __x);
+	}
       else if (__x > _Tp(100))
-        return __psi_asymp(__x);
+	return __psi_asymp(__x);
       else
-        return __psi_series(__x);
+	return __psi_series(__x);
     }
 
 
-    /**
-     *   @brief  Return the polygamma function @f$ \psi^{(n)}(x) @f$.
-     * 
-     *   The polygamma function is related to the Hurwitz zeta function:
-     *   @f[
-     *     \psi^{(n)}(x) = (-1)^{n+1} m! \zeta(m+1,x)
-     *   @f]
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the polygamma function @f$ \psi^{(n)}(x) @f$.
+   *
+   *   The polygamma function is related to the Hurwitz zeta function:
+   *   @f[
+   *     \psi^{(n)}(x) = (-1)^{n+1} m! \zeta(m+1,x)
+   *   @f]
+   */
+  template<typename _Tp>
     _Tp
-    __psi(const unsigned int __n, const _Tp __x)
+    __psi(unsigned int __n, _Tp __x)
     {
       if (__x <= _Tp(0))
-        std::__throw_domain_error(__N("Argument out of range "
-                                      "in __psi"));
+	std::__throw_domain_error(__N("__psi: argument out of range"));
       else if (__n == 0)
-        return __psi(__x);
+	return __psi(__x);
       else
-        {
-          const _Tp __hzeta = __hurwitz_zeta(_Tp(__n + 1), __x);
-#if _GLIBCXX_USE_C99_MATH_TR1
-          const _Tp __ln_nfact = std::tr1::lgamma(_Tp(__n + 1));
-#else
-          const _Tp __ln_nfact = __log_gamma(_Tp(__n + 1));
-#endif
-          _Tp __result = std::exp(__ln_nfact) * __hzeta;
-          if (__n % 2 == 1)
-            __result = -__result;
-          return __result;
-        }
+	{
+	  const _Tp __hzeta = __hurwitz_zeta(_Tp(__n + 1), __x);
+	  const _Tp __ln_nfact = __log_gamma(_Tp(__n + 1));
+	  _Tp __result = std::exp(__ln_nfact) * __hzeta;
+	  if (__n % 2 == 1)
+	    __result = -__result;
+	  return __result;
+	}
     }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
 
-#endif // _GLIBCXX_TR1_GAMMA_TCC
+#endif // _GLIBCXX_BITS_SF_GAMMA_TCC
 
Index: include/bits/sf_gegenbauer.tcc
===================================================================
--- include/bits/sf_gegenbauer.tcc	(revision 0)
+++ include/bits/sf_gegenbauer.tcc	(working copy)
@@ -0,0 +1,67 @@
+// Special functions -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/sf_gegenbauer.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{cmath}
+ */
+
+#ifndef _GLIBCXX_SF_GEGENBAUER_TCC
+#define _GLIBCXX_SF_GEGENBAUER_TCC 1
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// Implementation-space details.
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Tp>
+    _Tp
+    __gegenbauer_poly(unsigned int __n, _Tp __alpha, _Tp __x)
+    {
+      auto _C0 = _Tp(1);
+      if (__n == 0)
+        return _C0;
+
+      auto _C1 = _Tp(2) * __alpha * __x;
+      if (__n == 1)
+        return _C1;
+
+      auto _Cn = _Tp(0);
+      for (unsigned int __nn = 2; __nn <= __n; ++__nn)
+        {
+          _Cn = (_Tp(2) * (_Tp(__nn) - _Tp(1) + __alpha) * __x * _C1
+              - (_Tp(__nn) - _Tp(2) + _Tp(2) * __alpha) * _C0)
+              / _Tp(__nn);
+          _C0 = _C1;
+          _C1 = _Cn;
+        }
+      return _Cn;
+    }
+
+} // namespace __detail
+} // namespace std
+
+#endif // _GLIBCXX_SF_GEGENBAUER_TCC
Index: include/bits/sf_hyperg.tcc
===================================================================
--- include/bits/sf_hyperg.tcc	(revision 175789)
+++ include/bits/sf_hyperg.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,16 +22,18 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/hypergeometric.tcc
+/** @file bits/sf_hyperg.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
-// Written by Edward Smith-Rowland based:
+// Written by Edward Smith-Rowland.
+//
+// References:
 //   (1) Handbook of Mathematical Functions,
 //       ed. Milton Abramowitz and Irene A. Stegun,
 //       Dover Publications,
@@ -39,44 +40,40 @@
 //       Section 6, pp. 555-566
 //   (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
 
-#ifndef _GLIBCXX_TR1_HYPERGEOMETRIC_TCC
-#define _GLIBCXX_TR1_HYPERGEOMETRIC_TCC 1
+#ifndef _GLIBCXX_BITS_SF_HYPERG_TCC
+#define _GLIBCXX_BITS_SF_HYPERG_TCC 1
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // [5.2] Special functions
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-    /**
-     *   @brief This routine returns the confluent hypergeometric function
-     *          by series expansion.
-     * 
-     *   @f[
-     *     _1F_1(a;c;x) = \frac{\Gamma(c)}{\Gamma(a)}
-     *                      \sum_{n=0}^{\infty}
-     *                      \frac{\Gamma(a+n)}{\Gamma(c+n)}
-     *                      \frac{x^n}{n!}
-     *   @f]
-     * 
-     *   If a and b are integers and a < 0 and either b > 0 or b < a
-     *   then the series is a polynomial with a finite number of
-     *   terms.  If b is an integer and b <= 0 the confluent
-     *   hypergeometric function is undefined.
-     *
-     *   @param  __a  The "numerator" parameter.
-     *   @param  __c  The "denominator" parameter.
-     *   @param  __x  The argument of the confluent hypergeometric function.
-     *   @return  The confluent hypergeometric function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief This routine returns the confluent hypergeometric function
+   *          by series expansion.
+   *
+   *   @f[
+   *     _1F_1(a;c;x) = \frac{\Gamma(c)}{\Gamma(a)}
+   *                      \sum_{n=0}^{\infty}
+   *                      \frac{\Gamma(a+n)}{\Gamma(c+n)}
+   *                      \frac{x^n}{n!}
+   *   @f]
+   *
+   *   If a and b are integers and a < 0 and either b > 0 or b < a
+   *   then the series is a polynomial with a finite number of
+   *   terms.  If b is an integer and b <= 0 the confluent
+   *   hypergeometric function is undefined.
+   *
+   *   @param  __a  The "numerator" parameter.
+   *   @param  __c  The "denominator" parameter.
+   *   @param  __x  The argument of the confluent hypergeometric function.
+   *   @return  The confluent hypergeometric function.
+   */
+  template<typename _Tp>
     _Tp
-    __conf_hyperg_series(const _Tp __a, const _Tp __c, const _Tp __x)
+    __conf_hyperg_series(_Tp __a, _Tp __c, _Tp __x)
     {
       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
 
@@ -85,35 +82,33 @@
       const unsigned int __max_iter = 100000;
       unsigned int __i;
       for (__i = 0; __i < __max_iter; ++__i)
-        {
-          __term *= (__a + _Tp(__i)) * __x
-                  / ((__c + _Tp(__i)) * _Tp(1 + __i));
-          if (std::abs(__term) < __eps)
-            {
-              break;
-            }
-          __Fac += __term;
-        }
+	{
+	  __term *= (__a + _Tp(__i)) * __x
+		  / ((__c + _Tp(__i)) * _Tp(1 + __i));
+	  if (std::abs(__term) < __eps)
+	    break;
+	  __Fac += __term;
+	}
       if (__i == __max_iter)
-        std::__throw_runtime_error(__N("Series failed to converge "
-                                       "in __conf_hyperg_series."));
+	std::__throw_runtime_error(__N("__conf_hyperg_series: "
+				       "series failed to converge"));
 
       return __Fac;
     }
 
 
-    /**
-     *  @brief  Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$
-     *          by an iterative procedure described in
-     *          Luke, Algorithms for the Computation of Mathematical Functions.
-     *
-     *  Like the case of the 2F1 rational approximations, these are 
-     *  probably guaranteed to converge for x < 0, barring gross    
-     *  numerical instability in the pre-asymptotic regime.         
-     */
-    template<typename _Tp>
+  /**
+   *  @brief  Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$
+   *          by an iterative procedure described in
+   *          Luke, Algorithms for the Computation of Mathematical Functions.
+   *
+   *  Like the case of the 2F1 rational approximations, these are
+   *  probably guaranteed to converge for x < 0, barring gross
+   *  numerical instability in the pre-asymptotic regime.
+   */
+  template<typename _Tp>
     _Tp
-    __conf_hyperg_luke(const _Tp __a, const _Tp __c, const _Tp __xin)
+    __conf_hyperg_luke(_Tp __a, _Tp __c, _Tp __xin)
     {
       const _Tp __big = std::pow(std::numeric_limits<_Tp>::max(), _Tp(0.16L));
       const int __nmax = 20000;
@@ -133,139 +128,134 @@
       _Tp __Anm3 = _Tp(1);
       _Tp __Anm2 = __Bnm2 - __t0 * __x;
       _Tp __Anm1 = __Bnm1 - __t0 * (_Tp(1) + __t2 * __x) * __x
-                 + __t0 * __t1 * (__c / (__c + _Tp(1))) * __x * __x;
+		 + __t0 * __t1 * (__c / (__c + _Tp(1))) * __x * __x;
 
       int __n = 3;
-      while(1)
-        {
-          _Tp __npam1 = _Tp(__n - 1) + __a;
-          _Tp __npcm1 = _Tp(__n - 1) + __c;
-          _Tp __npam2 = _Tp(__n - 2) + __a;
-          _Tp __npcm2 = _Tp(__n - 2) + __c;
-          _Tp __tnm1  = _Tp(2 * __n - 1);
-          _Tp __tnm3  = _Tp(2 * __n - 3);
-          _Tp __tnm5  = _Tp(2 * __n - 5);
-          _Tp __F1 =  (_Tp(__n - 2) - __a) / (_Tp(2) * __tnm3 * __npcm1);
-          _Tp __F2 =  (_Tp(__n) + __a) * __npam1
-                   / (_Tp(4) * __tnm1 * __tnm3 * __npcm2 * __npcm1);
-          _Tp __F3 = -__npam2 * __npam1 * (_Tp(__n - 2) - __a)
-                   / (_Tp(8) * __tnm3 * __tnm3 * __tnm5
-                   * (_Tp(__n - 3) + __c) * __npcm2 * __npcm1);
-          _Tp __E  = -__npam1 * (_Tp(__n - 1) - __c)
-                   / (_Tp(2) * __tnm3 * __npcm2 * __npcm1);
+      while(true)
+	{
+	  _Tp __npam1 = _Tp(__n - 1) + __a;
+	  _Tp __npcm1 = _Tp(__n - 1) + __c;
+	  _Tp __npam2 = _Tp(__n - 2) + __a;
+	  _Tp __npcm2 = _Tp(__n - 2) + __c;
+	  _Tp __tnm1  = _Tp(2 * __n - 1);
+	  _Tp __tnm3  = _Tp(2 * __n - 3);
+	  _Tp __tnm5  = _Tp(2 * __n - 5);
+	  _Tp __F1 =  (_Tp(__n - 2) - __a) / (_Tp(2) * __tnm3 * __npcm1);
+	  _Tp __F2 =  (_Tp(__n) + __a) * __npam1
+		   / (_Tp(4) * __tnm1 * __tnm3 * __npcm2 * __npcm1);
+	  _Tp __F3 = -__npam2 * __npam1 * (_Tp(__n - 2) - __a)
+		   / (_Tp(8) * __tnm3 * __tnm3 * __tnm5
+		   * (_Tp(__n - 3) + __c) * __npcm2 * __npcm1);
+	  _Tp __E  = -__npam1 * (_Tp(__n - 1) - __c)
+		   / (_Tp(2) * __tnm3 * __npcm2 * __npcm1);
 
-          _Tp __An = (_Tp(1) + __F1 * __x) * __Anm1
-                   + (__E + __F2 * __x) * __x * __Anm2 + __F3 * __x3 * __Anm3;
-          _Tp __Bn = (_Tp(1) + __F1 * __x) * __Bnm1
-                   + (__E + __F2 * __x) * __x * __Bnm2 + __F3 * __x3 * __Bnm3;
-          _Tp __r = __An / __Bn;
+	  _Tp __An = (_Tp(1) + __F1 * __x) * __Anm1
+		   + (__E + __F2 * __x) * __x * __Anm2 + __F3 * __x3 * __Anm3;
+	  _Tp __Bn = (_Tp(1) + __F1 * __x) * __Bnm1
+		   + (__E + __F2 * __x) * __x * __Bnm2 + __F3 * __x3 * __Bnm3;
+	  _Tp __r = __An / __Bn;
 
-          __prec = std::abs((__F - __r) / __F);
-          __F = __r;
+	  __prec = std::abs((__F - __r) / __F);
+	  __F = __r;
 
-          if (__prec < __eps || __n > __nmax)
-            break;
+	  if (__prec < __eps || __n > __nmax)
+	    break;
 
-          if (std::abs(__An) > __big || std::abs(__Bn) > __big)
-            {
-              __An   /= __big;
-              __Bn   /= __big;
-              __Anm1 /= __big;
-              __Bnm1 /= __big;
-              __Anm2 /= __big;
-              __Bnm2 /= __big;
-              __Anm3 /= __big;
-              __Bnm3 /= __big;
-            }
-          else if (std::abs(__An) < _Tp(1) / __big
-                || std::abs(__Bn) < _Tp(1) / __big)
-            {
-              __An   *= __big;
-              __Bn   *= __big;
-              __Anm1 *= __big;
-              __Bnm1 *= __big;
-              __Anm2 *= __big;
-              __Bnm2 *= __big;
-              __Anm3 *= __big;
-              __Bnm3 *= __big;
-            }
+	  if (std::abs(__An) > __big || std::abs(__Bn) > __big)
+	    {
+	      __An   /= __big;
+	      __Bn   /= __big;
+	      __Anm1 /= __big;
+	      __Bnm1 /= __big;
+	      __Anm2 /= __big;
+	      __Bnm2 /= __big;
+	      __Anm3 /= __big;
+	      __Bnm3 /= __big;
+	    }
+	  else if (std::abs(__An) < _Tp(1) / __big
+		|| std::abs(__Bn) < _Tp(1) / __big)
+	    {
+	      __An   *= __big;
+	      __Bn   *= __big;
+	      __Anm1 *= __big;
+	      __Bnm1 *= __big;
+	      __Anm2 *= __big;
+	      __Bnm2 *= __big;
+	      __Anm3 *= __big;
+	      __Bnm3 *= __big;
+	    }
 
-          ++__n;
-          __Bnm3 = __Bnm2;
-          __Bnm2 = __Bnm1;
-          __Bnm1 = __Bn;
-          __Anm3 = __Anm2;
-          __Anm2 = __Anm1;
-          __Anm1 = __An;
-        }
+	  ++__n;
+	  __Bnm3 = __Bnm2;
+	  __Bnm2 = __Bnm1;
+	  __Bnm1 = __Bn;
+	  __Anm3 = __Anm2;
+	  __Anm2 = __Anm1;
+	  __Anm1 = __An;
+	}
 
       if (__n >= __nmax)
-        std::__throw_runtime_error(__N("Iteration failed to converge "
-                                       "in __conf_hyperg_luke."));
+	std::__throw_runtime_error(__N("__conf_hyperg_luke: "
+				       "iteration failed to converge"));
 
       return __F;
     }
 
 
-    /**
-     *   @brief  Return the confluent hypogeometric function
-     *           @f$ _1F_1(a;c;x) @f$.
-     * 
-     *   @todo  Handle b == nonpositive integer blowup - return NaN.
-     *
-     *   @param  __a  The @a numerator parameter.
-     *   @param  __c  The @a denominator parameter.
-     *   @param  __x  The argument of the confluent hypergeometric function.
-     *   @return  The confluent hypergeometric function.
-     */
-    template<typename _Tp>
-    inline _Tp
-    __conf_hyperg(const _Tp __a, const _Tp __c, const _Tp __x)
+  /**
+   *   @brief  Return the confluent hypogeometric function
+   *           @f$ _1F_1(a;c;x) @f$.
+   *
+   *   @todo  Handle b == nonpositive integer blowup - return NaN.
+   *
+   *   @param  __a  The @a numerator parameter.
+   *   @param  __c  The @a denominator parameter.
+   *   @param  __x  The argument of the confluent hypergeometric function.
+   *   @return  The confluent hypergeometric function.
+   */
+  template<typename _Tp>
+    _Tp
+    __conf_hyperg(_Tp __a, _Tp __c, _Tp __x)
     {
-#if _GLIBCXX_USE_C99_MATH_TR1
-      const _Tp __c_nint = std::tr1::nearbyint(__c);
-#else
-      const _Tp __c_nint = static_cast<int>(__c + _Tp(0.5L));
-#endif
+      const _Tp __c_nint = std::nearbyint(__c);
       if (__isnan(__a) || __isnan(__c) || __isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__c_nint == __c && __c_nint <= 0)
-        return std::numeric_limits<_Tp>::infinity();
+	return std::numeric_limits<_Tp>::infinity();
       else if (__a == _Tp(0))
-        return _Tp(1);
+	return _Tp(1);
       else if (__c == __a)
-        return std::exp(__x);
+	return std::exp(__x);
       else if (__x < _Tp(0))
-        return __conf_hyperg_luke(__a, __c, __x);
+	return __conf_hyperg_luke(__a, __c, __x);
       else
-        return __conf_hyperg_series(__a, __c, __x);
+	return __conf_hyperg_series(__a, __c, __x);
     }
 
 
-    /**
-     *   @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$
-     *   by series expansion.
-     * 
-     *   The hypogeometric function is defined by
-     *   @f[
-     *     _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)}
-     *                      \sum_{n=0}^{\infty}
-     *                      \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)}
-     *                      \frac{x^n}{n!}
-     *   @f]
-     * 
-     *   This works and it's pretty fast.
-     *
-     *   @param  __a  The first @a numerator parameter.
-     *   @param  __a  The second @a numerator parameter.
-     *   @param  __c  The @a denominator parameter.
-     *   @param  __x  The argument of the confluent hypergeometric function.
-     *   @return  The confluent hypergeometric function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$
+   *   by series expansion.
+   *
+   *   The hypogeometric function is defined by
+   *   @f[
+   *     _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)}
+   *                      \sum_{n=0}^{\infty}
+   *                      \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)}
+   *                      \frac{x^n}{n!}
+   *   @f]
+   *
+   *   This works and it's pretty fast.
+   *
+   *   @param  __a  The first @a numerator parameter.
+   *   @param  __a  The second @a numerator parameter.
+   *   @param  __c  The @a denominator parameter.
+   *   @param  __x  The argument of the confluent hypergeometric function.
+   *   @return  The confluent hypergeometric function.
+   */
+  template<typename _Tp>
     _Tp
-    __hyperg_series(const _Tp __a, const _Tp __b,
-                    const _Tp __c, const _Tp __x)
+    __hyperg_series(_Tp __a, _Tp __b, _Tp __c, _Tp __x)
     {
       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
 
@@ -274,32 +264,29 @@
       const unsigned int __max_iter = 100000;
       unsigned int __i;
       for (__i = 0; __i < __max_iter; ++__i)
-        {
-          __term *= (__a + _Tp(__i)) * (__b + _Tp(__i)) * __x
-                  / ((__c + _Tp(__i)) * _Tp(1 + __i));
-          if (std::abs(__term) < __eps)
-            {
-              break;
-            }
-          __Fabc += __term;
-        }
+	{
+	  __term *= (__a + _Tp(__i)) * (__b + _Tp(__i)) * __x
+		  / ((__c + _Tp(__i)) * _Tp(1 + __i));
+	  if (std::abs(__term) < __eps)
+	    break;
+	  __Fabc += __term;
+	}
       if (__i == __max_iter)
-        std::__throw_runtime_error(__N("Series failed to converge "
-                                       "in __hyperg_series."));
+	std::__throw_runtime_error(__N("Series failed to converge "
+				       "in __hyperg_series."));
 
       return __Fabc;
     }
 
 
-    /**
-     *   @brief  Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$
-     *           by an iterative procedure described in
-     *           Luke, Algorithms for the Computation of Mathematical Functions.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$
+   *           by an iterative procedure described in
+   *           Luke, Algorithms for the Computation of Mathematical Functions.
+   */
+  template<typename _Tp>
     _Tp
-    __hyperg_luke(const _Tp __a, const _Tp __b, const _Tp __c,
-                  const _Tp __xin)
+    __hyperg_luke(_Tp __a, _Tp __b, _Tp __c, _Tp __xin)
     {
       const _Tp __big = std::pow(std::numeric_limits<_Tp>::max(), _Tp(0.16L));
       const int __nmax = 20000;
@@ -309,7 +296,7 @@
       const _Tp __t0 = __a * __b / __c;
       const _Tp __t1 = (__a + _Tp(1)) * (__b + _Tp(1)) / (_Tp(2) * __c);
       const _Tp __t2 = (__a + _Tp(2)) * (__b + _Tp(2))
-                     / (_Tp(2) * (__c + _Tp(1)));
+		     / (_Tp(2) * (__c + _Tp(1)));
 
       _Tp __F = _Tp(1);
 
@@ -320,121 +307,120 @@
       _Tp __Anm3 = _Tp(1);
       _Tp __Anm2 = __Bnm2 - __t0 * __x;
       _Tp __Anm1 = __Bnm1 - __t0 * (_Tp(1) + __t2 * __x) * __x
-                 + __t0 * __t1 * (__c / (__c + _Tp(1))) * __x * __x;
+		 + __t0 * __t1 * (__c / (__c + _Tp(1))) * __x * __x;
 
       int __n = 3;
-      while (1)
-        {
-          const _Tp __npam1 = _Tp(__n - 1) + __a;
-          const _Tp __npbm1 = _Tp(__n - 1) + __b;
-          const _Tp __npcm1 = _Tp(__n - 1) + __c;
-          const _Tp __npam2 = _Tp(__n - 2) + __a;
-          const _Tp __npbm2 = _Tp(__n - 2) + __b;
-          const _Tp __npcm2 = _Tp(__n - 2) + __c;
-          const _Tp __tnm1  = _Tp(2 * __n - 1);
-          const _Tp __tnm3  = _Tp(2 * __n - 3);
-          const _Tp __tnm5  = _Tp(2 * __n - 5);
-          const _Tp __n2 = __n * __n;
-          const _Tp __F1 = (_Tp(3) * __n2 + (__a + __b - _Tp(6)) * __n
-                         + _Tp(2) - __a * __b - _Tp(2) * (__a + __b))
-                         / (_Tp(2) * __tnm3 * __npcm1);
-          const _Tp __F2 = -(_Tp(3) * __n2 - (__a + __b + _Tp(6)) * __n
-                         + _Tp(2) - __a * __b) * __npam1 * __npbm1
-                         / (_Tp(4) * __tnm1 * __tnm3 * __npcm2 * __npcm1);
-          const _Tp __F3 = (__npam2 * __npam1 * __npbm2 * __npbm1
-                         * (_Tp(__n - 2) - __a) * (_Tp(__n - 2) - __b))
-                         / (_Tp(8) * __tnm3 * __tnm3 * __tnm5
-                         * (_Tp(__n - 3) + __c) * __npcm2 * __npcm1);
-          const _Tp __E  = -__npam1 * __npbm1 * (_Tp(__n - 1) - __c)
-                         / (_Tp(2) * __tnm3 * __npcm2 * __npcm1);
+      while (true)
+	{
+	  const _Tp __npam1 = _Tp(__n - 1) + __a;
+	  const _Tp __npbm1 = _Tp(__n - 1) + __b;
+	  const _Tp __npcm1 = _Tp(__n - 1) + __c;
+	  const _Tp __npam2 = _Tp(__n - 2) + __a;
+	  const _Tp __npbm2 = _Tp(__n - 2) + __b;
+	  const _Tp __npcm2 = _Tp(__n - 2) + __c;
+	  const _Tp __tnm1  = _Tp(2 * __n - 1);
+	  const _Tp __tnm3  = _Tp(2 * __n - 3);
+	  const _Tp __tnm5  = _Tp(2 * __n - 5);
+	  const _Tp __n2 = __n * __n;
+	  const _Tp __F1 = (_Tp(3) * __n2 + (__a + __b - _Tp(6)) * __n
+			 + _Tp(2) - __a * __b - _Tp(2) * (__a + __b))
+			 / (_Tp(2) * __tnm3 * __npcm1);
+	  const _Tp __F2 = -(_Tp(3) * __n2 - (__a + __b + _Tp(6)) * __n
+			 + _Tp(2) - __a * __b) * __npam1 * __npbm1
+			 / (_Tp(4) * __tnm1 * __tnm3 * __npcm2 * __npcm1);
+	  const _Tp __F3 = (__npam2 * __npam1 * __npbm2 * __npbm1
+			 * (_Tp(__n - 2) - __a) * (_Tp(__n - 2) - __b))
+			 / (_Tp(8) * __tnm3 * __tnm3 * __tnm5
+			 * (_Tp(__n - 3) + __c) * __npcm2 * __npcm1);
+	  const _Tp __E  = -__npam1 * __npbm1 * (_Tp(__n - 1) - __c)
+			 / (_Tp(2) * __tnm3 * __npcm2 * __npcm1);
 
-          _Tp __An = (_Tp(1) + __F1 * __x) * __Anm1
-                   + (__E + __F2 * __x) * __x * __Anm2 + __F3 * __x3 * __Anm3;
-          _Tp __Bn = (_Tp(1) + __F1 * __x) * __Bnm1
-                   + (__E + __F2 * __x) * __x * __Bnm2 + __F3 * __x3 * __Bnm3;
-          const _Tp __r = __An / __Bn;
+	  _Tp __An = (_Tp(1) + __F1 * __x) * __Anm1
+		   + (__E + __F2 * __x) * __x * __Anm2 + __F3 * __x3 * __Anm3;
+	  _Tp __Bn = (_Tp(1) + __F1 * __x) * __Bnm1
+		   + (__E + __F2 * __x) * __x * __Bnm2 + __F3 * __x3 * __Bnm3;
+	  const _Tp __r = __An / __Bn;
 
-          const _Tp __prec = std::abs((__F - __r) / __F);
-          __F = __r;
+	  const _Tp __prec = std::abs((__F - __r) / __F);
+	  __F = __r;
 
-          if (__prec < __eps || __n > __nmax)
-            break;
+	  if (__prec < __eps || __n > __nmax)
+	    break;
 
-          if (std::abs(__An) > __big || std::abs(__Bn) > __big)
-            {
-              __An   /= __big;
-              __Bn   /= __big;
-              __Anm1 /= __big;
-              __Bnm1 /= __big;
-              __Anm2 /= __big;
-              __Bnm2 /= __big;
-              __Anm3 /= __big;
-              __Bnm3 /= __big;
-            }
-          else if (std::abs(__An) < _Tp(1) / __big
-                || std::abs(__Bn) < _Tp(1) / __big)
-            {
-              __An   *= __big;
-              __Bn   *= __big;
-              __Anm1 *= __big;
-              __Bnm1 *= __big;
-              __Anm2 *= __big;
-              __Bnm2 *= __big;
-              __Anm3 *= __big;
-              __Bnm3 *= __big;
-            }
+	  if (std::abs(__An) > __big || std::abs(__Bn) > __big)
+	    {
+	      __An   /= __big;
+	      __Bn   /= __big;
+	      __Anm1 /= __big;
+	      __Bnm1 /= __big;
+	      __Anm2 /= __big;
+	      __Bnm2 /= __big;
+	      __Anm3 /= __big;
+	      __Bnm3 /= __big;
+	    }
+	  else if (std::abs(__An) < _Tp(1) / __big
+		|| std::abs(__Bn) < _Tp(1) / __big)
+	    {
+	      __An   *= __big;
+	      __Bn   *= __big;
+	      __Anm1 *= __big;
+	      __Bnm1 *= __big;
+	      __Anm2 *= __big;
+	      __Bnm2 *= __big;
+	      __Anm3 *= __big;
+	      __Bnm3 *= __big;
+	    }
 
-          ++__n;
-          __Bnm3 = __Bnm2;
-          __Bnm2 = __Bnm1;
-          __Bnm1 = __Bn;
-          __Anm3 = __Anm2;
-          __Anm2 = __Anm1;
-          __Anm1 = __An;
-        }
+	  ++__n;
+	  __Bnm3 = __Bnm2;
+	  __Bnm2 = __Bnm1;
+	  __Bnm1 = __Bn;
+	  __Anm3 = __Anm2;
+	  __Anm2 = __Anm1;
+	  __Anm1 = __An;
+	}
 
       if (__n >= __nmax)
-        std::__throw_runtime_error(__N("Iteration failed to converge "
-                                       "in __hyperg_luke."));
+	std::__throw_runtime_error(__N("__hyperg_luke: "
+				       "iteration failed to converge"));
 
       return __F;
     }
 
 
-    /**
-     *  @brief  Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$ 
-     *  by the reflection formulae in Abramowitz & Stegun formula
-     *  15.3.6 for d = c - a - b not integral and formula 15.3.11 for
-     *  d = c - a - b integral.  This assumes a, b, c != negative
-     *  integer.
-     *
-     *   The hypogeometric function is defined by
-     *   @f[
-     *     _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)}
-     *                      \sum_{n=0}^{\infty}
-     *                      \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)}
-     *                      \frac{x^n}{n!}
-     *   @f]
-     *
-     *   The reflection formula for nonintegral @f$ d = c - a - b @f$ is:
-     *   @f[
-     *     _2F_1(a,b;c;x) = \frac{\Gamma(c)\Gamma(d)}{\Gamma(c-a)\Gamma(c-b)}
-     *                            _2F_1(a,b;1-d;1-x)
-     *                    + \frac{\Gamma(c)\Gamma(-d)}{\Gamma(a)\Gamma(b)}
-     *                            _2F_1(c-a,c-b;1+d;1-x)
-     *   @f]
-     *
-     *   The reflection formula for integral @f$ m = c - a - b @f$ is:
-     *   @f[
-     *     _2F_1(a,b;a+b+m;x) = \frac{\Gamma(m)\Gamma(a+b+m)}{\Gamma(a+m)\Gamma(b+m)}
-     *                        \sum_{k=0}^{m-1} \frac{(m+a)_k(m+b)_k}{k!(1-m)_k}
-     *                      - 
-     *   @f]
-     */
-    template<typename _Tp>
+  /**
+   *  @brief  Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$
+   *  by the reflection formulae in Abramowitz & Stegun formula
+   *  15.3.6 for d = c - a - b not integral and formula 15.3.11 for
+   *  d = c - a - b integral.  This assumes a, b, c != negative
+   *  integer.
+   *
+   *   The hypogeometric function is defined by
+   *   @f[
+   *     _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)}
+   *                      \sum_{n=0}^{\infty}
+   *                      \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)}
+   *                      \frac{x^n}{n!}
+   *   @f]
+   *
+   *   The reflection formula for nonintegral @f$ d = c - a - b @f$ is:
+   *   @f[
+   *     _2F_1(a,b;c;x) = \frac{\Gamma(c)\Gamma(d)}{\Gamma(c-a)\Gamma(c-b)}
+   *                            _2F_1(a,b;1-d;1-x)
+   *                    + \frac{\Gamma(c)\Gamma(-d)}{\Gamma(a)\Gamma(b)}
+   *                            _2F_1(c-a,c-b;1+d;1-x)
+   *   @f]
+   *
+   *   The reflection formula for integral @f$ m = c - a - b @f$ is:
+   *   @f[
+   *     _2F_1(a,b;a+b+m;x) = \frac{\Gamma(m)\Gamma(a+b+m)}{\Gamma(a+m)\Gamma(b+m)}
+   *                        \sum_{k=0}^{m-1} \frac{(m+a)_k(m+b)_k}{k!(1-m)_k}
+   *                      -
+   *   @f]
+   */
+  template<typename _Tp>
     _Tp
-    __hyperg_reflect(const _Tp __a, const _Tp __b, const _Tp __c,
-                     const _Tp __x)
+    __hyperg_reflect(_Tp __a, _Tp __b, _Tp __c, _Tp __x)
     {
       const _Tp __d = __c - __a - __b;
       const int __intd  = std::floor(__d + _Tp(0.5L));
@@ -444,336 +430,350 @@
       const bool __d_integer = (std::abs(__d - __intd) < __toler);
 
       if (__d_integer)
-        {
-          const _Tp __ln_omx = std::log(_Tp(1) - __x);
-          const _Tp __ad = std::abs(__d);
-          _Tp __F1, __F2;
+	{
+	  const _Tp __ln_omx = std::log(_Tp(1) - __x);
+	  const _Tp __ad = std::abs(__d);
+	  _Tp __F1, __F2;
 
-          _Tp __d1, __d2;
-          if (__d >= _Tp(0))
-            {
-              __d1 = __d;
-              __d2 = _Tp(0);
-            }
-          else
-            {
-              __d1 = _Tp(0);
-              __d2 = __d;
-            }
+	  _Tp __d1, __d2;
+	  if (__d >= _Tp(0))
+	    {
+	      __d1 = __d;
+	      __d2 = _Tp(0);
+	    }
+	  else
+	    {
+	      __d1 = _Tp(0);
+	      __d2 = __d;
+	    }
 
-          const _Tp __lng_c = __log_gamma(__c);
+	  const _Tp __lng_c = __log_gamma(__c);
 
-          //  Evaluate F1.
-          if (__ad < __eps)
-            {
-              //  d = c - a - b = 0.
-              __F1 = _Tp(0);
-            }
-          else
-            {
+	  //  Evaluate F1.
+	  if (__ad < __eps)
+	    {
+	      //  d = c - a - b = 0.
+	      __F1 = _Tp(0);
+	    }
+	  else
+	    {
 
-              bool __ok_d1 = true;
-              _Tp __lng_ad, __lng_ad1, __lng_bd1;
-              __try
-                {
-                  __lng_ad = __log_gamma(__ad);
-                  __lng_ad1 = __log_gamma(__a + __d1);
-                  __lng_bd1 = __log_gamma(__b + __d1);
-                }
-              __catch(...)
-                {
-                  __ok_d1 = false;
-                }
+	      bool __ok_d1 = true;
+	      _Tp __lng_ad, __lng_ad1, __lng_bd1;
+	      __try
+		{
+		  __lng_ad = __log_gamma(__ad);
+		  __lng_ad1 = __log_gamma(__a + __d1);
+		  __lng_bd1 = __log_gamma(__b + __d1);
+		}
+	      __catch(...)
+		{
+		  __ok_d1 = false;
+		}
 
-              if (__ok_d1)
-                {
-                  /* Gamma functions in the denominator are ok.
-                   * Proceed with evaluation.
-                   */
-                  _Tp __sum1 = _Tp(1);
-                  _Tp __term = _Tp(1);
-                  _Tp __ln_pre1 = __lng_ad + __lng_c + __d2 * __ln_omx
-                                - __lng_ad1 - __lng_bd1;
+	      if (__ok_d1)
+		{
+		  /* Gamma functions in the denominator are ok.
+		   * Proceed with evaluation.
+		   */
+		  _Tp __sum1 = _Tp(1);
+		  _Tp __term = _Tp(1);
+		  _Tp __ln_pre1 = __lng_ad + __lng_c + __d2 * __ln_omx
+				- __lng_ad1 - __lng_bd1;
 
-                  /* Do F1 sum.
-                   */
-                  for (int __i = 1; __i < __ad; ++__i)
-                    {
-                      const int __j = __i - 1;
-                      __term *= (__a + __d2 + __j) * (__b + __d2 + __j)
-                              / (_Tp(1) + __d2 + __j) / __i * (_Tp(1) - __x);
-                      __sum1 += __term;
-                    }
+		  /* Do F1 sum.
+		   */
+		  for (int __i = 1; __i < __ad; ++__i)
+		    {
+		      const int __j = __i - 1;
+		      __term *= (__a + __d2 + __j) * (__b + __d2 + __j)
+			      / (_Tp(1) + __d2 + __j) / __i * (_Tp(1) - __x);
+		      __sum1 += __term;
+		    }
 
-                  if (__ln_pre1 > __log_max)
-                    std::__throw_runtime_error(__N("Overflow of gamma functions"
-                                                   " in __hyperg_luke."));
-                  else
-                    __F1 = std::exp(__ln_pre1) * __sum1;
-                }
-              else
-                {
-                  //  Gamma functions in the denominator were not ok.
-                  //  So the F1 term is zero.
-                  __F1 = _Tp(0);
-                }
-            } // end F1 evaluation
+		  if (__ln_pre1 > __log_max)
+		    std::__throw_runtime_error(__N("__hyperg_luke: "
+						   "overflow of gamma functions"));
+		  else
+		    __F1 = std::exp(__ln_pre1) * __sum1;
+		}
+	      else
+		{
+		  //  Gamma functions in the denominator were not ok.
+		  //  So the F1 term is zero.
+		  __F1 = _Tp(0);
+		}
+	    } // end F1 evaluation
 
-          // Evaluate F2.
-          bool __ok_d2 = true;
-          _Tp __lng_ad2, __lng_bd2;
-          __try
-            {
-              __lng_ad2 = __log_gamma(__a + __d2);
-              __lng_bd2 = __log_gamma(__b + __d2);
-            }
-          __catch(...)
-            {
-              __ok_d2 = false;
-            }
+	  // Evaluate F2.
+	  bool __ok_d2 = true;
+	  _Tp __lng_ad2, __lng_bd2;
+	  __try
+	    {
+	      __lng_ad2 = __log_gamma(__a + __d2);
+	      __lng_bd2 = __log_gamma(__b + __d2);
+	    }
+	  __catch(...)
+	    {
+	      __ok_d2 = false;
+	    }
 
-          if (__ok_d2)
-            {
-              //  Gamma functions in the denominator are ok.
-              //  Proceed with evaluation.
-              const int __maxiter = 2000;
-              const _Tp __psi_1 = -__numeric_constants<_Tp>::__gamma_e();
-              const _Tp __psi_1pd = __psi(_Tp(1) + __ad);
-              const _Tp __psi_apd1 = __psi(__a + __d1);
-              const _Tp __psi_bpd1 = __psi(__b + __d1);
+	  if (__ok_d2)
+	    {
+	      //  Gamma functions in the denominator are ok.
+	      //  Proceed with evaluation.
+	      const int __maxiter = 2000;
+	      const _Tp __psi_1 = -__numeric_constants<_Tp>::__gamma_e();
+	      const _Tp __psi_1pd = __psi(_Tp(1) + __ad);
+	      const _Tp __psi_apd1 = __psi(__a + __d1);
+	      const _Tp __psi_bpd1 = __psi(__b + __d1);
 
-              _Tp __psi_term = __psi_1 + __psi_1pd - __psi_apd1
-                             - __psi_bpd1 - __ln_omx;
-              _Tp __fact = _Tp(1);
-              _Tp __sum2 = __psi_term;
-              _Tp __ln_pre2 = __lng_c + __d1 * __ln_omx
-                            - __lng_ad2 - __lng_bd2;
+	      _Tp __psi_term = __psi_1 + __psi_1pd - __psi_apd1
+			     - __psi_bpd1 - __ln_omx;
+	      _Tp __fact = _Tp(1);
+	      _Tp __sum2 = __psi_term;
+	      _Tp __ln_pre2 = __lng_c + __d1 * __ln_omx
+			    - __lng_ad2 - __lng_bd2;
 
-              // Do F2 sum.
-              int __j;
-              for (__j = 1; __j < __maxiter; ++__j)
-                {
-                  //  Values for psi functions use recurrence;
-                  //  Abramowitz & Stegun 6.3.5
-                  const _Tp __term1 = _Tp(1) / _Tp(__j)
-                                    + _Tp(1) / (__ad + __j);
-                  const _Tp __term2 = _Tp(1) / (__a + __d1 + _Tp(__j - 1))
-                                    + _Tp(1) / (__b + __d1 + _Tp(__j - 1));
-                  __psi_term += __term1 - __term2;
-                  __fact *= (__a + __d1 + _Tp(__j - 1))
-                          * (__b + __d1 + _Tp(__j - 1))
-                          / ((__ad + __j) * __j) * (_Tp(1) - __x);
-                  const _Tp __delta = __fact * __psi_term;
-                  __sum2 += __delta;
-                  if (std::abs(__delta) < __eps * std::abs(__sum2))
-                    break;
-                }
-              if (__j == __maxiter)
-                std::__throw_runtime_error(__N("Sum F2 failed to converge "
-                                               "in __hyperg_reflect"));
+	      // Do F2 sum.
+	      int __j;
+	      for (__j = 1; __j < __maxiter; ++__j)
+		{
+		  //  Values for psi functions use recurrence;
+		  //  Abramowitz & Stegun 6.3.5
+		  const _Tp __term1 = _Tp(1) / _Tp(__j)
+				    + _Tp(1) / (__ad + __j);
+		  const _Tp __term2 = _Tp(1) / (__a + __d1 + _Tp(__j - 1))
+				    + _Tp(1) / (__b + __d1 + _Tp(__j - 1));
+		  __psi_term += __term1 - __term2;
+		  __fact *= (__a + __d1 + _Tp(__j - 1))
+			  * (__b + __d1 + _Tp(__j - 1))
+			  / ((__ad + __j) * __j) * (_Tp(1) - __x);
+		  const _Tp __delta = __fact * __psi_term;
+		  __sum2 += __delta;
+		  if (std::abs(__delta) < __eps * std::abs(__sum2))
+		    break;
+		}
+	      if (__j == __maxiter)
+		std::__throw_runtime_error(__N("__hyperg_reflect: "
+					       "sum F2 failed to converge"));
 
-              if (__sum2 == _Tp(0))
-                __F2 = _Tp(0);
-              else
-                __F2 = std::exp(__ln_pre2) * __sum2;
-            }
-          else
-            {
-              // Gamma functions in the denominator not ok.
-              // So the F2 term is zero.
-              __F2 = _Tp(0);
-            } // end F2 evaluation
+	      if (__sum2 == _Tp(0))
+		__F2 = _Tp(0);
+	      else
+		__F2 = std::exp(__ln_pre2) * __sum2;
+	    }
+	  else
+	    {
+	      // Gamma functions in the denominator not ok.
+	      // So the F2 term is zero.
+	      __F2 = _Tp(0);
+	    } // end F2 evaluation
 
-          const _Tp __sgn_2 = (__intd % 2 == 1 ? -_Tp(1) : _Tp(1));
-          const _Tp __F = __F1 + __sgn_2 * __F2;
+	  const _Tp __sgn_2 = (__intd % 2 == 1 ? -_Tp(1) : _Tp(1));
+	  const _Tp __F = __F1 + __sgn_2 * __F2;
 
-          return __F;
-        }
+	  return __F;
+	}
       else
-        {
-          //  d = c - a - b not an integer.
+	{
+	  //  d = c - a - b not an integer.
 
-          //  These gamma functions appear in the denominator, so we
-          //  catch their harmless domain errors and set the terms to zero.
-          bool __ok1 = true;
-          _Tp __sgn_g1ca = _Tp(0), __ln_g1ca = _Tp(0);
-          _Tp __sgn_g1cb = _Tp(0), __ln_g1cb = _Tp(0);
-          __try
-            {
-              __sgn_g1ca = __log_gamma_sign(__c - __a);
-              __ln_g1ca = __log_gamma(__c - __a);
-              __sgn_g1cb = __log_gamma_sign(__c - __b);
-              __ln_g1cb = __log_gamma(__c - __b);
-            }
-          __catch(...)
-            {
-              __ok1 = false;
-            }
+	  //  These gamma functions appear in the denominator, so we
+	  //  catch their harmless domain errors and set the terms to zero.
+	  bool __ok1 = true;
+	  _Tp __sgn_g1ca = _Tp(0), __ln_g1ca = _Tp(0);
+	  _Tp __sgn_g1cb = _Tp(0), __ln_g1cb = _Tp(0);
+	  __try
+	    {
+	      __sgn_g1ca = __log_gamma_sign(__c - __a);
+	      __ln_g1ca = __log_gamma(__c - __a);
+	      __sgn_g1cb = __log_gamma_sign(__c - __b);
+	      __ln_g1cb = __log_gamma(__c - __b);
+	    }
+	  __catch(...)
+	    {
+	      __ok1 = false;
+	    }
 
-          bool __ok2 = true;
-          _Tp __sgn_g2a = _Tp(0), __ln_g2a = _Tp(0);
-          _Tp __sgn_g2b = _Tp(0), __ln_g2b = _Tp(0);
-          __try
-            {
-              __sgn_g2a = __log_gamma_sign(__a);
-              __ln_g2a = __log_gamma(__a);
-              __sgn_g2b = __log_gamma_sign(__b);
-              __ln_g2b = __log_gamma(__b);
-            }
-          __catch(...)
-            {
-              __ok2 = false;
-            }
+	  bool __ok2 = true;
+	  _Tp __sgn_g2a = _Tp(0), __ln_g2a = _Tp(0);
+	  _Tp __sgn_g2b = _Tp(0), __ln_g2b = _Tp(0);
+	  __try
+	    {
+	      __sgn_g2a = __log_gamma_sign(__a);
+	      __ln_g2a = __log_gamma(__a);
+	      __sgn_g2b = __log_gamma_sign(__b);
+	      __ln_g2b = __log_gamma(__b);
+	    }
+	  __catch(...)
+	    {
+	      __ok2 = false;
+	    }
 
-          const _Tp __sgn_gc = __log_gamma_sign(__c);
-          const _Tp __ln_gc = __log_gamma(__c);
-          const _Tp __sgn_gd = __log_gamma_sign(__d);
-          const _Tp __ln_gd = __log_gamma(__d);
-          const _Tp __sgn_gmd = __log_gamma_sign(-__d);
-          const _Tp __ln_gmd = __log_gamma(-__d);
+	  const _Tp __sgn_gc = __log_gamma_sign(__c);
+	  const _Tp __ln_gc = __log_gamma(__c);
+	  const _Tp __sgn_gd = __log_gamma_sign(__d);
+	  const _Tp __ln_gd = __log_gamma(__d);
+	  const _Tp __sgn_gmd = __log_gamma_sign(-__d);
+	  const _Tp __ln_gmd = __log_gamma(-__d);
 
-          const _Tp __sgn1 = __sgn_gc * __sgn_gd  * __sgn_g1ca * __sgn_g1cb;
-          const _Tp __sgn2 = __sgn_gc * __sgn_gmd * __sgn_g2a  * __sgn_g2b;
+	  const _Tp __sgn1 = __sgn_gc * __sgn_gd  * __sgn_g1ca * __sgn_g1cb;
+	  const _Tp __sgn2 = __sgn_gc * __sgn_gmd * __sgn_g2a  * __sgn_g2b;
 
-          _Tp __pre1, __pre2;
-          if (__ok1 && __ok2)
-            {
-              _Tp __ln_pre1 = __ln_gc + __ln_gd  - __ln_g1ca - __ln_g1cb;
-              _Tp __ln_pre2 = __ln_gc + __ln_gmd - __ln_g2a  - __ln_g2b
-                            + __d * std::log(_Tp(1) - __x);
-              if (__ln_pre1 < __log_max && __ln_pre2 < __log_max)
-                {
-                  __pre1 = std::exp(__ln_pre1);
-                  __pre2 = std::exp(__ln_pre2);
-                  __pre1 *= __sgn1;
-                  __pre2 *= __sgn2;
-                }
-              else
-                {
-                  std::__throw_runtime_error(__N("Overflow of gamma functions "
-                                                 "in __hyperg_reflect"));
-                }
-            }
-          else if (__ok1 && !__ok2)
-            {
-              _Tp __ln_pre1 = __ln_gc + __ln_gd - __ln_g1ca - __ln_g1cb;
-              if (__ln_pre1 < __log_max)
-                {
-                  __pre1 = std::exp(__ln_pre1);
-                  __pre1 *= __sgn1;
-                  __pre2 = _Tp(0);
-                }
-              else
-                {
-                  std::__throw_runtime_error(__N("Overflow of gamma functions "
-                                                 "in __hyperg_reflect"));
-                }
-            }
-          else if (!__ok1 && __ok2)
-            {
-              _Tp __ln_pre2 = __ln_gc + __ln_gmd - __ln_g2a - __ln_g2b
-                            + __d * std::log(_Tp(1) - __x);
-              if (__ln_pre2 < __log_max)
-                {
-                  __pre1 = _Tp(0);
-                  __pre2 = std::exp(__ln_pre2);
-                  __pre2 *= __sgn2;
-                }
-              else
-                {
-                  std::__throw_runtime_error(__N("Overflow of gamma functions "
-                                                 "in __hyperg_reflect"));
-                }
-            }
-          else
-            {
-              __pre1 = _Tp(0);
-              __pre2 = _Tp(0);
-              std::__throw_runtime_error(__N("Underflow of gamma functions "
-                                             "in __hyperg_reflect"));
-            }
+	  _Tp __pre1, __pre2;
+	  if (__ok1 && __ok2)
+	    {
+	      _Tp __ln_pre1 = __ln_gc + __ln_gd  - __ln_g1ca - __ln_g1cb;
+	      _Tp __ln_pre2 = __ln_gc + __ln_gmd - __ln_g2a  - __ln_g2b
+			    + __d * std::log(_Tp(1) - __x);
+	      if (__ln_pre1 < __log_max && __ln_pre2 < __log_max)
+		{
+		  __pre1 = std::exp(__ln_pre1);
+		  __pre2 = std::exp(__ln_pre2);
+		  __pre1 *= __sgn1;
+		  __pre2 *= __sgn2;
+		}
+	      else
+		{
+		  std::__throw_runtime_error(__N("__hyperg_reflect: "
+						"overflow of gamma functions"));
+		}
+	    }
+	  else if (__ok1 && !__ok2)
+	    {
+	      _Tp __ln_pre1 = __ln_gc + __ln_gd - __ln_g1ca - __ln_g1cb;
+	      if (__ln_pre1 < __log_max)
+		{
+		  __pre1 = std::exp(__ln_pre1);
+		  __pre1 *= __sgn1;
+		  __pre2 = _Tp(0);
+		}
+	      else
+		{
+		  std::__throw_runtime_error(__N("__hyperg_reflect: "
+						"overflow of gamma functions"));
+		}
+	    }
+	  else if (!__ok1 && __ok2)
+	    {
+	      _Tp __ln_pre2 = __ln_gc + __ln_gmd - __ln_g2a - __ln_g2b
+			    + __d * std::log(_Tp(1) - __x);
+	      if (__ln_pre2 < __log_max)
+		{
+		  __pre1 = _Tp(0);
+		  __pre2 = std::exp(__ln_pre2);
+		  __pre2 *= __sgn2;
+		}
+	      else
+		{
+		  std::__throw_runtime_error(__N("__hyperg_reflect: "
+						"overflow of gamma functions"));
+		}
+	    }
+	  else
+	    {
+	      __pre1 = _Tp(0);
+	      __pre2 = _Tp(0);
+	      std::__throw_runtime_error(__N("__hyperg_reflect: "
+					     "underflow of gamma functions"));
+	    }
 
-          const _Tp __F1 = __hyperg_series(__a, __b, _Tp(1) - __d,
-                                           _Tp(1) - __x);
-          const _Tp __F2 = __hyperg_series(__c - __a, __c - __b, _Tp(1) + __d,
-                                           _Tp(1) - __x);
+	  const _Tp __F1 = __hyperg_series(__a, __b, _Tp(1) - __d,
+					   _Tp(1) - __x);
+	  const _Tp __F2 = __hyperg_series(__c - __a, __c - __b, _Tp(1) + __d,
+					   _Tp(1) - __x);
 
-          const _Tp __F = __pre1 * __F1 + __pre2 * __F2;
+	  const _Tp __F = __pre1 * __F1 + __pre2 * __F2;
 
-          return __F;
-        }
+	  return __F;
+	}
     }
 
 
-    /**
-     *   @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$.
-     *
-     *   The hypogeometric function is defined by
-     *   @f[
-     *     _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)}
-     *                      \sum_{n=0}^{\infty}
-     *                      \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)}
-     *                      \frac{x^n}{n!}
-     *   @f]
-     *
-     *   @param  __a  The first @a numerator parameter.
-     *   @param  __a  The second @a numerator parameter.
-     *   @param  __c  The @a denominator parameter.
-     *   @param  __x  The argument of the confluent hypergeometric function.
-     *   @return  The confluent hypergeometric function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief Return the hypogeometric function @f$ _2F_1(a,b;c;x) @f$.
+   *
+   *   The hypogeometric function is defined by
+   *   @f[
+   *     _2F_1(a,b;c;x) = \frac{\Gamma(c)}{\Gamma(a)\Gamma(b)}
+   *                      \sum_{n=0}^{\infty}
+   *                      \frac{\Gamma(a+n)\Gamma(b+n)}{\Gamma(c+n)}
+   *                      \frac{x^n}{n!}
+   *   @f]
+   *
+   *   @param  __a  The first @a numerator parameter.
+   *   @param  __a  The second @a numerator parameter.
+   *   @param  __c  The @a denominator parameter.
+   *   @param  __x  The argument of the confluent hypergeometric function.
+   *   @return  The confluent hypergeometric function.
+   */
+  template<typename _Tp>
     inline _Tp
-    __hyperg(const _Tp __a, const _Tp __b, const _Tp __c, const _Tp __x)
+    __hyperg(_Tp __a, _Tp __b, _Tp __c, _Tp __x)
     {
-#if _GLIBCXX_USE_C99_MATH_TR1
-      const _Tp __a_nint = std::tr1::nearbyint(__a);
-      const _Tp __b_nint = std::tr1::nearbyint(__b);
-      const _Tp __c_nint = std::tr1::nearbyint(__c);
-#else
-      const _Tp __a_nint = static_cast<int>(__a + _Tp(0.5L));
-      const _Tp __b_nint = static_cast<int>(__b + _Tp(0.5L));
-      const _Tp __c_nint = static_cast<int>(__c + _Tp(0.5L));
-#endif
+      const _Tp __a_nint = std::nearbyint(__a);
+      const _Tp __b_nint = std::nearbyint(__b);
+      const _Tp __c_nint = std::nearbyint(__c);
       const _Tp __toler = _Tp(1000) * std::numeric_limits<_Tp>::epsilon();
-      if (std::abs(__x) >= _Tp(1))
-        std::__throw_domain_error(__N("Argument outside unit circle "
-                                      "in __hyperg."));
+      const bool __c_neg_integer
+		  = (__c < _Tp(0) && std::abs(__c - __c_nint) < __toler );
+      if (std::abs(__x - _Tp(1)) < __toler && __c - __b - __a > _Tp(0)
+       && __c != _Tp(0) && ! __c_neg_integer)
+	{
+	  const _Tp __log_gamc = __log_gamma(__c);
+	  const _Tp __sign_gamc = __log_gamma_sign(__c);
+	  const _Tp __log_gamcab = __log_gamma(__c - __a - __b);
+	  const _Tp __log_gamca = __log_gamma(__c - __a);
+	  const _Tp __sign_gamca = __log_gamma_sign(__c - __a);
+	  const _Tp __log_gamcb = __log_gamma(__c - __b);
+	  const _Tp __sign_gamcb = __log_gamma_sign(__c - __b);
+	  const _Tp __log_max = std::log(std::numeric_limits<_Tp>::max());
+	  const _Tp __log_pre = __log_gamc + __log_gamcab
+			      - __log_gamca - __log_gamcb;
+	  if (__log_pre < __log_max)
+	    return __sign_gamc * __sign_gamca * __sign_gamcb
+		   * std::exp(__log_pre);
+	  else
+	    std::__throw_domain_error(__N("__hyperg: "
+					  "overflow of gamma functions"));
+	}
+      else if (std::abs(__x) >= _Tp(1))
+	std::__throw_domain_error(__N("__hyperg: "
+				      "argument outside unit circle"));
       else if (__isnan(__a) || __isnan(__b)
-            || __isnan(__c) || __isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	    || __isnan(__c) || __isnan(__x))
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__c_nint == __c && __c_nint <= _Tp(0))
-        return std::numeric_limits<_Tp>::infinity();
+	return std::numeric_limits<_Tp>::infinity();
       else if (std::abs(__c - __b) < __toler || std::abs(__c - __a) < __toler)
-        return std::pow(_Tp(1) - __x, __c - __a - __b);
+	return std::pow(_Tp(1) - __x, __c - __a - __b);
       else if (__a >= _Tp(0) && __b >= _Tp(0) && __c >= _Tp(0)
-            && __x >= _Tp(0) && __x < _Tp(0.995L))
-        return __hyperg_series(__a, __b, __c, __x);
+	    && __x >= _Tp(0) && __x < _Tp(0.995L))
+	return __hyperg_series(__a, __b, __c, __x);
       else if (std::abs(__a) < _Tp(10) && std::abs(__b) < _Tp(10))
-        {
-          //  For integer a and b the hypergeometric function is a
-          //  finite polynomial.
-          if (__a < _Tp(0)  &&  std::abs(__a - __a_nint) < __toler)
-            return __hyperg_series(__a_nint, __b, __c, __x);
-          else if (__b < _Tp(0)  &&  std::abs(__b - __b_nint) < __toler)
-            return __hyperg_series(__a, __b_nint, __c, __x);
-          else if (__x < -_Tp(0.25L))
-            return __hyperg_luke(__a, __b, __c, __x);
-          else if (__x < _Tp(0.5L))
-            return __hyperg_series(__a, __b, __c, __x);
-          else
-            if (std::abs(__c) > _Tp(10))
-              return __hyperg_series(__a, __b, __c, __x);
-            else
-              return __hyperg_reflect(__a, __b, __c, __x);
-        }
+	{
+	  //  For integer a and b the hypergeometric function is a
+	  //  finite polynomial.
+	  if (__a < _Tp(0)  &&  std::abs(__a - __a_nint) < __toler)
+	    return __hyperg_series(__a_nint, __b, __c, __x);
+	  else if (__b < _Tp(0)  &&  std::abs(__b - __b_nint) < __toler)
+	    return __hyperg_series(__a, __b_nint, __c, __x);
+	  else if (__x < -_Tp(0.25L))
+	    return __hyperg_luke(__a, __b, __c, __x);
+	  else if (__x < _Tp(0.5L))
+	    return __hyperg_series(__a, __b, __c, __x);
+	  else if (std::abs(__c) > _Tp(10))
+	    return __hyperg_series(__a, __b, __c, __x);
+	  else
+	    return __hyperg_reflect(__a, __b, __c, __x);
+	}
       else
-        return __hyperg_luke(__a, __b, __c, __x);
+	return __hyperg_luke(__a, __b, __c, __x);
     }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
 
-#endif // _GLIBCXX_TR1_HYPERGEOMETRIC_TCC
+#endif // _GLIBCXX_BITS_SF_HYPERG_TCC
Index: include/bits/sf_hermite.tcc
===================================================================
--- include/bits/sf_hermite.tcc	(revision 175789)
+++ include/bits/sf_hermite.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,103 +22,99 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/poly_hermite.tcc
+/** @file bits/sf_hermite.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
-// Written by Edward Smith-Rowland based on:
+// Written by Edward Smith-Rowland.
+//
+// Reference:
 //   (1) Handbook of Mathematical Functions,
 //       Ed. Milton Abramowitz and Irene A. Stegun,
 //       Dover Publications, Section 22 pp. 773-802
 
-#ifndef _GLIBCXX_TR1_POLY_HERMITE_TCC
-#define _GLIBCXX_TR1_POLY_HERMITE_TCC 1
+#ifndef _GLIBCXX_BITS_SF_HERMITE_TCC
+#define _GLIBCXX_BITS_SF_HERMITE_TCC 1
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // [5.2] Special functions
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-    /**
-     *   @brief This routine returns the Hermite polynomial
-     *          of order n: \f$ H_n(x) \f$ by recursion on n.
-     * 
-     *   The Hermite polynomial is defined by:
-     *   @f[
-     *     H_n(x) = (-1)^n e^{x^2} \frac{d^n}{dx^n} e^{-x^2}
-     *   @f]
-     *
-     *   @param __n The order of the Hermite polynomial.
-     *   @param __x The argument of the Hermite polynomial.
-     *   @return The value of the Hermite polynomial of order n
-     *           and argument x.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief This routine returns the Hermite polynomial
+   *          of order n: \f$ H_n(x) \f$ by recursion on n.
+   *
+   *   The Hermite polynomial is defined by:
+   *   @f[
+   *     H_n(x) = (-1)^n e^{x^2} \frac{d^n}{dx^n} e^{-x^2}
+   *   @f]
+   *
+   *   @param __n The order of the Hermite polynomial.
+   *   @param __x The argument of the Hermite polynomial.
+   *   @return The value of the Hermite polynomial of order n
+   *           and argument x.
+   */
+  template<typename _Tp>
     _Tp
-    __poly_hermite_recursion(const unsigned int __n, const _Tp __x)
+    __poly_hermite_recursion(unsigned int __n, _Tp __x)
     {
       //  Compute H_0.
-      _Tp __H_0 = 1;
+      _Tp __H_nm2 = 1;
       if (__n == 0)
-        return __H_0;
+	return __H_nm2;
 
       //  Compute H_1.
-      _Tp __H_1 = 2 * __x;
+      _Tp __H_nm1 = 2 * __x;
       if (__n == 1)
-        return __H_1;
+	return __H_nm1;
 
       //  Compute H_n.
-      _Tp __H_n, __H_nm1, __H_nm2;
-      unsigned int __i;
-      for  (__H_nm2 = __H_0, __H_nm1 = __H_1, __i = 2; __i <= __n; ++__i)
-        {
-          __H_n = 2 * (__x * __H_nm1 + (__i - 1) * __H_nm2);
-          __H_nm2 = __H_nm1;
-          __H_nm1 = __H_n;
-        }
+      _Tp __H_n;
+      for (unsigned int __i = 2; __i <= __n; ++__i)
+	{
+	  __H_n = 2 * (__x * __H_nm1 - (__i - 1) * __H_nm2);
+	  __H_nm2 = __H_nm1;
+	  __H_nm1 = __H_n;
+	}
 
       return __H_n;
     }
 
 
-    /**
-     *   @brief This routine returns the Hermite polynomial
-     *          of order n: \f$ H_n(x) \f$.
-     * 
-     *   The Hermite polynomial is defined by:
-     *   @f[
-     *     H_n(x) = (-1)^n e^{x^2} \frac{d^n}{dx^n} e^{-x^2}
-     *   @f]
-     *
-     *   @param __n The order of the Hermite polynomial.
-     *   @param __x The argument of the Hermite polynomial.
-     *   @return The value of the Hermite polynomial of order n
-     *           and argument x.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief This routine returns the Hermite polynomial
+   *          of order n: \f$ H_n(x) \f$.
+   *
+   *   The Hermite polynomial is defined by:
+   *   @f[
+   *     H_n(x) = (-1)^n e^{x^2} \frac{d^n}{dx^n} e^{-x^2}
+   *   @f]
+   *
+   *   @param __n The order of the Hermite polynomial.
+   *   @param __x The argument of the Hermite polynomial.
+   *   @return The value of the Hermite polynomial of order n
+   *           and argument x.
+   */
+  template<typename _Tp>
     inline _Tp
-    __poly_hermite(const unsigned int __n, const _Tp __x)
+    __poly_hermite(unsigned int __n, _Tp __x)
     {
       if (__isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else
-        return __poly_hermite_recursion(__n, __x);
+	return __poly_hermite_recursion(__n, __x);
     }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
 
-#endif // _GLIBCXX_TR1_POLY_HERMITE_TCC
+#endif // _GLIBCXX_BITS_SF_HERMITE_TCC
Index: include/bits/sf_hypint.tcc
===================================================================
--- include/bits/sf_hypint.tcc	(revision 0)
+++ include/bits/sf_hypint.tcc	(working copy)
@@ -0,0 +1,189 @@
+// Special functions -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/sf_hypint.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{cmath}
+ */
+
+#ifndef _GLIBCXX_SF_HYPINT_TCC
+#define _GLIBCXX_SF_HYPINT_TCC 1
+
+#include <cmath>
+#include <complex>
+#include <stdexcept>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// Implementation-space details.
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   *  @brief This function computes the hyperbolic cosine @f$ Chi(x) @f$
+   *    and hyperbolic sine @f$ Shi(x) @f$ integrals
+   *    by continued fraction for positive argument.
+   */
+  ////FIXME!!!!
+  template<typename _Tp>
+    void
+    __chshint_cont_frac(_Tp __t, _Tp& _Chi, _Tp& _Shi)
+    {
+      constexpr unsigned int _S_max_iter = 100;
+      constexpr _Tp _S_eps = _Tp(5) * std::numeric_limits<_Tp>::epsilon();
+      constexpr _Tp _S_fp_min = std::numeric_limits<_Tp>::min();
+      constexpr _Tp _S_pi_2 = std::__detail::__numeric_constants<_Tp>::__pi_2();
+
+      //  Evaluate Chi and Shi by Lentz's modified method of continued fracions.
+      std::complex<_Tp> __b(_Tp(1), __t);
+      std::complex<_Tp> __c(_Tp(1) / _S_fp_min);
+      std::complex<_Tp> __d(_Tp(1) / __b);
+      std::complex<_Tp> __h(__d);
+      unsigned int i = 2;
+      while (true)
+	{
+	  _Tp __a = -(i - 1) * (i - 1);
+	  __b += _Tp(2);
+	  __d = _Tp(1) / (__a * __d + __b);
+	  __c = __b + __a / __c;
+	  auto __del = __c * __d;
+	  __h *= __del;
+	  if (std::abs(__del.real() - _Tp(1)) + std::abs(__del.imag()) < _S_eps)
+	    break;
+	  if (i > _S_max_iter)
+	    std::__throw_runtime_error("chishi: "
+				       "continued fraction evaluation failed");
+	  ++i;
+	}
+      __h *= std::polar(_Tp(1), -__t);
+      _Chi = -__h.real();
+      _Shi = _S_pi_2 + __h.imag();
+
+      return;
+    }
+
+
+  /**
+   *  @brief This function computes the hyperbolic cosine @f$ Chi(x) @f$
+   *    and hyperbolic sine @f$ Shi(x) @f$ integrals
+   *    by series summation for positive argument.
+   */
+  template<typename _Tp>
+    void
+    __chshint_series(_Tp __t, _Tp& _Chi, _Tp& _Shi)
+    {
+      constexpr auto _S_max_iter = 100;
+      constexpr auto _S_eps = _Tp(5) * std::numeric_limits<_Tp>::epsilon();
+      constexpr auto _S_fp_min = std::numeric_limits<_Tp>::min();
+      constexpr auto _S_gamma_e = std::__detail::__numeric_constants<_Tp>::__gamma_e();
+
+      //  Evaluate Chi and Shi by series simultaneously.
+      _Tp _Csum(0), _Ssum(0);
+      if (__t * __t < _S_fp_min)
+	{
+	  //  Avoid underflow.
+	  _Csum = _Tp(0);
+	  _Ssum = __t;
+	}
+      else
+	{
+	  /*
+	   *    Evaluate Shi and Chi by series expansion.
+	   */
+	  _Tp __sum(0);
+	  _Tp __fact(1);
+	  auto __odd = true;
+	  auto __k = 1;
+	  while (true)
+	    {
+	      __fact *= __t / __k;
+	      _Tp __term = __fact / __k;
+	      __sum += __term;
+	      _Tp __err = __term / std::abs(__sum);
+	      if (__odd)
+		{
+		  _Ssum = __sum;
+		  __sum = _Csum;
+		}
+	      else
+		{
+		  _Csum = __sum;
+		  __sum = _Ssum;
+		}
+	      if (__err < _S_eps)
+		break;
+	      __odd = !__odd;
+	      ++__k;
+	      if (__k > _S_max_iter)
+		std::__throw_runtime_error("chishi: series evaluation failed");
+	    }
+	}
+      _Chi = _S_gamma_e + std::log(__t) + _Csum;
+      _Shi = _Ssum;
+
+      return;
+    }
+
+
+  /**
+   *  @brief This function returns the hyperbolic cosine @f$ Ci(x) @f$
+   *    and hyperbolic sine @f$ Si(x) @f$ integrals as a pair.
+   *
+   *  The hyperbolic cosine integral is defined by:
+   *  @f[
+   *      Chi(x) = \gamma_E + \log(x) + \int_0^x dt \frac{\cosh(t) - 1}{t}
+   *  @f]
+   *
+   *  The hyperbolic sine integral is defined by:
+   *  @f[
+   *      Shi(x) = \int_0^x dt \frac{\sinh(t)}{t}
+   *  @f]
+   */
+  template<typename _Tp>
+    std::pair<_Tp, _Tp>
+    __chshint(_Tp __x, _Tp& _Chi, _Tp& _Shi)
+    {
+      auto __t = std::abs(__x);
+      if (__t == _Tp(0))
+	{
+	  _Chi = -std::numeric_limits<_Tp>::infinity();
+	  _Shi = _Tp(0);
+	}
+      else if (__t > _Tp(2))
+	__chshint_cont_frac(__t, _Chi, _Shi);
+      else
+	__chshint_series(__t, _Chi, _Shi);
+
+      if (__x < _Tp(0))
+	_Shi = -_Shi;
+
+      return std::make_pair(_Chi, _Shi);
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+}
+
+#endif // _GLIBCXX_SF_HYPINT_TCC
Index: include/bits/sf_jacobi.tcc
===================================================================
--- include/bits/sf_jacobi.tcc	(revision 0)
+++ include/bits/sf_jacobi.tcc	(working copy)
@@ -0,0 +1,96 @@
+// Special functions -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/sf_jacobi.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{cmath}
+ */
+
+#ifndef _GLIBCXX_SF_JACOBI_TCC
+#define _GLIBCXX_SF_JACOBI_TCC 1
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// Implementation-space details.
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Tp>
+    _Tp
+    __poly_jacobi(unsigned int __n, _Tp __alpha, _Tp __beta, _Tp __x)
+    {
+      auto _Pm2 = _Tp(1);
+      if (__n == 0)
+	return _Pm2;
+
+      auto __apb = __alpha + __beta;
+      auto __amb = __alpha - __beta;
+      auto _Pm1 = (__amb + (_Tp(2) + __apb) * __x) / _Tp(2);
+      if (__n == 1)
+	return _Pm1;
+
+      _Tp _P(0);
+      for (auto __j = 2; __j < __n; ++__j )
+	{
+	  auto __japb = _Tp(__j) + __apb;
+	  auto __japb1 = __japb + _Tp(1);
+	  auto __japb2 = __japb1 + _Tp(1);
+	  auto __c = _Tp(2) * _Tp(__j + 1) * __japb * __japb1;
+	  auto __d = (__japb1) * __apb * __amb;
+	  auto __e = __japb * __japb1 * __japb2;
+	  auto __f = _Tp(2) * (__j + __alpha) * (__j + __beta) * __japb2;
+
+	  if (__c == _Tp(0))
+	    std::__throw_runtime_error("poly_jacobi: error in recursion");
+	  _P = ((__d + __e * __x) * _Pm1 - __f * _Pm2) / __c;
+	  _Pm2 = _Pm1;
+	  _Pm1 = _P;
+	}
+      return _P;
+    }
+
+
+  template<typename _Tp>
+    _Tp
+    __poly_radial_jacobi(unsigned int __n, unsigned int __m, _Tp __rho)
+    {
+      if (__m > __n)
+	throw std::range_error("poly_radial_jacobi: m > n");
+      else if ((__n - __m) % 2 == 1)
+	return _Tp(0);
+      else
+	{
+	  auto __k = (__n - __m) / 2;
+	  return (__k % 2 == 0 ? 1 : -1) * std::pow(__rho, __m)
+	       * __poly_jacobi(__k, _Tp(__m), _Tp(0),
+			       _Tp(1) - _Tp(2) * __rho * __rho);
+	}
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+}
+
+#endif // _GLIBCXX_SF_JACOBI_TCC
Index: include/bits/sf_legendre.tcc
===================================================================
--- include/bits/sf_legendre.tcc	(revision 175789)
+++ include/bits/sf_legendre.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,16 +22,18 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/legendre_function.tcc
+/** @file bits/sf_legendre.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
-// Written by Edward Smith-Rowland based on:
+// Written by Edward Smith-Rowland.
+//
+// References:
 //   (1) Handbook of Mathematical Functions,
 //       ed. Milton Abramowitz and Irene A. Stegun,
 //       Dover Publications,
@@ -42,265 +43,242 @@
 //       W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
 //       2nd ed, pp. 252-254
 
-#ifndef _GLIBCXX_TR1_LEGENDRE_FUNCTION_TCC
-#define _GLIBCXX_TR1_LEGENDRE_FUNCTION_TCC 1
+#ifndef _GLIBCXX_BITS_SF_LEGENDRE_TCC
+#define _GLIBCXX_BITS_SF_LEGENDRE_TCC 1
 
-#include "special_function_util.h"
+#include <bits/specfun_util.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // [5.2] Special functions
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-    /**
-     *   @brief  Return the Legendre polynomial by recursion on order
-     *           @f$ l @f$.
-     * 
-     *   The Legendre function of @f$ l @f$ and @f$ x @f$,
-     *   @f$ P_l(x) @f$, is defined by:
-     *   @f[
-     *     P_l(x) = \frac{1}{2^l l!}\frac{d^l}{dx^l}(x^2 - 1)^{l}
-     *   @f]
-     * 
-     *   @param  l  The order of the Legendre polynomial.  @f$l >= 0@f$.
-     *   @param  x  The argument of the Legendre polynomial.  @f$|x| <= 1@f$.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the Legendre polynomial by recursion on order
+   *           @f$ l @f$.
+   *
+   *   The Legendre function of @f$ l @f$ and @f$ x @f$,
+   *   @f$ P_l(x) @f$, is defined by:
+   *   @f[
+   *     P_l(x) = \frac{1}{2^l l!}\frac{d^l}{dx^l}(x^2 - 1)^{l}
+   *   @f]
+   *
+   *   @param  l  The order of the Legendre polynomial.  @f$l >= 0@f$.
+   *   @param  x  The argument of the Legendre polynomial.  @f$|x| <= 1@f$.
+   */
+  template<typename _Tp>
     _Tp
-    __poly_legendre_p(const unsigned int __l, const _Tp __x)
+    __poly_legendre_p(unsigned int __l, _Tp __x)
     {
 
       if ((__x < _Tp(-1)) || (__x > _Tp(+1)))
-        std::__throw_domain_error(__N("Argument out of range"
-                                      " in __poly_legendre_p."));
+	std::__throw_domain_error(__N("__poly_legendre_p: argument out of range"));
       else if (__isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__x == +_Tp(1))
-        return +_Tp(1);
+	return +_Tp(1);
       else if (__x == -_Tp(1))
-        return (__l % 2 == 1 ? -_Tp(1) : +_Tp(1));
+	return (__l % 2 == 1 ? -_Tp(1) : +_Tp(1));
       else
-        {
-          _Tp __p_lm2 = _Tp(1);
-          if (__l == 0)
-            return __p_lm2;
+	{
+	  _Tp __p_lm2 = _Tp(1);
+	  if (__l == 0)
+	    return __p_lm2;
 
-          _Tp __p_lm1 = __x;
-          if (__l == 1)
-            return __p_lm1;
+	  _Tp __p_lm1 = __x;
+	  if (__l == 1)
+	    return __p_lm1;
 
-          _Tp __p_l = 0;
-          for (unsigned int __ll = 2; __ll <= __l; ++__ll)
-            {
-              //  This arrangement is supposed to be better for roundoff
-              //  protection, Arfken, 2nd Ed, Eq 12.17a.
-              __p_l = _Tp(2) * __x * __p_lm1 - __p_lm2
-                    - (__x * __p_lm1 - __p_lm2) / _Tp(__ll);
-              __p_lm2 = __p_lm1;
-              __p_lm1 = __p_l;
-            }
+	  _Tp __p_l = 0;
+	  for (unsigned int __ll = 2; __ll <= __l; ++__ll)
+	    {
+	      //  This arrangement is supposed to be better for roundoff
+	      //  protection, Arfken, 2nd Ed, Eq 12.17a.
+	      __p_l = _Tp(2) * __x * __p_lm1 - __p_lm2
+		    - (__x * __p_lm1 - __p_lm2) / _Tp(__ll);
+	      __p_lm2 = __p_lm1;
+	      __p_lm1 = __p_l;
+	    }
 
-          return __p_l;
-        }
+	  return __p_l;
+	}
     }
 
 
-    /**
-     *   @brief  Return the associated Legendre function by recursion
-     *           on @f$ l @f$.
-     * 
-     *   The associated Legendre function is derived from the Legendre function
-     *   @f$ P_l(x) @f$ by the Rodrigues formula:
-     *   @f[
-     *     P_l^m(x) = (1 - x^2)^{m/2}\frac{d^m}{dx^m}P_l(x)
-     *   @f]
-     * 
-     *   @param  l  The order of the associated Legendre function.
-     *              @f$ l >= 0 @f$.
-     *   @param  m  The order of the associated Legendre function.
-     *              @f$ m <= l @f$.
-     *   @param  x  The argument of the associated Legendre function.
-     *              @f$ |x| <= 1 @f$.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the associated Legendre function by recursion
+   *           on @f$ l @f$.
+   *
+   *   The associated Legendre function is derived from the Legendre function
+   *   @f$ P_l(x) @f$ by the Rodrigues formula:
+   *   @f[
+   *     P_l^m(x) = (1 - x^2)^{m/2}\frac{d^m}{dx^m}P_l(x)
+   *   @f]
+   *
+   *   @param  l  The order of the associated Legendre function.
+   *              @f$ l >= 0 @f$.
+   *   @param  m  The order of the associated Legendre function.
+   *              @f$ m <= l @f$.
+   *   @param  x  The argument of the associated Legendre function.
+   *              @f$ |x| <= 1 @f$.
+   */
+  template<typename _Tp>
     _Tp
-    __assoc_legendre_p(const unsigned int __l, const unsigned int __m,
-                       const _Tp __x)
+    __assoc_legendre_p(unsigned int __l, unsigned int __m, _Tp __x)
     {
 
       if (__x < _Tp(-1) || __x > _Tp(+1))
-        std::__throw_domain_error(__N("Argument out of range"
-                                      " in __assoc_legendre_p."));
+	std::__throw_domain_error(__N("__assoc_legendre_p: "
+				      "argument out of range"));
       else if (__m > __l)
-        std::__throw_domain_error(__N("Degree out of range"
-                                      " in __assoc_legendre_p."));
+	std::__throw_domain_error(__N("__assoc_legendre_p: "
+				      "degree out of range"));
       else if (__isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__m == 0)
-        return __poly_legendre_p(__l, __x);
+	return __poly_legendre_p(__l, __x);
       else
-        {
-          _Tp __p_mm = _Tp(1);
-          if (__m > 0)
-            {
-              //  Two square roots seem more accurate more of the time
-              //  than just one.
-              _Tp __root = std::sqrt(_Tp(1) - __x) * std::sqrt(_Tp(1) + __x);
-              _Tp __fact = _Tp(1);
-              for (unsigned int __i = 1; __i <= __m; ++__i)
-                {
-                  __p_mm *= -__fact * __root;
-                  __fact += _Tp(2);
-                }
-            }
-          if (__l == __m)
-            return __p_mm;
+	{
+	  _Tp __p_mm = _Tp(1);
+	  if (__m > 0)
+	    {
+	      //  Two square roots seem more accurate more of the time
+	      //  than just one.
+	      _Tp __root = std::sqrt(_Tp(1) - __x) * std::sqrt(_Tp(1) + __x);
+	      _Tp __fact = _Tp(1);
+	      for (unsigned int __i = 1; __i <= __m; ++__i)
+		{
+		  __p_mm *= -__fact * __root;
+		  __fact += _Tp(2);
+		}
+	    }
+	  if (__l == __m)
+	    return __p_mm;
 
-          _Tp __p_mp1m = _Tp(2 * __m + 1) * __x * __p_mm;
-          if (__l == __m + 1)
-            return __p_mp1m;
+	  _Tp __p_mp1m = _Tp(2 * __m + 1) * __x * __p_mm;
+	  if (__l == __m + 1)
+	    return __p_mp1m;
 
-          _Tp __p_lm2m = __p_mm;
-          _Tp __P_lm1m = __p_mp1m;
-          _Tp __p_lm = _Tp(0);
-          for (unsigned int __j = __m + 2; __j <= __l; ++__j)
-            {
-              __p_lm = (_Tp(2 * __j - 1) * __x * __P_lm1m
-                      - _Tp(__j + __m - 1) * __p_lm2m) / _Tp(__j - __m);
-              __p_lm2m = __P_lm1m;
-              __P_lm1m = __p_lm;
-            }
+	  _Tp __p_lm2m = __p_mm;
+	  _Tp __P_lm1m = __p_mp1m;
+	  _Tp __p_lm = _Tp(0);
+	  for (unsigned int __j = __m + 2; __j <= __l; ++__j)
+	    {
+	      __p_lm = (_Tp(2 * __j - 1) * __x * __P_lm1m
+		      - _Tp(__j + __m - 1) * __p_lm2m) / _Tp(__j - __m);
+	      __p_lm2m = __P_lm1m;
+	      __P_lm1m = __p_lm;
+	    }
 
-          return __p_lm;
-        }
+	  return __p_lm;
+	}
     }
 
 
-    /**
-     *   @brief  Return the spherical associated Legendre function.
-     * 
-     *   The spherical associated Legendre function of @f$ l @f$, @f$ m @f$,
-     *   and @f$ \theta @f$ is defined as @f$ Y_l^m(\theta,0) @f$ where
-     *   @f[
-     *      Y_l^m(\theta,\phi) = (-1)^m[\frac{(2l+1)}{4\pi}
-     *                                  \frac{(l-m)!}{(l+m)!}]
-     *                     P_l^m(\cos\theta) \exp^{im\phi}
-     *   @f]
-     *   is the spherical harmonic function and @f$ P_l^m(x) @f$ is the
-     *   associated Legendre function.
-     * 
-     *   This function differs from the associated Legendre function by
-     *   argument (@f$x = \cos(\theta)@f$) and by a normalization factor
-     *   but this factor is rather large for large @f$ l @f$ and @f$ m @f$
-     *   and so this function is stable for larger differences of @f$ l @f$
-     *   and @f$ m @f$.
-     * 
-     *   @param  l  The order of the spherical associated Legendre function.
-     *              @f$ l >= 0 @f$.
-     *   @param  m  The order of the spherical associated Legendre function.
-     *              @f$ m <= l @f$.
-     *   @param  theta  The radian angle argument of the spherical associated
-     *                  Legendre function.
-     */
-    template <typename _Tp>
+  /**
+   *   @brief  Return the spherical associated Legendre function.
+   *
+   *   The spherical associated Legendre function of @f$ l @f$, @f$ m @f$,
+   *   and @f$ \theta @f$ is defined as @f$ Y_l^m(\theta,0) @f$ where
+   *   @f[
+   *      Y_l^m(\theta,\phi) = (-1)^m[\frac{(2l+1)}{4\pi}
+   *                                  \frac{(l-m)!}{(l+m)!}]
+   *                     P_l^m(\cos\theta) \exp^{im\phi}
+   *   @f]
+   *   is the spherical harmonic function and @f$ P_l^m(x) @f$ is the
+   *   associated Legendre function.
+   *
+   *   This function differs from the associated Legendre function by
+   *   argument (@f$x = \cos(\theta)@f$) and by a normalization factor
+   *   but this factor is rather large for large @f$ l @f$ and @f$ m @f$
+   *   and so this function is stable for larger differences of @f$ l @f$
+   *   and @f$ m @f$.
+   *
+   *   @param  l  The order of the spherical associated Legendre function.
+   *              @f$ l >= 0 @f$.
+   *   @param  m  The order of the spherical associated Legendre function.
+   *              @f$ m <= l @f$.
+   *   @param  theta  The radian angle argument of the spherical associated
+   *                  Legendre function.
+   */
+  template<typename _Tp>
     _Tp
-    __sph_legendre(const unsigned int __l, const unsigned int __m,
-                   const _Tp __theta)
+    __sph_legendre(unsigned int __l, unsigned int __m, _Tp __theta)
     {
       if (__isnan(__theta))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
 
       const _Tp __x = std::cos(__theta);
 
       if (__l < __m)
-        {
-          std::__throw_domain_error(__N("Bad argument "
-                                        "in __sph_legendre."));
-        }
+	std::__throw_domain_error(__N("__sph_legendre: bad argument"));
       else if (__m == 0)
-        {
-          _Tp __P = __poly_legendre_p(__l, __x);
-          _Tp __fact = std::sqrt(_Tp(2 * __l + 1)
-                     / (_Tp(4) * __numeric_constants<_Tp>::__pi()));
-          __P *= __fact;
-          return __P;
-        }
+	{
+	  _Tp __P = __poly_legendre_p(__l, __x);
+	  _Tp __fact = std::sqrt(_Tp(2 * __l + 1)
+		     / (_Tp(4) * __numeric_constants<_Tp>::__pi()));
+	  __P *= __fact;
+	  return __P;
+	}
       else if (__x == _Tp(1) || __x == -_Tp(1))
-        {
-          //  m > 0 here
-          return _Tp(0);
-        }
+	return _Tp(0);  //  m > 0 here
       else
-        {
-          // m > 0 and |x| < 1 here
+	{
+	  // m > 0 and |x| < 1 here
 
-          // Starting value for recursion.
-          // Y_m^m(x) = sqrt( (2m+1)/(4pi m) gamma(m+1/2)/gamma(m) )
-          //             (-1)^m (1-x^2)^(m/2) / pi^(1/4)
-          const _Tp __sgn = ( __m % 2 == 1 ? -_Tp(1) : _Tp(1));
-          const _Tp __y_mp1m_factor = __x * std::sqrt(_Tp(2 * __m + 3));
-#if _GLIBCXX_USE_C99_MATH_TR1
-          const _Tp __lncirc = std::tr1::log1p(-__x * __x);
-#else
-          const _Tp __lncirc = std::log(_Tp(1) - __x * __x);
-#endif
-          //  Gamma(m+1/2) / Gamma(m)
-#if _GLIBCXX_USE_C99_MATH_TR1
-          const _Tp __lnpoch = std::tr1::lgamma(_Tp(__m + _Tp(0.5L)))
-                             - std::tr1::lgamma(_Tp(__m));
-#else
-          const _Tp __lnpoch = __log_gamma(_Tp(__m + _Tp(0.5L)))
-                             - __log_gamma(_Tp(__m));
-#endif
-          const _Tp __lnpre_val =
-                    -_Tp(0.25L) * __numeric_constants<_Tp>::__lnpi()
-                    + _Tp(0.5L) * (__lnpoch + __m * __lncirc);
-          _Tp __sr = std::sqrt((_Tp(2) + _Tp(1) / __m)
-                   / (_Tp(4) * __numeric_constants<_Tp>::__pi()));
-          _Tp __y_mm = __sgn * __sr * std::exp(__lnpre_val);
-          _Tp __y_mp1m = __y_mp1m_factor * __y_mm;
+	  // Starting value for recursion.
+	  // Y_m^m(x) = sqrt( (2m+1)/(4pi m) gamma(m+1/2)/gamma(m) )
+	  //             (-1)^m (1-x^2)^(m/2) / pi^(1/4)
+	  const _Tp __sgn = ( __m % 2 == 1 ? -_Tp(1) : _Tp(1));
+	  const _Tp __y_mp1m_factor = __x * std::sqrt(_Tp(2 * __m + 3));
+	  const _Tp __lncirc = std::log1p(-__x * __x);
+	  //  Gamma(m+1/2) / Gamma(m)
+	  const _Tp __lnpoch = __log_gamma(_Tp(__m + _Tp(0.5L)))
+			     - __log_gamma(_Tp(__m));
+	  const _Tp __lnpre_val =
+		    -_Tp(0.25L) * __numeric_constants<_Tp>::__lnpi()
+		    + _Tp(0.5L) * (__lnpoch + __m * __lncirc);
+	  _Tp __sr = std::sqrt((_Tp(2) + _Tp(1) / __m)
+		   / (_Tp(4) * __numeric_constants<_Tp>::__pi()));
+	  _Tp __y_mm = __sgn * __sr * std::exp(__lnpre_val);
+	  _Tp __y_mp1m = __y_mp1m_factor * __y_mm;
 
-          if (__l == __m)
-            {
-              return __y_mm;
-            }
-          else if (__l == __m + 1)
-            {
-              return __y_mp1m;
-            }
-          else
-            {
-              _Tp __y_lm = _Tp(0);
+	  if (__l == __m)
+	    {
+	      return __y_mm;
+	    }
+	  else if (__l == __m + 1)
+	    {
+	      return __y_mp1m;
+	    }
+	  else
+	    {
+	      _Tp __y_lm = _Tp(0);
 
-              // Compute Y_l^m, l > m+1, upward recursion on l.
-              for ( int __ll = __m + 2; __ll <= __l; ++__ll)
-                {
-                  const _Tp __rat1 = _Tp(__ll - __m) / _Tp(__ll + __m);
-                  const _Tp __rat2 = _Tp(__ll - __m - 1) / _Tp(__ll + __m - 1);
-                  const _Tp __fact1 = std::sqrt(__rat1 * _Tp(2 * __ll + 1)
-                                                       * _Tp(2 * __ll - 1));
-                  const _Tp __fact2 = std::sqrt(__rat1 * __rat2 * _Tp(2 * __ll + 1)
-                                                                / _Tp(2 * __ll - 3));
-                  __y_lm = (__x * __y_mp1m * __fact1
-                         - (__ll + __m - 1) * __y_mm * __fact2) / _Tp(__ll - __m);
-                  __y_mm = __y_mp1m;
-                  __y_mp1m = __y_lm;
-                }
+	      // Compute Y_l^m, l > m+1, upward recursion on l.
+	      for ( int __ll = __m + 2; __ll <= __l; ++__ll)
+		{
+		  const _Tp __rat1 = _Tp(__ll - __m) / _Tp(__ll + __m);
+		  const _Tp __rat2 = _Tp(__ll - __m - 1) / _Tp(__ll + __m - 1);
+		  const _Tp __fact1 = std::sqrt(__rat1 * _Tp(2 * __ll + 1)
+						       * _Tp(2 * __ll - 1));
+		  const _Tp __fact2 = std::sqrt(__rat1 * __rat2 * _Tp(2 * __ll + 1)
+								/ _Tp(2 * __ll - 3));
+		  __y_lm = (__x * __y_mp1m * __fact1
+			 - (__ll + __m - 1) * __y_mm * __fact2) / _Tp(__ll - __m);
+		  __y_mm = __y_mp1m;
+		  __y_mp1m = __y_lm;
+		}
 
-              return __y_lm;
-            }
-        }
+	      return __y_lm;
+	    }
+	}
     }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
 
-#endif // _GLIBCXX_TR1_LEGENDRE_FUNCTION_TCC
+#endif // _GLIBCXX_BITS_SF_LEGENDRE_TCC
Index: include/bits/sf_mod_bessel.tcc
===================================================================
--- include/bits/sf_mod_bessel.tcc	(revision 175789)
+++ include/bits/sf_mod_bessel.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,13 +22,13 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/modified_bessel_func.tcc
+/** @file bits/sf_mod_bessel.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
 // Written by Edward Smith-Rowland.
@@ -44,64 +43,60 @@
 //       W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
 //       2nd ed, pp. 246-249.
 
-#ifndef _GLIBCXX_TR1_MODIFIED_BESSEL_FUNC_TCC
-#define _GLIBCXX_TR1_MODIFIED_BESSEL_FUNC_TCC 1
+#ifndef _GLIBCXX_BITS_SF_MOD_BESSEL_TCC
+#define _GLIBCXX_BITS_SF_MOD_BESSEL_TCC 1
 
-#include "special_function_util.h"
+#include <bits/specfun_util.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // [5.2] Special functions
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-    /**
-     *   @brief  Compute the modified Bessel functions @f$ I_\nu(x) @f$ and
-     *           @f$ K_\nu(x) @f$ and their first derivatives
-     *           @f$ I'_\nu(x) @f$ and @f$ K'_\nu(x) @f$ respectively.
-     *           These four functions are computed together for numerical
-     *           stability.
-     *
-     *   @param  __nu  The order of the Bessel functions.
-     *   @param  __x   The argument of the Bessel functions.
-     *   @param  __Inu  The output regular modified Bessel function.
-     *   @param  __Knu  The output irregular modified Bessel function.
-     *   @param  __Ipnu  The output derivative of the regular
-     *                   modified Bessel function.
-     *   @param  __Kpnu  The output derivative of the irregular
-     *                   modified Bessel function.
-     */
-    template <typename _Tp>
+  /**
+   *   @brief  Compute the modified Bessel functions @f$ I_\nu(x) @f$ and
+   *           @f$ K_\nu(x) @f$ and their first derivatives
+   *           @f$ I'_\nu(x) @f$ and @f$ K'_\nu(x) @f$ respectively.
+   *           These four functions are computed together for numerical
+   *           stability.
+   *
+   *   @param  __nu  The order of the Bessel functions.
+   *   @param  __x   The argument of the Bessel functions.
+   *   @param  _Inu  The output regular modified Bessel function.
+   *   @param  _Knu  The output irregular modified Bessel function.
+   *   @param  _Ipnu  The output derivative of the regular
+   *                   modified Bessel function.
+   *   @param  _Kpnu  The output derivative of the irregular
+   *                   modified Bessel function.
+   */
+  template<typename _Tp>
     void
-    __bessel_ik(const _Tp __nu, const _Tp __x,
-                _Tp & __Inu, _Tp & __Knu, _Tp & __Ipnu, _Tp & __Kpnu)
+    __bessel_ik(_Tp __nu, _Tp __x,
+		_Tp & _Inu, _Tp & _Knu, _Tp & _Ipnu, _Tp & _Kpnu)
     {
       if (__x == _Tp(0))
-        {
-          if (__nu == _Tp(0))
-            {
-              __Inu = _Tp(1);
-              __Ipnu = _Tp(0);
-            }
-          else if (__nu == _Tp(1))
-            {
-              __Inu = _Tp(0);
-              __Ipnu = _Tp(0.5L);
-            }
-          else
-            {
-              __Inu = _Tp(0);
-              __Ipnu = _Tp(0);
-            }
-          __Knu = std::numeric_limits<_Tp>::infinity();
-          __Kpnu = -std::numeric_limits<_Tp>::infinity();
-          return;
-        }
+	{
+	  if (__nu == _Tp(0))
+	    {
+	      _Inu = _Tp(1);
+	      _Ipnu = _Tp(0);
+	    }
+	  else if (__nu == _Tp(1))
+	    {
+	      _Inu = _Tp(0);
+	      _Ipnu = _Tp(0.5L);
+	    }
+	  else
+	    {
+	      _Inu = _Tp(0);
+	      _Ipnu = _Tp(0);
+	    }
+	  _Knu = std::numeric_limits<_Tp>::infinity();
+	  _Kpnu = -std::numeric_limits<_Tp>::infinity();
+	  return;
+	}
 
       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
       const _Tp __fp_min = _Tp(10) * std::numeric_limits<_Tp>::epsilon();
@@ -116,322 +111,346 @@
       const _Tp __xi2 = _Tp(2) * __xi;
       _Tp __h = __nu * __xi;
       if ( __h < __fp_min )
-        __h = __fp_min;
+	__h = __fp_min;
       _Tp __b = __xi2 * __nu;
       _Tp __d = _Tp(0);
       _Tp __c = __h;
       int __i;
       for ( __i = 1; __i <= __max_iter; ++__i )
-        {
-          __b += __xi2;
-          __d = _Tp(1) / (__b + __d);
-          __c = __b + _Tp(1) / __c;
-          const _Tp __del = __c * __d;
-          __h *= __del;
-          if (std::abs(__del - _Tp(1)) < __eps)
-            break;
-        }
+	{
+	  __b += __xi2;
+	  __d = _Tp(1) / (__b + __d);
+	  __c = __b + _Tp(1) / __c;
+	  const _Tp __del = __c * __d;
+	  __h *= __del;
+	  if (std::abs(__del - _Tp(1)) < __eps)
+	    break;
+	}
       if (__i > __max_iter)
-        std::__throw_runtime_error(__N("Argument x too large "
-                                       "in __bessel_jn; "
-                                       "try asymptotic expansion."));
-      _Tp __Inul = __fp_min;
-      _Tp __Ipnul = __h * __Inul;
-      _Tp __Inul1 = __Inul;
-      _Tp __Ipnu1 = __Ipnul;
+	std::__throw_runtime_error(__N("__bessel_ik: argument x too large; "
+				       "try asymptotic expansion"));
+      _Tp _Inul = __fp_min;
+      _Tp _Ipnul = __h * _Inul;
+      _Tp _Inul1 = _Inul;
+      _Tp _Ipnu1 = _Ipnul;
       _Tp __fact = __nu * __xi;
       for (int __l = __nl; __l >= 1; --__l)
-        {
-          const _Tp __Inutemp = __fact * __Inul + __Ipnul;
-          __fact -= __xi;
-          __Ipnul = __fact * __Inutemp + __Inul;
-          __Inul = __Inutemp;
-        }
-      _Tp __f = __Ipnul / __Inul;
-      _Tp __Kmu, __Knu1;
+	{
+	  const _Tp _Inutemp = __fact * _Inul + _Ipnul;
+	  __fact -= __xi;
+	  _Ipnul = __fact * _Inutemp + _Inul;
+	  _Inul = _Inutemp;
+	}
+      _Tp __f = _Ipnul / _Inul;
+      _Tp _Kmu, _Knu1;
       if (__x < __x_min)
-        {
-          const _Tp __x2 = __x / _Tp(2);
-          const _Tp __pimu = __numeric_constants<_Tp>::__pi() * __mu;
-          const _Tp __fact = (std::abs(__pimu) < __eps
-                            ? _Tp(1) : __pimu / std::sin(__pimu));
-          _Tp __d = -std::log(__x2);
-          _Tp __e = __mu * __d;
-          const _Tp __fact2 = (std::abs(__e) < __eps
-                            ? _Tp(1) : std::sinh(__e) / __e);
-          _Tp __gam1, __gam2, __gampl, __gammi;
-          __gamma_temme(__mu, __gam1, __gam2, __gampl, __gammi);
-          _Tp __ff = __fact
-                   * (__gam1 * std::cosh(__e) + __gam2 * __fact2 * __d);
-          _Tp __sum = __ff;
-          __e = std::exp(__e);
-          _Tp __p = __e / (_Tp(2) * __gampl);
-          _Tp __q = _Tp(1) / (_Tp(2) * __e * __gammi);
-          _Tp __c = _Tp(1);
-          __d = __x2 * __x2;
-          _Tp __sum1 = __p;
-          int __i;
-          for (__i = 1; __i <= __max_iter; ++__i)
-            {
-              __ff = (__i * __ff + __p + __q) / (__i * __i - __mu2);
-              __c *= __d / __i;
-              __p /= __i - __mu;
-              __q /= __i + __mu;
-              const _Tp __del = __c * __ff;
-              __sum += __del; 
-              const _Tp __del1 = __c * (__p - __i * __ff);
-              __sum1 += __del1;
-              if (std::abs(__del) < __eps * std::abs(__sum))
-                break;
-            }
-          if (__i > __max_iter)
-            std::__throw_runtime_error(__N("Bessel k series failed to converge "
-                                           "in __bessel_jn."));
-          __Kmu = __sum;
-          __Knu1 = __sum1 * __xi2;
-        }
+	{
+	  const _Tp __x2 = __x / _Tp(2);
+	  const _Tp __pimu = __numeric_constants<_Tp>::__pi() * __mu;
+	  const _Tp __fact = (std::abs(__pimu) < __eps
+			    ? _Tp(1) : __pimu / std::sin(__pimu));
+	  _Tp __d = -std::log(__x2);
+	  _Tp __e = __mu * __d;
+	  const _Tp __fact2 = (std::abs(__e) < __eps
+			    ? _Tp(1) : std::sinh(__e) / __e);
+	  _Tp __gam1, __gam2, __gampl, __gammi;
+	  __gamma_temme(__mu, __gam1, __gam2, __gampl, __gammi);
+	  _Tp __ff = __fact
+		   * (__gam1 * std::cosh(__e) + __gam2 * __fact2 * __d);
+	  _Tp __sum = __ff;
+	  __e = std::exp(__e);
+	  _Tp __p = __e / (_Tp(2) * __gampl);
+	  _Tp __q = _Tp(1) / (_Tp(2) * __e * __gammi);
+	  _Tp __c = _Tp(1);
+	  __d = __x2 * __x2;
+	  _Tp __sum1 = __p;
+	  int __i;
+	  for (__i = 1; __i <= __max_iter; ++__i)
+	    {
+	      __ff = (__i * __ff + __p + __q) / (__i * __i - __mu2);
+	      __c *= __d / __i;
+	      __p /= __i - __mu;
+	      __q /= __i + __mu;
+	      const _Tp __del = __c * __ff;
+	      __sum += __del;
+	      const _Tp __del1 = __c * (__p - __i * __ff);
+	      __sum1 += __del1;
+	      if (std::abs(__del) < __eps * std::abs(__sum))
+		break;
+	    }
+	  if (__i > __max_iter)
+	    std::__throw_runtime_error(__N("__bessel_ik: "
+					   "Bessel K-series failed to converge"));
+	  _Kmu = __sum;
+	  _Knu1 = __sum1 * __xi2;
+	}
       else
-        {
-          _Tp __b = _Tp(2) * (_Tp(1) + __x);
-          _Tp __d = _Tp(1) / __b;
-          _Tp __delh = __d;
-          _Tp __h = __delh;
-          _Tp __q1 = _Tp(0);
-          _Tp __q2 = _Tp(1);
-          _Tp __a1 = _Tp(0.25L) - __mu2;
-          _Tp __q = __c = __a1;
-          _Tp __a = -__a1;
-          _Tp __s = _Tp(1) + __q * __delh;
-          int __i;
-          for (__i = 2; __i <= __max_iter; ++__i)
-            {
-              __a -= 2 * (__i - 1);
-              __c = -__a * __c / __i;
-              const _Tp __qnew = (__q1 - __b * __q2) / __a;
-              __q1 = __q2;
-              __q2 = __qnew;
-              __q += __c * __qnew;
-              __b += _Tp(2);
-              __d = _Tp(1) / (__b + __a * __d);
-              __delh = (__b * __d - _Tp(1)) * __delh;
-              __h += __delh;
-              const _Tp __dels = __q * __delh;
-              __s += __dels;
-              if ( std::abs(__dels / __s) < __eps )
-                break;
-            }
-          if (__i > __max_iter)
-            std::__throw_runtime_error(__N("Steed's method failed "
-                                           "in __bessel_jn."));
-          __h = __a1 * __h;
-          __Kmu = std::sqrt(__numeric_constants<_Tp>::__pi() / (_Tp(2) * __x))
-                * std::exp(-__x) / __s;
-          __Knu1 = __Kmu * (__mu + __x + _Tp(0.5L) - __h) * __xi;
-        }
+	{
+	  _Tp __b = _Tp(2) * (_Tp(1) + __x);
+	  _Tp __d = _Tp(1) / __b;
+	  _Tp __delh = __d;
+	  _Tp __h = __delh;
+	  _Tp __q1 = _Tp(0);
+	  _Tp __q2 = _Tp(1);
+	  _Tp __a1 = _Tp(0.25L) - __mu2;
+	  _Tp __q = __c = __a1;
+	  _Tp __a = -__a1;
+	  _Tp __s = _Tp(1) + __q * __delh;
+	  int __i;
+	  for (__i = 2; __i <= __max_iter; ++__i)
+	    {
+	      __a -= 2 * (__i - 1);
+	      __c = -__a * __c / __i;
+	      const _Tp __qnew = (__q1 - __b * __q2) / __a;
+	      __q1 = __q2;
+	      __q2 = __qnew;
+	      __q += __c * __qnew;
+	      __b += _Tp(2);
+	      __d = _Tp(1) / (__b + __a * __d);
+	      __delh = (__b * __d - _Tp(1)) * __delh;
+	      __h += __delh;
+	      const _Tp __dels = __q * __delh;
+	      __s += __dels;
+	      if ( std::abs(__dels / __s) < __eps )
+		break;
+	    }
+	  if (__i > __max_iter)
+	    std::__throw_runtime_error(__N("__bessel_ik: "
+					   "Steed's method failed"));
+	  __h = __a1 * __h;
+	  _Kmu = std::sqrt(__numeric_constants<_Tp>::__pi() / (_Tp(2) * __x))
+		* std::exp(-__x) / __s;
+	  _Knu1 = _Kmu * (__mu + __x + _Tp(0.5L) - __h) * __xi;
+	}
 
-      _Tp __Kpmu = __mu * __xi * __Kmu - __Knu1;
-      _Tp __Inumu = __xi / (__f * __Kmu - __Kpmu);
-      __Inu = __Inumu * __Inul1 / __Inul;
-      __Ipnu = __Inumu * __Ipnu1 / __Inul;
+      _Tp _Kpmu = __mu * __xi * _Kmu - _Knu1;
+      _Tp _Inumu = __xi / (__f * _Kmu - _Kpmu);
+      _Inu = _Inumu * _Inul1 / _Inul;
+      _Ipnu = _Inumu * _Ipnu1 / _Inul;
       for ( __i = 1; __i <= __nl; ++__i )
-        {
-          const _Tp __Knutemp = (__mu + __i) * __xi2 * __Knu1 + __Kmu;
-          __Kmu = __Knu1;
-          __Knu1 = __Knutemp;
-        }
-      __Knu = __Kmu;
-      __Kpnu = __nu * __xi * __Kmu - __Knu1;
-  
+	{
+	  const _Tp _Knutemp = (__mu + __i) * __xi2 * _Knu1 + _Kmu;
+	  _Kmu = _Knu1;
+	  _Knu1 = _Knutemp;
+	}
+      _Knu = _Kmu;
+      _Kpnu = __nu * __xi * _Kmu - _Knu1;
+
       return;
     }
 
 
-    /**
-     *   @brief  Return the regular modified Bessel function of order
-     *           \f$ \nu \f$: \f$ I_{\nu}(x) \f$.
-     *
-     *   The regular modified cylindrical Bessel function is:
-     *   @f[
-     *    I_{\nu}(x) = \sum_{k=0}^{\infty}
-     *              \frac{(x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)}
-     *   @f]
-     *
-     *   @param  __nu  The order of the regular modified Bessel function.
-     *   @param  __x   The argument of the regular modified Bessel function.
-     *   @return  The output regular modified Bessel function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the regular modified Bessel function of order
+   *           \f$ \nu \f$: \f$ I_{\nu}(x) \f$.
+   *
+   *   The regular modified cylindrical Bessel function is:
+   *   @f[
+   *    I_{\nu}(x) = \sum_{k=0}^{\infty}
+   *              \frac{(x/2)^{\nu + 2k}}{k!\Gamma(\nu+k+1)}
+   *   @f]
+   *
+   *   @param  __nu  The order of the regular modified Bessel function.
+   *   @param  __x   The argument of the regular modified Bessel function.
+   *   @return  The output regular modified Bessel function.
+   */
+  template<typename _Tp>
     _Tp
-    __cyl_bessel_i(const _Tp __nu, const _Tp __x)
+    __cyl_bessel_i(_Tp __nu, _Tp __x)
     {
       if (__nu < _Tp(0) || __x < _Tp(0))
-        std::__throw_domain_error(__N("Bad argument "
-                                      "in __cyl_bessel_i."));
+	std::__throw_domain_error(__N("__cyl_bessel_i: bad argument"));
       else if (__isnan(__nu) || __isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__x * __x < _Tp(10) * (__nu + _Tp(1)))
-        return __cyl_bessel_ij_series(__nu, __x, +_Tp(1), 200);
+	return __cyl_bessel_ij_series(__nu, __x, +_Tp(1), 200);
       else
-        {
-          _Tp __I_nu, __K_nu, __Ip_nu, __Kp_nu;
-          __bessel_ik(__nu, __x, __I_nu, __K_nu, __Ip_nu, __Kp_nu);
-          return __I_nu;
-        }
+	{
+	  _Tp _I_nu, _K_nu, _Ip_nu, _Kp_nu;
+	  __bessel_ik(__nu, __x, _I_nu, _K_nu, _Ip_nu, _Kp_nu);
+	  return _I_nu;
+	}
     }
 
 
-    /**
-     *   @brief  Return the irregular modified Bessel function
-     *           \f$ K_{\nu}(x) \f$ of order \f$ \nu \f$.
-     *
-     *   The irregular modified Bessel function is defined by:
-     *   @f[
-     *      K_{\nu}(x) = \frac{\pi}{2}
-     *                   \frac{I_{-\nu}(x) - I_{\nu}(x)}{\sin \nu\pi}
-     *   @f]
-     *   where for integral \f$ \nu = n \f$ a limit is taken:
-     *   \f$ lim_{\nu \to n} \f$.
-     *
-     *   @param  __nu  The order of the irregular modified Bessel function.
-     *   @param  __x   The argument of the irregular modified Bessel function.
-     *   @return  The output irregular modified Bessel function.
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the irregular modified Bessel function
+   *           \f$ K_{\nu}(x) \f$ of order \f$ \nu \f$.
+   *
+   *   The irregular modified Bessel function is defined by:
+   *   @f[
+   *      K_{\nu}(x) = \frac{\pi}{2}
+   *                   \frac{I_{-\nu}(x) - I_{\nu}(x)}{\sin \nu\pi}
+   *   @f]
+   *   where for integral \f$ \nu = n \f$ a limit is taken:
+   *   \f$ lim_{\nu \to n} \f$.
+   *
+   *   @param  __nu  The order of the irregular modified Bessel function.
+   *   @param  __x   The argument of the irregular modified Bessel function.
+   *   @return  The output irregular modified Bessel function.
+   */
+  template<typename _Tp>
     _Tp
-    __cyl_bessel_k(const _Tp __nu, const _Tp __x)
+    __cyl_bessel_k(_Tp __nu, _Tp __x)
     {
       if (__nu < _Tp(0) || __x < _Tp(0))
-        std::__throw_domain_error(__N("Bad argument "
-                                      "in __cyl_bessel_k."));
+	std::__throw_domain_error(__N("__cyl_bessel_k: Bad argument"));
       else if (__isnan(__nu) || __isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else
-        {
-          _Tp __I_nu, __K_nu, __Ip_nu, __Kp_nu;
-          __bessel_ik(__nu, __x, __I_nu, __K_nu, __Ip_nu, __Kp_nu);
-          return __K_nu;
-        }
+	{
+	  _Tp _I_nu, _K_nu, _Ip_nu, _Kp_nu;
+	  __bessel_ik(__nu, __x, _I_nu, _K_nu, _Ip_nu, _Kp_nu);
+	  return _K_nu;
+	}
     }
 
 
-    /**
-     *   @brief  Compute the spherical modified Bessel functions
-     *           @f$ i_n(x) @f$ and @f$ k_n(x) @f$ and their first
-     *           derivatives @f$ i'_n(x) @f$ and @f$ k'_n(x) @f$
-     *           respectively.
-     *
-     *   @param  __n  The order of the modified spherical Bessel function.
-     *   @param  __x  The argument of the modified spherical Bessel function.
-     *   @param  __i_n  The output regular modified spherical Bessel function.
-     *   @param  __k_n  The output irregular modified spherical
-     *                  Bessel function.
-     *   @param  __ip_n  The output derivative of the regular modified
-     *                   spherical Bessel function.
-     *   @param  __kp_n  The output derivative of the irregular modified
-     *                   spherical Bessel function.
-     */
-    template <typename _Tp>
+  /**
+   *   @brief  Compute the spherical modified Bessel functions
+   *           @f$ i_n(x) @f$ and @f$ k_n(x) @f$ and their first
+   *           derivatives @f$ i'_n(x) @f$ and @f$ k'_n(x) @f$
+   *           respectively.
+   *
+   *   @param  __n  The order of the modified spherical Bessel function.
+   *   @param  __x  The argument of the modified spherical Bessel function.
+   *   @param  __i_n  The output regular modified spherical Bessel function.
+   *   @param  __k_n  The output irregular modified spherical
+   *                  Bessel function.
+   *   @param  __ip_n  The output derivative of the regular modified
+   *                   spherical Bessel function.
+   *   @param  __kp_n  The output derivative of the irregular modified
+   *                   spherical Bessel function.
+   */
+  template<typename _Tp>
     void
-    __sph_bessel_ik(const unsigned int __n, const _Tp __x,
-                    _Tp & __i_n, _Tp & __k_n, _Tp & __ip_n, _Tp & __kp_n)
+    __sph_bessel_ik(unsigned int __n, _Tp __x,
+		    _Tp & __i_n, _Tp & __k_n, _Tp & __ip_n, _Tp & __kp_n)
     {
       const _Tp __nu = _Tp(__n) + _Tp(0.5L);
 
-      _Tp __I_nu, __Ip_nu, __K_nu, __Kp_nu;
-      __bessel_ik(__nu, __x, __I_nu, __K_nu, __Ip_nu, __Kp_nu);
+      _Tp _I_nu, _Ip_nu, _K_nu, _Kp_nu;
+      __bessel_ik(__nu, __x, _I_nu, _K_nu, _Ip_nu, _Kp_nu);
 
       const _Tp __factor = __numeric_constants<_Tp>::__sqrtpio2()
-                         / std::sqrt(__x);
+			 / std::sqrt(__x);
 
-      __i_n = __factor * __I_nu;
-      __k_n = __factor * __K_nu;
-      __ip_n = __factor * __Ip_nu - __i_n / (_Tp(2) * __x);
-      __kp_n = __factor * __Kp_nu - __k_n / (_Tp(2) * __x);
+      __i_n = __factor * _I_nu;
+      __k_n = __factor * _K_nu;
+      __ip_n = __factor * _Ip_nu - __i_n / (_Tp(2) * __x);
+      __kp_n = __factor * _Kp_nu - __k_n / (_Tp(2) * __x);
 
       return;
     }
 
 
-    /**
-     *   @brief  Compute the Airy functions
-     *           @f$ Ai(x) @f$ and @f$ Bi(x) @f$ and their first
-     *           derivatives @f$ Ai'(x) @f$ and @f$ Bi(x) @f$
-     *           respectively.
-     *
-     *   @param  __n  The order of the Airy functions.
-     *   @param  __x  The argument of the Airy functions.
-     *   @param  __i_n  The output Airy function.
-     *   @param  __k_n  The output Airy function.
-     *   @param  __ip_n  The output derivative of the Airy function.
-     *   @param  __kp_n  The output derivative of the Airy function.
-     */
-    template <typename _Tp>
+  /**
+   *   @brief  Compute the Airy functions
+   *           @f$ Ai(x) @f$ and @f$ Bi(x) @f$ and their first
+   *           derivatives @f$ Ai'(x) @f$ and @f$ Bi(x) @f$
+   *           respectively.
+   *
+   *   @param  __x  The argument of the Airy functions.
+   *   @param  _Ai  The output Airy function of the first kind.
+   *   @param  _Bi  The output Airy function of the second kind.
+   *   @param  _Aip  The output derivative of the Airy function
+   *                  of the first kind.
+   *   @param  _Bip  The output derivative of the Airy function
+   *                  of the second kind.
+   */
+  template<typename _Tp>
     void
-    __airy(const _Tp __x,
-           _Tp & __Ai, _Tp & __Bi, _Tp & __Aip, _Tp & __Bip)
+    __airy(_Tp __z, _Tp & _Ai, _Tp & _Bi, _Tp & _Aip, _Tp & _Bip)
     {
-      const _Tp __absx = std::abs(__x);
-      const _Tp __rootx = std::sqrt(__absx);
-      const _Tp __z = _Tp(2) * __absx * __rootx / _Tp(3);
+      constexpr _Tp _S_pi = __numeric_constants<_Tp>::__pi();
+      constexpr _Tp _S_sqrt3 = __numeric_constants<_Tp>::__sqrt3();
+      const _Tp __absz = std::abs(__z);
+      const _Tp __rootz = std::sqrt(__absz);
+      const _Tp __xi = _Tp(2) * __absz * __rootz / _Tp(3);
 
-      if (__isnan(__x))
-        return std::numeric_limits<_Tp>::quiet_NaN();
-      else if (__x > _Tp(0))
-        {
-          _Tp __I_nu, __Ip_nu, __K_nu, __Kp_nu;
+      if (__z > _Tp(0))
+	{
+	  _Tp _I_nu, _K_nu, _Ip_nu, _Kp_nu;
 
-          __bessel_ik(_Tp(1) / _Tp(3), __z, __I_nu, __K_nu, __Ip_nu, __Kp_nu);
-          __Ai = __rootx * __K_nu
-               / (__numeric_constants<_Tp>::__sqrt3()
-                * __numeric_constants<_Tp>::__pi());
-          __Bi = __rootx * (__K_nu / __numeric_constants<_Tp>::__pi()
-                 + _Tp(2) * __I_nu / __numeric_constants<_Tp>::__sqrt3());
+	  __bessel_ik(_Tp(1) / _Tp(3), __xi, _I_nu, _K_nu, _Ip_nu, _Kp_nu);
+	  _Ai = __rootz * _K_nu / (_S_sqrt3 * _S_pi);
+	  _Bi = __rootz * (_K_nu / _S_pi + _Tp(2) * _I_nu / _S_sqrt3);
 
-          __bessel_ik(_Tp(2) / _Tp(3), __z, __I_nu, __K_nu, __Ip_nu, __Kp_nu);
-          __Aip = -__x * __K_nu
-                / (__numeric_constants<_Tp>::__sqrt3()
-                 * __numeric_constants<_Tp>::__pi());
-          __Bip = __x * (__K_nu / __numeric_constants<_Tp>::__pi()
-                      + _Tp(2) * __I_nu
-                      / __numeric_constants<_Tp>::__sqrt3());
-        }
-      else if (__x < _Tp(0))
-        {
-          _Tp __J_nu, __Jp_nu, __N_nu, __Np_nu;
+	  __bessel_ik(_Tp(2) / _Tp(3), __xi, _I_nu, _Ip_nu, _K_nu, _Kp_nu);
+	  _Aip = -__z * _K_nu / (_S_sqrt3 * _S_pi);
+	  _Bip = __z * (_K_nu / _S_pi + _Tp(2) * _I_nu / _S_sqrt3);
+	}
+      else if (__z < _Tp(0))
+	{
+	  _Tp _J_nu, _N_nu, _Jp_nu, _Np_nu;
 
-          __bessel_jn(_Tp(1) / _Tp(3), __z, __J_nu, __N_nu, __Jp_nu, __Np_nu);
-          __Ai = __rootx * (__J_nu
-                    - __N_nu / __numeric_constants<_Tp>::__sqrt3()) / _Tp(2);
-          __Bi = -__rootx * (__N_nu
-                    + __J_nu / __numeric_constants<_Tp>::__sqrt3()) / _Tp(2);
+	  __bessel_jn(_Tp(1) / _Tp(3), __xi, _J_nu, _N_nu, _Jp_nu, _Np_nu);
+	  _Ai = +__rootz * (_J_nu - _N_nu / _S_sqrt3) / _Tp(2);
+	  _Bi = -__rootz * (_N_nu + _J_nu / _S_sqrt3) / _Tp(2);
 
-          __bessel_jn(_Tp(2) / _Tp(3), __z, __J_nu, __N_nu, __Jp_nu, __Np_nu);
-          __Aip = __absx * (__N_nu / __numeric_constants<_Tp>::__sqrt3()
-                          + __J_nu) / _Tp(2);
-          __Bip = __absx * (__J_nu / __numeric_constants<_Tp>::__sqrt3()
-                          - __N_nu) / _Tp(2);
-        }
+	  __bessel_jn(_Tp(2) / _Tp(3), __xi, _J_nu, _N_nu, _Jp_nu, _Np_nu);
+	  _Aip = __absz * (_N_nu / _S_sqrt3 + _J_nu) / _Tp(2);
+	  _Bip = __absz * (_J_nu / _S_sqrt3 - _N_nu) / _Tp(2);
+	}
       else
-        {
-          //  Reference:
-          //    Abramowitz & Stegun, page 446 section 10.4.4 on Airy functions.
-          //  The number is Ai(0) = 3^{-2/3}/\Gamma(2/3).
-          __Ai = _Tp(0.35502805388781723926L);
-          __Bi = __Ai * __numeric_constants<_Tp>::__sqrt3();
+	{
+	  //  Reference:
+	  //    Abramowitz & Stegun, page 446 section 10.4.4 on Airy functions.
+	  //  The number is Ai(0) = 3^{-2/3}/\Gamma(2/3).
+	  _Ai = _Tp(0.35502805388781723926L);
+	  _Bi = _Ai * _S_sqrt3;
 
-          //  Reference:
-          //    Abramowitz & Stegun, page 446 section 10.4.5 on Airy functions.
-          //  The number is Ai'(0) = -3^{-1/3}/\Gamma(1/3).
-          __Aip = -_Tp(0.25881940379280679840L);
-          __Bip = -__Aip * __numeric_constants<_Tp>::__sqrt3();
-        }
+	  //  Reference:
+	  //    Abramowitz & Stegun, page 446 section 10.4.5 on Airy functions.
+	  //  The number is Ai'(0) = -3^{-1/3}/\Gamma(1/3).
+	  _Aip = -_Tp(0.25881940379280679840L);
+	  _Bip = -_Aip * _S_sqrt3;
+	}
 
       return;
     }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  /**
+   *   @brief  Compute the Fock type Airy functions
+   *           @f$ w_1(x) @f$ and @f$ w_2(x) @f$ and their first
+   *           derivatives @f$ w_1'(x) @f$ and @f$ w_2'(x) @f$
+   *           respectively.
+   *   @f[
+   *     w_1(x) = \sqrt{\pi}(Ai(x) + iBi(x))
+   *   @f]
+   *   @f[
+   *     w_2(x) = \sqrt{\pi}(Ai(x) - iBi(x))
+   *   @f]
+   *
+   *   @param  __x   The argument of the Airy functions.
+   *   @param  __w1  The output Fock type Airy function of the first kind.
+   *   @param  __w2  The output Fock type Airy function of the second kind.
+   *   @param  __w1p  The output derivative of the Fock type Airy function
+   *                  of the first kind.
+   *   @param  __w2p  The output derivative of the Fock type Airy function
+   *                  of the second kind.
+   */
+  template<typename _Tp>
+    void
+    __fock_airy(_Tp x,
+		std::complex<_Tp>& __w1, std::complex<_Tp>& __w2,
+		std::complex<_Tp>& __w1p, std::complex<_Tp>& __w2p)
+    {
+      constexpr _Tp _S_sqrtpi = 1.772453850905516027298167483341145182797L;
+
+      _Tp _Ai, _Bi, _Aip, _Bip;
+      airy(x, &_Ai, &_Bi, &_Aip, &_Bip);
+
+      __w1 = _S_sqrtpi * std::complex<_Tp>(_Ai, _Bi);
+      __w2 = _S_sqrtpi * std::complex<_Tp>(_Ai, -_Bi);
+      __w1p = _S_sqrtpi * std::complex<_Tp>(_Aip, _Bip);
+      __w2p = _S_sqrtpi * std::complex<_Tp>(_Aip, -_Bip);
+    }
+
 }
-}
 
-#endif // _GLIBCXX_TR1_MODIFIED_BESSEL_FUNC_TCC
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#endif // _GLIBCXX_BITS_SF_MOD_BESSEL_TCC
Index: include/bits/sf_theta.tcc
===================================================================
--- include/bits/sf_theta.tcc	(revision 0)
+++ include/bits/sf_theta.tcc	(working copy)
@@ -0,0 +1,116 @@
+// Special functions -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/sf_theta.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{cmath}
+ */
+
+#ifndef _GLIBCXX_SF_THETA_TCC
+#define _GLIBCXX_SF_THETA_TCC 1
+
+#include <array>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// Implementation-space details.
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  template<typename _Tp>
+    void
+    __jacobi_cnsndn(_Tp __k, _Tp __u, _Tp& __cn, _Tp& __sn, _Tp& __dn)
+    {
+      _Tp __b, __c, __d;
+
+      constexpr auto _S_N = 20;
+      constexpr auto _S_CA = _Tp(0.00001);
+
+      std::array<_Tp, _S_N> __m;
+      std::array<_Tp, _S_N> __n;
+
+      if (__k != _Tp(0))
+	{
+	  bool __bo = (__k < _Tp(0));
+	  if (__bo)
+	    {
+	      __d = _Tp(1) - __k;
+	      __k /= -_Tp(1) / __d;
+	      __u *= (__d = std::sqrt(__d));
+	    }
+	  auto __a = _Tp(1);
+	  __dn = _Tp(1);
+	  auto __l = _S_N;
+	  for (auto __i = 0; __i < _S_N; ++__i)
+	    {
+	      __l = __i;
+	      __m[__i] = __a;
+	      __n[__i] = (__k = std::sqrt(__k));
+	      __c = 0.5 * (__a + __k);
+	      if (std::abs(__a - __k) <= _S_CA * __a)
+		break;
+	      __k *= __a;
+	      __a = __c;
+	    }
+	  __u *= __c;
+	  __cn = std::cos(__u);
+	  __sn = std::sin(__u);
+	  if (__sn != _Tp(0))
+	    {
+	      __a = __cn / __sn;
+	      __c *= __a;
+	      for (auto __ii = __l; __ii + 1 >= 1; --__ii)
+		{
+		  _Tp __b = __m[__ii];
+		  __a *= __c;
+		  __c *= (__dn);
+		  __dn = (__n[__ii] + __a) / (__b + __a);
+		  __a = __c / __b;
+		}
+	      __a = _Tp(1) / std::sqrt(__c * __c + _Tp(1));
+	      __sn = std::copysign(__a, __sn);
+	      __cn = __c * __sn;
+	    }
+	  if (__bo)
+	    {
+	      __a = __dn;
+	      __dn = __cn;
+	      __cn = __a;
+	      __sn /= __d;
+	    }
+	}
+      else
+	{
+	  __cn = _Tp(1) / std::cosh(__u);
+	  __sn = std::tanh(__u);
+	  __dn = __cn;
+	}
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#endif // _GLIBCXX_SF_THETA_TCC
Index: include/bits/sf_trigint.tcc
===================================================================
--- include/bits/sf_trigint.tcc	(revision 0)
+++ include/bits/sf_trigint.tcc	(working copy)
@@ -0,0 +1,240 @@
+// Special functions -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/sf_trigint.tcc
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly. @headername{cmath}
+ */
+
+#ifndef _GLIBCXX_SF_TRIGINT_TCC
+#define _GLIBCXX_SF_TRIGINT_TCC 1
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+// Implementation-space details.
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   *  @brief This function computes the cosine @f$ Ci(x) @f$ and sine @f$ Si(x) @f$
+   *    integrals by continued fraction for positive argument.
+   */
+  template<typename _Tp>
+    void
+    __csint_cont_frac(_Tp __t, _Tp& _Ci, _Tp& _Si)
+    {
+      constexpr auto _S_max_iter = 100;
+      constexpr auto _S_eps = _Tp(5) * std::numeric_limits<_Tp>::epsilon();
+      constexpr auto _S_fp_min = std::numeric_limits<_Tp>::min();
+      constexpr auto _S_pi_2 = std::__detail::__numeric_constants<_Tp>::__pi_2();
+
+      //  Evaluate Ci and Si by Lentz's modified method of continued fractions.
+      std::complex<_Tp> __b(_Tp(1), __t);
+      std::complex<_Tp> __c(_Tp(1) / _S_fp_min);
+      std::complex<_Tp> __d(_Tp(1) / __b);
+      std::complex<_Tp> __h(__d);
+      int i = 2;
+      while (true)
+	{
+	  _Tp __a = -(i - 1) * (i - 1);
+	  __b += _Tp(2);
+	  __d = _Tp(1) / (__a * __d + __b);
+	  __c = __b + __a / __c;
+	  std::complex<_Tp> __del = __c * __d;
+	  __h *= __del;
+	  if (std::abs(__del - _Tp(1)) < _S_eps)
+	    break;
+	  if (i > _S_max_iter)
+	    std::__throw_runtime_error("csint_cont_frac: "
+				   "continued fraction evaluation failed");
+	  ++i;
+	}
+      __h *= std::polar(_Tp(1), -__t);
+      _Ci = -__h.real();
+      _Si = _S_pi_2 + __h.imag();
+
+      return;
+    }
+
+
+  /**
+   *  @brief This function computes the cosine @f$ Ci(x) @f$ and sine @f$ Si(x) @f$
+   *    integrals by series summation for positive argument.
+   */
+  template<typename _Tp>
+    void
+    __csint_series(_Tp __t, _Tp& _Ci, _Tp& _Si)
+    {
+      constexpr auto _S_max_iter = 100;
+      constexpr auto _S_eps = _Tp(5) * std::numeric_limits<_Tp>::epsilon();
+      constexpr auto _S_fp_min = std::numeric_limits<_Tp>::min();
+      constexpr auto _S_gamma_e = std::__detail::__numeric_constants<_Tp>::__gamma_e();
+
+      //  Evaluate Ci and Si by series simultaneously.
+      _Tp __sumc(0), __sums(0);
+      if (__t * __t < _S_fp_min)
+	{
+	  //  Avoid underflow.
+	  __sumc = _Tp(0);
+	  __sums = __t;
+	}
+      else
+	{
+	  //  Evaluate Si and Ci by series expansion.
+	  _Tp __sum(0);
+	  _Tp __sign(1), __fact(1);
+	  bool __odd = true;
+	  unsigned int __k = 1;
+	  while (true)
+	    {
+	      __fact *= __t / __k;
+	      _Tp __term = __fact / __k;
+	      __sum += __sign * __term;
+	      _Tp __err = __term / std::abs(__sum);
+	      if (__odd)
+		{
+		  __sign = -__sign;
+		  __sums = __sum;
+		  __sum = __sumc;
+		}
+	      else
+		{
+		  __sumc = __sum;
+		  __sum = __sums;
+		}
+	      if (__err < _S_eps)
+		break;
+	      __odd = !__odd;
+	      ++__k;
+	      if (__k > _S_max_iter)
+		std::__throw_runtime_error("csint_series: "
+					"series evaluation failed");
+	    }
+	}
+      _Ci = _S_gamma_e + std::log(__t) + __sumc;
+      _Si = __sums;
+
+      return;
+    }
+
+
+  /**
+   *  @brief This function computes the cosine @f$ Ci(x) @f$ and sine @f$ Si(x) @f$
+   *    integrals by asymptotic series summation for positive argument.
+   *    The asymptotic series is very good for x > 50.
+   */
+  template<typename _Tp>
+    void
+    __csint_asymp(_Tp __t, _Tp& _Ci, _Tp& _Si)
+    {
+      const auto _S_max_iter = 100;
+      constexpr auto _S_eps = _Tp(5) * std::numeric_limits<_Tp>::epsilon();
+      constexpr auto _S_pi_2 = std::__detail::__numeric_constants<_Tp>::__pi_2();
+
+      auto __invt = _Tp(1) / __t;
+      auto __term = _Tp(1); // 0!
+      auto __sume = _Tp(__term);
+      __term *= __invt; // 1! / t
+      auto __sumo = _Tp(__term);
+      auto __sign = _Tp(1);
+      auto __even = true;
+      auto __k = 2;
+      while (true)
+	{
+	  __term *= __k * __invt;
+
+	  if (__even)
+	    {
+	      __sign = -__sign;
+	      __sume += __sign * __term;
+
+	    }
+	  else
+	    {
+	      __sumo += __sign * __term;
+	      if (__term / std::abs(__sumo) < _S_eps)
+		break;
+	    }
+
+	  __even = !__even;
+
+	  if (__k > _S_max_iter)
+	    std::__throw_runtime_error("csint_asymp: series evaluation failed");
+	  ++__k;
+	}
+
+      _Ci = std::sin(__t) * __invt * __sume
+	   - std::cos(__t) * __invt * __sumo;
+      _Si = _S_pi_2
+	   - std::cos(__t) * __invt * __sume
+	   - std::sin(__t) * __invt * __sumo;
+
+      return;
+    }
+
+
+  /**
+   *  @brief This function returns the cosine @f$ Ci(x) @f$ and
+   *    sine @f$ Si(x) @f$ integrals as a pair.
+   *
+   *  The cosine integral is defined by:
+   *  @f[
+   *      Ci(x) = \gamma_E + \log(x) + \int_0^x dt \frac{\cos(t) - 1}{t}
+   *  @f]
+   *
+   *  The sine integral is defined by:
+   *  @f[
+   *      Si(x) = \int_0^x dt \frac{\sin(t)}{t}
+   *  @f]
+   */
+  template<typename _Tp>
+    std::pair<_Tp, _Tp>
+    __csint(_Tp __x)
+    {
+      auto __t = std::abs(__x);
+      _Tp _Ci, _Si;
+      if (__t == _Tp(0))
+	{
+	  _Ci = -std::numeric_limits<_Tp>::infinity();
+	  _Si = _Tp(0);
+	}
+      else if (__t > _Tp(1000)) // Check this!
+	__csint_asymp(__t, _Ci, _Si);
+      else if (__t > _Tp(2))
+	__csint_cont_frac(__t, _Ci, _Si);
+      else
+	__csint_series(__t, _Ci, _Si);
+
+      if (__x < _Tp(0))
+	_Si = -_Si;
+
+      return std::make_pair(_Ci, _Si);
+    }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#endif // _GLIBCXX_SF_TRIGINT_TCC
Index: include/bits/sf_zeta.tcc
===================================================================
--- include/bits/sf_zeta.tcc	(revision 175789)
+++ include/bits/sf_zeta.tcc	(working copy)
@@ -1,7 +1,6 @@
 // Special functions -*- C++ -*-
 
-// Copyright (C) 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 2006-2015 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -23,16 +22,18 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-/** @file tr1/riemann_zeta.tcc
+/** @file bits/sf_zeta.tcc
  *  This is an internal header file, included by other library headers.
- *  Do not attempt to use it directly. @headername{tr1/cmath}
+ *  Do not attempt to use it directly. @headername{cmath}
  */
 
 //
-// ISO C++ 14882 TR1: 5.2  Special functions
+// ISO C++ 14882 TR29124: Mathematical Special Functions
 //
 
-// Written by Edward Smith-Rowland based on:
+// Written by Edward Smith-Rowland
+//
+// References:
 //   (1) Handbook of Mathematical Functions,
 //       Ed. by Milton Abramowitz and Irene A. Stegun,
 //       Dover Publications, New-York, Section 5, pp. 807-808.
@@ -40,86 +41,150 @@
 //   (3) Gamma, Exploring Euler's Constant, Julian Havil,
 //       Princeton, 2003.
 
-#ifndef _GLIBCXX_TR1_RIEMANN_ZETA_TCC
-#define _GLIBCXX_TR1_RIEMANN_ZETA_TCC 1
+#ifndef _GLIBCXX_BITS_SF_ZETA_TCC
+#define _GLIBCXX_BITS_SF_ZETA_TCC 1
 
-#include "special_function_util.h"
+#include <bits/specfun_util.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
-namespace tr1
+// Implementation-space details.
+namespace __detail
 {
-  // [5.2] Special functions
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  // Implementation-space details.
-  namespace __detail
-  {
-  _GLIBCXX_BEGIN_NAMESPACE_VERSION
+  /**
+   *   @brief  Compute the dilogarithm function @f$ Li_2(x) @f$
+   *           by summation for x <= 1.
+   *
+   *   The Riemann zeta function is defined by:
+   *    \f[
+   *      Li_2(x) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1
+   *    \f]
+   *   For |x| near 1 use the reflection formulae:
+   *    \f[
+   *      Li_2(-x) + Li_2(1-x) = \frac{\pi^2}{6} - \ln(x) \ln(1-x)
+   *    \f]
+   *    \f[
+   *      Li_2(-x) - Li_2(1-x) - \frac{1}{2}Li_2(1-x^2) = -\frac{\pi^2}{12} - \ln(x) \ln(1-x)
+   *    \f]
+   *   For x < 1 use the reflection formula:
+   *    \f[
+   *      Li_2(1-x) - Li_2(1-\frac{1}{1-x}) - \frac{1}{2}(\ln(x))^2
+   *    \f]
+   */
+  template<typename _Tp>
+    _Tp
+    __dilog(_Tp __x)
+    {
+      static constexpr unsigned long long _S_maxit = 100000ULL;
+      static constexpr _Tp _S_eps = 10 * std::numeric_limits<_Tp>::epsilon();
+      static constexpr _Tp _S_pipio6
+	= 1.644934066848226436472415166646025189219L;
+      if (__isnan(__x))
+	return std::numeric_limits<_Tp>::quiet_NaN();
+      else if (__x > +_Tp(1))
+	std::__throw_range_error(__N("dilog: argument greater than one"));
+      else if (__x < -_Tp(1))
+	{
+	  auto __lnfact = std::log(_Tp(1) - __x);
+	  return -__dilog(_Tp(1) - _Tp(1) / (_Tp(1) - __x))
+		 - _Tp(0.5L) * __lnfact * __lnfact;
+	}
+      else if (__x == _Tp(1))
+	return _S_pipio6;
+      else if (__x == -_Tp(1))
+	return -_Tp(0.5L) * _S_pipio6;
+      else if (__x > _Tp(0.5))
+	return _S_pipio6 - std::log(__x) * std::log(_Tp(1) - __x)
+	     - __dilog(_Tp(1) - __x);
+      else if (__x < -_Tp(0.5))
+	return -_Tp(0.5L) * _S_pipio6 - std::log(_Tp(1) + __x) * std::log(-__x)
+	     + __dilog(_Tp(1) + __x) - __dilog(_Tp(1) - __x * __x);
+      else
+	{
+	  _Tp __sum = 0;
+	  _Tp __fact = 1;
+	  for (auto __i = 1ULL; __i < _S_maxit; ++__i)
+	    {
+	      __fact *= __x;
+	      auto __term = __fact / (__i * __i);
+	      __sum += __term;
+	      if (std::abs(__term) < _S_eps)
+		{
+		  std::cout << __i << " - ";
+		  break;
+		}
+	      if (__i + 1 == _S_maxit)
+		std::__throw_runtime_error("__dilog: sum failed");
+	    }
+	  return __sum;
+	}
+    }
 
-    /**
-     *   @brief  Compute the Riemann zeta function @f$ \zeta(s) @f$
-     *           by summation for s > 1.
-     * 
-     *   The Riemann zeta function is defined by:
-     *    \f[
-     *      \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1
-     *    \f]
-     *   For s < 1 use the reflection formula:
-     *    \f[
-     *      \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s)
-     *    \f]
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Compute the Riemann zeta function @f$ \zeta(s) @f$
+   *           by summation for s > 1.
+   *
+   *   The Riemann zeta function is defined by:
+   *    \f[
+   *      \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1
+   *    \f]
+   *   For s < 1 use the reflection formula:
+   *    \f[
+   *      \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s)
+   *    \f]
+   */
+  template<typename _Tp>
     _Tp
-    __riemann_zeta_sum(const _Tp __s)
+    __riemann_zeta_sum(_Tp __s)
     {
       //  A user shouldn't get to this.
       if (__s < _Tp(1))
-        std::__throw_domain_error(__N("Bad argument in zeta sum."));
+	std::__throw_domain_error(__N("Bad argument in zeta sum."));
 
       const unsigned int max_iter = 10000;
       _Tp __zeta = _Tp(0);
       for (unsigned int __k = 1; __k < max_iter; ++__k)
-        {
-          _Tp __term = std::pow(static_cast<_Tp>(__k), -__s);
-          if (__term < std::numeric_limits<_Tp>::epsilon())
-            {
-              break;
-            }
-          __zeta += __term;
-        }
+	{
+	  _Tp __term = std::pow(static_cast<_Tp>(__k), -__s);
+	  if (__term < std::numeric_limits<_Tp>::epsilon())
+	    break;
+	  __zeta += __term;
+	}
 
       return __zeta;
     }
 
 
-    /**
-     *   @brief  Evaluate the Riemann zeta function @f$ \zeta(s) @f$
-     *           by an alternate series for s > 0.
-     * 
-     *   The Riemann zeta function is defined by:
-     *    \f[
-     *      \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1
-     *    \f]
-     *   For s < 1 use the reflection formula:
-     *    \f[
-     *      \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s)
-     *    \f]
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Evaluate the Riemann zeta function @f$ \zeta(s) @f$
+   *           by an alternate series for s > 0.
+   *
+   *   The Riemann zeta function is defined by:
+   *    \f[
+   *      \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1
+   *    \f]
+   *   For s < 1 use the reflection formula:
+   *    \f[
+   *      \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s)
+   *    \f]
+   */
+  template<typename _Tp>
     _Tp
-    __riemann_zeta_alt(const _Tp __s)
+    __riemann_zeta_alt(_Tp __s)
     {
+      const unsigned int __max_iter = 10000000;
       _Tp __sgn = _Tp(1);
       _Tp __zeta = _Tp(0);
-      for (unsigned int __i = 1; __i < 10000000; ++__i)
-        {
-          _Tp __term = __sgn / std::pow(__i, __s);
-          if (std::abs(__term) < std::numeric_limits<_Tp>::epsilon())
-            break;
-          __zeta += __term;
-          __sgn *= _Tp(-1);
-        }
+      for (unsigned int __i = 1; __i < __max_iter; ++__i)
+	{
+	  _Tp __term = __sgn / std::pow(__i, __s);
+	  if (std::abs(__term) < std::numeric_limits<_Tp>::epsilon())
+	    break;
+	  __zeta += __term;
+	  __sgn *= _Tp(-1);
+	}
       __zeta /= _Tp(1) - std::pow(_Tp(2), _Tp(1) - __s);
 
       return __zeta;
@@ -126,31 +191,31 @@
     }
 
 
-    /**
-     *   @brief  Evaluate the Riemann zeta function by series for all s != 1.
-     *           Convergence is great until largish negative numbers.
-     *           Then the convergence of the > 0 sum gets better.
-     *
-     *   The series is:
-     *    \f[
-     *      \zeta(s) = \frac{1}{1-2^{1-s}}
-     *                 \sum_{n=0}^{\infty} \frac{1}{2^{n+1}}
-     *                 \sum_{k=0}^{n} (-1)^k \frac{n!}{(n-k)!k!} (k+1)^{-s}
-     *    \f]
-     *   Havil 2003, p. 206.
-     *
-     *   The Riemann zeta function is defined by:
-     *    \f[
-     *      \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1
-     *    \f]
-     *   For s < 1 use the reflection formula:
-     *    \f[
-     *      \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s)
-     *    \f]
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Evaluate the Riemann zeta function by series for all s != 1.
+   *           Convergence is great until largish negative numbers.
+   *           Then the convergence of the > 0 sum gets better.
+   *
+   *   The series is:
+   *    \f[
+   *      \zeta(s) = \frac{1}{1-2^{1-s}}
+   *                 \sum_{n=0}^{\infty} \frac{1}{2^{n+1}}
+   *                 \sum_{k=0}^{n} (-1)^k \frac{n!}{(n-k)!k!} (k+1)^{-s}
+   *    \f]
+   *   Havil 2003, p. 206.
+   *
+   *   The Riemann zeta function is defined by:
+   *    \f[
+   *      \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1
+   *    \f]
+   *   For s < 1 use the reflection formula:
+   *    \f[
+   *      \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s)
+   *    \f]
+   */
+  template<typename _Tp>
     _Tp
-    __riemann_zeta_glob(const _Tp __s)
+    __riemann_zeta_glob(_Tp __s)
     {
       _Tp __zeta = _Tp(0);
 
@@ -157,68 +222,53 @@
       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
       //  Max e exponent before overflow.
       const _Tp __max_bincoeff = std::numeric_limits<_Tp>::max_exponent10
-                               * std::log(_Tp(10)) - _Tp(1);
+			       * std::log(_Tp(10)) - _Tp(1);
 
       //  This series works until the binomial coefficient blows up
       //  so use reflection.
       if (__s < _Tp(0))
-        {
-#if _GLIBCXX_USE_C99_MATH_TR1
-          if (std::tr1::fmod(__s,_Tp(2)) == _Tp(0))
-            return _Tp(0);
-          else
-#endif
-            {
-              _Tp __zeta = __riemann_zeta_glob(_Tp(1) - __s);
-              __zeta *= std::pow(_Tp(2)
-                     * __numeric_constants<_Tp>::__pi(), __s)
-                     * std::sin(__numeric_constants<_Tp>::__pi_2() * __s)
-#if _GLIBCXX_USE_C99_MATH_TR1
-                     * std::exp(std::tr1::lgamma(_Tp(1) - __s))
-#else
-                     * std::exp(__log_gamma(_Tp(1) - __s))
-#endif
-                     / __numeric_constants<_Tp>::__pi();
-              return __zeta;
-            }
-        }
+	{
+	  if (std::fmod(__s,_Tp(2)) == _Tp(0))
+	    return _Tp(0);
+	  else
+	    {
+	      _Tp __zeta = __riemann_zeta_glob(_Tp(1) - __s);
+	      __zeta *= std::pow(_Tp(2)
+		     * __numeric_constants<_Tp>::__pi(), __s)
+		     * std::sin(__numeric_constants<_Tp>::__pi_2() * __s)
+		     * std::exp(__log_gamma(_Tp(1) - __s))
+		     / __numeric_constants<_Tp>::__pi();
+	      return __zeta;
+	    }
+	}
 
-      _Tp __num = _Tp(0.5L);
+      _Tp __num = _Tp(0.25L);
       const unsigned int __maxit = 10000;
-      for (unsigned int __i = 0; __i < __maxit; ++__i)
-        {
-          bool __punt = false;
-          _Tp __sgn = _Tp(1);
-          _Tp __term = _Tp(0);
-          for (unsigned int __j = 0; __j <= __i; ++__j)
-            {
-#if _GLIBCXX_USE_C99_MATH_TR1
-              _Tp __bincoeff =  std::tr1::lgamma(_Tp(1 + __i))
-                              - std::tr1::lgamma(_Tp(1 + __j))
-                              - std::tr1::lgamma(_Tp(1 + __i - __j));
-#else
-              _Tp __bincoeff =  __log_gamma(_Tp(1 + __i))
-                              - __log_gamma(_Tp(1 + __j))
-                              - __log_gamma(_Tp(1 + __i - __j));
-#endif
-              if (__bincoeff > __max_bincoeff)
-                {
-                  //  This only gets hit for x << 0.
-                  __punt = true;
-                  break;
-                }
-              __bincoeff = std::exp(__bincoeff);
-              __term += __sgn * __bincoeff * std::pow(_Tp(1 + __j), -__s);
-              __sgn *= _Tp(-1);
-            }
-          if (__punt)
-            break;
-          __term *= __num;
-          __zeta += __term;
-          if (std::abs(__term/__zeta) < __eps)
-            break;
-          __num *= _Tp(0.5L);
-        }
+      __zeta = _Tp(0.5L); // Zeroth order contribution already calculated.
+      for (unsigned int __i = 1; __i < __maxit; ++__i)
+	{
+	  bool __punt = false;
+	  _Tp __term = _Tp(1); // Again, the zeroth order.
+	  _Tp __bincoeff = _Tp(1);
+	  for (unsigned int __j = 1; __j <= __i; ++__j)
+	    {
+	      __bincoeff *= -_Tp(__i - __j + 1) / __j;
+	      if(std::fabs(__bincoeff) > __max_bincoeff )
+	      {
+		//  This only gets hit for x << 0.
+		__punt = true;
+		break;
+	      }
+	      __term += __bincoeff * std::pow(_Tp(1 + __j), -__s);
+	    }
+	  if (__punt)
+	    break;
+	  __term *= __num;
+	  __zeta += __term;
+	  if (std::abs(__term/__zeta) < __eps)
+	    break;
+	  __num *= _Tp(0.5L);
+	}
 
       __zeta /= _Tp(1) - std::pow(_Tp(2), _Tp(1) - __s);
 
@@ -226,43 +276,45 @@
     }
 
 
-    /**
-     *   @brief  Compute the Riemann zeta function @f$ \zeta(s) @f$
-     *           using the product over prime factors.
-     *    \f[
-     *      \zeta(s) = \Pi_{i=1}^\infty \frac{1}{1 - p_i^{-s}}
-     *    \f]
-     *    where @f$ {p_i} @f$ are the prime numbers.
-     * 
-     *   The Riemann zeta function is defined by:
-     *    \f[
-     *      \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1
-     *    \f]
-     *   For s < 1 use the reflection formula:
-     *    \f[
-     *      \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s)
-     *    \f]
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Compute the Riemann zeta function @f$ \zeta(s) @f$
+   *           using the product over prime factors.
+   *    \f[
+   *      \zeta(s) = \Pi_{i=1}^\infty \frac{1}{1 - p_i^{-s}}
+   *    \f]
+   *    where @f$ {p_i} @f$ are the prime numbers.
+   *
+   *   The Riemann zeta function is defined by:
+   *    \f[
+   *      \zeta(s) = \sum_{k=1}^{\infty} \frac{1}{k^{s}} for s > 1
+   *    \f]
+   *   For s < 1 use the reflection formula:
+   *    \f[
+   *      \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s)
+   *    \f]
+   */
+  template<typename _Tp>
     _Tp
-    __riemann_zeta_product(const _Tp __s)
+    __riemann_zeta_product(_Tp __s)
     {
-      static const _Tp __prime[] = {
-        _Tp(2), _Tp(3), _Tp(5), _Tp(7), _Tp(11), _Tp(13), _Tp(17), _Tp(19),
-        _Tp(23), _Tp(29), _Tp(31), _Tp(37), _Tp(41), _Tp(43), _Tp(47),
-        _Tp(53), _Tp(59), _Tp(61), _Tp(67), _Tp(71), _Tp(73), _Tp(79),
-        _Tp(83), _Tp(89), _Tp(97), _Tp(101), _Tp(103), _Tp(107), _Tp(109)
+      static constexpr _Tp
+      __prime[]
+      {
+	_Tp(2), _Tp(3), _Tp(5), _Tp(7), _Tp(11), _Tp(13), _Tp(17), _Tp(19),
+	_Tp(23), _Tp(29), _Tp(31), _Tp(37), _Tp(41), _Tp(43), _Tp(47),
+	_Tp(53), _Tp(59), _Tp(61), _Tp(67), _Tp(71), _Tp(73), _Tp(79),
+	_Tp(83), _Tp(89), _Tp(97), _Tp(101), _Tp(103), _Tp(107), _Tp(109)
       };
-      static const unsigned int __num_primes = sizeof(__prime) / sizeof(_Tp);
+      static constexpr unsigned int __num_primes = sizeof(__prime) / sizeof(_Tp);
 
       _Tp __zeta = _Tp(1);
       for (unsigned int __i = 0; __i < __num_primes; ++__i)
-        {
-          const _Tp __fact = _Tp(1) - std::pow(__prime[__i], -__s);
-          __zeta *= __fact;
-          if (_Tp(1) - __fact < std::numeric_limits<_Tp>::epsilon())
-            break;
-        }
+	{
+	  const _Tp __fact = _Tp(1) - std::pow(__prime[__i], -__s);
+	  __zeta *= __fact;
+	  if (_Tp(1) - __fact < std::numeric_limits<_Tp>::epsilon())
+	    break;
+	}
 
       __zeta = _Tp(1) / __zeta;
 
@@ -270,95 +322,87 @@
     }
 
 
-    /**
-     *   @brief  Return the Riemann zeta function @f$ \zeta(s) @f$.
-     * 
-     *   The Riemann zeta function is defined by:
-     *    \f[
-     *      \zeta(s) = \sum_{k=1}^{\infty} k^{-s} for s > 1
-     *                 \frac{(2\pi)^s}{pi} sin(\frac{\pi s}{2})
-     *                 \Gamma (1 - s) \zeta (1 - s) for s < 1
-     *    \f]
-     *   For s < 1 use the reflection formula:
-     *    \f[
-     *      \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s)
-     *    \f]
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the Riemann zeta function @f$ \zeta(s) @f$.
+   *
+   *   The Riemann zeta function is defined by:
+   *    \f[
+   *      \zeta(s) = \sum_{k=1}^{\infty} k^{-s} for s > 1
+   *                 \frac{(2\pi)^s}{pi} sin(\frac{\pi s}{2})
+   *                 \Gamma (1 - s) \zeta (1 - s) for s < 1
+   *    \f]
+   *   For s < 1 use the reflection formula:
+   *    \f[
+   *      \zeta(s) = 2^s \pi^{s-1} \Gamma(1-s) \zeta(1-s)
+   *    \f]
+   */
+  template<typename _Tp>
     _Tp
-    __riemann_zeta(const _Tp __s)
+    __riemann_zeta(_Tp __s)
     {
       if (__isnan(__s))
-        return std::numeric_limits<_Tp>::quiet_NaN();
+	return std::numeric_limits<_Tp>::quiet_NaN();
       else if (__s == _Tp(1))
-        return std::numeric_limits<_Tp>::infinity();
+	return std::numeric_limits<_Tp>::infinity();
       else if (__s < -_Tp(19))
-        {
-          _Tp __zeta = __riemann_zeta_product(_Tp(1) - __s);
-          __zeta *= std::pow(_Tp(2) * __numeric_constants<_Tp>::__pi(), __s)
-                 * std::sin(__numeric_constants<_Tp>::__pi_2() * __s)
-#if _GLIBCXX_USE_C99_MATH_TR1
-                 * std::exp(std::tr1::lgamma(_Tp(1) - __s))
-#else
-                 * std::exp(__log_gamma(_Tp(1) - __s))
-#endif
-                 / __numeric_constants<_Tp>::__pi();
-          return __zeta;
-        }
+	{
+	  _Tp __zeta = __riemann_zeta_product(_Tp(1) - __s);
+	  __zeta *= std::pow(_Tp(2) * __numeric_constants<_Tp>::__pi(), __s)
+		 * std::sin(__numeric_constants<_Tp>::__pi_2() * __s)
+		 * std::exp(__log_gamma(_Tp(1) - __s))
+		 / __numeric_constants<_Tp>::__pi();
+	  return __zeta;
+	}
       else if (__s < _Tp(20))
-        {
-          //  Global double sum or McLaurin?
-          bool __glob = true;
-          if (__glob)
-            return __riemann_zeta_glob(__s);
-          else
-            {
-              if (__s > _Tp(1))
-                return __riemann_zeta_sum(__s);
-              else
-                {
-                  _Tp __zeta = std::pow(_Tp(2)
-                                * __numeric_constants<_Tp>::__pi(), __s)
-                         * std::sin(__numeric_constants<_Tp>::__pi_2() * __s)
-#if _GLIBCXX_USE_C99_MATH_TR1
-                             * std::tr1::tgamma(_Tp(1) - __s)
-#else
-                             * std::exp(__log_gamma(_Tp(1) - __s))
-#endif
-                             * __riemann_zeta_sum(_Tp(1) - __s);
-                  return __zeta;
-                }
-            }
-        }
+	{
+	  //  Global double sum or McLaurin?
+	  bool __glob = true;
+	  if (__glob)
+	    return __riemann_zeta_glob(__s);
+	  else
+	    {
+	      if (__s > _Tp(1))
+		return __riemann_zeta_sum(__s);
+	      else
+		{
+		  _Tp __zeta = std::pow(_Tp(2)
+			     * __numeric_constants<_Tp>::__pi(), __s)
+			     * std::sin(__numeric_constants<_Tp>::__pi_2() * __s)
+			     * __gamma(_Tp(1) - __s)
+			     * __riemann_zeta_sum(_Tp(1) - __s);
+		  return __zeta;
+		}
+	    }
+	}
       else
-        return __riemann_zeta_product(__s);
+	return __riemann_zeta_product(__s);
     }
 
 
-    /**
-     *   @brief  Return the Hurwitz zeta function @f$ \zeta(x,s) @f$
-     *           for all s != 1 and x > -1.
-     * 
-     *   The Hurwitz zeta function is defined by:
-     *   @f[
-     *     \zeta(x,s) = \sum_{n=0}^{\infty} \frac{1}{(n + x)^s}
-     *   @f]
-     *   The Riemann zeta function is a special case:
-     *   @f[
-     *     \zeta(s) = \zeta(1,s)
-     *   @f]
-     * 
-     *   This functions uses the double sum that converges for s != 1
-     *   and x > -1:
-     *   @f[
-     *     \zeta(x,s) = \frac{1}{s-1}
-     *                \sum_{n=0}^{\infty} \frac{1}{n + 1}
-     *                \sum_{k=0}^{n} (-1)^k \frac{n!}{(n-k)!k!} (x+k)^{-s}
-     *   @f]
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the Hurwitz zeta function @f$ \zeta(x,s) @f$
+   *           for all s != 1 and x > -1.
+   *
+   *   The Hurwitz zeta function is defined by:
+   *   @f[
+   *     \zeta(x,s) = \sum_{n=0}^{\infty} \frac{1}{(n + x)^s}
+   *   @f]
+   *   The Riemann zeta function is a special case:
+   *   @f[
+   *     \zeta(s) = \zeta(1,s)
+   *   @f]
+   *
+   *   This functions uses the double sum that converges for s != 1
+   *   and x > -1:
+   *   @f[
+   *     \zeta(x,s) = \frac{1}{s-1}
+   *                \sum_{n=0}^{\infty} \frac{1}{n + 1}
+   *                \sum_{k=0}^{n} (-1)^k \frac{n!}{(n-k)!k!} (x+k)^{-s}
+   *   @f]
+   */
+  template<typename _Tp>
     _Tp
-    __hurwitz_zeta_glob(const _Tp __a, const _Tp __s)
+    __hurwitz_zeta_glob(_Tp __a, _Tp __s)
     {
       _Tp __zeta = _Tp(0);
 
@@ -365,42 +409,33 @@
       const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
       //  Max e exponent before overflow.
       const _Tp __max_bincoeff = std::numeric_limits<_Tp>::max_exponent10
-                               * std::log(_Tp(10)) - _Tp(1);
+			       * std::log(_Tp(10)) - _Tp(1);
 
       const unsigned int __maxit = 10000;
-      for (unsigned int __i = 0; __i < __maxit; ++__i)
-        {
-          bool __punt = false;
-          _Tp __sgn = _Tp(1);
-          _Tp __term = _Tp(0);
-          for (unsigned int __j = 0; __j <= __i; ++__j)
-            {
-#if _GLIBCXX_USE_C99_MATH_TR1
-              _Tp __bincoeff =  std::tr1::lgamma(_Tp(1 + __i))
-                              - std::tr1::lgamma(_Tp(1 + __j))
-                              - std::tr1::lgamma(_Tp(1 + __i - __j));
-#else
-              _Tp __bincoeff =  __log_gamma(_Tp(1 + __i))
-                              - __log_gamma(_Tp(1 + __j))
-                              - __log_gamma(_Tp(1 + __i - __j));
-#endif
-              if (__bincoeff > __max_bincoeff)
-                {
-                  //  This only gets hit for x << 0.
-                  __punt = true;
-                  break;
-                }
-              __bincoeff = std::exp(__bincoeff);
-              __term += __sgn * __bincoeff * std::pow(_Tp(__a + __j), -__s);
-              __sgn *= _Tp(-1);
-            }
-          if (__punt)
-            break;
-          __term /= _Tp(__i + 1);
-          if (std::abs(__term / __zeta) < __eps)
-            break;
-          __zeta += __term;
-        }
+      __zeta = _Tp(0.5L); // Zeroth order contribution already calculated.
+      for (unsigned int __i = 1; __i < __maxit; ++__i)
+	{
+	  bool __punt = false;
+	  _Tp __term = _Tp(1); // Again, the zeroth order.
+	  _Tp __bincoeff = _Tp(1);
+	  for (unsigned int __j = 1; __j <= __i; ++__j)
+	    {
+	      __bincoeff *= -_Tp(__i - __j + 1) / __j;
+	      if(std::fabs(__bincoeff) > __max_bincoeff )
+	      {
+		//  This only gets hit for x << 0.
+		__punt = true;
+		break;
+	      }
+	      __term += __bincoeff * std::pow(_Tp(__a + __j), -__s);
+	    }
+	  if (__punt)
+	    break;
+	  __term /= _Tp(__i + 1);
+	  if (std::abs(__term / __zeta) < __eps)
+	    break;
+	  __zeta += __term;
+	}
 
       __zeta /= __s - _Tp(1);
 
@@ -408,29 +443,26 @@
     }
 
 
-    /**
-     *   @brief  Return the Hurwitz zeta function @f$ \zeta(x,s) @f$
-     *           for all s != 1 and x > -1.
-     * 
-     *   The Hurwitz zeta function is defined by:
-     *   @f[
-     *     \zeta(x,s) = \sum_{n=0}^{\infty} \frac{1}{(n + x)^s}
-     *   @f]
-     *   The Riemann zeta function is a special case:
-     *   @f[
-     *     \zeta(s) = \zeta(1,s)
-     *   @f]
-     */
-    template<typename _Tp>
+  /**
+   *   @brief  Return the Hurwitz zeta function @f$ \zeta(x,s) @f$
+   *           for all s != 1 and x > -1.
+   *
+   *   The Hurwitz zeta function is defined by:
+   *   @f[
+   *     \zeta(x,s) = \sum_{n=0}^{\infty} \frac{1}{(n + x)^s}
+   *   @f]
+   *   The Riemann zeta function is a special case:
+   *   @f[
+   *     \zeta(s) = \zeta(1,s)
+   *   @f]
+   */
+  template<typename _Tp>
     inline _Tp
-    __hurwitz_zeta(const _Tp __a, const _Tp __s)
-    {
-      return __hurwitz_zeta_glob(__a, __s);
-    }
+    __hurwitz_zeta(_Tp __a, _Tp __s)
+    { return __hurwitz_zeta_glob(__a, __s); }
 
-  _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
 
-#endif // _GLIBCXX_TR1_RIEMANN_ZETA_TCC
+#endif // _GLIBCXX_BITS_SF_ZETA_TCC
Index: include/tr1/special_function_util.h
===================================================================
--- include/tr1/special_function_util.h	(revision 230377)
+++ include/tr1/special_function_util.h	(working copy)
@@ -38,8 +38,13 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   namespace __detail
   {
   _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -128,8 +133,10 @@
 
   _GLIBCXX_END_NAMESPACE_VERSION
   } // namespace __detail
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_SPECIAL_FUNCTION_UTIL_H
 
Index: include/tr1/bessel_function.tcc
===================================================================
--- include/tr1/bessel_function.tcc	(revision 230377)
+++ include/tr1/bessel_function.tcc	(working copy)
@@ -50,8 +50,15 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+# define _GLIBCXX_MATH_NS ::std
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+# define _GLIBCXX_MATH_NS ::std::tr1
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // [5.2] Special functions
 
   // Implementation-space details.
@@ -90,8 +97,8 @@
                   _Tp & __gam1, _Tp & __gam2, _Tp & __gampl, _Tp & __gammi)
     {
 #if _GLIBCXX_USE_C99_MATH_TR1
-      __gampl = _Tp(1) / std::tr1::tgamma(_Tp(1) + __mu);
-      __gammi = _Tp(1) / std::tr1::tgamma(_Tp(1) - __mu);
+      __gampl = _Tp(1) / _GLIBCXX_MATH_NS::tgamma(_Tp(1) + __mu);
+      __gammi = _Tp(1) / _GLIBCXX_MATH_NS::tgamma(_Tp(1) - __mu);
 #else
       __gampl = _Tp(1) / __gamma(_Tp(1) + __mu);
       __gammi = _Tp(1) / __gamma(_Tp(1) - __mu);
@@ -306,7 +313,7 @@
           const _Tp __gam = (__p - __f) / __q;
           __Jmu = std::sqrt(__w / ((__p - __f) * __gam + __q));
 #if _GLIBCXX_USE_C99_MATH_TR1
-          __Jmu = std::tr1::copysign(__Jmu, __Jnul);
+          __Jmu = _GLIBCXX_MATH_NS::copysign(__Jmu, __Jnul);
 #else
           if (__Jmu * __Jnul < _Tp(0))
             __Jmu = -__Jmu;
@@ -414,7 +421,7 @@
       const _Tp __x2 = __x / _Tp(2);
       _Tp __fact = __nu * std::log(__x2);
 #if _GLIBCXX_USE_C99_MATH_TR1
-      __fact -= std::tr1::lgamma(__nu + _Tp(1));
+      __fact -= _GLIBCXX_MATH_NS::lgamma(__nu + _Tp(1));
 #else
       __fact -= __log_gamma(__nu + _Tp(1));
 #endif
@@ -621,8 +628,11 @@
     }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  } // namespace __detail
+#undef _GLIBCXX_MATH_NS
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_BESSEL_FUNCTION_TCC
Index: include/tr1/beta_function.tcc
===================================================================
--- include/tr1/beta_function.tcc	(revision 230377)
+++ include/tr1/beta_function.tcc	(working copy)
@@ -48,8 +48,15 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+# define _GLIBCXX_MATH_NS ::std
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+# define _GLIBCXX_MATH_NS ::std::tr1
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // [5.2] Special functions
 
   // Implementation-space details.
@@ -78,15 +85,15 @@
 #if _GLIBCXX_USE_C99_MATH_TR1
       if (__x > __y)
         {
-          __bet = std::tr1::tgamma(__x)
-                / std::tr1::tgamma(__x + __y);
-          __bet *= std::tr1::tgamma(__y);
+          __bet = _GLIBCXX_MATH_NS::tgamma(__x)
+                / _GLIBCXX_MATH_NS::tgamma(__x + __y);
+          __bet *= _GLIBCXX_MATH_NS::tgamma(__y);
         }
       else
         {
-          __bet = std::tr1::tgamma(__y)
-                / std::tr1::tgamma(__x + __y);
-          __bet *= std::tr1::tgamma(__x);
+          __bet = _GLIBCXX_MATH_NS::tgamma(__y)
+                / _GLIBCXX_MATH_NS::tgamma(__x + __y);
+          __bet *= _GLIBCXX_MATH_NS::tgamma(__x);
         }
 #else
       if (__x > __y)
@@ -122,9 +129,9 @@
     __beta_lgamma(_Tp __x, _Tp __y)
     {
 #if _GLIBCXX_USE_C99_MATH_TR1
-      _Tp __bet = std::tr1::lgamma(__x)
-                + std::tr1::lgamma(__y)
-                - std::tr1::lgamma(__x + __y);
+      _Tp __bet = _GLIBCXX_MATH_NS::lgamma(__x)
+                + _GLIBCXX_MATH_NS::lgamma(__y)
+                - _GLIBCXX_MATH_NS::lgamma(__x + __y);
 #else
       _Tp __bet = __log_gamma(__x)
                 + __log_gamma(__y)
@@ -190,8 +197,11 @@
     }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  } // namespace __detail
+#undef _GLIBCXX_MATH_NS
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_BETA_FUNCTION_TCC
Index: include/tr1/cmath
===================================================================
--- include/tr1/cmath	(revision 230377)
+++ include/tr1/cmath	(working copy)
@@ -1014,6 +1014,121 @@
 }
 }
 
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace tr1
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  /**
+   * @defgroup tr1_math_spec_func Mathematical Special Functions
+   * @ingroup numerics
+   *
+   * A collection of advanced mathematical special functions.
+   * @{
+   */
+
+  using std::assoc_laguerref;
+  using std::assoc_laguerrel;
+  using std::assoc_laguerre;
+
+  using std::assoc_legendref;
+  using std::assoc_legendrel;
+  using std::assoc_legendre;
+
+  using std::betaf;
+  using std::betal;
+  using std::beta;
+
+  using std::comp_ellint_1f;
+  using std::comp_ellint_1l;
+  using std::comp_ellint_1;
+
+  using std::comp_ellint_2f;
+  using std::comp_ellint_2l;
+  using std::comp_ellint_2;
+
+  using std::comp_ellint_3f;
+  using std::comp_ellint_3l;
+  using std::comp_ellint_3;
+
+  using std::conf_hypergf;
+  using std::conf_hypergl;
+  using std::conf_hyperg;
+
+  using std::cyl_bessel_if;
+  using std::cyl_bessel_il;
+  using std::cyl_bessel_i;
+
+  using std::cyl_bessel_jf;
+  using std::cyl_bessel_jl;
+  using std::cyl_bessel_j;
+
+  using std::cyl_bessel_kf;
+  using std::cyl_bessel_kl;
+  using std::cyl_bessel_k;
+
+  using std::cyl_neumannf;
+  using std::cyl_neumannl;
+  using std::cyl_neumann;
+
+  using std::ellint_1f;
+  using std::ellint_1l;
+  using std::ellint_1;
+
+  using std::ellint_2f;
+  using std::ellint_2l;
+  using std::ellint_2;
+
+  using std::ellint_3f;
+  using std::ellint_3l;
+  using std::ellint_3;
+
+  using std::expintf;
+  using std::expintl;
+  using std::expint;
+
+  using std::hermitef;
+  using std::hermitel;
+  using std::hermite;
+
+  using std::hypergf;
+  using std::hypergl;
+  using std::hyperg;
+
+  using std::laguerref;
+  using std::laguerrel;
+  using std::laguerre;
+
+  using std::legendref;
+  using std::legendrel;
+  using std::legendre;
+
+  using std::riemann_zetaf;
+  using std::riemann_zetal;
+  using std::riemann_zeta;
+
+  using std::sph_besself;
+  using std::sph_bessell;
+  using std::sph_bessel;
+
+  using std::sph_legendref;
+  using std::sph_legendrel;
+  using std::sph_legendre;
+
+  using std::sph_neumannf;
+  using std::sph_neumannl;
+  using std::sph_neumann;
+
+  /* @} */ // tr1_math_spec_func
+_GLIBCXX_END_NAMESPACE_VERSION
+}
+}
+
+#else // ! __STDCPP_WANT_MATH_SPEC_FUNCS__
+
 #include <bits/stl_algobase.h>
 #include <limits>
 #include <tr1/type_traits>
@@ -1441,5 +1556,6 @@
 _GLIBCXX_END_NAMESPACE_VERSION
 }
 }
+#endif // __STDCPP_WANT_MATH_SPEC_FUNCS__
 
 #endif // _GLIBCXX_TR1_CMATH
Index: include/tr1/ell_integral.tcc
===================================================================
--- include/tr1/ell_integral.tcc	(revision 230377)
+++ include/tr1/ell_integral.tcc	(working copy)
@@ -44,8 +44,13 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // [5.2] Special functions
 
   // Implementation-space details.
@@ -742,9 +747,11 @@
     }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  } // namespace __detail
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_ELL_INTEGRAL_TCC
 
Index: include/tr1/exp_integral.tcc
===================================================================
--- include/tr1/exp_integral.tcc	(revision 230377)
+++ include/tr1/exp_integral.tcc	(working copy)
@@ -49,8 +49,13 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // [5.2] Special functions
 
   // Implementation-space details.
@@ -519,8 +524,10 @@
     }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  } // namespace __detail
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_EXP_INTEGRAL_TCC
Index: include/tr1/gamma.tcc
===================================================================
--- include/tr1/gamma.tcc	(revision 230377)
+++ include/tr1/gamma.tcc	(working copy)
@@ -46,12 +46,19 @@
 #ifndef _GLIBCXX_TR1_GAMMA_TCC
 #define _GLIBCXX_TR1_GAMMA_TCC 1
 
-#include "special_function_util.h"
+#include <tr1/special_function_util.h>
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+# define _GLIBCXX_MATH_NS ::std
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+# define _GLIBCXX_MATH_NS ::std::tr1
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // Implementation-space details.
   namespace __detail
   {
@@ -282,9 +289,9 @@
                       = std::numeric_limits<_Tp>::max_exponent10
                       * std::log(_Tp(10)) - _Tp(1);
 #if _GLIBCXX_USE_C99_MATH_TR1
-      _Tp __coeff =  std::tr1::lgamma(_Tp(1 + __n))
-                  - std::tr1::lgamma(_Tp(1 + __k))
-                  - std::tr1::lgamma(_Tp(1 + __n - __k));
+      _Tp __coeff =  _GLIBCXX_MATH_NS::lgamma(_Tp(1 + __n))
+                  - _GLIBCXX_MATH_NS::lgamma(_Tp(1 + __k))
+                  - _GLIBCXX_MATH_NS::lgamma(_Tp(1 + __n - __k));
 #else
       _Tp __coeff =  __log_gamma(_Tp(1 + __n))
                   - __log_gamma(_Tp(1 + __k))
@@ -449,7 +456,7 @@
         {
           const _Tp __hzeta = __hurwitz_zeta(_Tp(__n + 1), __x);
 #if _GLIBCXX_USE_C99_MATH_TR1
-          const _Tp __ln_nfact = std::tr1::lgamma(_Tp(__n + 1));
+          const _Tp __ln_nfact = _GLIBCXX_MATH_NS::lgamma(_Tp(__n + 1));
 #else
           const _Tp __ln_nfact = __log_gamma(_Tp(__n + 1));
 #endif
@@ -461,9 +468,12 @@
     }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
-}
-}
+  } // namespace __detail
+#undef _GLIBCXX_MATH_NS
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
+} // namespace std
 
 #endif // _GLIBCXX_TR1_GAMMA_TCC
 
Index: include/tr1/hypergeometric.tcc
===================================================================
--- include/tr1/hypergeometric.tcc	(revision 230377)
+++ include/tr1/hypergeometric.tcc	(working copy)
@@ -43,8 +43,15 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+# define _GLIBCXX_MATH_NS ::std
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+# define _GLIBCXX_MATH_NS ::std::tr1
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // [5.2] Special functions
 
   // Implementation-space details.
@@ -222,7 +229,7 @@
     __conf_hyperg(_Tp __a, _Tp __c, _Tp __x)
     {
 #if _GLIBCXX_USE_C99_MATH_TR1
-      const _Tp __c_nint = std::tr1::nearbyint(__c);
+      const _Tp __c_nint = _GLIBCXX_MATH_NS::nearbyint(__c);
 #else
       const _Tp __c_nint = static_cast<int>(__c + _Tp(0.5L));
 #endif
@@ -723,9 +730,9 @@
     __hyperg(_Tp __a, _Tp __b, _Tp __c, _Tp __x)
     {
 #if _GLIBCXX_USE_C99_MATH_TR1
-      const _Tp __a_nint = std::tr1::nearbyint(__a);
-      const _Tp __b_nint = std::tr1::nearbyint(__b);
-      const _Tp __c_nint = std::tr1::nearbyint(__c);
+      const _Tp __a_nint = _GLIBCXX_MATH_NS::nearbyint(__a);
+      const _Tp __b_nint = _GLIBCXX_MATH_NS::nearbyint(__b);
+      const _Tp __c_nint = _GLIBCXX_MATH_NS::nearbyint(__c);
 #else
       const _Tp __a_nint = static_cast<int>(__a + _Tp(0.5L));
       const _Tp __b_nint = static_cast<int>(__b + _Tp(0.5L));
@@ -768,8 +775,11 @@
     }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  } // namespace __detail
+#undef _GLIBCXX_MATH_NS
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_HYPERGEOMETRIC_TCC
Index: include/tr1/legendre_function.tcc
===================================================================
--- include/tr1/legendre_function.tcc	(revision 230377)
+++ include/tr1/legendre_function.tcc	(working copy)
@@ -48,8 +48,15 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+# define _GLIBCXX_MATH_NS ::std
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+# define _GLIBCXX_MATH_NS ::std::tr1
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // [5.2] Special functions
 
   // Implementation-space details.
@@ -243,14 +250,14 @@
           const _Tp __sgn = ( __m % 2 == 1 ? -_Tp(1) : _Tp(1));
           const _Tp __y_mp1m_factor = __x * std::sqrt(_Tp(2 * __m + 3));
 #if _GLIBCXX_USE_C99_MATH_TR1
-          const _Tp __lncirc = std::tr1::log1p(-__x * __x);
+          const _Tp __lncirc = _GLIBCXX_MATH_NS::log1p(-__x * __x);
 #else
           const _Tp __lncirc = std::log(_Tp(1) - __x * __x);
 #endif
           //  Gamma(m+1/2) / Gamma(m)
 #if _GLIBCXX_USE_C99_MATH_TR1
-          const _Tp __lnpoch = std::tr1::lgamma(_Tp(__m + _Tp(0.5L)))
-                             - std::tr1::lgamma(_Tp(__m));
+          const _Tp __lnpoch = _GLIBCXX_MATH_NS::lgamma(_Tp(__m + _Tp(0.5L)))
+                             - _GLIBCXX_MATH_NS::lgamma(_Tp(__m));
 #else
           const _Tp __lnpoch = __log_gamma(_Tp(__m + _Tp(0.5L)))
                              - __log_gamma(_Tp(__m));
@@ -296,8 +303,11 @@
     }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  } // namespace __detail
+#undef _GLIBCXX_MATH_NS
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_LEGENDRE_FUNCTION_TCC
Index: include/tr1/modified_bessel_func.tcc
===================================================================
--- include/tr1/modified_bessel_func.tcc	(revision 230377)
+++ include/tr1/modified_bessel_func.tcc	(working copy)
@@ -50,8 +50,13 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // [5.2] Special functions
 
   // Implementation-space details.
@@ -427,8 +432,10 @@
     }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  } // namespace __detail
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_MODIFIED_BESSEL_FUNC_TCC
Index: include/tr1/poly_hermite.tcc
===================================================================
--- include/tr1/poly_hermite.tcc	(revision 230377)
+++ include/tr1/poly_hermite.tcc	(working copy)
@@ -41,8 +41,13 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // [5.2] Special functions
 
   // Implementation-space details.
@@ -117,8 +122,10 @@
     }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  } // namespace __detail
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_POLY_HERMITE_TCC
Index: include/tr1/poly_laguerre.tcc
===================================================================
--- include/tr1/poly_laguerre.tcc	(revision 230377)
+++ include/tr1/poly_laguerre.tcc	(working copy)
@@ -43,8 +43,15 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+# define _GLIBCXX_MATH_NS ::std
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+# define _GLIBCXX_MATH_NS ::std::tr1
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // [5.2] Special functions
 
   // Implementation-space details.
@@ -80,8 +87,8 @@
                         * __eta * __eta * __cos2th * __sin2th;
 
 #if _GLIBCXX_USE_C99_MATH_TR1
-      const _Tp __lg_b = std::tr1::lgamma(_Tp(__n) + __b);
-      const _Tp __lnfact = std::tr1::lgamma(_Tp(__n + 1));
+      const _Tp __lg_b = _GLIBCXX_MATH_NS::lgamma(_Tp(__n) + __b);
+      const _Tp __lnfact = _GLIBCXX_MATH_NS::lgamma(_Tp(__n + 1));
 #else
       const _Tp __lg_b = __log_gamma(_Tp(__n) + __b);
       const _Tp __lnfact = __log_gamma(_Tp(__n + 1));
@@ -312,8 +319,11 @@
     { return __poly_laguerre<unsigned int, _Tp>(__n, 0, __x); }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  } // namespace __detail
+#undef _GLIBCXX_MATH_NS
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_POLY_LAGUERRE_TCC
Index: include/tr1/riemann_zeta.tcc
===================================================================
--- include/tr1/riemann_zeta.tcc	(revision 230377)
+++ include/tr1/riemann_zeta.tcc	(working copy)
@@ -46,8 +46,15 @@
 
 namespace std _GLIBCXX_VISIBILITY(default)
 {
+#if __STDCPP_WANT_MATH_SPEC_FUNCS__
+# define _GLIBCXX_MATH_NS ::std
+#elif defined(_GLIBCXX_TR1_CMATH)
 namespace tr1
 {
+# define _GLIBCXX_MATH_NS ::std::tr1
+#else
+# error do not include this header directly, use <cmath> or <tr1/cmath>
+#endif
   // [5.2] Special functions
 
   // Implementation-space details.
@@ -163,7 +170,7 @@
       if (__s < _Tp(0))
         {
 #if _GLIBCXX_USE_C99_MATH_TR1
-          if (std::tr1::fmod(__s,_Tp(2)) == _Tp(0))
+          if (_GLIBCXX_MATH_NS::fmod(__s,_Tp(2)) == _Tp(0))
             return _Tp(0);
           else
 #endif
@@ -173,7 +180,7 @@
                      * __numeric_constants<_Tp>::__pi(), __s)
                      * std::sin(__numeric_constants<_Tp>::__pi_2() * __s)
 #if _GLIBCXX_USE_C99_MATH_TR1
-                     * std::exp(std::tr1::lgamma(_Tp(1) - __s))
+                     * std::exp(_GLIBCXX_MATH_NS::lgamma(_Tp(1) - __s))
 #else
                      * std::exp(__log_gamma(_Tp(1) - __s))
 #endif
@@ -192,9 +199,9 @@
           for (unsigned int __j = 0; __j <= __i; ++__j)
             {
 #if _GLIBCXX_USE_C99_MATH_TR1
-              _Tp __bincoeff =  std::tr1::lgamma(_Tp(1 + __i))
-                              - std::tr1::lgamma(_Tp(1 + __j))
-                              - std::tr1::lgamma(_Tp(1 + __i - __j));
+              _Tp __bincoeff =  _GLIBCXX_MATH_NS::lgamma(_Tp(1 + __i))
+                              - _GLIBCXX_MATH_NS::lgamma(_Tp(1 + __j))
+                              - _GLIBCXX_MATH_NS::lgamma(_Tp(1 + __i - __j));
 #else
               _Tp __bincoeff =  __log_gamma(_Tp(1 + __i))
                               - __log_gamma(_Tp(1 + __j))
@@ -297,7 +304,7 @@
           __zeta *= std::pow(_Tp(2) * __numeric_constants<_Tp>::__pi(), __s)
                  * std::sin(__numeric_constants<_Tp>::__pi_2() * __s)
 #if _GLIBCXX_USE_C99_MATH_TR1
-                 * std::exp(std::tr1::lgamma(_Tp(1) - __s))
+                 * std::exp(_GLIBCXX_MATH_NS::lgamma(_Tp(1) - __s))
 #else
                  * std::exp(__log_gamma(_Tp(1) - __s))
 #endif
@@ -320,7 +327,7 @@
                                 * __numeric_constants<_Tp>::__pi(), __s)
                          * std::sin(__numeric_constants<_Tp>::__pi_2() * __s)
 #if _GLIBCXX_USE_C99_MATH_TR1
-                             * std::tr1::tgamma(_Tp(1) - __s)
+                             * _GLIBCXX_MATH_NS::tgamma(_Tp(1) - __s)
 #else
                              * std::exp(__log_gamma(_Tp(1) - __s))
 #endif
@@ -375,9 +382,9 @@
           for (unsigned int __j = 0; __j <= __i; ++__j)
             {
 #if _GLIBCXX_USE_C99_MATH_TR1
-              _Tp __bincoeff =  std::tr1::lgamma(_Tp(1 + __i))
-                              - std::tr1::lgamma(_Tp(1 + __j))
-                              - std::tr1::lgamma(_Tp(1 + __i - __j));
+              _Tp __bincoeff =  _GLIBCXX_MATH_NS::lgamma(_Tp(1 + __i))
+                              - _GLIBCXX_MATH_NS::lgamma(_Tp(1 + __j))
+                              - _GLIBCXX_MATH_NS::lgamma(_Tp(1 + __i - __j));
 #else
               _Tp __bincoeff =  __log_gamma(_Tp(1 + __i))
                               - __log_gamma(_Tp(1 + __j))
@@ -426,8 +433,11 @@
     { return __hurwitz_zeta_glob(__a, __s); }
 
   _GLIBCXX_END_NAMESPACE_VERSION
-  } // namespace std::tr1::__detail
+  } // namespace __detail
+#undef _GLIBCXX_MATH_NS
+#if ! __STDCPP_WANT_MATH_SPEC_FUNCS__ && defined(_GLIBCXX_TR1_CMATH)
+} // namespace tr1
+#endif
 }
-}
 
 #endif // _GLIBCXX_TR1_RIEMANN_ZETA_TCC
Index: testsuite/libstdc++-dg/conformance.exp
===================================================================
--- testsuite/libstdc++-dg/conformance.exp	(revision 230377)
+++ testsuite/libstdc++-dg/conformance.exp	(working copy)
@@ -61,6 +61,7 @@
     lappend subdirs "$srcdir/tr2"
     lappend subdirs "$srcdir/decimal"
     lappend subdirs "$srcdir/experimental"
+    lappend subdirs "$srcdir/special_functions"
     verbose "subdirs are $subdirs"
 
     # Find all the tests.
Index: testsuite/special_functions/01_assoc_laguerre/check_nan.cc
===================================================================
--- testsuite/special_functions/01_assoc_laguerre/check_nan.cc	(revision 0)
+++ testsuite/special_functions/01_assoc_laguerre/check_nan.cc	(working copy)
@@ -0,0 +1,58 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.1 assoc_laguerre
+
+#include <cmath>
+#include <limits>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  bool test [[gnu::unused]] = true;
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+  unsigned int n = 2, m = 1;
+
+  float a = std::assoc_laguerre(n, m, xf);
+  float b = std::assoc_laguerref(n, m, xf);
+  double c = std::assoc_laguerre(n, m, xd);
+  long double d = std::assoc_laguerre(n, m, xl);
+  long double e = std::assoc_laguerrel(n, m, xl);
+
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/01_assoc_laguerre/check_value.cc
===================================================================
--- testsuite/special_functions/01_assoc_laguerre/check_value.cc	(revision 0)
+++ testsuite/special_functions/01_assoc_laguerre/check_value.cc	(working copy)
@@ -0,0 +1,3692 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  assoc_laguerre
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for n=0, m=0.
+testcase_assoc_laguerre<double> data001[] = {
+  { 1.0000000000000000, 0, 0, 
+	  0.0000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  10.000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  20.000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  30.000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  40.000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  50.000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  60.000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  70.000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  80.000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  90.000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  100.00000000000000 },
+};
+
+// Test function for n=0, m=0.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data001[i].n), Tp(data001[i].m),
+		     Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=0, m=1.
+testcase_assoc_laguerre<double> data002[] = {
+  { 1.0000000000000000, 0, 1, 
+	  0.0000000000000000 },
+  { 1.0000000000000000, 0, 1, 
+	  10.000000000000000 },
+  { 1.0000000000000000, 0, 1, 
+	  20.000000000000000 },
+  { 1.0000000000000000, 0, 1, 
+	  30.000000000000000 },
+  { 1.0000000000000000, 0, 1, 
+	  40.000000000000000 },
+  { 1.0000000000000000, 0, 1, 
+	  50.000000000000000 },
+  { 1.0000000000000000, 0, 1, 
+	  60.000000000000000 },
+  { 1.0000000000000000, 0, 1, 
+	  70.000000000000000 },
+  { 1.0000000000000000, 0, 1, 
+	  80.000000000000000 },
+  { 1.0000000000000000, 0, 1, 
+	  90.000000000000000 },
+  { 1.0000000000000000, 0, 1, 
+	  100.00000000000000 },
+};
+
+// Test function for n=0, m=1.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data002[i].n), Tp(data002[i].m),
+		     Tp(data002[i].x));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=0, m=2.
+testcase_assoc_laguerre<double> data003[] = {
+  { 1.0000000000000000, 0, 2, 
+	  0.0000000000000000 },
+  { 1.0000000000000000, 0, 2, 
+	  10.000000000000000 },
+  { 1.0000000000000000, 0, 2, 
+	  20.000000000000000 },
+  { 1.0000000000000000, 0, 2, 
+	  30.000000000000000 },
+  { 1.0000000000000000, 0, 2, 
+	  40.000000000000000 },
+  { 1.0000000000000000, 0, 2, 
+	  50.000000000000000 },
+  { 1.0000000000000000, 0, 2, 
+	  60.000000000000000 },
+  { 1.0000000000000000, 0, 2, 
+	  70.000000000000000 },
+  { 1.0000000000000000, 0, 2, 
+	  80.000000000000000 },
+  { 1.0000000000000000, 0, 2, 
+	  90.000000000000000 },
+  { 1.0000000000000000, 0, 2, 
+	  100.00000000000000 },
+};
+
+// Test function for n=0, m=2.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data003[i].n), Tp(data003[i].m),
+		     Tp(data003[i].x));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=0, m=5.
+testcase_assoc_laguerre<double> data004[] = {
+  { 1.0000000000000000, 0, 5, 
+	  0.0000000000000000 },
+  { 1.0000000000000000, 0, 5, 
+	  10.000000000000000 },
+  { 1.0000000000000000, 0, 5, 
+	  20.000000000000000 },
+  { 1.0000000000000000, 0, 5, 
+	  30.000000000000000 },
+  { 1.0000000000000000, 0, 5, 
+	  40.000000000000000 },
+  { 1.0000000000000000, 0, 5, 
+	  50.000000000000000 },
+  { 1.0000000000000000, 0, 5, 
+	  60.000000000000000 },
+  { 1.0000000000000000, 0, 5, 
+	  70.000000000000000 },
+  { 1.0000000000000000, 0, 5, 
+	  80.000000000000000 },
+  { 1.0000000000000000, 0, 5, 
+	  90.000000000000000 },
+  { 1.0000000000000000, 0, 5, 
+	  100.00000000000000 },
+};
+
+// Test function for n=0, m=5.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data004[i].n), Tp(data004[i].m),
+		     Tp(data004[i].x));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=0, m=10.
+testcase_assoc_laguerre<double> data005[] = {
+  { 1.0000000000000000, 0, 10, 
+	  0.0000000000000000 },
+  { 1.0000000000000000, 0, 10, 
+	  10.000000000000000 },
+  { 1.0000000000000000, 0, 10, 
+	  20.000000000000000 },
+  { 1.0000000000000000, 0, 10, 
+	  30.000000000000000 },
+  { 1.0000000000000000, 0, 10, 
+	  40.000000000000000 },
+  { 1.0000000000000000, 0, 10, 
+	  50.000000000000000 },
+  { 1.0000000000000000, 0, 10, 
+	  60.000000000000000 },
+  { 1.0000000000000000, 0, 10, 
+	  70.000000000000000 },
+  { 1.0000000000000000, 0, 10, 
+	  80.000000000000000 },
+  { 1.0000000000000000, 0, 10, 
+	  90.000000000000000 },
+  { 1.0000000000000000, 0, 10, 
+	  100.00000000000000 },
+};
+
+// Test function for n=0, m=10.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data005[i].n), Tp(data005[i].m),
+		     Tp(data005[i].x));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=0, m=20.
+testcase_assoc_laguerre<double> data006[] = {
+  { 1.0000000000000000, 0, 20, 
+	  0.0000000000000000 },
+  { 1.0000000000000000, 0, 20, 
+	  10.000000000000000 },
+  { 1.0000000000000000, 0, 20, 
+	  20.000000000000000 },
+  { 1.0000000000000000, 0, 20, 
+	  30.000000000000000 },
+  { 1.0000000000000000, 0, 20, 
+	  40.000000000000000 },
+  { 1.0000000000000000, 0, 20, 
+	  50.000000000000000 },
+  { 1.0000000000000000, 0, 20, 
+	  60.000000000000000 },
+  { 1.0000000000000000, 0, 20, 
+	  70.000000000000000 },
+  { 1.0000000000000000, 0, 20, 
+	  80.000000000000000 },
+  { 1.0000000000000000, 0, 20, 
+	  90.000000000000000 },
+  { 1.0000000000000000, 0, 20, 
+	  100.00000000000000 },
+};
+
+// Test function for n=0, m=20.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data006[i].n), Tp(data006[i].m),
+		     Tp(data006[i].x));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=0, m=50.
+testcase_assoc_laguerre<double> data007[] = {
+  { 1.0000000000000000, 0, 50, 
+	  0.0000000000000000 },
+  { 1.0000000000000000, 0, 50, 
+	  10.000000000000000 },
+  { 1.0000000000000000, 0, 50, 
+	  20.000000000000000 },
+  { 1.0000000000000000, 0, 50, 
+	  30.000000000000000 },
+  { 1.0000000000000000, 0, 50, 
+	  40.000000000000000 },
+  { 1.0000000000000000, 0, 50, 
+	  50.000000000000000 },
+  { 1.0000000000000000, 0, 50, 
+	  60.000000000000000 },
+  { 1.0000000000000000, 0, 50, 
+	  70.000000000000000 },
+  { 1.0000000000000000, 0, 50, 
+	  80.000000000000000 },
+  { 1.0000000000000000, 0, 50, 
+	  90.000000000000000 },
+  { 1.0000000000000000, 0, 50, 
+	  100.00000000000000 },
+};
+
+// Test function for n=0, m=50.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data007[i].n), Tp(data007[i].m),
+		     Tp(data007[i].x));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=0, m=100.
+testcase_assoc_laguerre<double> data008[] = {
+  { 1.0000000000000000, 0, 100, 
+	  0.0000000000000000 },
+  { 1.0000000000000000, 0, 100, 
+	  10.000000000000000 },
+  { 1.0000000000000000, 0, 100, 
+	  20.000000000000000 },
+  { 1.0000000000000000, 0, 100, 
+	  30.000000000000000 },
+  { 1.0000000000000000, 0, 100, 
+	  40.000000000000000 },
+  { 1.0000000000000000, 0, 100, 
+	  50.000000000000000 },
+  { 1.0000000000000000, 0, 100, 
+	  60.000000000000000 },
+  { 1.0000000000000000, 0, 100, 
+	  70.000000000000000 },
+  { 1.0000000000000000, 0, 100, 
+	  80.000000000000000 },
+  { 1.0000000000000000, 0, 100, 
+	  90.000000000000000 },
+  { 1.0000000000000000, 0, 100, 
+	  100.00000000000000 },
+};
+
+// Test function for n=0, m=100.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data008[i].n), Tp(data008[i].m),
+		     Tp(data008[i].x));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=1, m=0.
+testcase_assoc_laguerre<double> data009[] = {
+  { 1.0000000000000000, 1, 0, 
+	  0.0000000000000000 },
+  { -9.0000000000000000, 1, 0, 
+	  10.000000000000000 },
+  { -19.000000000000000, 1, 0, 
+	  20.000000000000000 },
+  { -29.000000000000000, 1, 0, 
+	  30.000000000000000 },
+  { -39.000000000000000, 1, 0, 
+	  40.000000000000000 },
+  { -49.000000000000000, 1, 0, 
+	  50.000000000000000 },
+  { -59.000000000000000, 1, 0, 
+	  60.000000000000000 },
+  { -69.000000000000000, 1, 0, 
+	  70.000000000000000 },
+  { -79.000000000000000, 1, 0, 
+	  80.000000000000000 },
+  { -89.000000000000000, 1, 0, 
+	  90.000000000000000 },
+  { -99.000000000000000, 1, 0, 
+	  100.00000000000000 },
+};
+
+// Test function for n=1, m=0.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data009[i].n), Tp(data009[i].m),
+		     Tp(data009[i].x));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=1, m=1.
+testcase_assoc_laguerre<double> data010[] = {
+  { 2.0000000000000000, 1, 1, 
+	  0.0000000000000000 },
+  { -8.0000000000000000, 1, 1, 
+	  10.000000000000000 },
+  { -18.000000000000000, 1, 1, 
+	  20.000000000000000 },
+  { -28.000000000000000, 1, 1, 
+	  30.000000000000000 },
+  { -38.000000000000000, 1, 1, 
+	  40.000000000000000 },
+  { -48.000000000000000, 1, 1, 
+	  50.000000000000000 },
+  { -58.000000000000000, 1, 1, 
+	  60.000000000000000 },
+  { -68.000000000000000, 1, 1, 
+	  70.000000000000000 },
+  { -78.000000000000000, 1, 1, 
+	  80.000000000000000 },
+  { -88.000000000000000, 1, 1, 
+	  90.000000000000000 },
+  { -98.000000000000000, 1, 1, 
+	  100.00000000000000 },
+};
+
+// Test function for n=1, m=1.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data010[i].n), Tp(data010[i].m),
+		     Tp(data010[i].x));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=1, m=2.
+testcase_assoc_laguerre<double> data011[] = {
+  { 3.0000000000000000, 1, 2, 
+	  0.0000000000000000 },
+  { -7.0000000000000000, 1, 2, 
+	  10.000000000000000 },
+  { -17.000000000000000, 1, 2, 
+	  20.000000000000000 },
+  { -27.000000000000000, 1, 2, 
+	  30.000000000000000 },
+  { -37.000000000000000, 1, 2, 
+	  40.000000000000000 },
+  { -47.000000000000000, 1, 2, 
+	  50.000000000000000 },
+  { -57.000000000000000, 1, 2, 
+	  60.000000000000000 },
+  { -67.000000000000000, 1, 2, 
+	  70.000000000000000 },
+  { -77.000000000000000, 1, 2, 
+	  80.000000000000000 },
+  { -87.000000000000000, 1, 2, 
+	  90.000000000000000 },
+  { -97.000000000000000, 1, 2, 
+	  100.00000000000000 },
+};
+
+// Test function for n=1, m=2.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data011[i].n), Tp(data011[i].m),
+		     Tp(data011[i].x));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=1, m=5.
+testcase_assoc_laguerre<double> data012[] = {
+  { 6.0000000000000000, 1, 5, 
+	  0.0000000000000000 },
+  { -4.0000000000000000, 1, 5, 
+	  10.000000000000000 },
+  { -14.000000000000000, 1, 5, 
+	  20.000000000000000 },
+  { -24.000000000000000, 1, 5, 
+	  30.000000000000000 },
+  { -34.000000000000000, 1, 5, 
+	  40.000000000000000 },
+  { -44.000000000000000, 1, 5, 
+	  50.000000000000000 },
+  { -54.000000000000000, 1, 5, 
+	  60.000000000000000 },
+  { -64.000000000000000, 1, 5, 
+	  70.000000000000000 },
+  { -74.000000000000000, 1, 5, 
+	  80.000000000000000 },
+  { -84.000000000000000, 1, 5, 
+	  90.000000000000000 },
+  { -94.000000000000000, 1, 5, 
+	  100.00000000000000 },
+};
+
+// Test function for n=1, m=5.
+template<typename Tp>
+  void
+  test012()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data012)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data012[i].n), Tp(data012[i].m),
+		     Tp(data012[i].x));
+	const Tp f0 = data012[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=1, m=10.
+testcase_assoc_laguerre<double> data013[] = {
+  { 11.000000000000000, 1, 10, 
+	  0.0000000000000000 },
+  { 1.0000000000000000, 1, 10, 
+	  10.000000000000000 },
+  { -9.0000000000000000, 1, 10, 
+	  20.000000000000000 },
+  { -19.000000000000000, 1, 10, 
+	  30.000000000000000 },
+  { -29.000000000000000, 1, 10, 
+	  40.000000000000000 },
+  { -39.000000000000000, 1, 10, 
+	  50.000000000000000 },
+  { -49.000000000000000, 1, 10, 
+	  60.000000000000000 },
+  { -59.000000000000000, 1, 10, 
+	  70.000000000000000 },
+  { -69.000000000000000, 1, 10, 
+	  80.000000000000000 },
+  { -79.000000000000000, 1, 10, 
+	  90.000000000000000 },
+  { -89.000000000000000, 1, 10, 
+	  100.00000000000000 },
+};
+
+// Test function for n=1, m=10.
+template<typename Tp>
+  void
+  test013()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data013)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data013[i].n), Tp(data013[i].m),
+		     Tp(data013[i].x));
+	const Tp f0 = data013[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=1, m=20.
+testcase_assoc_laguerre<double> data014[] = {
+  { 21.000000000000000, 1, 20, 
+	  0.0000000000000000 },
+  { 11.000000000000000, 1, 20, 
+	  10.000000000000000 },
+  { 1.0000000000000000, 1, 20, 
+	  20.000000000000000 },
+  { -9.0000000000000000, 1, 20, 
+	  30.000000000000000 },
+  { -19.000000000000000, 1, 20, 
+	  40.000000000000000 },
+  { -29.000000000000000, 1, 20, 
+	  50.000000000000000 },
+  { -39.000000000000000, 1, 20, 
+	  60.000000000000000 },
+  { -49.000000000000000, 1, 20, 
+	  70.000000000000000 },
+  { -59.000000000000000, 1, 20, 
+	  80.000000000000000 },
+  { -69.000000000000000, 1, 20, 
+	  90.000000000000000 },
+  { -79.000000000000000, 1, 20, 
+	  100.00000000000000 },
+};
+
+// Test function for n=1, m=20.
+template<typename Tp>
+  void
+  test014()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data014)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data014[i].n), Tp(data014[i].m),
+		     Tp(data014[i].x));
+	const Tp f0 = data014[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=1, m=50.
+testcase_assoc_laguerre<double> data015[] = {
+  { 51.000000000000000, 1, 50, 
+	  0.0000000000000000 },
+  { 41.000000000000000, 1, 50, 
+	  10.000000000000000 },
+  { 31.000000000000000, 1, 50, 
+	  20.000000000000000 },
+  { 21.000000000000000, 1, 50, 
+	  30.000000000000000 },
+  { 11.000000000000000, 1, 50, 
+	  40.000000000000000 },
+  { 1.0000000000000000, 1, 50, 
+	  50.000000000000000 },
+  { -9.0000000000000000, 1, 50, 
+	  60.000000000000000 },
+  { -19.000000000000000, 1, 50, 
+	  70.000000000000000 },
+  { -29.000000000000000, 1, 50, 
+	  80.000000000000000 },
+  { -39.000000000000000, 1, 50, 
+	  90.000000000000000 },
+  { -49.000000000000000, 1, 50, 
+	  100.00000000000000 },
+};
+
+// Test function for n=1, m=50.
+template<typename Tp>
+  void
+  test015()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data015)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data015[i].n), Tp(data015[i].m),
+		     Tp(data015[i].x));
+	const Tp f0 = data015[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=1, m=100.
+testcase_assoc_laguerre<double> data016[] = {
+  { 101.00000000000000, 1, 100, 
+	  0.0000000000000000 },
+  { 91.000000000000000, 1, 100, 
+	  10.000000000000000 },
+  { 81.000000000000000, 1, 100, 
+	  20.000000000000000 },
+  { 71.000000000000000, 1, 100, 
+	  30.000000000000000 },
+  { 61.000000000000000, 1, 100, 
+	  40.000000000000000 },
+  { 51.000000000000000, 1, 100, 
+	  50.000000000000000 },
+  { 41.000000000000000, 1, 100, 
+	  60.000000000000000 },
+  { 31.000000000000000, 1, 100, 
+	  70.000000000000000 },
+  { 21.000000000000000, 1, 100, 
+	  80.000000000000000 },
+  { 11.000000000000000, 1, 100, 
+	  90.000000000000000 },
+  { 1.0000000000000000, 1, 100, 
+	  100.00000000000000 },
+};
+
+// Test function for n=1, m=100.
+template<typename Tp>
+  void
+  test016()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data016)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data016[i].n), Tp(data016[i].m),
+		     Tp(data016[i].x));
+	const Tp f0 = data016[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=2, m=0.
+testcase_assoc_laguerre<double> data017[] = {
+  { 1.0000000000000000, 2, 0, 
+	  0.0000000000000000 },
+  { 31.000000000000000, 2, 0, 
+	  10.000000000000000 },
+  { 161.00000000000000, 2, 0, 
+	  20.000000000000000 },
+  { 391.00000000000000, 2, 0, 
+	  30.000000000000000 },
+  { 721.00000000000000, 2, 0, 
+	  40.000000000000000 },
+  { 1151.0000000000000, 2, 0, 
+	  50.000000000000000 },
+  { 1681.0000000000000, 2, 0, 
+	  60.000000000000000 },
+  { 2311.0000000000000, 2, 0, 
+	  70.000000000000000 },
+  { 3041.0000000000000, 2, 0, 
+	  80.000000000000000 },
+  { 3871.0000000000000, 2, 0, 
+	  90.000000000000000 },
+  { 4801.0000000000000, 2, 0, 
+	  100.00000000000000 },
+};
+
+// Test function for n=2, m=0.
+template<typename Tp>
+  void
+  test017()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data017)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data017[i].n), Tp(data017[i].m),
+		     Tp(data017[i].x));
+	const Tp f0 = data017[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=2, m=1.
+testcase_assoc_laguerre<double> data018[] = {
+  { 3.0000000000000000, 2, 1, 
+	  0.0000000000000000 },
+  { 23.000000000000000, 2, 1, 
+	  10.000000000000000 },
+  { 143.00000000000000, 2, 1, 
+	  20.000000000000000 },
+  { 363.00000000000000, 2, 1, 
+	  30.000000000000000 },
+  { 683.00000000000000, 2, 1, 
+	  40.000000000000000 },
+  { 1103.0000000000000, 2, 1, 
+	  50.000000000000000 },
+  { 1623.0000000000000, 2, 1, 
+	  60.000000000000000 },
+  { 2243.0000000000000, 2, 1, 
+	  70.000000000000000 },
+  { 2963.0000000000000, 2, 1, 
+	  80.000000000000000 },
+  { 3783.0000000000000, 2, 1, 
+	  90.000000000000000 },
+  { 4703.0000000000000, 2, 1, 
+	  100.00000000000000 },
+};
+
+// Test function for n=2, m=1.
+template<typename Tp>
+  void
+  test018()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data018)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data018[i].n), Tp(data018[i].m),
+		     Tp(data018[i].x));
+	const Tp f0 = data018[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=2, m=2.
+testcase_assoc_laguerre<double> data019[] = {
+  { 6.0000000000000000, 2, 2, 
+	  0.0000000000000000 },
+  { 16.000000000000000, 2, 2, 
+	  10.000000000000000 },
+  { 126.00000000000000, 2, 2, 
+	  20.000000000000000 },
+  { 336.00000000000000, 2, 2, 
+	  30.000000000000000 },
+  { 646.00000000000000, 2, 2, 
+	  40.000000000000000 },
+  { 1056.0000000000000, 2, 2, 
+	  50.000000000000000 },
+  { 1566.0000000000000, 2, 2, 
+	  60.000000000000000 },
+  { 2176.0000000000000, 2, 2, 
+	  70.000000000000000 },
+  { 2886.0000000000000, 2, 2, 
+	  80.000000000000000 },
+  { 3696.0000000000000, 2, 2, 
+	  90.000000000000000 },
+  { 4606.0000000000000, 2, 2, 
+	  100.00000000000000 },
+};
+
+// Test function for n=2, m=2.
+template<typename Tp>
+  void
+  test019()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data019)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data019[i].n), Tp(data019[i].m),
+		     Tp(data019[i].x));
+	const Tp f0 = data019[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=2, m=5.
+testcase_assoc_laguerre<double> data020[] = {
+  { 21.000000000000000, 2, 5, 
+	  0.0000000000000000 },
+  { 0.99999999999999545, 2, 5, 
+	  10.000000000000000 },
+  { 81.000000000000000, 2, 5, 
+	  20.000000000000000 },
+  { 261.00000000000000, 2, 5, 
+	  30.000000000000000 },
+  { 541.00000000000000, 2, 5, 
+	  40.000000000000000 },
+  { 921.00000000000000, 2, 5, 
+	  50.000000000000000 },
+  { 1401.0000000000000, 2, 5, 
+	  60.000000000000000 },
+  { 1981.0000000000000, 2, 5, 
+	  70.000000000000000 },
+  { 2661.0000000000000, 2, 5, 
+	  80.000000000000000 },
+  { 3441.0000000000000, 2, 5, 
+	  90.000000000000000 },
+  { 4321.0000000000000, 2, 5, 
+	  100.00000000000000 },
+};
+
+// Test function for n=2, m=5.
+template<typename Tp>
+  void
+  test020()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data020)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data020[i].n), Tp(data020[i].m),
+		     Tp(data020[i].x));
+	const Tp f0 = data020[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=2, m=10.
+testcase_assoc_laguerre<double> data021[] = {
+  { 66.000000000000000, 2, 10, 
+	  0.0000000000000000 },
+  { -4.0000000000000098, 2, 10, 
+	  10.000000000000000 },
+  { 25.999999999999964, 2, 10, 
+	  20.000000000000000 },
+  { 156.00000000000000, 2, 10, 
+	  30.000000000000000 },
+  { 386.00000000000000, 2, 10, 
+	  40.000000000000000 },
+  { 716.00000000000000, 2, 10, 
+	  50.000000000000000 },
+  { 1146.0000000000000, 2, 10, 
+	  60.000000000000000 },
+  { 1676.0000000000000, 2, 10, 
+	  70.000000000000000 },
+  { 2306.0000000000000, 2, 10, 
+	  80.000000000000000 },
+  { 3036.0000000000000, 2, 10, 
+	  90.000000000000000 },
+  { 3866.0000000000000, 2, 10, 
+	  100.00000000000000 },
+};
+
+// Test function for n=2, m=10.
+template<typename Tp>
+  void
+  test021()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data021)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data021[i].n), Tp(data021[i].m),
+		     Tp(data021[i].x));
+	const Tp f0 = data021[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=2, m=20.
+testcase_assoc_laguerre<double> data022[] = {
+  { 231.00000000000000, 2, 20, 
+	  0.0000000000000000 },
+  { 61.000000000000206, 2, 20, 
+	  10.000000000000000 },
+  { -9.0000000000000053, 2, 20, 
+	  20.000000000000000 },
+  { 21.000000000000124, 2, 20, 
+	  30.000000000000000 },
+  { 151.00000000000057, 2, 20, 
+	  40.000000000000000 },
+  { 381.00000000000000, 2, 20, 
+	  50.000000000000000 },
+  { 711.00000000000000, 2, 20, 
+	  60.000000000000000 },
+  { 1141.0000000000000, 2, 20, 
+	  70.000000000000000 },
+  { 1670.9999999999998, 2, 20, 
+	  80.000000000000000 },
+  { 2301.0000000000000, 2, 20, 
+	  90.000000000000000 },
+  { 3031.0000000000000, 2, 20, 
+	  100.00000000000000 },
+};
+
+// Test function for n=2, m=20.
+template<typename Tp>
+  void
+  test022()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data022)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data022[i].n), Tp(data022[i].m),
+		     Tp(data022[i].x));
+	const Tp f0 = data022[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=2, m=50.
+testcase_assoc_laguerre<double> data023[] = {
+  { 1326.0000000000000, 2, 50, 
+	  0.0000000000000000 },
+  { 855.99999999999693, 2, 50, 
+	  10.000000000000000 },
+  { 485.99999999999835, 2, 50, 
+	  20.000000000000000 },
+  { 215.99999999999937, 2, 50, 
+	  30.000000000000000 },
+  { 45.999999999999829, 2, 50, 
+	  40.000000000000000 },
+  { -23.999999999999538, 2, 50, 
+	  50.000000000000000 },
+  { 6.0000000000001057, 2, 50, 
+	  60.000000000000000 },
+  { 135.99999999999963, 2, 50, 
+	  70.000000000000000 },
+  { 365.99999999999892, 2, 50, 
+	  80.000000000000000 },
+  { 695.99999999999784, 2, 50, 
+	  90.000000000000000 },
+  { 1125.9999999999964, 2, 50, 
+	  100.00000000000000 },
+};
+
+// Test function for n=2, m=50.
+template<typename Tp>
+  void
+  test023()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data023)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data023[i].n), Tp(data023[i].m),
+		     Tp(data023[i].x));
+	const Tp f0 = data023[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for n=2, m=100.
+testcase_assoc_laguerre<double> data024[] = {
+  { 5151.0000000000000, 2, 100, 
+	  0.0000000000000000 },
+  { 4181.0000000000655, 2, 100, 
+	  10.000000000000000 },
+  { 3311.0000000000518, 2, 100, 
+	  20.000000000000000 },
+  { 2541.0000000000400, 2, 100, 
+	  30.000000000000000 },
+  { 1871.0000000000291, 2, 100, 
+	  40.000000000000000 },
+  { 1301.0000000000207, 2, 100, 
+	  50.000000000000000 },
+  { 831.00000000001364, 2, 100, 
+	  60.000000000000000 },
+  { 461.00000000000682, 2, 100, 
+	  70.000000000000000 },
+  { 191.00000000000250, 2, 100, 
+	  80.000000000000000 },
+  { 21.000000000000046, 2, 100, 
+	  90.000000000000000 },
+  { -48.999999999999915, 2, 100, 
+	  100.00000000000000 },
+};
+
+// Test function for n=2, m=100.
+template<typename Tp>
+  void
+  test024()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data024)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data024[i].n), Tp(data024[i].m),
+		     Tp(data024[i].x));
+	const Tp f0 = data024[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for n=5, m=0.
+testcase_assoc_laguerre<double> data025[] = {
+  { 1.0000000000000000, 5, 0, 
+	  0.0000000000000000 },
+  { 34.333333333333329, 5, 0, 
+	  10.000000000000000 },
+  { -4765.6666666666670, 5, 0, 
+	  20.000000000000000 },
+  { -74399.000000000000, 5, 0, 
+	  30.000000000000000 },
+  { -418865.66666666663, 5, 0, 
+	  40.000000000000000 },
+  { -1498165.6666666665, 5, 0, 
+	  50.000000000000000 },
+  { -4122299.0000000000, 5, 0, 
+	  60.000000000000000 },
+  { -9551265.6666666679, 5, 0, 
+	  70.000000000000000 },
+  { -19595065.666666664, 5, 0, 
+	  80.000000000000000 },
+  { -36713699.000000000, 5, 0, 
+	  90.000000000000000 },
+  { -64117165.666666664, 5, 0, 
+	  100.00000000000000 },
+};
+
+// Test function for n=5, m=0.
+template<typename Tp>
+  void
+  test025()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data025)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data025[i].n), Tp(data025[i].m),
+		     Tp(data025[i].x));
+	const Tp f0 = data025[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=5, m=1.
+testcase_assoc_laguerre<double> data026[] = {
+  { 6.0000000000000000, 5, 1, 
+	  0.0000000000000000 },
+  { 22.666666666666661, 5, 1, 
+	  10.000000000000000 },
+  { -2960.6666666666661, 5, 1, 
+	  20.000000000000000 },
+  { -58944.000000000000, 5, 1, 
+	  30.000000000000000 },
+  { -357927.33333333326, 5, 1, 
+	  40.000000000000000 },
+  { -1329910.6666666665, 5, 1, 
+	  50.000000000000000 },
+  { -3744894.0000000000, 5, 1, 
+	  60.000000000000000 },
+  { -8812877.3333333321, 5, 1, 
+	  70.000000000000000 },
+  { -18283860.666666664, 5, 1, 
+	  80.000000000000000 },
+  { -34547844.000000000, 5, 1, 
+	  90.000000000000000 },
+  { -60734827.333333336, 5, 1, 
+	  100.00000000000000 },
+};
+
+// Test function for n=5, m=1.
+template<typename Tp>
+  void
+  test026()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data026)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data026[i].n), Tp(data026[i].m),
+		     Tp(data026[i].x));
+	const Tp f0 = data026[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=5, m=2.
+testcase_assoc_laguerre<double> data027[] = {
+  { 21.000000000000000, 5, 2, 
+	  0.0000000000000000 },
+  { 4.3333333333333339, 5, 2, 
+	  10.000000000000000 },
+  { -1679.0000000000000, 5, 2, 
+	  20.000000000000000 },
+  { -46029.000000000000, 5, 2, 
+	  30.000000000000000 },
+  { -304045.66666666669, 5, 2, 
+	  40.000000000000000 },
+  { -1176729.0000000002, 5, 2, 
+	  50.000000000000000 },
+  { -3395079.0000000000, 5, 2, 
+	  60.000000000000000 },
+  { -8120095.6666666660, 5, 2, 
+	  70.000000000000000 },
+  { -17042778.999999996, 5, 2, 
+	  80.000000000000000 },
+  { -32484129.000000000, 5, 2, 
+	  90.000000000000000 },
+  { -57495145.666666664, 5, 2, 
+	  100.00000000000000 },
+};
+
+// Test function for n=5, m=2.
+template<typename Tp>
+  void
+  test027()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data027)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data027[i].n), Tp(data027[i].m),
+		     Tp(data027[i].x));
+	const Tp f0 = data027[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=5, m=5.
+testcase_assoc_laguerre<double> data028[] = {
+  { 252.00000000000000, 5, 5, 
+	  0.0000000000000000 },
+  { -14.666666666666654, 5, 5, 
+	  10.000000000000000 },
+  { 51.999999999999908, 5, 5, 
+	  20.000000000000000 },
+  { -19548.000000000000, 5, 5, 
+	  30.000000000000000 },
+  { -178814.66666666660, 5, 5, 
+	  40.000000000000000 },
+  { -797747.99999999977, 5, 5, 
+	  50.000000000000000 },
+  { -2496348.0000000000, 5, 5, 
+	  60.000000000000000 },
+  { -6294614.6666666660, 5, 5, 
+	  70.000000000000000 },
+  { -13712547.999999996, 5, 5, 
+	  80.000000000000000 },
+  { -26870147.999999993, 5, 5, 
+	  90.000000000000000 },
+  { -48587414.666666672, 5, 5, 
+	  100.00000000000000 },
+};
+
+// Test function for n=5, m=5.
+template<typename Tp>
+  void
+  test028()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data028)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data028[i].n), Tp(data028[i].m),
+		     Tp(data028[i].x));
+	const Tp f0 = data028[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=5, m=10.
+testcase_assoc_laguerre<double> data029[] = {
+  { 3003.0000000000000, 5, 10, 
+	  0.0000000000000000 },
+  { 19.666666666666668, 5, 10, 
+	  10.000000000000000 },
+  { 36.333333333333272, 5, 10, 
+	  20.000000000000000 },
+  { -1947.0000000000000, 5, 10, 
+	  30.000000000000000 },
+  { -60930.333333333314, 5, 10, 
+	  40.000000000000000 },
+  { -381913.66666666651, 5, 10, 
+	  50.000000000000000 },
+  { -1419897.0000000000, 5, 10, 
+	  60.000000000000000 },
+  { -3979880.3333333330, 5, 10, 
+	  70.000000000000000 },
+  { -9316863.6666666642, 5, 10, 
+	  80.000000000000000 },
+  { -19235847.000000000, 5, 10, 
+	  90.000000000000000 },
+  { -36191830.333333328, 5, 10, 
+	  100.00000000000000 },
+};
+
+// Test function for n=5, m=10.
+template<typename Tp>
+  void
+  test029()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data029)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data029[i].n), Tp(data029[i].m),
+		     Tp(data029[i].x));
+	const Tp f0 = data029[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=5, m=20.
+testcase_assoc_laguerre<double> data030[] = {
+  { 53130.000000000000, 5, 20, 
+	  0.0000000000000000 },
+  { 1213.3333333333335, 5, 20, 
+	  10.000000000000000 },
+  { 129.99999999999963, 5, 20, 
+	  20.000000000000000 },
+  { -119.99999999999974, 5, 20, 
+	  30.000000000000000 },
+  { 463.33333333333320, 5, 20, 
+	  40.000000000000000 },
+  { -48120.000000000015, 5, 20, 
+	  50.000000000000000 },
+  { -345870.00000000017, 5, 20, 
+	  60.000000000000000 },
+  { -1342786.6666666667, 5, 20, 
+	  70.000000000000000 },
+  { -3838870.0000000009, 5, 20, 
+	  80.000000000000000 },
+  { -9084120.0000000000, 5, 20, 
+	  90.000000000000000 },
+  { -18878536.666666668, 5, 20, 
+	  100.00000000000000 },
+};
+
+// Test function for n=5, m=20.
+template<typename Tp>
+  void
+  test030()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data030)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data030[i].n), Tp(data030[i].m),
+		     Tp(data030[i].x));
+	const Tp f0 = data030[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=5, m=50.
+testcase_assoc_laguerre<double> data031[] = {
+  { 3478761.0000000000, 5, 50, 
+	  0.0000000000000000 },
+  { 1154544.3333333335, 5, 50, 
+	  10.000000000000000 },
+  { 264661.00000000006, 5, 50, 
+	  20.000000000000000 },
+  { 24111.000000000033, 5, 50, 
+	  30.000000000000000 },
+  { -2105.6666666666665, 5, 50, 
+	  40.000000000000000 },
+  { 1010.9999999999916, 5, 50, 
+	  50.000000000000000 },
+  { -1538.9999999999955, 5, 50, 
+	  60.000000000000000 },
+  { 5244.3333333333449, 5, 50, 
+	  70.000000000000000 },
+  { -13639.000000000011, 5, 50, 
+	  80.000000000000000 },
+  { -243189.00000000006, 5, 50, 
+	  90.000000000000000 },
+  { -1118405.6666666667, 5, 50, 
+	  100.00000000000000 },
+};
+
+// Test function for n=5, m=50.
+template<typename Tp>
+  void
+  test031()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data031)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data031[i].n), Tp(data031[i].m),
+		     Tp(data031[i].x));
+	const Tp f0 = data031[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=5, m=100.
+testcase_assoc_laguerre<double> data032[] = {
+  { 96560646.000000000, 5, 100, 
+	  0.0000000000000000 },
+  { 57264262.666666649, 5, 100, 
+	  10.000000000000000 },
+  { 31841379.333333332, 5, 100, 
+	  20.000000000000000 },
+  { 16281996.000000000, 5, 100, 
+	  30.000000000000000 },
+  { 7426112.6666666670, 5, 100, 
+	  40.000000000000000 },
+  { 2863729.3333333330, 5, 100, 
+	  50.000000000000000 },
+  { 834846.00000000000, 5, 100, 
+	  60.000000000000000 },
+  { 129462.66666666663, 5, 100, 
+	  70.000000000000000 },
+  { -12420.666666666668, 5, 100, 
+	  80.000000000000000 },
+  { -804.00000000000000, 5, 100, 
+	  90.000000000000000 },
+  { 4312.6666666666670, 5, 100, 
+	  100.00000000000000 },
+};
+
+// Test function for n=5, m=100.
+template<typename Tp>
+  void
+  test032()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data032)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data032[i].n), Tp(data032[i].m),
+		     Tp(data032[i].x));
+	const Tp f0 = data032[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=10, m=0.
+testcase_assoc_laguerre<double> data033[] = {
+  { 1.0000000000000000, 10, 0, 
+	  0.0000000000000000 },
+  { 27.984126984126977, 10, 0, 
+	  10.000000000000000 },
+  { 3227.8077601410932, 10, 0, 
+	  20.000000000000000 },
+  { 15129.571428571455, 10, 0, 
+	  30.000000000000000 },
+  { 79724066.608465582, 10, 0, 
+	  40.000000000000000 },
+  { 2037190065.3738980, 10, 0, 
+	  50.000000000000000 },
+  { 21804200401.000000, 10, 0, 
+	  60.000000000000000 },
+  { 144688291819.51855, 10, 0, 
+	  70.000000000000000 },
+  { 703324772760.08276, 10, 0, 
+	  80.000000000000000 },
+  { 2741055412243.8569, 10, 0, 
+	  90.000000000000000 },
+  { 9051283795429.5723, 10, 0, 
+	  100.00000000000000 },
+};
+
+// Test function for n=10, m=0.
+template<typename Tp>
+  void
+  test033()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data033)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data033[i].n), Tp(data033[i].m),
+		     Tp(data033[i].x));
+	const Tp f0 = data033[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=10, m=1.
+testcase_assoc_laguerre<double> data034[] = {
+  { 11.000000000000000, 10, 1, 
+	  0.0000000000000000 },
+  { 14.791887125220455, 10, 1, 
+	  10.000000000000000 },
+  { 2704.6507936507933, 10, 1, 
+	  20.000000000000000 },
+  { -182924.71428571423, 10, 1, 
+	  30.000000000000000 },
+  { 48066036.749559075, 10, 1, 
+	  40.000000000000000 },
+  { 1486264192.2169311, 10, 1, 
+	  50.000000000000000 },
+  { 17239562282.428574, 10, 1, 
+	  60.000000000000000 },
+  { 119837491630.13579, 10, 1, 
+	  70.000000000000000 },
+  { 600681375251.21167, 10, 1, 
+	  80.000000000000000 },
+  { 2392908405632.4287, 10, 1, 
+	  90.000000000000000 },
+  { 8033035722509.2373, 10, 1, 
+	  100.00000000000000 },
+};
+
+// Test function for n=10, m=1.
+template<typename Tp>
+  void
+  test034()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data034)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data034[i].n), Tp(data034[i].m),
+		     Tp(data034[i].x));
+	const Tp f0 = data034[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=10, m=2.
+testcase_assoc_laguerre<double> data035[] = {
+  { 66.000000000000000, 10, 2, 
+	  0.0000000000000000 },
+  { -14.511463844797181, 10, 2, 
+	  10.000000000000000 },
+  { 1064.5890652557316, 10, 2, 
+	  20.000000000000000 },
+  { -194569.71428571429, 10, 2, 
+	  30.000000000000000 },
+  { 27343569.350970022, 10, 2, 
+	  40.000000000000000 },
+  { 1067807661.6790125, 10, 2, 
+	  50.000000000000000 },
+  { 13529451580.285711, 10, 2, 
+	  60.000000000000000 },
+  { 98812724224.641937, 10, 2, 
+	  70.000000000000000 },
+  { 511482736187.34021, 10, 2, 
+	  80.000000000000000 },
+  { 2084478393087.4285, 10, 2, 
+	  90.000000000000000 },
+  { 7117724862237.0752, 10, 2, 
+	  100.00000000000000 },
+};
+
+// Test function for n=10, m=2.
+template<typename Tp>
+  void
+  test035()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data035)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data035[i].n), Tp(data035[i].m),
+		     Tp(data035[i].x));
+	const Tp f0 = data035[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=10, m=5.
+testcase_assoc_laguerre<double> data036[] = {
+  { 3003.0000000000000, 10, 5, 
+	  0.0000000000000000 },
+  { 11.641975308642031, 10, 5, 
+	  10.000000000000000 },
+  { -1137.5643738977069, 10, 5, 
+	  20.000000000000000 },
+  { -9254.1428571428605, 10, 5, 
+	  30.000000000000000 },
+  { 2121878.8377425023, 10, 5, 
+	  40.000000000000000 },
+  { 352060171.43033499, 10, 5, 
+	  50.000000000000000 },
+  { 6212028560.1428576, 10, 5, 
+	  60.000000000000000 },
+  { 53782171674.604919, 10, 5, 
+	  70.000000000000000 },
+  { 309720255837.56775, 10, 5, 
+	  80.000000000000000 },
+  { 1359043035731.5713, 10, 5, 
+	  90.000000000000000 },
+  { 4900625954398.9434, 10, 5, 
+	  100.00000000000000 },
+};
+
+// Test function for n=10, m=5.
+template<typename Tp>
+  void
+  test036()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data036)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data036[i].n), Tp(data036[i].m),
+		     Tp(data036[i].x));
+	const Tp f0 = data036[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=10, m=10.
+testcase_assoc_laguerre<double> data037[] = {
+  { 184756.00000000000, 10, 10, 
+	  0.0000000000000000 },
+  { -210.84303350970018, 10, 10, 
+	  10.000000000000000 },
+  { 508.38095238095184, 10, 10, 
+	  20.000000000000000 },
+  { 2098.8571428571431, 10, 10, 
+	  30.000000000000000 },
+  { -536338.88536155177, 10, 10, 
+	  40.000000000000000 },
+  { 24865988.804232784, 10, 10, 
+	  50.000000000000000 },
+  { 1343756013.1428571, 10, 10, 
+	  60.000000000000000 },
+  { 17298791247.358025, 10, 10, 
+	  70.000000000000000 },
+  { 124528450897.79892, 10, 10, 
+	  80.000000000000000 },
+  { 632674413641.71423, 10, 10, 
+	  90.000000000000000 },
+  { 2533008935405.0298, 10, 10, 
+	  100.00000000000000 },
+};
+
+// Test function for n=10, m=10.
+template<typename Tp>
+  void
+  test037()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data037)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data037[i].n), Tp(data037[i].m),
+		     Tp(data037[i].x));
+	const Tp f0 = data037[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=10, m=20.
+testcase_assoc_laguerre<double> data038[] = {
+  { 30045014.999999993, 10, 20, 
+	  0.0000000000000000 },
+  { -23087.733686067022, 10, 20, 
+	  10.000000000000000 },
+  { 207.23985890652330, 10, 20, 
+	  20.000000000000000 },
+  { 1407.8571428571508, 10, 20, 
+	  30.000000000000000 },
+  { -44618.156966490322, 10, 20, 
+	  40.000000000000000 },
+  { 158690.04409171100, 10, 20, 
+	  50.000000000000000 },
+  { -6870413.5714285728, 10, 20, 
+	  60.000000000000000 },
+  { 793841351.41975331, 10, 20, 
+	  70.000000000000000 },
+  { 13358288958.562618, 10, 20, 
+	  80.000000000000000 },
+  { 106073722407.85715, 10, 20, 
+	  90.000000000000000 },
+  { 566337213392.42493, 10, 20, 
+	  100.00000000000000 },
+};
+
+// Test function for n=10, m=20.
+template<typename Tp>
+  void
+  test038()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data038)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data038[i].n), Tp(data038[i].m),
+		     Tp(data038[i].x));
+	const Tp f0 = data038[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for n=10, m=50.
+testcase_assoc_laguerre<double> data039[] = {
+  { 75394027566.000000, 10, 50, 
+	  0.0000000000000000 },
+  { 8048106183.3721361, 10, 50, 
+	  10.000000000000000 },
+  { 328045023.84832460, 10, 50, 
+	  20.000000000000000 },
+  { -2568769.7142857178, 10, 50, 
+	  30.000000000000000 },
+  { 6971.9964726631533, 10, 50, 
+	  40.000000000000000 },
+  { 136111.41446207993, 10, 50, 
+	  50.000000000000000 },
+  { -62462.571428570242, 10, 50, 
+	  60.000000000000000 },
+  { -248167.95061728527, 10, 50, 
+	  70.000000000000000 },
+  { 1941270.4091710770, 10, 50, 
+	  80.000000000000000 },
+  { -8643512.5714285765, 10, 50, 
+	  90.000000000000000 },
+  { -140863522.18342152, 10, 50, 
+	  100.00000000000000 },
+};
+
+// Test function for n=10, m=50.
+template<typename Tp>
+  void
+  test039()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data039)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data039[i].n), Tp(data039[i].m),
+		     Tp(data039[i].x));
+	const Tp f0 = data039[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for n=10, m=100.
+testcase_assoc_laguerre<double> data040[] = {
+  { 46897636623981.000, 10, 100, 
+	  0.0000000000000000 },
+  { 16444031323272.084, 10, 100, 
+	  10.000000000000000 },
+  { 5020343986463.5391, 10, 100, 
+	  20.000000000000000 },
+  { 1270977490645.2859, 10, 100, 
+	  30.000000000000000 },
+  { 244835756822.62262, 10, 100, 
+	  40.000000000000000 },
+  { 29786827693.962959, 10, 100, 
+	  50.000000000000000 },
+  { 1127612095.2857144, 10, 100, 
+	  60.000000000000000 },
+  { -66370555.419753075, 10, 100, 
+	  70.000000000000000 },
+  { 10420852.957671870, 10, 100, 
+	  80.000000000000000 },
+  { -3373097.5714285718, 10, 100, 
+	  90.000000000000000 },
+  { 2065423.6807760145, 10, 100, 
+	  100.00000000000000 },
+};
+
+// Test function for n=10, m=100.
+template<typename Tp>
+  void
+  test040()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data040)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data040[i].n), Tp(data040[i].m),
+		     Tp(data040[i].x));
+	const Tp f0 = data040[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=20, m=0.
+testcase_assoc_laguerre<double> data041[] = {
+  { 1.0000000000000000, 20, 0, 
+	  0.0000000000000000 },
+  { -11.961333867812119, 20, 0, 
+	  10.000000000000000 },
+  { 2829.4728613531743, 20, 0, 
+	  20.000000000000000 },
+  { -18439.424502520938, 20, 0, 
+	  30.000000000000000 },
+  { 24799805.877530713, 20, 0, 
+	  40.000000000000000 },
+  { 7551960453.7672548, 20, 0, 
+	  50.000000000000000 },
+  { -1379223608444.9155, 20, 0, 
+	  60.000000000000000 },
+  { 165423821874449.94, 20, 0, 
+	  70.000000000000000 },
+  { 29500368536981676., 20, 0, 
+	  80.000000000000000 },
+  { 1.1292309514432901e+18, 20, 0, 
+	  90.000000000000000 },
+  { 2.2061882785931735e+19, 20, 0, 
+	  100.00000000000000 },
+};
+
+// Test function for n=20, m=0.
+template<typename Tp>
+  void
+  test041()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data041)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data041[i].n), Tp(data041[i].m),
+		     Tp(data041[i].x));
+	const Tp f0 = data041[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=20, m=1.
+testcase_assoc_laguerre<double> data042[] = {
+  { 21.000000000000000, 20, 1, 
+	  0.0000000000000000 },
+  { 19.900488129734079, 20, 1, 
+	  10.000000000000000 },
+  { 2208.0318569557585, 20, 1, 
+	  20.000000000000000 },
+  { 263690.96303121914, 20, 1, 
+	  30.000000000000000 },
+  { 40667285.630564235, 20, 1, 
+	  40.000000000000000 },
+  { 1737442572.8115399, 20, 1, 
+	  50.000000000000000 },
+  { -588280953643.28125, 20, 1, 
+	  60.000000000000000 },
+  { 45617733778241.328, 20, 1, 
+	  70.000000000000000 },
+  { 17293487114876864., 20, 1, 
+	  80.000000000000000 },
+  { 7.6219135858585062e+17, 20, 1, 
+	  90.000000000000000 },
+  { 1.6037288204336759e+19, 20, 1, 
+	  100.00000000000000 },
+};
+
+// Test function for n=20, m=1.
+template<typename Tp>
+  void
+  test042()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data042)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data042[i].n), Tp(data042[i].m),
+		     Tp(data042[i].x));
+	const Tp f0 = data042[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=20, m=2.
+testcase_assoc_laguerre<double> data043[] = {
+  { 231.00000000000003, 20, 2, 
+	  0.0000000000000000 },
+  { 47.009338065112921, 20, 2, 
+	  10.000000000000000 },
+  { -652.51305461728589, 20, 2, 
+	  20.000000000000000 },
+  { 285388.25895069109, 20, 2, 
+	  30.000000000000000 },
+  { 28664069.685624730, 20, 2, 
+	  40.000000000000000 },
+  { -1399631966.3144732, 20, 2, 
+	  50.000000000000000 },
+  { -115357373248.28194, 20, 2, 
+	  60.000000000000000 },
+  { -3357730872975.8750, 20, 2, 
+	  70.000000000000000 },
+  { 9765808962855122.0, 20, 2, 
+	  80.000000000000000 },
+  { 5.0717292945559181e+17, 20, 2, 
+	  90.000000000000000 },
+  { 1.1564665701334456e+19, 20, 2, 
+	  100.00000000000000 },
+};
+
+// Test function for n=20, m=2.
+template<typename Tp>
+  void
+  test043()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data043)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data043[i].n), Tp(data043[i].m),
+		     Tp(data043[i].x));
+	const Tp f0 = data043[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=20, m=5.
+testcase_assoc_laguerre<double> data044[] = {
+  { 53130.000000000000, 20, 5, 
+	  0.0000000000000000 },
+  { -158.69554500944142, 20, 5, 
+	  10.000000000000000 },
+  { 334.08012288038952, 20, 5, 
+	  20.000000000000000 },
+  { -198372.47662554163, 20, 5, 
+	  30.000000000000000 },
+  { -13627144.088579426, 20, 5, 
+	  40.000000000000000 },
+  { -780579985.44731510, 20, 5, 
+	  50.000000000000000 },
+  { 116648634237.73535, 20, 5, 
+	  60.000000000000000 },
+  { -12347348707739.742, 20, 5, 
+	  70.000000000000000 },
+  { 1199516248034090.8, 20, 5, 
+	  80.000000000000000 },
+  { 1.3451503195078531e+17, 20, 5, 
+	  90.000000000000000 },
+  { 4.1058904276111483e+18, 20, 5, 
+	  100.00000000000000 },
+};
+
+// Test function for n=20, m=5.
+template<typename Tp>
+  void
+  test044()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data044)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data044[i].n), Tp(data044[i].m),
+		     Tp(data044[i].x));
+	const Tp f0 = data044[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=20, m=10.
+testcase_assoc_laguerre<double> data045[] = {
+  { 30045015.000000000, 20, 10, 
+	  0.0000000000000000 },
+  { -1755.6226861258601, 20, 10, 
+	  10.000000000000000 },
+  { -9081.6726644737901, 20, 10, 
+	  20.000000000000000 },
+  { 95771.650912113109, 20, 10, 
+	  30.000000000000000 },
+  { 5089151.9272779236, 20, 10, 
+	  40.000000000000000 },
+  { 97400399.450206712, 20, 10, 
+	  50.000000000000000 },
+  { -16009352450.477026, 20, 10, 
+	  60.000000000000000 },
+  { 842271286905.01050, 20, 10, 
+	  70.000000000000000 },
+  { -79901725466796.938, 20, 10, 
+	  80.000000000000000 },
+  { 7944103675858637.0, 20, 10, 
+	  90.000000000000000 },
+  { 5.7429821893388288e+17, 20, 10, 
+	  100.00000000000000 },
+};
+
+// Test function for n=20, m=10.
+template<typename Tp>
+  void
+  test045()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data045)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data045[i].n), Tp(data045[i].m),
+		     Tp(data045[i].x));
+	const Tp f0 = data045[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=20, m=20.
+testcase_assoc_laguerre<double> data046[] = {
+  { 137846528819.99994, 20, 20, 
+	  0.0000000000000000 },
+  { -136976.49571333229, 20, 20, 
+	  10.000000000000000 },
+  { 113878.49908041643, 20, 20, 
+	  20.000000000000000 },
+  { -342529.21778796182, 20, 20, 
+	  30.000000000000000 },
+  { -350112.66981443466, 20, 20, 
+	  40.000000000000000 },
+  { -10791735.172977809, 20, 20, 
+	  50.000000000000000 },
+  { -1038073940.0811402, 20, 20, 
+	  60.000000000000000 },
+  { 667312550.63616335, 20, 20, 
+	  70.000000000000000 },
+  { 741537869902.29028, 20, 20, 
+	  80.000000000000000 },
+  { -32378376755737.418, 20, 20, 
+	  90.000000000000000 },
+  { -601760332167937.62, 20, 20, 
+	  100.00000000000000 },
+};
+
+// Test function for n=20, m=20.
+template<typename Tp>
+  void
+  test046()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data046)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data046[i].n), Tp(data046[i].m),
+		     Tp(data046[i].x));
+	const Tp f0 = data046[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for n=20, m=50.
+testcase_assoc_laguerre<double> data047[] = {
+  { 1.6188460366265789e+17, 20, 50, 
+	  0.0000000000000000 },
+  { 1599011936804291.5, 20, 50, 
+	  10.000000000000000 },
+  { -131273880831.42432, 20, 50, 
+	  20.000000000000000 },
+  { -3133213093.6903548, 20, 50, 
+	  30.000000000000000 },
+  { -213935628.04985175, 20, 50, 
+	  40.000000000000000 },
+  { -47375578.495921060, 20, 50, 
+	  50.000000000000000 },
+  { -115731015.14034876, 20, 50, 
+	  60.000000000000000 },
+  { -737415147.29420292, 20, 50, 
+	  70.000000000000000 },
+  { -2123455626.8621769, 20, 50, 
+	  80.000000000000000 },
+  { 29801266858.608929, 20, 50, 
+	  90.000000000000000 },
+  { -132886631026.82553, 20, 50, 
+	  100.00000000000000 },
+};
+
+// Test function for n=20, m=50.
+template<typename Tp>
+  void
+  test047()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data047)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data047[i].n), Tp(data047[i].m),
+		     Tp(data047[i].x));
+	const Tp f0 = data047[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for n=20, m=100.
+testcase_assoc_laguerre<double> data048[] = {
+  { 2.9462227291176643e+22, 20, 100, 
+	  0.0000000000000000 },
+  { 3.5777890748701244e+21, 20, 100, 
+	  10.000000000000000 },
+  { 3.1584925521456759e+20, 20, 100, 
+	  20.000000000000000 },
+  { 1.7389599388424864e+19, 20, 100, 
+	  30.000000000000000 },
+  { 4.1401342745980634e+17, 20, 100, 
+	  40.000000000000000 },
+  { -79359706102062.594, 20, 100, 
+	  50.000000000000000 },
+  { 22736203650743.145, 20, 100, 
+	  60.000000000000000 },
+  { 65679006380.095703, 20, 100, 
+	  70.000000000000000 },
+  { -236263257610.77792, 20, 100, 
+	  80.000000000000000 },
+  { -38072644585.303101, 20, 100, 
+	  90.000000000000000 },
+  { 68236474365.173973, 20, 100, 
+	  100.00000000000000 },
+};
+
+// Test function for n=20, m=100.
+template<typename Tp>
+  void
+  test048()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data048)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data048[i].n), Tp(data048[i].m),
+		     Tp(data048[i].x));
+	const Tp f0 = data048[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+// Test data for n=50, m=0.
+testcase_assoc_laguerre<double> data049[] = {
+  { 1.0000000000000000, 50, 0, 
+	  0.0000000000000000 },
+  { 17.534183446338233, 50, 0, 
+	  10.000000000000000 },
+  { 980.26961889791028, 50, 0, 
+	  20.000000000000000 },
+  { 293000.50735962362, 50, 0, 
+	  30.000000000000000 },
+  { -14896937.968694873, 50, 0, 
+	  40.000000000000000 },
+  { 2513677852.6916871, 50, 0, 
+	  50.000000000000000 },
+  { -883876565337.99219, 50, 0, 
+	  60.000000000000000 },
+  { -80967880733583.234, 50, 0, 
+	  70.000000000000000 },
+  { -8217471769564841.0, 50, 0, 
+	  80.000000000000000 },
+  { -2.1140031308048891e+18, 50, 0, 
+	  90.000000000000000 },
+  { -3.9710103487094692e+20, 50, 0, 
+	  100.00000000000000 },
+};
+
+// Test function for n=50, m=0.
+template<typename Tp>
+  void
+  test049()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data049)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data049[i].n), Tp(data049[i].m),
+		     Tp(data049[i].x));
+	const Tp f0 = data049[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=50, m=1.
+testcase_assoc_laguerre<double> data050[] = {
+  { 51.000000000000021, 50, 1, 
+	  0.0000000000000000 },
+  { 1.4214573271639575, 50, 1, 
+	  10.000000000000000 },
+  { -2574.8072295127827, 50, 1, 
+	  20.000000000000000 },
+  { 35846.479728359205, 50, 1, 
+	  30.000000000000000 },
+  { -48263698.768318526, 50, 1, 
+	  40.000000000000000 },
+  { 6161525870.2738533, 50, 1, 
+	  50.000000000000000 },
+  { -382655486658.47125, 50, 1, 
+	  60.000000000000000 },
+  { -109635579833241.72, 50, 1, 
+	  70.000000000000000 },
+  { -14623805817283490., 50, 1, 
+	  80.000000000000000 },
+  { -2.0666847190878152e+18, 50, 1, 
+	  90.000000000000000 },
+  { -1.4385187953997626e+20, 50, 1, 
+	  100.00000000000000 },
+};
+
+// Test function for n=50, m=1.
+template<typename Tp>
+  void
+  test050()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data050)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data050[i].n), Tp(data050[i].m),
+		     Tp(data050[i].x));
+	const Tp f0 = data050[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+// Test data for n=50, m=2.
+testcase_assoc_laguerre<double> data051[] = {
+  { 1326.0000000000000, 50, 2, 
+	  0.0000000000000000 },
+  { -87.860732516444529, 50, 2, 
+	  10.000000000000000 },
+  { -5203.2351191780917, 50, 2, 
+	  20.000000000000000 },
+  { -461059.50012538867, 50, 2, 
+	  30.000000000000000 },
+  { -30476695.327440590, 50, 2, 
+	  40.000000000000000 },
+  { 3720804977.9338136, 50, 2, 
+	  50.000000000000000 },
+  { 362262002434.51453, 50, 2, 
+	  60.000000000000000 },
+  { -52210917867820.227, 50, 2, 
+	  70.000000000000000 },
+  { -9567965136901914.0, 50, 2, 
+	  80.000000000000000 },
+  { -8.9171277517712883e+17, 50, 2, 
+	  90.000000000000000 },
+  { 5.7231129448806982e+19, 50, 2, 
+	  100.00000000000000 },
+};
+
+// Test function for n=50, m=2.
+template<typename Tp>
+  void
+  test051()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data051)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data051[i].n), Tp(data051[i].m),
+		     Tp(data051[i].x));
+	const Tp f0 = data051[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=50, m=5.
+testcase_assoc_laguerre<double> data052[] = {
+  { 3478761.0000000000, 50, 5, 
+	  0.0000000000000000 },
+  { 1055.8381917651498, 50, 5, 
+	  10.000000000000000 },
+  { 15264.646660345055, 50, 5, 
+	  20.000000000000000 },
+  { 1229651.8966600848, 50, 5, 
+	  30.000000000000000 },
+  { 39270451.823656842, 50, 5, 
+	  40.000000000000000 },
+  { -4424062601.1152029, 50, 5, 
+	  50.000000000000000 },
+  { -186017434284.19223, 50, 5, 
+	  60.000000000000000 },
+  { 50972853949302.609, 50, 5, 
+	  70.000000000000000 },
+  { 6530702754012517.0, 50, 5, 
+	  80.000000000000000 },
+  { 6.8387592714678029e+17, 50, 5, 
+	  90.000000000000000 },
+  { 3.9198742504338391e+19, 50, 5, 
+	  100.00000000000000 },
+};
+
+// Test function for n=50, m=5.
+template<typename Tp>
+  void
+  test052()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data052)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data052[i].n), Tp(data052[i].m),
+		     Tp(data052[i].x));
+	const Tp f0 = data052[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=50, m=10.
+testcase_assoc_laguerre<double> data053[] = {
+  { 75394027565.999985, 50, 10, 
+	  0.0000000000000000 },
+  { 91833.924098770178, 50, 10, 
+	  10.000000000000000 },
+  { 330501.87929778261, 50, 10, 
+	  20.000000000000000 },
+  { 3625088.1635972536, 50, 10, 
+	  30.000000000000000 },
+  { 213954727.28632012, 50, 10, 
+	  40.000000000000000 },
+  { -9381006937.7517681, 50, 10, 
+	  50.000000000000000 },
+  { 535333683777.48615, 50, 10, 
+	  60.000000000000000 },
+  { 18824406573722.172, 50, 10, 
+	  70.000000000000000 },
+  { -533858276780013.12, 50, 10, 
+	  80.000000000000000 },
+  { -52995774666704016., 50, 10, 
+	  90.000000000000000 },
+  { 6.0504182862448783e+18, 50, 10, 
+	  100.00000000000000 },
+};
+
+// Test function for n=50, m=10.
+template<typename Tp>
+  void
+  test053()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data053)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data053[i].n), Tp(data053[i].m),
+		     Tp(data053[i].x));
+	const Tp f0 = data053[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=50, m=20.
+testcase_assoc_laguerre<double> data054[] = {
+  { 1.6188460366265779e+17, 50, 20, 
+	  0.0000000000000000 },
+  { -307637087.25169408, 50, 20, 
+	  10.000000000000000 },
+  { 12524651.102974586, 50, 20, 
+	  20.000000000000000 },
+  { -315460483.86210561, 50, 20, 
+	  30.000000000000000 },
+  { -1889683587.3459988, 50, 20, 
+	  40.000000000000000 },
+  { 37457044404.200348, 50, 20, 
+	  50.000000000000000 },
+  { -843831858224.71802, 50, 20, 
+	  60.000000000000000 },
+  { -92231643172.307495, 50, 20, 
+	  70.000000000000000 },
+  { 904211757769501.00, 50, 20, 
+	  80.000000000000000 },
+  { 46508193600283272., 50, 20, 
+	  90.000000000000000 },
+  { 2.3216887928162719e+18, 50, 20, 
+	  100.00000000000000 },
+};
+
+// Test function for n=50, m=20.
+template<typename Tp>
+  void
+  test054()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data054)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data054[i].n), Tp(data054[i].m),
+		     Tp(data054[i].x));
+	const Tp f0 = data054[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000029e-12));
+  }
+
+// Test data for n=50, m=50.
+testcase_assoc_laguerre<double> data055[] = {
+  { 1.0089134454556417e+29, 50, 50, 
+	  0.0000000000000000 },
+  { 1.3822795753070493e+23, 50, 50, 
+	  10.000000000000000 },
+  { 95817260381628336., 50, 50, 
+	  20.000000000000000 },
+  { -910798580856015.38, 50, 50, 
+	  30.000000000000000 },
+  { 50513254049166.922, 50, 50, 
+	  40.000000000000000 },
+  { 84159703903348.938, 50, 50, 
+	  50.000000000000000 },
+  { -138805244691822.72, 50, 50, 
+	  60.000000000000000 },
+  { 181046391269246.25, 50, 50, 
+	  70.000000000000000 },
+  { 2086884905317107.5, 50, 50, 
+	  80.000000000000000 },
+  { -2765620139862428.0, 50, 50, 
+	  90.000000000000000 },
+  { -1.3706751678146290e+17, 50, 50, 
+	  100.00000000000000 },
+};
+
+// Test function for n=50, m=50.
+template<typename Tp>
+  void
+  test055()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data055)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data055[i].n), Tp(data055[i].m),
+		     Tp(data055[i].x));
+	const Tp f0 = data055[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for n=50, m=100.
+testcase_assoc_laguerre<double> data056[] = {
+  { 2.0128660909731929e+40, 50, 100, 
+	  0.0000000000000000 },
+  { 9.3675094807695474e+37, 50, 100, 
+	  10.000000000000000 },
+  { 1.3009321481877196e+35, 50, 100, 
+	  20.000000000000000 },
+  { 7.3720026893233823e+30, 50, 100, 
+	  30.000000000000000 },
+  { -6.0824679079634667e+25, 50, 100, 
+	  40.000000000000000 },
+  { -6.0053188793543450e+23, 50, 100, 
+	  50.000000000000000 },
+  { 1.4178129287264692e+22, 50, 100, 
+	  60.000000000000000 },
+  { -5.4652099341566706e+20, 50, 100, 
+	  70.000000000000000 },
+  { -1.0817271759263274e+20, 50, 100, 
+	  80.000000000000000 },
+  { 3.8058734007924195e+19, 50, 100, 
+	  90.000000000000000 },
+  { 4.7439240848028344e+19, 50, 100, 
+	  100.00000000000000 },
+};
+
+// Test function for n=50, m=100.
+template<typename Tp>
+  void
+  test056()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data056)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data056[i].n), Tp(data056[i].m),
+		     Tp(data056[i].x));
+	const Tp f0 = data056[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+// Test data for n=100, m=0.
+testcase_assoc_laguerre<double> data057[] = {
+  { 1.0000000000000000, 100, 0, 
+	  0.0000000000000000 },
+  { 13.277662844303450, 100, 0, 
+	  10.000000000000000 },
+  { 1854.0367283243388, 100, 0, 
+	  20.000000000000000 },
+  { 170141.86987046551, 100, 0, 
+	  30.000000000000000 },
+  { -7272442.3156006960, 100, 0, 
+	  40.000000000000000 },
+  { 4847420871.2690506, 100, 0, 
+	  50.000000000000000 },
+  { 693492765740.29688, 100, 0, 
+	  60.000000000000000 },
+  { 17125518672239.770, 100, 0, 
+	  70.000000000000000 },
+  { -13763178176383768., 100, 0, 
+	  80.000000000000000 },
+  { 2.1307220490380173e+18, 100, 0, 
+	  90.000000000000000 },
+  { -2.6292260693068916e+20, 100, 0, 
+	  100.00000000000000 },
+};
+
+// Test function for n=100, m=0.
+template<typename Tp>
+  void
+  test057()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data057)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data057[i].n), Tp(data057[i].m),
+		     Tp(data057[i].x));
+	const Tp f0 = data057[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=100, m=1.
+testcase_assoc_laguerre<double> data058[] = {
+  { 101.00000000000003, 100, 1, 
+	  0.0000000000000000 },
+  { -14.650661983680420, 100, 1, 
+	  10.000000000000000 },
+  { 1626.5010939361582, 100, 1, 
+	  20.000000000000000 },
+  { 417884.77658268728, 100, 1, 
+	  30.000000000000000 },
+  { -55617646.951649837, 100, 1, 
+	  40.000000000000000 },
+  { 884829874.26626217, 100, 1, 
+	  50.000000000000000 },
+  { 154466082750.32202, 100, 1, 
+	  60.000000000000000 },
+  { -101423973484646.00, 100, 1, 
+	  70.000000000000000 },
+  { -1388352348671756.8, 100, 1, 
+	  80.000000000000000 },
+  { 7.8048705513268582e+17, 100, 1, 
+	  90.000000000000000 },
+  { 1.6948925059042755e+19, 100, 1, 
+	  100.00000000000000 },
+};
+
+// Test function for n=100, m=1.
+template<typename Tp>
+  void
+  test058()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data058)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data058[i].n), Tp(data058[i].m),
+		     Tp(data058[i].x));
+	const Tp f0 = data058[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for n=100, m=2.
+testcase_assoc_laguerre<double> data059[] = {
+  { 5151.0000000000055, 100, 2, 
+	  0.0000000000000000 },
+  { -150.22012290951324, 100, 2, 
+	  10.000000000000000 },
+  { -7655.0593294049449, 100, 2, 
+	  20.000000000000000 },
+  { -140996.69276179091, 100, 2, 
+	  30.000000000000000 },
+  { -38645171.278549351, 100, 2, 
+	  40.000000000000000 },
+  { -8889263688.2118931, 100, 2, 
+	  50.000000000000000 },
+  { -1010338971533.3400, 100, 2, 
+	  60.000000000000000 },
+  { -127582564332943.91, 100, 2, 
+	  70.000000000000000 },
+  { 15970305694654312., 100, 2, 
+	  80.000000000000000 },
+  { -1.6019844992862820e+18, 100, 2, 
+	  90.000000000000000 },
+  { 2.8267024730962955e+20, 100, 2, 
+	  100.00000000000000 },
+};
+
+// Test function for n=100, m=2.
+template<typename Tp>
+  void
+  test059()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data059)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data059[i].n), Tp(data059[i].m),
+		     Tp(data059[i].x));
+	const Tp f0 = data059[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=100, m=5.
+testcase_assoc_laguerre<double> data060[] = {
+  { 96560646.000000030, 100, 5, 
+	  0.0000000000000000 },
+  { 2430.6732236677612, 100, 5, 
+	  10.000000000000000 },
+  { 111162.32026994647, 100, 5, 
+	  20.000000000000000 },
+  { 4036708.2599413628, 100, 5, 
+	  30.000000000000000 },
+  { -34055982.664405443, 100, 5, 
+	  40.000000000000000 },
+  { 30110688343.562328, 100, 5, 
+	  50.000000000000000 },
+  { 2651429940558.2974, 100, 5, 
+	  60.000000000000000 },
+  { 192108556058943.09, 100, 5, 
+	  70.000000000000000 },
+  { -25410533973455528., 100, 5, 
+	  80.000000000000000 },
+  { 2.1072955633564431e+18, 100, 5, 
+	  90.000000000000000 },
+  { -2.9434005355877289e+20, 100, 5, 
+	  100.00000000000000 },
+};
+
+// Test function for n=100, m=5.
+template<typename Tp>
+  void
+  test060()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data060)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data060[i].n), Tp(data060[i].m),
+		     Tp(data060[i].x));
+	const Tp f0 = data060[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=100, m=10.
+testcase_assoc_laguerre<double> data061[] = {
+  { 46897636623981.039, 100, 10, 
+	  0.0000000000000000 },
+  { 529208.11550990329, 100, 10, 
+	  10.000000000000000 },
+  { 7402892.1748803817, 100, 10, 
+	  20.000000000000000 },
+  { 88369632.083243579, 100, 10, 
+	  30.000000000000000 },
+  { 822187797.59096563, 100, 10, 
+	  40.000000000000000 },
+  { 180231446033.06866, 100, 10, 
+	  50.000000000000000 },
+  { 7922942703798.1309, 100, 10, 
+	  60.000000000000000 },
+  { 784424250559042.12, 100, 10, 
+	  70.000000000000000 },
+  { -16325634720239370., 100, 10, 
+	  80.000000000000000 },
+  { -1.0879588307443162e+18, 100, 10, 
+	  90.000000000000000 },
+  { 3.0114394463610642e+19, 100, 10, 
+	  100.00000000000000 },
+};
+
+// Test function for n=100, m=10.
+template<typename Tp>
+  void
+  test061()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data061)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data061[i].n), Tp(data061[i].m),
+		     Tp(data061[i].x));
+	const Tp f0 = data061[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=100, m=20.
+testcase_assoc_laguerre<double> data062[] = {
+  { 2.9462227291176614e+22, 100, 20, 
+	  0.0000000000000000 },
+  { 313694958939.90405, 100, 20, 
+	  10.000000000000000 },
+  { 45396489338.096191, 100, 20, 
+	  20.000000000000000 },
+  { -7215826758.0081253, 100, 20, 
+	  30.000000000000000 },
+  { 825949194005.88855, 100, 20, 
+	  40.000000000000000 },
+  { -2764742119971.0811, 100, 20, 
+	  50.000000000000000 },
+  { -219802198273516.03, 100, 20, 
+	  60.000000000000000 },
+  { -1699053306145262.0, 100, 20, 
+	  70.000000000000000 },
+  { 3.5495709345023846e+17, 100, 20, 
+	  80.000000000000000 },
+  { -9.6128675110292419e+18, 100, 20, 
+	  90.000000000000000 },
+  { 4.3619868422072212e+20, 100, 20, 
+	  100.00000000000000 },
+};
+
+// Test function for n=100, m=20.
+template<typename Tp>
+  void
+  test062()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data062)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data062[i].n), Tp(data062[i].m),
+		     Tp(data062[i].x));
+	const Tp f0 = data062[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+// Test data for n=100, m=50.
+testcase_assoc_laguerre<double> data063[] = {
+  { 2.0128660909731931e+40, 100, 50, 
+	  0.0000000000000000 },
+  { -4.0151443913473373e+28, 100, 50, 
+	  10.000000000000000 },
+  { 3.2199632594551924e+22, 100, 50, 
+	  20.000000000000000 },
+  { -2.7568702092659756e+20, 100, 50, 
+	  30.000000000000000 },
+  { 7.5553066015421563e+19, 100, 50, 
+	  40.000000000000000 },
+  { -2.7651625252387734e+19, 100, 50, 
+	  50.000000000000000 },
+  { -5.8963680147283804e+19, 100, 50, 
+	  60.000000000000000 },
+  { -1.8082798163033106e+20, 100, 50, 
+	  70.000000000000000 },
+  { -3.9044276986817249e+20, 100, 50, 
+	  80.000000000000000 },
+  { 6.9926310700401904e+21, 100, 50, 
+	  90.000000000000000 },
+  { -5.5727272809923646e+22, 100, 50, 
+	  100.00000000000000 },
+};
+
+// Test function for n=100, m=50.
+template<typename Tp>
+  void
+  test063()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data063)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data063[i].n), Tp(data063[i].m),
+		     Tp(data063[i].x));
+	const Tp f0 = data063[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for n=100, m=100.
+testcase_assoc_laguerre<double> data064[] = {
+  { 9.0548514656103225e+58, 100, 100, 
+	  0.0000000000000000 },
+  { 1.3334078033060556e+54, 100, 100, 
+	  10.000000000000000 },
+  { 2.1002639254211340e+46, 100, 100, 
+	  20.000000000000000 },
+  { -1.1073158068796292e+39, 100, 100, 
+	  30.000000000000000 },
+  { -8.3640937363981346e+35, 100, 100, 
+	  40.000000000000000 },
+  { -6.5879339429312686e+32, 100, 100, 
+	  50.000000000000000 },
+  { -2.4190645077698771e+30, 100, 100, 
+	  60.000000000000000 },
+  { -7.9224960465662171e+29, 100, 100, 
+	  70.000000000000000 },
+  { -2.8605772478408694e+29, 100, 100, 
+	  80.000000000000000 },
+  { 2.4149589189609957e+28, 100, 100, 
+	  90.000000000000000 },
+  { 5.1146476014859021e+28, 100, 100, 
+	  100.00000000000000 },
+};
+
+// Test function for n=100, m=100.
+template<typename Tp>
+  void
+  test064()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data064)
+			   / sizeof(testcase_assoc_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_laguerre(Tp(data064[i].n), Tp(data064[i].m),
+		     Tp(data064[i].x));
+	const Tp f0 = data064[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  test012<double>();
+  test013<double>();
+  test014<double>();
+  test015<double>();
+  test016<double>();
+  test017<double>();
+  test018<double>();
+  test019<double>();
+  test020<double>();
+  test021<double>();
+  test022<double>();
+  test023<double>();
+  test024<double>();
+  test025<double>();
+  test026<double>();
+  test027<double>();
+  test028<double>();
+  test029<double>();
+  test030<double>();
+  test031<double>();
+  test032<double>();
+  test033<double>();
+  test034<double>();
+  test035<double>();
+  test036<double>();
+  test037<double>();
+  test038<double>();
+  test039<double>();
+  test040<double>();
+  test041<double>();
+  test042<double>();
+  test043<double>();
+  test044<double>();
+  test045<double>();
+  test046<double>();
+  test047<double>();
+  test048<double>();
+  test049<double>();
+  test050<double>();
+  test051<double>();
+  test052<double>();
+  test053<double>();
+  test054<double>();
+  test055<double>();
+  test056<double>();
+  test057<double>();
+  test058<double>();
+  test059<double>();
+  test060<double>();
+  test061<double>();
+  test062<double>();
+  test063<double>();
+  test064<double>();
+  return 0;
+}
Index: testsuite/special_functions/01_assoc_laguerre/compile.cc
===================================================================
--- testsuite/special_functions/01_assoc_laguerre/compile.cc	(revision 0)
+++ testsuite/special_functions/01_assoc_laguerre/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.1 assoc_laguerre
+
+#include <cmath>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+  unsigned int n = 2, m = 1;
+
+  std::assoc_laguerre(n, m, xf);
+  std::assoc_laguerref(n, m, xf);
+  std::assoc_laguerre(n, m, xd);
+  std::assoc_laguerre(n, m, xl);
+  std::assoc_laguerrel(n, m, xl);
+
+  return;
+}
Index: testsuite/special_functions/01_assoc_laguerre/compile_2.cc
===================================================================
--- testsuite/special_functions/01_assoc_laguerre/compile_2.cc	(revision 0)
+++ testsuite/special_functions/01_assoc_laguerre/compile_2.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.1 assoc_laguerre
+
+#include <math.h>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+  unsigned int n = 2, m = 1;
+
+  assoc_laguerre(n, m, xf);
+  assoc_laguerref(n, m, xf);
+  assoc_laguerre(n, m, xd);
+  assoc_laguerre(n, m, xl);
+  assoc_laguerrel(n, m, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/02_assoc_legendre/check_nan.cc
===================================================================
--- testsuite/special_functions/02_assoc_legendre/check_nan.cc	(revision 0)
+++ testsuite/special_functions/02_assoc_legendre/check_nan.cc	(working copy)
@@ -0,0 +1,58 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.2 assoc_legendre
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  unsigned int l = 2, m = 1;
+
+  float a = std::assoc_legendre(l, m, xf);
+  float b = std::assoc_legendref(l, m, xf);
+  double c = std::assoc_legendre(l, m, xd);
+  long double d = std::assoc_legendre(l, m, xl);
+  long double e = std::assoc_legendrel(l, m, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/02_assoc_legendre/check_value.cc
===================================================================
--- testsuite/special_functions/02_assoc_legendre/check_value.cc	(revision 0)
+++ testsuite/special_functions/02_assoc_legendre/check_value.cc	(working copy)
@@ -0,0 +1,2816 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  assoc_legendre
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for l=0, m=0.
+testcase_assoc_legendre<double> data001[] = {
+  { 1.0000000000000000, 0, 0, 
+	  -1.0000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  -0.90000000000000002 },
+  { 1.0000000000000000, 0, 0, 
+	  -0.80000000000000004 },
+  { 1.0000000000000000, 0, 0, 
+	  -0.69999999999999996 },
+  { 1.0000000000000000, 0, 0, 
+	  -0.59999999999999998 },
+  { 1.0000000000000000, 0, 0, 
+	  -0.50000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  -0.40000000000000002 },
+  { 1.0000000000000000, 0, 0, 
+	  -0.30000000000000004 },
+  { 1.0000000000000000, 0, 0, 
+	  -0.19999999999999996 },
+  { 1.0000000000000000, 0, 0, 
+	  -0.099999999999999978 },
+  { 1.0000000000000000, 0, 0, 
+	  0.0000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  0.10000000000000009 },
+  { 1.0000000000000000, 0, 0, 
+	  0.19999999999999996 },
+  { 1.0000000000000000, 0, 0, 
+	  0.30000000000000004 },
+  { 1.0000000000000000, 0, 0, 
+	  0.39999999999999991 },
+  { 1.0000000000000000, 0, 0, 
+	  0.50000000000000000 },
+  { 1.0000000000000000, 0, 0, 
+	  0.60000000000000009 },
+  { 1.0000000000000000, 0, 0, 
+	  0.69999999999999996 },
+  { 1.0000000000000000, 0, 0, 
+	  0.80000000000000004 },
+  { 1.0000000000000000, 0, 0, 
+	  0.89999999999999991 },
+  { 1.0000000000000000, 0, 0, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=0, m=0.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data001[i].l), Tp(data001[i].m),
+		     Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=1, m=0.
+testcase_assoc_legendre<double> data002[] = {
+  { -1.0000000000000000, 1, 0, 
+	  -1.0000000000000000 },
+  { -0.90000000000000002, 1, 0, 
+	  -0.90000000000000002 },
+  { -0.80000000000000004, 1, 0, 
+	  -0.80000000000000004 },
+  { -0.69999999999999996, 1, 0, 
+	  -0.69999999999999996 },
+  { -0.59999999999999998, 1, 0, 
+	  -0.59999999999999998 },
+  { -0.50000000000000000, 1, 0, 
+	  -0.50000000000000000 },
+  { -0.40000000000000002, 1, 0, 
+	  -0.40000000000000002 },
+  { -0.30000000000000004, 1, 0, 
+	  -0.30000000000000004 },
+  { -0.19999999999999996, 1, 0, 
+	  -0.19999999999999996 },
+  { -0.099999999999999978, 1, 0, 
+	  -0.099999999999999978 },
+  { 0.0000000000000000, 1, 0, 
+	  0.0000000000000000 },
+  { 0.10000000000000009, 1, 0, 
+	  0.10000000000000009 },
+  { 0.19999999999999996, 1, 0, 
+	  0.19999999999999996 },
+  { 0.30000000000000004, 1, 0, 
+	  0.30000000000000004 },
+  { 0.39999999999999991, 1, 0, 
+	  0.39999999999999991 },
+  { 0.50000000000000000, 1, 0, 
+	  0.50000000000000000 },
+  { 0.60000000000000009, 1, 0, 
+	  0.60000000000000009 },
+  { 0.69999999999999996, 1, 0, 
+	  0.69999999999999996 },
+  { 0.80000000000000004, 1, 0, 
+	  0.80000000000000004 },
+  { 0.89999999999999991, 1, 0, 
+	  0.89999999999999991 },
+  { 1.0000000000000000, 1, 0, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=1, m=0.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data002[i].l), Tp(data002[i].m),
+		     Tp(data002[i].x));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=1, m=1.
+testcase_assoc_legendre<double> data003[] = {
+  { -0.0000000000000000, 1, 1, 
+	  -1.0000000000000000 },
+  { -0.43588989435406728, 1, 1, 
+	  -0.90000000000000002 },
+  { -0.59999999999999987, 1, 1, 
+	  -0.80000000000000004 },
+  { -0.71414284285428509, 1, 1, 
+	  -0.69999999999999996 },
+  { -0.80000000000000004, 1, 1, 
+	  -0.59999999999999998 },
+  { -0.86602540378443860, 1, 1, 
+	  -0.50000000000000000 },
+  { -0.91651513899116799, 1, 1, 
+	  -0.40000000000000002 },
+  { -0.95393920141694577, 1, 1, 
+	  -0.30000000000000004 },
+  { -0.97979589711327120, 1, 1, 
+	  -0.19999999999999996 },
+  { -0.99498743710661997, 1, 1, 
+	  -0.099999999999999978 },
+  { -1.0000000000000000, 1, 1, 
+	  0.0000000000000000 },
+  { -0.99498743710661997, 1, 1, 
+	  0.10000000000000009 },
+  { -0.97979589711327120, 1, 1, 
+	  0.19999999999999996 },
+  { -0.95393920141694577, 1, 1, 
+	  0.30000000000000004 },
+  { -0.91651513899116799, 1, 1, 
+	  0.39999999999999991 },
+  { -0.86602540378443860, 1, 1, 
+	  0.50000000000000000 },
+  { -0.79999999999999993, 1, 1, 
+	  0.60000000000000009 },
+  { -0.71414284285428509, 1, 1, 
+	  0.69999999999999996 },
+  { -0.59999999999999987, 1, 1, 
+	  0.80000000000000004 },
+  { -0.43588989435406750, 1, 1, 
+	  0.89999999999999991 },
+  { -0.0000000000000000, 1, 1, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=1, m=1.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data003[i].l), Tp(data003[i].m),
+		     Tp(data003[i].x));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=2, m=0.
+testcase_assoc_legendre<double> data004[] = {
+  { 1.0000000000000000, 2, 0, 
+	  -1.0000000000000000 },
+  { 0.71500000000000008, 2, 0, 
+	  -0.90000000000000002 },
+  { 0.46000000000000019, 2, 0, 
+	  -0.80000000000000004 },
+  { 0.23499999999999988, 2, 0, 
+	  -0.69999999999999996 },
+  { 0.039999999999999925, 2, 0, 
+	  -0.59999999999999998 },
+  { -0.12500000000000000, 2, 0, 
+	  -0.50000000000000000 },
+  { -0.25999999999999995, 2, 0, 
+	  -0.40000000000000002 },
+  { -0.36499999999999999, 2, 0, 
+	  -0.30000000000000004 },
+  { -0.44000000000000006, 2, 0, 
+	  -0.19999999999999996 },
+  { -0.48499999999999999, 2, 0, 
+	  -0.099999999999999978 },
+  { -0.50000000000000000, 2, 0, 
+	  0.0000000000000000 },
+  { -0.48499999999999999, 2, 0, 
+	  0.10000000000000009 },
+  { -0.44000000000000006, 2, 0, 
+	  0.19999999999999996 },
+  { -0.36499999999999999, 2, 0, 
+	  0.30000000000000004 },
+  { -0.26000000000000012, 2, 0, 
+	  0.39999999999999991 },
+  { -0.12500000000000000, 2, 0, 
+	  0.50000000000000000 },
+  { 0.040000000000000147, 2, 0, 
+	  0.60000000000000009 },
+  { 0.23499999999999988, 2, 0, 
+	  0.69999999999999996 },
+  { 0.46000000000000019, 2, 0, 
+	  0.80000000000000004 },
+  { 0.71499999999999986, 2, 0, 
+	  0.89999999999999991 },
+  { 1.0000000000000000, 2, 0, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=2, m=0.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data004[i].l), Tp(data004[i].m),
+		     Tp(data004[i].x));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=2, m=1.
+testcase_assoc_legendre<double> data005[] = {
+  { 0.0000000000000000, 2, 1, 
+	  -1.0000000000000000 },
+  { 1.1769027147559816, 2, 1, 
+	  -0.90000000000000002 },
+  { 1.4399999999999999, 2, 1, 
+	  -0.80000000000000004 },
+  { 1.4996999699939983, 2, 1, 
+	  -0.69999999999999996 },
+  { 1.4399999999999999, 2, 1, 
+	  -0.59999999999999998 },
+  { 1.2990381056766580, 2, 1, 
+	  -0.50000000000000000 },
+  { 1.0998181667894018, 2, 1, 
+	  -0.40000000000000002 },
+  { 0.85854528127525132, 2, 1, 
+	  -0.30000000000000004 },
+  { 0.58787753826796263, 2, 1, 
+	  -0.19999999999999996 },
+  { 0.29849623113198592, 2, 1, 
+	  -0.099999999999999978 },
+  { -0.0000000000000000, 2, 1, 
+	  0.0000000000000000 },
+  { -0.29849623113198626, 2, 1, 
+	  0.10000000000000009 },
+  { -0.58787753826796263, 2, 1, 
+	  0.19999999999999996 },
+  { -0.85854528127525132, 2, 1, 
+	  0.30000000000000004 },
+  { -1.0998181667894014, 2, 1, 
+	  0.39999999999999991 },
+  { -1.2990381056766580, 2, 1, 
+	  0.50000000000000000 },
+  { -1.4400000000000002, 2, 1, 
+	  0.60000000000000009 },
+  { -1.4996999699939983, 2, 1, 
+	  0.69999999999999996 },
+  { -1.4399999999999999, 2, 1, 
+	  0.80000000000000004 },
+  { -1.1769027147559821, 2, 1, 
+	  0.89999999999999991 },
+  { -0.0000000000000000, 2, 1, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=2, m=1.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data005[i].l), Tp(data005[i].m),
+		     Tp(data005[i].x));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=2, m=2.
+testcase_assoc_legendre<double> data006[] = {
+  { 0.0000000000000000, 2, 2, 
+	  -1.0000000000000000 },
+  { 0.56999999999999984, 2, 2, 
+	  -0.90000000000000002 },
+  { 1.0799999999999996, 2, 2, 
+	  -0.80000000000000004 },
+  { 1.5300000000000005, 2, 2, 
+	  -0.69999999999999996 },
+  { 1.9200000000000004, 2, 2, 
+	  -0.59999999999999998 },
+  { 2.2500000000000000, 2, 2, 
+	  -0.50000000000000000 },
+  { 2.5200000000000000, 2, 2, 
+	  -0.40000000000000002 },
+  { 2.7300000000000004, 2, 2, 
+	  -0.30000000000000004 },
+  { 2.8799999999999999, 2, 2, 
+	  -0.19999999999999996 },
+  { 2.9700000000000002, 2, 2, 
+	  -0.099999999999999978 },
+  { 3.0000000000000000, 2, 2, 
+	  0.0000000000000000 },
+  { 2.9700000000000002, 2, 2, 
+	  0.10000000000000009 },
+  { 2.8799999999999999, 2, 2, 
+	  0.19999999999999996 },
+  { 2.7300000000000004, 2, 2, 
+	  0.30000000000000004 },
+  { 2.5200000000000000, 2, 2, 
+	  0.39999999999999991 },
+  { 2.2500000000000000, 2, 2, 
+	  0.50000000000000000 },
+  { 1.9199999999999997, 2, 2, 
+	  0.60000000000000009 },
+  { 1.5300000000000005, 2, 2, 
+	  0.69999999999999996 },
+  { 1.0799999999999996, 2, 2, 
+	  0.80000000000000004 },
+  { 0.57000000000000040, 2, 2, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 2, 2, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=2, m=2.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data006[i].l), Tp(data006[i].m),
+		     Tp(data006[i].x));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=5, m=0.
+testcase_assoc_legendre<double> data007[] = {
+  { -1.0000000000000000, 5, 0, 
+	  -1.0000000000000000 },
+  { 0.041141250000000087, 5, 0, 
+	  -0.90000000000000002 },
+  { 0.39951999999999993, 5, 0, 
+	  -0.80000000000000004 },
+  { 0.36519874999999991, 5, 0, 
+	  -0.69999999999999996 },
+  { 0.15263999999999994, 5, 0, 
+	  -0.59999999999999998 },
+  { -0.089843750000000000, 5, 0, 
+	  -0.50000000000000000 },
+  { -0.27063999999999994, 5, 0, 
+	  -0.40000000000000002 },
+  { -0.34538625000000001, 5, 0, 
+	  -0.30000000000000004 },
+  { -0.30751999999999996, 5, 0, 
+	  -0.19999999999999996 },
+  { -0.17882874999999995, 5, 0, 
+	  -0.099999999999999978 },
+  { 0.0000000000000000, 5, 0, 
+	  0.0000000000000000 },
+  { 0.17882875000000015, 5, 0, 
+	  0.10000000000000009 },
+  { 0.30751999999999996, 5, 0, 
+	  0.19999999999999996 },
+  { 0.34538625000000001, 5, 0, 
+	  0.30000000000000004 },
+  { 0.27064000000000010, 5, 0, 
+	  0.39999999999999991 },
+  { 0.089843750000000000, 5, 0, 
+	  0.50000000000000000 },
+  { -0.15264000000000016, 5, 0, 
+	  0.60000000000000009 },
+  { -0.36519874999999991, 5, 0, 
+	  0.69999999999999996 },
+  { -0.39951999999999993, 5, 0, 
+	  0.80000000000000004 },
+  { -0.041141250000000261, 5, 0, 
+	  0.89999999999999991 },
+  { 1.0000000000000000, 5, 0, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=5, m=0.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data007[i].l), Tp(data007[i].m),
+		     Tp(data007[i].x));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=5, m=1.
+testcase_assoc_legendre<double> data008[] = {
+  { 0.0000000000000000, 5, 1, 
+	  -1.0000000000000000 },
+  { -2.8099369608350981, 5, 1, 
+	  -0.90000000000000002 },
+  { -0.72180000000000089, 5, 1, 
+	  -0.80000000000000004 },
+  { 1.0951826834447254, 5, 1, 
+	  -0.69999999999999996 },
+  { 1.9775999999999998, 5, 1, 
+	  -0.59999999999999998 },
+  { 1.9282596881137892, 5, 1, 
+	  -0.50000000000000000 },
+  { 1.2070504380513685, 5, 1, 
+	  -0.40000000000000002 },
+  { 0.16079837663884422, 5, 1, 
+	  -0.30000000000000004 },
+  { -0.87005875663658538, 5, 1, 
+	  -0.19999999999999996 },
+  { -1.6083350053680323, 5, 1, 
+	  -0.099999999999999978 },
+  { -1.8750000000000000, 5, 1, 
+	  0.0000000000000000 },
+  { -1.6083350053680314, 5, 1, 
+	  0.10000000000000009 },
+  { -0.87005875663658538, 5, 1, 
+	  0.19999999999999996 },
+  { 0.16079837663884422, 5, 1, 
+	  0.30000000000000004 },
+  { 1.2070504380513671, 5, 1, 
+	  0.39999999999999991 },
+  { 1.9282596881137892, 5, 1, 
+	  0.50000000000000000 },
+  { 1.9775999999999998, 5, 1, 
+	  0.60000000000000009 },
+  { 1.0951826834447254, 5, 1, 
+	  0.69999999999999996 },
+  { -0.72180000000000089, 5, 1, 
+	  0.80000000000000004 },
+  { -2.8099369608350973, 5, 1, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 5, 1, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=5, m=1.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data008[i].l), Tp(data008[i].m),
+		     Tp(data008[i].x));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=5, m=2.
+testcase_assoc_legendre<double> data009[] = {
+  { 0.0000000000000000, 5, 2, 
+	  -1.0000000000000000 },
+  { -12.837825000000000, 5, 2, 
+	  -0.90000000000000002 },
+  { -13.910400000000001, 5, 2, 
+	  -0.80000000000000004 },
+  { -8.8089749999999967, 5, 2, 
+	  -0.69999999999999996 },
+  { -1.6128000000000000, 5, 2, 
+	  -0.59999999999999998 },
+  { 4.9218750000000000, 5, 2, 
+	  -0.50000000000000000 },
+  { 9.1728000000000005, 5, 2, 
+	  -0.40000000000000002 },
+  { 10.462725000000001, 5, 2, 
+	  -0.30000000000000004 },
+  { 8.8703999999999983, 5, 2, 
+	  -0.19999999999999996 },
+  { 5.0415749999999990, 5, 2, 
+	  -0.099999999999999978 },
+  { -0.0000000000000000, 5, 2, 
+	  0.0000000000000000 },
+  { -5.0415750000000044, 5, 2, 
+	  0.10000000000000009 },
+  { -8.8703999999999983, 5, 2, 
+	  0.19999999999999996 },
+  { -10.462725000000001, 5, 2, 
+	  0.30000000000000004 },
+  { -9.1728000000000005, 5, 2, 
+	  0.39999999999999991 },
+  { -4.9218750000000000, 5, 2, 
+	  0.50000000000000000 },
+  { 1.6128000000000047, 5, 2, 
+	  0.60000000000000009 },
+  { 8.8089749999999967, 5, 2, 
+	  0.69999999999999996 },
+  { 13.910400000000001, 5, 2, 
+	  0.80000000000000004 },
+  { 12.837825000000004, 5, 2, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 5, 2, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=5, m=2.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data009[i].l), Tp(data009[i].m),
+		     Tp(data009[i].x));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=5, m=5.
+testcase_assoc_legendre<double> data010[] = {
+  { -0.0000000000000000, 5, 5, 
+	  -1.0000000000000000 },
+  { -14.870165800941818, 5, 5, 
+	  -0.90000000000000002 },
+  { -73.483199999999925, 5, 5, 
+	  -0.80000000000000004 },
+  { -175.53238298794764, 5, 5, 
+	  -0.69999999999999996 },
+  { -309.65760000000006, 5, 5, 
+	  -0.59999999999999998 },
+  { -460.34662869916559, 5, 5, 
+	  -0.50000000000000000 },
+  { -611.12496255819883, 5, 5, 
+	  -0.40000000000000002 },
+  { -746.50941479523760, 5, 5, 
+	  -0.30000000000000004 },
+  { -853.31600434671316, 5, 5, 
+	  -0.19999999999999996 },
+  { -921.55189181724734, 5, 5, 
+	  -0.099999999999999978 },
+  { -945.00000000000000, 5, 5, 
+	  0.0000000000000000 },
+  { -921.55189181724734, 5, 5, 
+	  0.10000000000000009 },
+  { -853.31600434671316, 5, 5, 
+	  0.19999999999999996 },
+  { -746.50941479523760, 5, 5, 
+	  0.30000000000000004 },
+  { -611.12496255819883, 5, 5, 
+	  0.39999999999999991 },
+  { -460.34662869916559, 5, 5, 
+	  0.50000000000000000 },
+  { -309.65759999999989, 5, 5, 
+	  0.60000000000000009 },
+  { -175.53238298794764, 5, 5, 
+	  0.69999999999999996 },
+  { -73.483199999999925, 5, 5, 
+	  0.80000000000000004 },
+  { -14.870165800941855, 5, 5, 
+	  0.89999999999999991 },
+  { -0.0000000000000000, 5, 5, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=5, m=5.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data010[i].l), Tp(data010[i].m),
+		     Tp(data010[i].x));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10, m=0.
+testcase_assoc_legendre<double> data011[] = {
+  { 1.0000000000000000, 10, 0, 
+	  -1.0000000000000000 },
+  { -0.26314561785585960, 10, 0, 
+	  -0.90000000000000002 },
+  { 0.30052979560000004, 10, 0, 
+	  -0.80000000000000004 },
+  { 0.085805795531640333, 10, 0, 
+	  -0.69999999999999996 },
+  { -0.24366274560000001, 10, 0, 
+	  -0.59999999999999998 },
+  { -0.18822860717773438, 10, 0, 
+	  -0.50000000000000000 },
+  { 0.096839064399999925, 10, 0, 
+	  -0.40000000000000002 },
+  { 0.25147634951601561, 10, 0, 
+	  -0.30000000000000004 },
+  { 0.12907202559999983, 10, 0, 
+	  -0.19999999999999996 },
+  { -0.12212499738710943, 10, 0, 
+	  -0.099999999999999978 },
+  { -0.24609375000000000, 10, 0, 
+	  0.0000000000000000 },
+  { -0.12212499738710922, 10, 0, 
+	  0.10000000000000009 },
+  { 0.12907202559999983, 10, 0, 
+	  0.19999999999999996 },
+  { 0.25147634951601561, 10, 0, 
+	  0.30000000000000004 },
+  { 0.096839064400000258, 10, 0, 
+	  0.39999999999999991 },
+  { -0.18822860717773438, 10, 0, 
+	  0.50000000000000000 },
+  { -0.24366274559999984, 10, 0, 
+	  0.60000000000000009 },
+  { 0.085805795531640333, 10, 0, 
+	  0.69999999999999996 },
+  { 0.30052979560000004, 10, 0, 
+	  0.80000000000000004 },
+  { -0.26314561785585899, 10, 0, 
+	  0.89999999999999991 },
+  { 1.0000000000000000, 10, 0, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=10, m=0.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data011[i].l), Tp(data011[i].m),
+		     Tp(data011[i].x));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10, m=1.
+testcase_assoc_legendre<double> data012[] = {
+  { -0.0000000000000000, 10, 1, 
+	  -1.0000000000000000 },
+  { -3.0438748781479039, 10, 1, 
+	  -0.90000000000000002 },
+  { -0.87614260800000254, 10, 1, 
+	  -0.80000000000000004 },
+  { 2.9685359952934527, 10, 1, 
+	  -0.69999999999999996 },
+  { 1.2511825919999997, 10, 1, 
+	  -0.59999999999999998 },
+  { -2.0066877394361260, 10, 1, 
+	  -0.50000000000000000 },
+  { -2.4822196173476661, 10, 1, 
+	  -0.40000000000000002 },
+  { -0.12309508907433910, 10, 1, 
+	  -0.30000000000000004 },
+  { 2.2468221751958413, 10, 1, 
+	  -0.19999999999999996 },
+  { 2.2472659777983512, 10, 1, 
+	  -0.099999999999999978 },
+  { -0.0000000000000000, 10, 1, 
+	  0.0000000000000000 },
+  { -2.2472659777983535, 10, 1, 
+	  0.10000000000000009 },
+  { -2.2468221751958413, 10, 1, 
+	  0.19999999999999996 },
+  { 0.12309508907433910, 10, 1, 
+	  0.30000000000000004 },
+  { 2.4822196173476647, 10, 1, 
+	  0.39999999999999991 },
+  { 2.0066877394361260, 10, 1, 
+	  0.50000000000000000 },
+  { -1.2511825920000037, 10, 1, 
+	  0.60000000000000009 },
+  { -2.9685359952934527, 10, 1, 
+	  0.69999999999999996 },
+  { 0.87614260800000254, 10, 1, 
+	  0.80000000000000004 },
+  { 3.0438748781479115, 10, 1, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 10, 1, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=10, m=1.
+template<typename Tp>
+  void
+  test012()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data012)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data012[i].l), Tp(data012[i].m),
+		     Tp(data012[i].x));
+	const Tp f0 = data012[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10, m=2.
+testcase_assoc_legendre<double> data013[] = {
+  { 0.0000000000000000, 10, 2, 
+	  -1.0000000000000000 },
+  { 16.376387762496137, 10, 2, 
+	  -0.90000000000000002 },
+  { -35.394657804000005, 10, 2, 
+	  -0.80000000000000004 },
+  { -3.6191429423788648, 10, 2, 
+	  -0.69999999999999996 },
+  { 28.679675904000014, 10, 2, 
+	  -0.59999999999999998 },
+  { 18.388023376464844, 10, 2, 
+	  -0.50000000000000000 },
+  { -12.818955995999994, 10, 2, 
+	  -0.40000000000000002 },
+  { -27.739821675972664, 10, 2, 
+	  -0.30000000000000004 },
+  { -13.280661503999987, 10, 2, 
+	  -0.19999999999999996 },
+  { 13.885467170308601, 10, 2, 
+	  -0.099999999999999978 },
+  { 27.070312500000000, 10, 2, 
+	  0.0000000000000000 },
+  { 13.885467170308573, 10, 2, 
+	  0.10000000000000009 },
+  { -13.280661503999987, 10, 2, 
+	  0.19999999999999996 },
+  { -27.739821675972664, 10, 2, 
+	  0.30000000000000004 },
+  { -12.818955996000021, 10, 2, 
+	  0.39999999999999991 },
+  { 18.388023376464844, 10, 2, 
+	  0.50000000000000000 },
+  { 28.679675904000000, 10, 2, 
+	  0.60000000000000009 },
+  { -3.6191429423788648, 10, 2, 
+	  0.69999999999999996 },
+  { -35.394657804000005, 10, 2, 
+	  0.80000000000000004 },
+  { 16.376387762496009, 10, 2, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 10, 2, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=10, m=2.
+template<typename Tp>
+  void
+  test013()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data013)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data013[i].l), Tp(data013[i].m),
+		     Tp(data013[i].x));
+	const Tp f0 = data013[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10, m=5.
+testcase_assoc_legendre<double> data014[] = {
+  { 0.0000000000000000, 10, 5, 
+	  -1.0000000000000000 },
+  { 21343.618518164680, 10, 5, 
+	  -0.90000000000000002 },
+  { 40457.016407807983, 10, 5, 
+	  -0.80000000000000004 },
+  { 20321.279317331315, 10, 5, 
+	  -0.69999999999999996 },
+  { -14410.820616192004, 10, 5, 
+	  -0.59999999999999998 },
+  { -30086.169706116176, 10, 5, 
+	  -0.50000000000000000 },
+  { -17177.549337582859, 10, 5, 
+	  -0.40000000000000002 },
+  { 9272.5119495412364, 10, 5, 
+	  -0.30000000000000004 },
+  { 26591.511184414714, 10, 5, 
+	  -0.19999999999999996 },
+  { 21961.951238504211, 10, 5, 
+	  -0.099999999999999978 },
+  { -0.0000000000000000, 10, 5, 
+	  0.0000000000000000 },
+  { -21961.951238504229, 10, 5, 
+	  0.10000000000000009 },
+  { -26591.511184414714, 10, 5, 
+	  0.19999999999999996 },
+  { -9272.5119495412364, 10, 5, 
+	  0.30000000000000004 },
+  { 17177.549337582834, 10, 5, 
+	  0.39999999999999991 },
+  { 30086.169706116176, 10, 5, 
+	  0.50000000000000000 },
+  { 14410.820616191972, 10, 5, 
+	  0.60000000000000009 },
+  { -20321.279317331315, 10, 5, 
+	  0.69999999999999996 },
+  { -40457.016407807983, 10, 5, 
+	  0.80000000000000004 },
+  { -21343.618518164694, 10, 5, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 10, 5, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=10, m=5.
+template<typename Tp>
+  void
+  test014()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data014)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data014[i].l), Tp(data014[i].m),
+		     Tp(data014[i].x));
+	const Tp f0 = data014[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10, m=10.
+testcase_assoc_legendre<double> data015[] = {
+  { 0.0000000000000000, 10, 10, 
+	  -1.0000000000000000 },
+  { 162117.40078784220, 10, 10, 
+	  -0.90000000000000002 },
+  { 3958896.3481267113, 10, 10, 
+	  -0.80000000000000004 },
+  { 22589806.343887307, 10, 10, 
+	  -0.69999999999999996 },
+  { 70300999.121633321, 10, 10, 
+	  -0.59999999999999998 },
+  { 155370278.54003900, 10, 10, 
+	  -0.50000000000000000 },
+  { 273815518.20150518, 10, 10, 
+	  -0.40000000000000002 },
+  { 408571989.13158917, 10, 10, 
+	  -0.30000000000000004 },
+  { 533848212.07990247, 10, 10, 
+	  -0.19999999999999996 },
+  { 622640835.70523083, 10, 10, 
+	  -0.099999999999999978 },
+  { 654729075.00000000, 10, 10, 
+	  0.0000000000000000 },
+  { 622640835.70523083, 10, 10, 
+	  0.10000000000000009 },
+  { 533848212.07990247, 10, 10, 
+	  0.19999999999999996 },
+  { 408571989.13158917, 10, 10, 
+	  0.30000000000000004 },
+  { 273815518.20150518, 10, 10, 
+	  0.39999999999999991 },
+  { 155370278.54003900, 10, 10, 
+	  0.50000000000000000 },
+  { 70300999.121633217, 10, 10, 
+	  0.60000000000000009 },
+  { 22589806.343887307, 10, 10, 
+	  0.69999999999999996 },
+  { 3958896.3481267113, 10, 10, 
+	  0.80000000000000004 },
+  { 162117.40078784304, 10, 10, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 10, 10, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=10, m=10.
+template<typename Tp>
+  void
+  test015()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data015)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data015[i].l), Tp(data015[i].m),
+		     Tp(data015[i].x));
+	const Tp f0 = data015[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=20, m=0.
+testcase_assoc_legendre<double> data016[] = {
+  { 1.0000000000000000, 20, 0, 
+	  -1.0000000000000000 },
+  { -0.14930823530984835, 20, 0, 
+	  -0.90000000000000002 },
+  { 0.22420460541741347, 20, 0, 
+	  -0.80000000000000004 },
+  { -0.20457394463834172, 20, 0, 
+	  -0.69999999999999996 },
+  { 0.15916752910098109, 20, 0, 
+	  -0.59999999999999998 },
+  { -0.048358381067373557, 20, 0, 
+	  -0.50000000000000000 },
+  { -0.10159261558628156, 20, 0, 
+	  -0.40000000000000002 },
+  { 0.18028715947998042, 20, 0, 
+	  -0.30000000000000004 },
+  { -0.098042194344594796, 20, 0, 
+	  -0.19999999999999996 },
+  { -0.082077130944527663, 20, 0, 
+	  -0.099999999999999978 },
+  { 0.17619705200195312, 20, 0, 
+	  0.0000000000000000 },
+  { -0.082077130944528023, 20, 0, 
+	  0.10000000000000009 },
+  { -0.098042194344594796, 20, 0, 
+	  0.19999999999999996 },
+  { 0.18028715947998042, 20, 0, 
+	  0.30000000000000004 },
+  { -0.10159261558628112, 20, 0, 
+	  0.39999999999999991 },
+  { -0.048358381067373557, 20, 0, 
+	  0.50000000000000000 },
+  { 0.15916752910098075, 20, 0, 
+	  0.60000000000000009 },
+  { -0.20457394463834172, 20, 0, 
+	  0.69999999999999996 },
+  { 0.22420460541741347, 20, 0, 
+	  0.80000000000000004 },
+  { -0.14930823530984924, 20, 0, 
+	  0.89999999999999991 },
+  { 1.0000000000000000, 20, 0, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=20, m=0.
+template<typename Tp>
+  void
+  test016()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data016)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data016[i].l), Tp(data016[i].m),
+		     Tp(data016[i].x));
+	const Tp f0 = data016[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=20, m=1.
+testcase_assoc_legendre<double> data017[] = {
+  { 0.0000000000000000, 20, 1, 
+	  -1.0000000000000000 },
+  { 4.3838334818220499, 20, 1, 
+	  -0.90000000000000002 },
+  { -0.63138296146340844, 20, 1, 
+	  -0.80000000000000004 },
+  { 0.72274871413391395, 20, 1, 
+	  -0.69999999999999996 },
+  { -2.3203528743824910, 20, 1, 
+	  -0.59999999999999998 },
+  { 3.7399919228791405, 20, 1, 
+	  -0.50000000000000000 },
+  { -3.1692202279270041, 20, 1, 
+	  -0.40000000000000002 },
+  { 0.15804468835344135, 20, 1, 
+	  -0.30000000000000004 },
+  { 3.0366182393271171, 20, 1, 
+	  -0.19999999999999996 },
+  { -3.2115523815580209, 20, 1, 
+	  -0.099999999999999978 },
+  { 0.0000000000000000, 20, 1, 
+	  0.0000000000000000 },
+  { 3.2115523815580169, 20, 1, 
+	  0.10000000000000009 },
+  { -3.0366182393271171, 20, 1, 
+	  0.19999999999999996 },
+  { -0.15804468835344135, 20, 1, 
+	  0.30000000000000004 },
+  { 3.1692202279270085, 20, 1, 
+	  0.39999999999999991 },
+  { -3.7399919228791405, 20, 1, 
+	  0.50000000000000000 },
+  { 2.3203528743824995, 20, 1, 
+	  0.60000000000000009 },
+  { -0.72274871413391395, 20, 1, 
+	  0.69999999999999996 },
+  { 0.63138296146340844, 20, 1, 
+	  0.80000000000000004 },
+  { -4.3838334818220339, 20, 1, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 20, 1, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=20, m=1.
+template<typename Tp>
+  void
+  test017()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data017)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data017[i].l), Tp(data017[i].m),
+		     Tp(data017[i].x));
+	const Tp f0 = data017[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=20, m=2.
+testcase_assoc_legendre<double> data018[] = {
+  { 0.0000000000000000, 20, 2, 
+	  -1.0000000000000000 },
+  { 80.812425587310102, 20, 2, 
+	  -0.90000000000000002 },
+  { -95.849622172549374, 20, 2, 
+	  -0.80000000000000004 },
+  { 87.337927630325510, 20, 2, 
+	  -0.69999999999999996 },
+  { -70.330891533985834, 20, 2, 
+	  -0.59999999999999998 },
+  { 24.629090735179489, 20, 2, 
+	  -0.50000000000000000 },
+  { 39.902576338912425, 20, 2, 
+	  -0.40000000000000002 },
+  { -75.621201471396603, 20, 2, 
+	  -0.30000000000000004 },
+  { 42.417415829726494, 20, 2, 
+	  -0.19999999999999996 },
+  { 33.826848678871293, 20, 2, 
+	  -0.099999999999999978 },
+  { -74.002761840820312, 20, 2, 
+	  0.0000000000000000 },
+  { 33.826848678871464, 20, 2, 
+	  0.10000000000000009 },
+  { 42.417415829726494, 20, 2, 
+	  0.19999999999999996 },
+  { -75.621201471396603, 20, 2, 
+	  0.30000000000000004 },
+  { 39.902576338912247, 20, 2, 
+	  0.39999999999999991 },
+  { 24.629090735179489, 20, 2, 
+	  0.50000000000000000 },
+  { -70.330891533985721, 20, 2, 
+	  0.60000000000000009 },
+  { 87.337927630325510, 20, 2, 
+	  0.69999999999999996 },
+  { -95.849622172549374, 20, 2, 
+	  0.80000000000000004 },
+  { 80.812425587310500, 20, 2, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 20, 2, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=20, m=2.
+template<typename Tp>
+  void
+  test018()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data018)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data018[i].l), Tp(data018[i].m),
+		     Tp(data018[i].x));
+	const Tp f0 = data018[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=20, m=5.
+testcase_assoc_legendre<double> data019[] = {
+  { -0.0000000000000000, 20, 5, 
+	  -1.0000000000000000 },
+  { -315702.32715134218, 20, 5, 
+	  -0.90000000000000002 },
+  { 503060.91484852589, 20, 5, 
+	  -0.80000000000000004 },
+  { -298127.28360361955, 20, 5, 
+	  -0.69999999999999996 },
+  { -114444.61447464029, 20, 5, 
+	  -0.59999999999999998 },
+  { 543428.40914592845, 20, 5, 
+	  -0.50000000000000000 },
+  { -613842.07728185470, 20, 5, 
+	  -0.40000000000000002 },
+  { 143765.42411270936, 20, 5, 
+	  -0.30000000000000004 },
+  { 472600.45321372285, 20, 5, 
+	  -0.19999999999999996 },
+  { -563861.76771496492, 20, 5, 
+	  -0.099999999999999978 },
+  { 0.0000000000000000, 20, 5, 
+	  0.0000000000000000 },
+  { 563861.76771496458, 20, 5, 
+	  0.10000000000000009 },
+  { -472600.45321372285, 20, 5, 
+	  0.19999999999999996 },
+  { -143765.42411270936, 20, 5, 
+	  0.30000000000000004 },
+  { 613842.07728185481, 20, 5, 
+	  0.39999999999999991 },
+  { -543428.40914592845, 20, 5, 
+	  0.50000000000000000 },
+  { 114444.61447464178, 20, 5, 
+	  0.60000000000000009 },
+  { 298127.28360361955, 20, 5, 
+	  0.69999999999999996 },
+  { -503060.91484852589, 20, 5, 
+	  0.80000000000000004 },
+  { 315702.32715134491, 20, 5, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 20, 5, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=20, m=5.
+template<typename Tp>
+  void
+  test019()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data019)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data019[i].l), Tp(data019[i].m),
+		     Tp(data019[i].x));
+	const Tp f0 = data019[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=20, m=10.
+testcase_assoc_legendre<double> data020[] = {
+  { -0.0000000000000000, 20, 10, 
+	  -1.0000000000000000 },
+  { 990017476694.99084, 20, 10, 
+	  -0.90000000000000002 },
+  { 2392757933281.0498, 20, 10, 
+	  -0.80000000000000004 },
+  { -1548364524949.5808, 20, 10, 
+	  -0.69999999999999996 },
+  { -424471915195.05627, 20, 10, 
+	  -0.59999999999999998 },
+  { 1744502295946.2073, 20, 10, 
+	  -0.50000000000000000 },
+  { -899973487310.55212, 20, 10, 
+	  -0.40000000000000002 },
+  { -1092420454297.7161, 20, 10, 
+	  -0.30000000000000004 },
+  { 1466609267659.8816, 20, 10, 
+	  -0.19999999999999996 },
+  { 356041756390.71674, 20, 10, 
+	  -0.099999999999999978 },
+  { -1612052956674.3164, 20, 10, 
+	  0.0000000000000000 },
+  { 356041756390.71985, 20, 10, 
+	  0.10000000000000009 },
+  { 1466609267659.8816, 20, 10, 
+	  0.19999999999999996 },
+  { -1092420454297.7161, 20, 10, 
+	  0.30000000000000004 },
+  { -899973487310.55530, 20, 10, 
+	  0.39999999999999991 },
+  { 1744502295946.2073, 20, 10, 
+	  0.50000000000000000 },
+  { -424471915195.05896, 20, 10, 
+	  0.60000000000000009 },
+  { -1548364524949.5808, 20, 10, 
+	  0.69999999999999996 },
+  { 2392757933281.0498, 20, 10, 
+	  0.80000000000000004 },
+  { 990017476694.99316, 20, 10, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 20, 10, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=20, m=10.
+template<typename Tp>
+  void
+  test020()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data020)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data020[i].l), Tp(data020[i].m),
+		     Tp(data020[i].x));
+	const Tp f0 = data020[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=20, m=20.
+testcase_assoc_legendre<double> data021[] = {
+  { 0.0000000000000000, 20, 20, 
+	  -1.0000000000000000 },
+  { 19609049712023808., 20, 20, 
+	  -0.90000000000000002 },
+  { 1.1693527616833221e+19, 20, 20, 
+	  -0.80000000000000004 },
+  { 3.8073455880620691e+20, 20, 20, 
+	  -0.69999999999999996 },
+  { 3.6874002249007927e+21, 20, 20, 
+	  -0.59999999999999998 },
+  { 1.8010806978179592e+22, 20, 20, 
+	  -0.50000000000000000 },
+  { 5.5938832584012466e+22, 20, 20, 
+	  -0.40000000000000002 },
+  { 1.2454734132297811e+23, 20, 20, 
+	  -0.30000000000000004 },
+  { 2.1263407800797497e+23, 20, 20, 
+	  -0.19999999999999996 },
+  { 2.8924941146976873e+23, 20, 20, 
+	  -0.099999999999999978 },
+  { 3.1983098677287775e+23, 20, 20, 
+	  0.0000000000000000 },
+  { 2.8924941146976873e+23, 20, 20, 
+	  0.10000000000000009 },
+  { 2.1263407800797497e+23, 20, 20, 
+	  0.19999999999999996 },
+  { 1.2454734132297811e+23, 20, 20, 
+	  0.30000000000000004 },
+  { 5.5938832584012466e+22, 20, 20, 
+	  0.39999999999999991 },
+  { 1.8010806978179592e+22, 20, 20, 
+	  0.50000000000000000 },
+  { 3.6874002249007807e+21, 20, 20, 
+	  0.60000000000000009 },
+  { 3.8073455880620691e+20, 20, 20, 
+	  0.69999999999999996 },
+  { 1.1693527616833221e+19, 20, 20, 
+	  0.80000000000000004 },
+  { 19609049712024020., 20, 20, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 20, 20, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=20, m=20.
+template<typename Tp>
+  void
+  test021()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data021)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data021[i].l), Tp(data021[i].m),
+		     Tp(data021[i].x));
+	const Tp f0 = data021[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=50, m=0.
+testcase_assoc_legendre<double> data022[] = {
+  { 1.0000000000000000, 50, 0, 
+	  -1.0000000000000000 },
+  { -0.17003765994383671, 50, 0, 
+	  -0.90000000000000002 },
+  { 0.13879737345093113, 50, 0, 
+	  -0.80000000000000004 },
+  { -0.014572731645892852, 50, 0, 
+	  -0.69999999999999996 },
+  { -0.058860798844002096, 50, 0, 
+	  -0.59999999999999998 },
+  { -0.031059099239609811, 50, 0, 
+	  -0.50000000000000000 },
+  { 0.041569033381825375, 50, 0, 
+	  -0.40000000000000002 },
+  { 0.10911051574714797, 50, 0, 
+	  -0.30000000000000004 },
+  { 0.083432272204197494, 50, 0, 
+	  -0.19999999999999996 },
+  { -0.038205812661313600, 50, 0, 
+	  -0.099999999999999978 },
+  { -0.11227517265921705, 50, 0, 
+	  0.0000000000000000 },
+  { -0.038205812661314155, 50, 0, 
+	  0.10000000000000009 },
+  { 0.083432272204197494, 50, 0, 
+	  0.19999999999999996 },
+  { 0.10911051574714797, 50, 0, 
+	  0.30000000000000004 },
+  { 0.041569033381824674, 50, 0, 
+	  0.39999999999999991 },
+  { -0.031059099239609811, 50, 0, 
+	  0.50000000000000000 },
+  { -0.058860798844001430, 50, 0, 
+	  0.60000000000000009 },
+  { -0.014572731645892852, 50, 0, 
+	  0.69999999999999996 },
+  { 0.13879737345093113, 50, 0, 
+	  0.80000000000000004 },
+  { -0.17003765994383657, 50, 0, 
+	  0.89999999999999991 },
+  { 1.0000000000000000, 50, 0, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=50, m=0.
+template<typename Tp>
+  void
+  test022()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data022)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data022[i].l), Tp(data022[i].m),
+		     Tp(data022[i].x));
+	const Tp f0 = data022[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=50, m=1.
+testcase_assoc_legendre<double> data023[] = {
+  { 0.0000000000000000, 50, 1, 
+	  -1.0000000000000000 },
+  { -0.13424149984449490, 50, 1, 
+	  -0.90000000000000002 },
+  { 2.2011219672413018, 50, 1, 
+	  -0.80000000000000004 },
+  { 6.6622414993232004, 50, 1, 
+	  -0.69999999999999996 },
+  { 5.5772846936919249, 50, 1, 
+	  -0.59999999999999998 },
+  { 5.8787148815607608, 50, 1, 
+	  -0.50000000000000000 },
+  { 5.5473459458633974, 50, 1, 
+	  -0.40000000000000002 },
+  { 1.8444956647619930, 50, 1, 
+	  -0.30000000000000004 },
+  { -3.8722014306642127, 50, 1, 
+	  -0.19999999999999996 },
+  { -5.3488751322285628, 50, 1, 
+	  -0.099999999999999978 },
+  { -0.0000000000000000, 50, 1, 
+	  0.0000000000000000 },
+  { 5.3488751322285522, 50, 1, 
+	  0.10000000000000009 },
+  { 3.8722014306642127, 50, 1, 
+	  0.19999999999999996 },
+  { -1.8444956647619930, 50, 1, 
+	  0.30000000000000004 },
+  { -5.5473459458634080, 50, 1, 
+	  0.39999999999999991 },
+  { -5.8787148815607608, 50, 1, 
+	  0.50000000000000000 },
+  { -5.5772846936919453, 50, 1, 
+	  0.60000000000000009 },
+  { -6.6622414993232004, 50, 1, 
+	  0.69999999999999996 },
+  { -2.2011219672413018, 50, 1, 
+	  0.80000000000000004 },
+  { 0.13424149984462019, 50, 1, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 50, 1, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=50, m=1.
+template<typename Tp>
+  void
+  test023()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data023)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data023[i].l), Tp(data023[i].m),
+		     Tp(data023[i].x));
+	const Tp f0 = data023[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=50, m=2.
+testcase_assoc_legendre<double> data024[] = {
+  { 0.0000000000000000, 50, 2, 
+	  -1.0000000000000000 },
+  { 433.04168483713511, 50, 2, 
+	  -0.90000000000000002 },
+  { -348.06364372056424, 50, 2, 
+	  -0.80000000000000004 },
+  { 50.221071418108444, 50, 2, 
+	  -0.69999999999999996 },
+  { 158.46096409274352, 50, 2, 
+	  -0.59999999999999998 },
+  { 85.988858299721457, 50, 2, 
+	  -0.50000000000000000 },
+  { -101.15891460879270, 50, 2, 
+	  -0.40000000000000002 },
+  { -277.07168105316617, 50, 2, 
+	  -0.30000000000000004 },
+  { -214.33311373510401, 50, 2, 
+	  -0.19999999999999996 },
+  { 96.349657930951665, 50, 2, 
+	  -0.099999999999999978 },
+  { 286.30169028100346, 50, 2, 
+	  0.0000000000000000 },
+  { 96.349657930953242, 50, 2, 
+	  0.10000000000000009 },
+  { -214.33311373510401, 50, 2, 
+	  0.19999999999999996 },
+  { -277.07168105316617, 50, 2, 
+	  0.30000000000000004 },
+  { -101.15891460879088, 50, 2, 
+	  0.39999999999999991 },
+  { 85.988858299721457, 50, 2, 
+	  0.50000000000000000 },
+  { 158.46096409274153, 50, 2, 
+	  0.60000000000000009 },
+  { 50.221071418108444, 50, 2, 
+	  0.69999999999999996 },
+  { -348.06364372056424, 50, 2, 
+	  0.80000000000000004 },
+  { 433.04168483713374, 50, 2, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 50, 2, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=50, m=2.
+template<typename Tp>
+  void
+  test024()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data024)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data024[i].l), Tp(data024[i].m),
+		     Tp(data024[i].x));
+	const Tp f0 = data024[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=50, m=5.
+testcase_assoc_legendre<double> data025[] = {
+  { -0.0000000000000000, 50, 5, 
+	  -1.0000000000000000 },
+  { -27340473.952132829, 50, 5, 
+	  -0.90000000000000002 },
+  { 27753716.768532373, 50, 5, 
+	  -0.80000000000000004 },
+  { 40808153.913493633, 50, 5, 
+	  -0.69999999999999996 },
+  { 32071189.035790090, 50, 5, 
+	  -0.59999999999999998 },
+  { 36265736.218529105, 50, 5, 
+	  -0.50000000000000000 },
+  { 37089596.700204901, 50, 5, 
+	  -0.40000000000000002 },
+  { 14562029.629244499, 50, 5, 
+	  -0.30000000000000004 },
+  { -23686895.217517190, 50, 5, 
+	  -0.19999999999999996 },
+  { -34878992.965676002, 50, 5, 
+	  -0.099999999999999978 },
+  { -0.0000000000000000, 50, 5, 
+	  0.0000000000000000 },
+  { 34878992.965675958, 50, 5, 
+	  0.10000000000000009 },
+  { 23686895.217517190, 50, 5, 
+	  0.19999999999999996 },
+  { -14562029.629244499, 50, 5, 
+	  0.30000000000000004 },
+  { -37089596.700204931, 50, 5, 
+	  0.39999999999999991 },
+  { -36265736.218529105, 50, 5, 
+	  0.50000000000000000 },
+  { -32071189.035790242, 50, 5, 
+	  0.60000000000000009 },
+  { -40808153.913493633, 50, 5, 
+	  0.69999999999999996 },
+  { -27753716.768532373, 50, 5, 
+	  0.80000000000000004 },
+  { 27340473.952133428, 50, 5, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 50, 5, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=50, m=5.
+template<typename Tp>
+  void
+  test025()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data025)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data025[i].l), Tp(data025[i].m),
+		     Tp(data025[i].x));
+	const Tp f0 = data025[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=50, m=10.
+testcase_assoc_legendre<double> data026[] = {
+  { -0.0000000000000000, 50, 10, 
+	  -1.0000000000000000 },
+  { -8994661710093155.0, 50, 10, 
+	  -0.90000000000000002 },
+  { 932311375306569.62, 50, 10, 
+	  -0.80000000000000004 },
+  { 12153535011507012., 50, 10, 
+	  -0.69999999999999996 },
+  { 12176690755542240., 50, 10, 
+	  -0.59999999999999998 },
+  { 9180035388465754.0, 50, 10, 
+	  -0.50000000000000000 },
+  { 889201701866910.38, 50, 10, 
+	  -0.40000000000000002 },
+  { -9451384032851604.0, 50, 10, 
+	  -0.30000000000000004 },
+  { -9926439446673564.0, 50, 10, 
+	  -0.19999999999999996 },
+  { 2794368162749970.5, 50, 10, 
+	  -0.099999999999999978 },
+  { 11452238249246346., 50, 10, 
+	  0.0000000000000000 },
+  { 2794368162750031.0, 50, 10, 
+	  0.10000000000000009 },
+  { -9926439446673564.0, 50, 10, 
+	  0.19999999999999996 },
+  { -9451384032851604.0, 50, 10, 
+	  0.30000000000000004 },
+  { 889201701866984.00, 50, 10, 
+	  0.39999999999999991 },
+  { 9180035388465754.0, 50, 10, 
+	  0.50000000000000000 },
+  { 12176690755542214., 50, 10, 
+	  0.60000000000000009 },
+  { 12153535011507012., 50, 10, 
+	  0.69999999999999996 },
+  { 932311375306569.62, 50, 10, 
+	  0.80000000000000004 },
+  { -8994661710093362.0, 50, 10, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 50, 10, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=50, m=10.
+template<typename Tp>
+  void
+  test026()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data026)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data026[i].l), Tp(data026[i].m),
+		     Tp(data026[i].x));
+	const Tp f0 = data026[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=50, m=20.
+testcase_assoc_legendre<double> data027[] = {
+  { 0.0000000000000000, 50, 20, 
+	  -1.0000000000000000 },
+  { 1.6630925158645501e+33, 50, 20, 
+	  -0.90000000000000002 },
+  { 1.0622676657892052e+33, 50, 20, 
+	  -0.80000000000000004 },
+  { 8.6022521164717112e+32, 50, 20, 
+	  -0.69999999999999996 },
+  { 4.0860128756808466e+32, 50, 20, 
+	  -0.59999999999999998 },
+  { -4.0169860814274459e+32, 50, 20, 
+	  -0.50000000000000000 },
+  { -8.2324325279774037e+32, 50, 20, 
+	  -0.40000000000000002 },
+  { -4.0054067236243731e+31, 50, 20, 
+	  -0.30000000000000004 },
+  { 7.9309266056434309e+32, 50, 20, 
+	  -0.19999999999999996 },
+  { 5.4151358290898977e+31, 50, 20, 
+	  -0.099999999999999978 },
+  { -7.8735935697332210e+32, 50, 20, 
+	  0.0000000000000000 },
+  { 5.4151358290894924e+31, 50, 20, 
+	  0.10000000000000009 },
+  { 7.9309266056434309e+32, 50, 20, 
+	  0.19999999999999996 },
+  { -4.0054067236243731e+31, 50, 20, 
+	  0.30000000000000004 },
+  { -8.2324325279773994e+32, 50, 20, 
+	  0.39999999999999991 },
+  { -4.0169860814274459e+32, 50, 20, 
+	  0.50000000000000000 },
+  { 4.0860128756807846e+32, 50, 20, 
+	  0.60000000000000009 },
+  { 8.6022521164717112e+32, 50, 20, 
+	  0.69999999999999996 },
+  { 1.0622676657892052e+33, 50, 20, 
+	  0.80000000000000004 },
+  { 1.6630925158645483e+33, 50, 20, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 50, 20, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=50, m=20.
+template<typename Tp>
+  void
+  test027()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data027)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data027[i].l), Tp(data027[i].m),
+		     Tp(data027[i].x));
+	const Tp f0 = data027[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=50, m=50.
+testcase_assoc_legendre<double> data028[] = {
+  { 0.0000000000000000, 50, 50, 
+	  -1.0000000000000000 },
+  { 2.5366994974431341e+60, 50, 50, 
+	  -0.90000000000000002 },
+  { 2.2028834403101213e+67, 50, 50, 
+	  -0.80000000000000004 },
+  { 1.3325496559566651e+71, 50, 50, 
+	  -0.69999999999999996 },
+  { 3.8898096431781969e+73, 50, 50, 
+	  -0.59999999999999998 },
+  { 2.0509760257037188e+75, 50, 50, 
+	  -0.50000000000000000 },
+  { 3.4866724533443283e+76, 50, 50, 
+	  -0.40000000000000002 },
+  { 2.5790740224150207e+77, 50, 50, 
+	  -0.30000000000000004 },
+  { 9.8222237931680989e+77, 50, 50, 
+	  -0.19999999999999996 },
+  { 2.1198682190366617e+78, 50, 50, 
+	  -0.099999999999999978 },
+  { 2.7253921397507295e+78, 50, 50, 
+	  0.0000000000000000 },
+  { 2.1198682190366617e+78, 50, 50, 
+	  0.10000000000000009 },
+  { 9.8222237931680989e+77, 50, 50, 
+	  0.19999999999999996 },
+  { 2.5790740224150207e+77, 50, 50, 
+	  0.30000000000000004 },
+  { 3.4866724533443283e+76, 50, 50, 
+	  0.39999999999999991 },
+  { 2.0509760257037188e+75, 50, 50, 
+	  0.50000000000000000 },
+  { 3.8898096431781724e+73, 50, 50, 
+	  0.60000000000000009 },
+  { 1.3325496559566651e+71, 50, 50, 
+	  0.69999999999999996 },
+  { 2.2028834403101213e+67, 50, 50, 
+	  0.80000000000000004 },
+  { 2.5366994974431990e+60, 50, 50, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 50, 50, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=50, m=50.
+template<typename Tp>
+  void
+  test028()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data028)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data028[i].l), Tp(data028[i].m),
+		     Tp(data028[i].x));
+	const Tp f0 = data028[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=100, m=0.
+testcase_assoc_legendre<double> data029[] = {
+  { 1.0000000000000000, 100, 0, 
+	  -1.0000000000000000 },
+  { 0.10226582055871893, 100, 0, 
+	  -0.90000000000000002 },
+  { 0.050861167913584228, 100, 0, 
+	  -0.80000000000000004 },
+  { -0.077132507199778641, 100, 0, 
+	  -0.69999999999999996 },
+  { -0.023747023905133141, 100, 0, 
+	  -0.59999999999999998 },
+  { -0.060518025961861198, 100, 0, 
+	  -0.50000000000000000 },
+  { -0.072258202125684470, 100, 0, 
+	  -0.40000000000000002 },
+  { 0.057127392202801566, 100, 0, 
+	  -0.30000000000000004 },
+  { 0.014681835355659706, 100, 0, 
+	  -0.19999999999999996 },
+  { -0.063895098434750205, 100, 0, 
+	  -0.099999999999999978 },
+  { 0.079589237387178727, 100, 0, 
+	  0.0000000000000000 },
+  { -0.063895098434749761, 100, 0, 
+	  0.10000000000000009 },
+  { 0.014681835355659706, 100, 0, 
+	  0.19999999999999996 },
+  { 0.057127392202801566, 100, 0, 
+	  0.30000000000000004 },
+  { -0.072258202125685025, 100, 0, 
+	  0.39999999999999991 },
+  { -0.060518025961861198, 100, 0, 
+	  0.50000000000000000 },
+  { -0.023747023905134217, 100, 0, 
+	  0.60000000000000009 },
+  { -0.077132507199778641, 100, 0, 
+	  0.69999999999999996 },
+  { 0.050861167913584228, 100, 0, 
+	  0.80000000000000004 },
+  { 0.10226582055871711, 100, 0, 
+	  0.89999999999999991 },
+  { 1.0000000000000000, 100, 0, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=100, m=0.
+template<typename Tp>
+  void
+  test029()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data029)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data029[i].l), Tp(data029[i].m),
+		     Tp(data029[i].x));
+	const Tp f0 = data029[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for l=100, m=1.
+testcase_assoc_legendre<double> data030[] = {
+  { -0.0000000000000000, 100, 1, 
+	  -1.0000000000000000 },
+  { 6.5200167187780345, 100, 1, 
+	  -0.90000000000000002 },
+  { 9.0065170007027486, 100, 1, 
+	  -0.80000000000000004 },
+  { -5.4690908541180976, 100, 1, 
+	  -0.69999999999999996 },
+  { -8.6275439170430790, 100, 1, 
+	  -0.59999999999999998 },
+  { -6.0909031663448454, 100, 1, 
+	  -0.50000000000000000 },
+  { 4.1160338699561212, 100, 1, 
+	  -0.40000000000000002 },
+  { 5.8491043010758013, 100, 1, 
+	  -0.30000000000000004 },
+  { -7.9435138723089826, 100, 1, 
+	  -0.19999999999999996 },
+  { 4.7996285823989355, 100, 1, 
+	  -0.099999999999999978 },
+  { 0.0000000000000000, 100, 1, 
+	  0.0000000000000000 },
+  { -4.7996285823990101, 100, 1, 
+	  0.10000000000000009 },
+  { 7.9435138723089826, 100, 1, 
+	  0.19999999999999996 },
+  { -5.8491043010758013, 100, 1, 
+	  0.30000000000000004 },
+  { -4.1160338699560395, 100, 1, 
+	  0.39999999999999991 },
+  { 6.0909031663448454, 100, 1, 
+	  0.50000000000000000 },
+  { 8.6275439170430470, 100, 1, 
+	  0.60000000000000009 },
+  { 5.4690908541180976, 100, 1, 
+	  0.69999999999999996 },
+  { -9.0065170007027486, 100, 1, 
+	  0.80000000000000004 },
+  { -6.5200167187783542, 100, 1, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 100, 1, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=100, m=1.
+template<typename Tp>
+  void
+  test030()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data030)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data030[i].l), Tp(data030[i].m),
+		     Tp(data030[i].x));
+	const Tp f0 = data030[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=100, m=2.
+testcase_assoc_legendre<double> data031[] = {
+  { 0.0000000000000000, 100, 2, 
+	  -1.0000000000000000 },
+  { -1005.9604880761002, 100, 2, 
+	  -0.90000000000000002 },
+  { -489.68041725865947, 100, 2, 
+	  -0.80000000000000004 },
+  { 768.31676011669924, 100, 2, 
+	  -0.69999999999999996 },
+  { 226.90362556627937, 100, 2, 
+	  -0.59999999999999998 },
+  { 604.19889304940341, 100, 2, 
+	  -0.50000000000000000 },
+  { 733.40061037838029, 100, 2, 
+	  -0.40000000000000002 },
+  { -573.30774483996390, 100, 2, 
+	  -0.30000000000000004 },
+  { -151.52946305080880, 100, 2, 
+	  -0.19999999999999996 },
+  { 646.30525583587985, 100, 2, 
+	  -0.099999999999999978 },
+  { -803.85129761050518, 100, 2, 
+	  0.0000000000000000 },
+  { 646.30525583587439, 100, 2, 
+	  0.10000000000000009 },
+  { -151.52946305080880, 100, 2, 
+	  0.19999999999999996 },
+  { -573.30774483996390, 100, 2, 
+	  0.30000000000000004 },
+  { 733.40061037838518, 100, 2, 
+	  0.39999999999999991 },
+  { 604.19889304940341, 100, 2, 
+	  0.50000000000000000 },
+  { 226.90362556629168, 100, 2, 
+	  0.60000000000000009 },
+  { 768.31676011669924, 100, 2, 
+	  0.69999999999999996 },
+  { -489.68041725865947, 100, 2, 
+	  0.80000000000000004 },
+  { -1005.9604880760779, 100, 2, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 100, 2, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=100, m=2.
+template<typename Tp>
+  void
+  test031()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data031)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data031[i].l), Tp(data031[i].m),
+		     Tp(data031[i].x));
+	const Tp f0 = data031[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=100, m=5.
+testcase_assoc_legendre<double> data032[] = {
+  { 0.0000000000000000, 100, 5, 
+	  -1.0000000000000000 },
+  { 900551126.09653807, 100, 5, 
+	  -0.90000000000000002 },
+  { 988567431.55756140, 100, 5, 
+	  -0.80000000000000004 },
+  { -645646451.90344620, 100, 5, 
+	  -0.69999999999999996 },
+  { -897114585.29920685, 100, 5, 
+	  -0.59999999999999998 },
+  { -661710744.42483854, 100, 5, 
+	  -0.50000000000000000 },
+  { 380163158.51425636, 100, 5, 
+	  -0.40000000000000002 },
+  { 617391071.36632574, 100, 5, 
+	  -0.30000000000000004 },
+  { -805288801.85509109, 100, 5, 
+	  -0.19999999999999996 },
+  { 481041740.16728652, 100, 5, 
+	  -0.099999999999999978 },
+  { 0.0000000000000000, 100, 5, 
+	  0.0000000000000000 },
+  { -481041740.16729391, 100, 5, 
+	  0.10000000000000009 },
+  { 805288801.85509109, 100, 5, 
+	  0.19999999999999996 },
+  { -617391071.36632574, 100, 5, 
+	  0.30000000000000004 },
+  { -380163158.51424754, 100, 5, 
+	  0.39999999999999991 },
+  { 661710744.42483854, 100, 5, 
+	  0.50000000000000000 },
+  { 897114585.29920483, 100, 5, 
+	  0.60000000000000009 },
+  { 645646451.90344620, 100, 5, 
+	  0.69999999999999996 },
+  { -988567431.55756140, 100, 5, 
+	  0.80000000000000004 },
+  { -900551126.09655857, 100, 5, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 100, 5, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=100, m=5.
+template<typename Tp>
+  void
+  test032()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data032)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data032[i].l), Tp(data032[i].m),
+		     Tp(data032[i].x));
+	const Tp f0 = data032[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=100, m=10.
+testcase_assoc_legendre<double> data033[] = {
+  { 0.0000000000000000, 100, 10, 
+	  -1.0000000000000000 },
+  { 2.5643395957658602e+17, 100, 10, 
+	  -0.90000000000000002 },
+  { 1.5778673545673485e+18, 100, 10, 
+	  -0.80000000000000004 },
+  { 4.4355048487496801e+18, 100, 10, 
+	  -0.69999999999999996 },
+  { -9.5936111659124288e+17, 100, 10, 
+	  -0.59999999999999998 },
+  { 4.2387123021963438e+18, 100, 10, 
+	  -0.50000000000000000 },
+  { 8.2370834618426542e+18, 100, 10, 
+	  -0.40000000000000002 },
+  { -4.9089358388052941e+18, 100, 10, 
+	  -0.30000000000000004 },
+  { -2.3468810358091274e+18, 100, 10, 
+	  -0.19999999999999996 },
+  { 6.8627855225034568e+18, 100, 10, 
+	  -0.099999999999999978 },
+  { -8.2494597181670380e+18, 100, 10, 
+	  0.0000000000000000 },
+  { 6.8627855225034056e+18, 100, 10, 
+	  0.10000000000000009 },
+  { -2.3468810358091274e+18, 100, 10, 
+	  0.19999999999999996 },
+  { -4.9089358388052941e+18, 100, 10, 
+	  0.30000000000000004 },
+  { 8.2370834618426767e+18, 100, 10, 
+	  0.39999999999999991 },
+  { 4.2387123021963438e+18, 100, 10, 
+	  0.50000000000000000 },
+  { -9.5936111659112640e+17, 100, 10, 
+	  0.60000000000000009 },
+  { 4.4355048487496801e+18, 100, 10, 
+	  0.69999999999999996 },
+  { 1.5778673545673485e+18, 100, 10, 
+	  0.80000000000000004 },
+  { 2.5643395957697341e+17, 100, 10, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 100, 10, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=100, m=10.
+template<typename Tp>
+  void
+  test033()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data033)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data033[i].l), Tp(data033[i].m),
+		     Tp(data033[i].x));
+	const Tp f0 = data033[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=100, m=20.
+testcase_assoc_legendre<double> data034[] = {
+  { 0.0000000000000000, 100, 20, 
+	  -1.0000000000000000 },
+  { 7.1604344878780134e+37, 100, 20, 
+	  -0.90000000000000002 },
+  { -8.3963895116962231e+38, 100, 20, 
+	  -0.80000000000000004 },
+  { 7.9022236853110145e+38, 100, 20, 
+	  -0.69999999999999996 },
+  { 8.2680005574121013e+38, 100, 20, 
+	  -0.59999999999999998 },
+  { 3.0750497039999552e+38, 100, 20, 
+	  -0.50000000000000000 },
+  { -7.6120586043843889e+38, 100, 20, 
+	  -0.40000000000000002 },
+  { 1.1474496891901797e+38, 100, 20, 
+	  -0.30000000000000004 },
+  { 4.3966251307444241e+38, 100, 20, 
+	  -0.19999999999999996 },
+  { -7.0503266451702591e+38, 100, 20, 
+	  -0.099999999999999978 },
+  { 7.7727439836159581e+38, 100, 20, 
+	  0.0000000000000000 },
+  { -7.0503266451702213e+38, 100, 20, 
+	  0.10000000000000009 },
+  { 4.3966251307444241e+38, 100, 20, 
+	  0.19999999999999996 },
+  { 1.1474496891901797e+38, 100, 20, 
+	  0.30000000000000004 },
+  { -7.6120586043843556e+38, 100, 20, 
+	  0.39999999999999991 },
+  { 3.0750497039999552e+38, 100, 20, 
+	  0.50000000000000000 },
+  { 8.2680005574120394e+38, 100, 20, 
+	  0.60000000000000009 },
+  { 7.9022236853110145e+38, 100, 20, 
+	  0.69999999999999996 },
+  { -8.3963895116962231e+38, 100, 20, 
+	  0.80000000000000004 },
+  { 7.1604344878812652e+37, 100, 20, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 100, 20, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=100, m=20.
+template<typename Tp>
+  void
+  test034()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data034)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data034[i].l), Tp(data034[i].m),
+		     Tp(data034[i].x));
+	const Tp f0 = data034[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=100, m=50.
+testcase_assoc_legendre<double> data035[] = {
+  { 0.0000000000000000, 100, 50, 
+	  -1.0000000000000000 },
+  { 9.3231278516893716e+96, 100, 50, 
+	  -0.90000000000000002 },
+  { -1.1029797977454281e+98, 100, 50, 
+	  -0.80000000000000004 },
+  { 1.8089333903465606e+97, 100, 50, 
+	  -0.69999999999999996 },
+  { 5.9364045925669405e+97, 100, 50, 
+	  -0.59999999999999998 },
+  { -8.2252620339727118e+97, 100, 50, 
+	  -0.50000000000000000 },
+  { 7.1431385093739863e+97, 100, 50, 
+	  -0.40000000000000002 },
+  { -3.3520602067479344e+97, 100, 50, 
+	  -0.30000000000000004 },
+  { -2.7791149588121382e+97, 100, 50, 
+	  -0.19999999999999996 },
+  { 9.0119338550180417e+97, 100, 50, 
+	  -0.099999999999999978 },
+  { -1.1712145031578381e+98, 100, 50, 
+	  0.0000000000000000 },
+  { 9.0119338550181207e+97, 100, 50, 
+	  0.10000000000000009 },
+  { -2.7791149588121382e+97, 100, 50, 
+	  0.19999999999999996 },
+  { -3.3520602067479344e+97, 100, 50, 
+	  0.30000000000000004 },
+  { 7.1431385093740728e+97, 100, 50, 
+	  0.39999999999999991 },
+  { -8.2252620339727118e+97, 100, 50, 
+	  0.50000000000000000 },
+  { 5.9364045925668024e+97, 100, 50, 
+	  0.60000000000000009 },
+  { 1.8089333903465606e+97, 100, 50, 
+	  0.69999999999999996 },
+  { -1.1029797977454281e+98, 100, 50, 
+	  0.80000000000000004 },
+  { 9.3231278516894968e+96, 100, 50, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 100, 50, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=100, m=50.
+template<typename Tp>
+  void
+  test035()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data035)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data035[i].l), Tp(data035[i].m),
+		     Tp(data035[i].x));
+	const Tp f0 = data035[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=100, m=100.
+testcase_assoc_legendre<double> data036[] = {
+  { 0.0000000000000000, 100, 100, 
+	  -1.0000000000000000 },
+  { 5.7751792255758316e+150, 100, 100, 
+	  -0.90000000000000002 },
+  { 4.3552236041585515e+164, 100, 100, 
+	  -0.80000000000000004 },
+  { 1.5936546850595123e+172, 100, 100, 
+	  -0.69999999999999996 },
+  { 1.3579510590289176e+177, 100, 100, 
+	  -0.59999999999999998 },
+  { 3.7752749682889513e+180, 100, 100, 
+	  -0.50000000000000000 },
+  { 1.0910627330458913e+183, 100, 100, 
+	  -0.40000000000000002 },
+  { 5.9697347526822483e+184, 100, 100, 
+	  -0.30000000000000004 },
+  { 8.6585879147526714e+185, 100, 100, 
+	  -0.19999999999999996 },
+  { 4.0331571908057011e+186, 100, 100, 
+	  -0.099999999999999978 },
+  { 6.6663086700729543e+186, 100, 100, 
+	  0.0000000000000000 },
+  { 4.0331571908057011e+186, 100, 100, 
+	  0.10000000000000009 },
+  { 8.6585879147526714e+185, 100, 100, 
+	  0.19999999999999996 },
+  { 5.9697347526822483e+184, 100, 100, 
+	  0.30000000000000004 },
+  { 1.0910627330458913e+183, 100, 100, 
+	  0.39999999999999991 },
+  { 3.7752749682889513e+180, 100, 100, 
+	  0.50000000000000000 },
+  { 1.3579510590289000e+177, 100, 100, 
+	  0.60000000000000009 },
+  { 1.5936546850595123e+172, 100, 100, 
+	  0.69999999999999996 },
+  { 4.3552236041585515e+164, 100, 100, 
+	  0.80000000000000004 },
+  { 5.7751792255761289e+150, 100, 100, 
+	  0.89999999999999991 },
+  { 0.0000000000000000, 100, 100, 
+	  1.0000000000000000 },
+};
+
+// Test function for l=100, m=100.
+template<typename Tp>
+  void
+  test036()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data036)
+			   / sizeof(testcase_assoc_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::assoc_legendre(Tp(data036[i].l), Tp(data036[i].m),
+		     Tp(data036[i].x));
+	const Tp f0 = data036[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  test012<double>();
+  test013<double>();
+  test014<double>();
+  test015<double>();
+  test016<double>();
+  test017<double>();
+  test018<double>();
+  test019<double>();
+  test020<double>();
+  test021<double>();
+  test022<double>();
+  test023<double>();
+  test024<double>();
+  test025<double>();
+  test026<double>();
+  test027<double>();
+  test028<double>();
+  test029<double>();
+  test030<double>();
+  test031<double>();
+  test032<double>();
+  test033<double>();
+  test034<double>();
+  test035<double>();
+  test036<double>();
+  return 0;
+}
Index: testsuite/special_functions/02_assoc_legendre/compile.cc
===================================================================
--- testsuite/special_functions/02_assoc_legendre/compile.cc	(revision 0)
+++ testsuite/special_functions/02_assoc_legendre/compile.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.2 assoc_legendre
+
+#include <cmath>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+  unsigned int l = 2, m = 1;
+
+  std::assoc_legendre(l, m, xf);
+  std::assoc_legendref(l, m, xf);
+  std::assoc_legendre(l, m, xd);
+  std::assoc_legendre(l, m, xl);
+  std::assoc_legendrel(l, m, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/02_assoc_legendre/compile_2.cc
===================================================================
--- testsuite/special_functions/02_assoc_legendre/compile_2.cc	(revision 0)
+++ testsuite/special_functions/02_assoc_legendre/compile_2.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.2 assoc_legendre
+
+#include <math.h>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+  unsigned int l = 2, m = 1;
+
+  assoc_legendre(l, m, xf);
+  assoc_legendref(l, m, xf);
+  assoc_legendre(l, m, xd);
+  assoc_legendre(l, m, xl);
+  assoc_legendrel(l, m, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/03_beta/check_nan.cc
===================================================================
--- testsuite/special_functions/03_beta/check_nan.cc	(revision 0)
+++ testsuite/special_functions/03_beta/check_nan.cc	(working copy)
@@ -0,0 +1,88 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.3 beta
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  float yf = 0.0F;
+  double yd = 0.0;
+  long double yl = 0.0L;
+
+  float a = std::beta(xf, yf);
+  float b = std::betaf(xf, yf);
+  double c = std::beta(xd, yd);
+  long double d = std::beta(xl, yl);
+  long double e = std::betal(xl, yl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+void
+test02()
+{
+  float xf = 1.0F;
+  double xd = 1.0;
+  long double xl = 1.0L;
+
+  float yf = std::numeric_limits<float>::quiet_NaN();
+  double yd = std::numeric_limits<double>::quiet_NaN();
+  long double yl = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::beta(xf, yf);
+  float b = std::betaf(xf, yf);
+  double c = std::beta(xd, yd);
+  long double d = std::beta(xl, yl);
+  long double e = std::betal(xl, yl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  return 0;
+}
+
Index: testsuite/special_functions/03_beta/check_value.cc
===================================================================
--- testsuite/special_functions/03_beta/check_value.cc	(revision 0)
+++ testsuite/special_functions/03_beta/check_value.cc	(working copy)
@@ -0,0 +1,484 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  beta
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for x=10.000000000000000.
+testcase_beta<double> data001[] = {
+  { 1.0825088224469029e-06, 10.000000000000000, 10.000000000000000 },
+  { 4.9925087406346778e-09, 10.000000000000000, 20.000000000000000 },
+  { 1.5729567312509485e-10, 10.000000000000000, 30.000000000000000 },
+  { 1.2168673582561288e-11, 10.000000000000000, 40.000000000000000 },
+  { 1.5916380099863291e-12, 10.000000000000000, 50.000000000000000 },
+  { 2.9408957938463963e-13, 10.000000000000000, 60.000000000000000 },
+  { 6.9411637980691676e-14, 10.000000000000000, 70.000000000000000 },
+  { 1.9665612972502651e-14, 10.000000000000000, 80.000000000000000 },
+  { 6.4187824828154399e-15, 10.000000000000000, 90.000000000000000 },
+  { 2.3455339739604842e-15, 10.000000000000000, 100.00000000000000 },
+};
+
+// Test function for x=10.000000000000000.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_beta<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::beta(Tp(data001[i].x), Tp(data001[i].y));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000029e-12));
+  }
+
+// Test data for x=20.000000000000000.
+testcase_beta<double> data002[] = {
+  { 4.9925087406346778e-09, 20.000000000000000, 10.000000000000000 },
+  { 7.2544445519248436e-13, 20.000000000000000, 20.000000000000000 },
+  { 1.7681885473062028e-15, 20.000000000000000, 30.000000000000000 },
+  { 1.7891885039182335e-17, 20.000000000000000, 40.000000000000000 },
+  { 4.3240677875623635e-19, 20.000000000000000, 50.000000000000000 },
+  { 1.8857342309689050e-20, 20.000000000000000, 60.000000000000000 },
+  { 1.2609804003539998e-21, 20.000000000000000, 70.000000000000000 },
+  { 1.1660809542079041e-22, 20.000000000000000, 80.000000000000000 },
+  { 1.3907944279729071e-23, 20.000000000000000, 90.000000000000000 },
+  { 2.0365059099917614e-24, 20.000000000000000, 100.00000000000000 },
+};
+
+// Test function for x=20.000000000000000.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_beta<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::beta(Tp(data002[i].x), Tp(data002[i].y));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for x=30.000000000000000.
+testcase_beta<double> data003[] = {
+  { 1.5729567312509485e-10, 30.000000000000000, 10.000000000000000 },
+  { 1.7681885473062028e-15, 30.000000000000000, 20.000000000000000 },
+  { 5.6370779640482451e-19, 30.000000000000000, 30.000000000000000 },
+  { 1.0539424603796547e-21, 30.000000000000000, 40.000000000000000 },
+  { 6.0118197777273836e-24, 30.000000000000000, 50.000000000000000 },
+  { 7.4279528553260165e-26, 30.000000000000000, 60.000000000000000 },
+  { 1.6212207780604767e-27, 30.000000000000000, 70.000000000000000 },
+  { 5.4783729715317616e-29, 30.000000000000000, 80.000000000000000 },
+  { 2.6183005659681346e-30, 30.000000000000000, 90.000000000000000 },
+  { 1.6587948222122229e-31, 30.000000000000000, 100.00000000000000 },
+};
+
+// Test function for x=30.000000000000000.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_beta<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::beta(Tp(data003[i].x), Tp(data003[i].y));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for x=40.000000000000000.
+testcase_beta<double> data004[] = {
+  { 1.2168673582561288e-11, 40.000000000000000, 10.000000000000000 },
+  { 1.7891885039182335e-17, 40.000000000000000, 20.000000000000000 },
+  { 1.0539424603796547e-21, 40.000000000000000, 30.000000000000000 },
+  { 4.6508509140090659e-25, 40.000000000000000, 40.000000000000000 },
+  { 7.5161712118557719e-28, 40.000000000000000, 50.000000000000000 },
+  { 3.0311331979886071e-30, 40.000000000000000, 60.000000000000000 },
+  { 2.4175035070466313e-32, 40.000000000000000, 70.000000000000000 },
+  { 3.2734839142758369e-34, 40.000000000000000, 80.000000000000000 },
+  { 6.7690629601315579e-36, 40.000000000000000, 90.000000000000000 },
+  { 1.9797337118812366e-37, 40.000000000000000, 100.00000000000000 },
+};
+
+// Test function for x=40.000000000000000.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_beta<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::beta(Tp(data004[i].x), Tp(data004[i].y));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+// Test data for x=50.000000000000000.
+testcase_beta<double> data005[] = {
+  { 1.5916380099863291e-12, 50.000000000000000, 10.000000000000000 },
+  { 4.3240677875623635e-19, 50.000000000000000, 20.000000000000000 },
+  { 6.0118197777273836e-24, 50.000000000000000, 30.000000000000000 },
+  { 7.5161712118557719e-28, 50.000000000000000, 40.000000000000000 },
+  { 3.9646612085674138e-31, 50.000000000000000, 50.000000000000000 },
+  { 5.8425643906418403e-34, 50.000000000000000, 60.000000000000000 },
+  { 1.8672362180783552e-36, 50.000000000000000, 70.000000000000000 },
+  { 1.0939382296458962e-38, 50.000000000000000, 80.000000000000000 },
+  { 1.0442781609881063e-40, 50.000000000000000, 90.000000000000000 },
+  { 1.4904121110954370e-42, 50.000000000000000, 100.00000000000000 },
+};
+
+// Test function for x=50.000000000000000.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_beta<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::beta(Tp(data005[i].x), Tp(data005[i].y));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for x=60.000000000000000.
+testcase_beta<double> data006[] = {
+  { 2.9408957938463963e-13, 60.000000000000000, 10.000000000000000 },
+  { 1.8857342309689050e-20, 60.000000000000000, 20.000000000000000 },
+  { 7.4279528553260165e-26, 60.000000000000000, 30.000000000000000 },
+  { 3.0311331979886071e-30, 60.000000000000000, 40.000000000000000 },
+  { 5.8425643906418403e-34, 60.000000000000000, 50.000000000000000 },
+  { 3.4501231469782229e-37, 60.000000000000000, 60.000000000000000 },
+  { 4.7706855386086599e-40, 60.000000000000000, 70.000000000000000 },
+  { 1.2902663809722593e-42, 60.000000000000000, 80.000000000000000 },
+  { 6.0105571058570508e-45, 60.000000000000000, 90.000000000000000 },
+  { 4.3922898898347209e-47, 60.000000000000000, 100.00000000000000 },
+};
+
+// Test function for x=60.000000000000000.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_beta<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::beta(Tp(data006[i].x), Tp(data006[i].y));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000029e-12));
+  }
+
+// Test data for x=70.000000000000000.
+testcase_beta<double> data007[] = {
+  { 6.9411637980691676e-14, 70.000000000000000, 10.000000000000000 },
+  { 1.2609804003539998e-21, 70.000000000000000, 20.000000000000000 },
+  { 1.6212207780604767e-27, 70.000000000000000, 30.000000000000000 },
+  { 2.4175035070466313e-32, 70.000000000000000, 40.000000000000000 },
+  { 1.8672362180783552e-36, 70.000000000000000, 50.000000000000000 },
+  { 4.7706855386086599e-40, 70.000000000000000, 60.000000000000000 },
+  { 3.0453137143486369e-43, 70.000000000000000, 70.000000000000000 },
+  { 4.0192274082013779e-46, 70.000000000000000, 80.000000000000000 },
+  { 9.5865870063501807e-49, 70.000000000000000, 90.000000000000000 },
+  { 3.7409127305819802e-51, 70.000000000000000, 100.00000000000000 },
+};
+
+// Test function for x=70.000000000000000.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_beta<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::beta(Tp(data007[i].x), Tp(data007[i].y));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000029e-12));
+  }
+
+// Test data for x=80.000000000000000.
+testcase_beta<double> data008[] = {
+  { 1.9665612972502651e-14, 80.000000000000000, 10.000000000000000 },
+  { 1.1660809542079041e-22, 80.000000000000000, 20.000000000000000 },
+  { 5.4783729715317616e-29, 80.000000000000000, 30.000000000000000 },
+  { 3.2734839142758369e-34, 80.000000000000000, 40.000000000000000 },
+  { 1.0939382296458962e-38, 80.000000000000000, 50.000000000000000 },
+  { 1.2902663809722593e-42, 80.000000000000000, 60.000000000000000 },
+  { 4.0192274082013779e-46, 80.000000000000000, 70.000000000000000 },
+  { 2.7160590828669411e-49, 80.000000000000000, 80.000000000000000 },
+  { 3.4593773902125368e-52, 80.000000000000000, 90.000000000000000 },
+  { 7.4807039968503468e-55, 80.000000000000000, 100.00000000000000 },
+};
+
+// Test function for x=80.000000000000000.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_beta<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::beta(Tp(data008[i].x), Tp(data008[i].y));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000029e-12));
+  }
+
+// Test data for x=90.000000000000000.
+testcase_beta<double> data009[] = {
+  { 6.4187824828154399e-15, 90.000000000000000, 10.000000000000000 },
+  { 1.3907944279729071e-23, 90.000000000000000, 20.000000000000000 },
+  { 2.6183005659681346e-30, 90.000000000000000, 30.000000000000000 },
+  { 6.7690629601315579e-36, 90.000000000000000, 40.000000000000000 },
+  { 1.0442781609881063e-40, 90.000000000000000, 50.000000000000000 },
+  { 6.0105571058570508e-45, 90.000000000000000, 60.000000000000000 },
+  { 9.5865870063501807e-49, 90.000000000000000, 70.000000000000000 },
+  { 3.4593773902125368e-52, 90.000000000000000, 80.000000000000000 },
+  { 2.4416737907558032e-55, 90.000000000000000, 90.000000000000000 },
+  { 3.0238531916564246e-58, 90.000000000000000, 100.00000000000000 },
+};
+
+// Test function for x=90.000000000000000.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_beta<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::beta(Tp(data009[i].x), Tp(data009[i].y));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+// Test data for x=100.00000000000000.
+testcase_beta<double> data010[] = {
+  { 2.3455339739604842e-15, 100.00000000000000, 10.000000000000000 },
+  { 2.0365059099917614e-24, 100.00000000000000, 20.000000000000000 },
+  { 1.6587948222122229e-31, 100.00000000000000, 30.000000000000000 },
+  { 1.9797337118812366e-37, 100.00000000000000, 40.000000000000000 },
+  { 1.4904121110954370e-42, 100.00000000000000, 50.000000000000000 },
+  { 4.3922898898347209e-47, 100.00000000000000, 60.000000000000000 },
+  { 3.7409127305819802e-51, 100.00000000000000, 70.000000000000000 },
+  { 7.4807039968503468e-55, 100.00000000000000, 80.000000000000000 },
+  { 3.0238531916564246e-58, 100.00000000000000, 90.000000000000000 },
+  { 2.2087606931991853e-61, 100.00000000000000, 100.00000000000000 },
+};
+
+// Test function for x=100.00000000000000.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_beta<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::beta(Tp(data010[i].x), Tp(data010[i].y));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  return 0;
+}
Index: testsuite/special_functions/03_beta/compile.cc
===================================================================
--- testsuite/special_functions/03_beta/compile.cc	(revision 0)
+++ testsuite/special_functions/03_beta/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.3 beta
+
+#include <cmath>
+
+void
+test01()
+{
+  float xf = 0.5F, yf = 0.5F;
+  double xd = 0.5, yd = 0.5;
+  long double xl = 0.5L, yl = 0.5L;
+
+  std::beta(xf, yf);
+  std::betaf(xf, yf);
+  std::beta(xd, yd);
+  std::beta(xl, yl);
+  std::betal(xl, yl);
+
+  return;
+}
+
Index: testsuite/special_functions/03_beta/compile_2.cc
===================================================================
--- testsuite/special_functions/03_beta/compile_2.cc	(revision 0)
+++ testsuite/special_functions/03_beta/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.3 beta
+
+#include <math.h>
+
+void
+test01()
+{
+  float xf = 0.5F, yf = 0.5F;
+  double xd = 0.5, yd = 0.5;
+  long double xl = 0.5L, yl = 0.5L;
+
+  beta(xf, yf);
+  betaf(xf, yf);
+  beta(xd, yd);
+  beta(xl, yl);
+  betal(xl, yl);
+
+  return;
+}
+
Index: testsuite/special_functions/04_comp_ellint_1/check_nan.cc
===================================================================
--- testsuite/special_functions/04_comp_ellint_1/check_nan.cc	(revision 0)
+++ testsuite/special_functions/04_comp_ellint_1/check_nan.cc	(working copy)
@@ -0,0 +1,56 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.4 comp_ellint_1
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float kf = std::numeric_limits<float>::quiet_NaN();
+  double kd = std::numeric_limits<double>::quiet_NaN();
+  long double kl = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::comp_ellint_1(kf);
+  float b = std::comp_ellint_1f(kf);
+  double c = std::comp_ellint_1(kd);
+  long double d = std::comp_ellint_1(kl);
+  long double e = std::comp_ellint_1l(kl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/04_comp_ellint_1/check_value.cc
===================================================================
--- testsuite/special_functions/04_comp_ellint_1/check_value.cc	(revision 0)
+++ testsuite/special_functions/04_comp_ellint_1/check_value.cc	(working copy)
@@ -0,0 +1,97 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  comp_ellint_1
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data.
+testcase_comp_ellint_1<double> data001[] = {
+  { 2.2805491384227703, -0.90000000000000002 },
+  { 1.9953027776647296, -0.80000000000000004 },
+  { 1.8456939983747236, -0.69999999999999996 },
+  { 1.7507538029157526, -0.59999999999999998 },
+  { 1.6857503548125963, -0.50000000000000000 },
+  { 1.6399998658645112, -0.40000000000000002 },
+  { 1.6080486199305128, -0.30000000000000004 },
+  { 1.5868678474541660, -0.19999999999999996 },
+  { 1.5747455615173562, -0.099999999999999978 },
+  { 1.5707963267948966, 0.0000000000000000 },
+  { 1.5747455615173562, 0.10000000000000009 },
+  { 1.5868678474541660, 0.19999999999999996 },
+  { 1.6080486199305128, 0.30000000000000004 },
+  { 1.6399998658645112, 0.39999999999999991 },
+  { 1.6857503548125963, 0.50000000000000000 },
+  { 1.7507538029157526, 0.60000000000000009 },
+  { 1.8456939983747236, 0.69999999999999996 },
+  { 1.9953027776647296, 0.80000000000000004 },
+  { 2.2805491384227703, 0.89999999999999991 },
+};
+
+// Test function.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_comp_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_1(Tp(data001[i].k));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  return 0;
+}
Index: testsuite/special_functions/04_comp_ellint_1/compile.cc
===================================================================
--- testsuite/special_functions/04_comp_ellint_1/compile.cc	(revision 0)
+++ testsuite/special_functions/04_comp_ellint_1/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.4 comp_ellint_1
+
+#include <cmath>
+
+void
+test01()
+{
+  float kf = 0.5F;
+  double kd = 0.5;
+  long double kl = 0.5L;
+
+  std::comp_ellint_1(kf);
+  std::comp_ellint_1f(kf);
+  std::comp_ellint_1(kd);
+  std::comp_ellint_1(kl);
+  std::comp_ellint_1l(kl);
+
+  return;
+}
+
Index: testsuite/special_functions/04_comp_ellint_1/compile_2.cc
===================================================================
--- testsuite/special_functions/04_comp_ellint_1/compile_2.cc	(revision 0)
+++ testsuite/special_functions/04_comp_ellint_1/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.4 comp_ellint_1
+
+#include <math.h>
+
+void
+test01()
+{
+  float kf = 0.5F;
+  double kd = 0.5;
+  long double kl = 0.5L;
+
+  comp_ellint_1(kf);
+  comp_ellint_1f(kf);
+  comp_ellint_1(kd);
+  comp_ellint_1(kl);
+  comp_ellint_1l(kl);
+
+  return;
+}
+
Index: testsuite/special_functions/05_comp_ellint_2/check_nan.cc
===================================================================
--- testsuite/special_functions/05_comp_ellint_2/check_nan.cc	(revision 0)
+++ testsuite/special_functions/05_comp_ellint_2/check_nan.cc	(working copy)
@@ -0,0 +1,56 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.5 comp_ellint_2
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float kf = std::numeric_limits<float>::quiet_NaN();
+  double kd = std::numeric_limits<double>::quiet_NaN();
+  long double kl = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::comp_ellint_2(kf);
+  float b = std::comp_ellint_2f(kf);
+  double c = std::comp_ellint_2(kd);
+  long double d = std::comp_ellint_2(kl);
+  long double e = std::comp_ellint_2l(kl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/05_comp_ellint_2/check_value.cc
===================================================================
--- testsuite/special_functions/05_comp_ellint_2/check_value.cc	(revision 0)
+++ testsuite/special_functions/05_comp_ellint_2/check_value.cc	(working copy)
@@ -0,0 +1,97 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  comp_ellint_2
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data.
+testcase_comp_ellint_2<double> data001[] = {
+  { 1.1716970527816140, -0.90000000000000002 },
+  { 1.2763499431699064, -0.80000000000000004 },
+  { 1.3556611355719554, -0.69999999999999996 },
+  { 1.4180833944487241, -0.59999999999999998 },
+  { 1.4674622093394274, -0.50000000000000000 },
+  { 1.5059416123600402, -0.40000000000000002 },
+  { 1.5348334649232491, -0.30000000000000004 },
+  { 1.5549685462425291, -0.19999999999999996 },
+  { 1.5668619420216685, -0.099999999999999978 },
+  { 1.5707963267948966, 0.0000000000000000 },
+  { 1.5668619420216685, 0.10000000000000009 },
+  { 1.5549685462425291, 0.19999999999999996 },
+  { 1.5348334649232491, 0.30000000000000004 },
+  { 1.5059416123600404, 0.39999999999999991 },
+  { 1.4674622093394274, 0.50000000000000000 },
+  { 1.4180833944487241, 0.60000000000000009 },
+  { 1.3556611355719554, 0.69999999999999996 },
+  { 1.2763499431699064, 0.80000000000000004 },
+  { 1.1716970527816144, 0.89999999999999991 },
+};
+
+// Test function.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_comp_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_2(Tp(data001[i].k));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  return 0;
+}
Index: testsuite/special_functions/05_comp_ellint_2/compile.cc
===================================================================
--- testsuite/special_functions/05_comp_ellint_2/compile.cc	(revision 0)
+++ testsuite/special_functions/05_comp_ellint_2/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.5 comp_ellint_2
+
+#include <cmath>
+
+void
+test01()
+{
+  float kf = 0.5F;
+  double kd = 0.5;
+  long double kl = 0.5L;
+
+  std::comp_ellint_2(kf);
+  std::comp_ellint_2f(kf);
+  std::comp_ellint_2(kd);
+  std::comp_ellint_2(kl);
+  std::comp_ellint_2l(kl);
+
+  return;
+}
+
Index: testsuite/special_functions/05_comp_ellint_2/compile_2.cc
===================================================================
--- testsuite/special_functions/05_comp_ellint_2/compile_2.cc	(revision 0)
+++ testsuite/special_functions/05_comp_ellint_2/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.5 comp_ellint_2
+
+#include <math.h>
+
+void
+test01()
+{
+  float kf = 0.5F;
+  double kd = 0.5;
+  long double kl = 0.5L;
+
+  comp_ellint_2(kf);
+  comp_ellint_2f(kf);
+  comp_ellint_2(kd);
+  comp_ellint_2(kl);
+  comp_ellint_2l(kl);
+
+  return;
+}
+
Index: testsuite/special_functions/06_comp_ellint_3/check_nan.cc
===================================================================
--- testsuite/special_functions/06_comp_ellint_3/check_nan.cc	(revision 0)
+++ testsuite/special_functions/06_comp_ellint_3/check_nan.cc	(working copy)
@@ -0,0 +1,88 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.6 comp_ellint_3
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float kf = std::numeric_limits<float>::quiet_NaN();
+  double kd = std::numeric_limits<double>::quiet_NaN();
+  long double kl = std::numeric_limits<long double>::quiet_NaN();
+
+  float nuf = 0.0F;
+  double nud = 0.0;
+  long double nul = 0.0L;
+
+  float a = std::comp_ellint_3(kf, nuf);
+  float b = std::comp_ellint_3f(kf, nuf);
+  double c = std::comp_ellint_3(kd, nud);
+  long double d = std::comp_ellint_3(kl, nul);
+  long double e = std::comp_ellint_3l(kl, nul);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+void
+test02()
+{
+  float kf = 1.0F;
+  double kd = 1.0;
+  long double kl = 1.0L;
+
+  float nuf = std::numeric_limits<float>::quiet_NaN();
+  double nud = std::numeric_limits<double>::quiet_NaN();
+  long double nul = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::comp_ellint_3(kf, nuf);
+  float b = std::comp_ellint_3f(kf, nuf);
+  double c = std::comp_ellint_3(kd, nud);
+  long double d = std::comp_ellint_3(kl, nul);
+  long double e = std::comp_ellint_3l(kl, nul);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  return 0;
+}
+
Index: testsuite/special_functions/06_comp_ellint_3/check_value.cc
===================================================================
--- testsuite/special_functions/06_comp_ellint_3/check_value.cc	(revision 0)
+++ testsuite/special_functions/06_comp_ellint_3/check_value.cc	(working copy)
@@ -0,0 +1,880 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  comp_ellint_3
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for k=-0.90000000000000002.
+testcase_comp_ellint_3<double> data001[] = {
+  { 2.2805491384227703, -0.90000000000000002, 0.0000000000000000 },
+  { 2.1537868513875287, -0.90000000000000002, 0.10000000000000001 },
+  { 2.0443194576468890, -0.90000000000000002, 0.20000000000000001 },
+  { 1.9486280260314426, -0.90000000000000002, 0.29999999999999999 },
+  { 1.8641114227238349, -0.90000000000000002, 0.40000000000000002 },
+  { 1.7888013241937861, -0.90000000000000002, 0.50000000000000000 },
+  { 1.7211781128919523, -0.90000000000000002, 0.59999999999999998 },
+  { 1.6600480747670940, -0.90000000000000002, 0.69999999999999996 },
+  { 1.6044591960982202, -0.90000000000000002, 0.80000000000000004 },
+  { 1.5536420236310946, -0.90000000000000002, 0.90000000000000002 },
+};
+
+// Test function for k=-0.90000000000000002.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data001[i].k), Tp(data001[i].nu));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004.
+testcase_comp_ellint_3<double> data002[] = {
+  { 1.9953027776647296, -0.80000000000000004, 0.0000000000000000 },
+  { 1.8910755418379521, -0.80000000000000004, 0.10000000000000001 },
+  { 1.8007226661734588, -0.80000000000000004, 0.20000000000000001 },
+  { 1.7214611048717301, -0.80000000000000004, 0.29999999999999999 },
+  { 1.6512267838651289, -0.80000000000000004, 0.40000000000000002 },
+  { 1.5884528947755532, -0.80000000000000004, 0.50000000000000000 },
+  { 1.5319262547427865, -0.80000000000000004, 0.59999999999999998 },
+  { 1.4806912324625332, -0.80000000000000004, 0.69999999999999996 },
+  { 1.4339837018309471, -0.80000000000000004, 0.80000000000000004 },
+  { 1.3911845406776222, -0.80000000000000004, 0.90000000000000002 },
+};
+
+// Test function for k=-0.80000000000000004.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data002[i].k), Tp(data002[i].nu));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996.
+testcase_comp_ellint_3<double> data003[] = {
+  { 1.8456939983747236, -0.69999999999999996, 0.0000000000000000 },
+  { 1.7528050171757608, -0.69999999999999996, 0.10000000000000001 },
+  { 1.6721098780092145, -0.69999999999999996, 0.20000000000000001 },
+  { 1.6011813647733213, -0.69999999999999996, 0.29999999999999999 },
+  { 1.5382162002954762, -0.69999999999999996, 0.40000000000000002 },
+  { 1.4818433192178544, -0.69999999999999996, 0.50000000000000000 },
+  { 1.4309994736080540, -0.69999999999999996, 0.59999999999999998 },
+  { 1.3848459188329196, -0.69999999999999996, 0.69999999999999996 },
+  { 1.3427110650397531, -0.69999999999999996, 0.80000000000000004 },
+  { 1.3040500499695913, -0.69999999999999996, 0.90000000000000002 },
+};
+
+// Test function for k=-0.69999999999999996.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data003[i].k), Tp(data003[i].nu));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998.
+testcase_comp_ellint_3<double> data004[] = {
+  { 1.7507538029157526, -0.59999999999999998, 0.0000000000000000 },
+  { 1.6648615773343014, -0.59999999999999998, 0.10000000000000001 },
+  { 1.5901418016279374, -0.59999999999999998, 0.20000000000000001 },
+  { 1.5243814243493585, -0.59999999999999998, 0.29999999999999999 },
+  { 1.4659345278069984, -0.59999999999999998, 0.40000000000000002 },
+  { 1.4135484285693078, -0.59999999999999998, 0.50000000000000000 },
+  { 1.3662507535812816, -0.59999999999999998, 0.59999999999999998 },
+  { 1.3232737468822813, -0.59999999999999998, 0.69999999999999996 },
+  { 1.2840021261752192, -0.59999999999999998, 0.80000000000000004 },
+  { 1.2479362973851875, -0.59999999999999998, 0.90000000000000002 },
+};
+
+// Test function for k=-0.59999999999999998.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data004[i].k), Tp(data004[i].nu));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000.
+testcase_comp_ellint_3<double> data005[] = {
+  { 1.6857503548125963, -0.50000000000000000, 0.0000000000000000 },
+  { 1.6045524936084892, -0.50000000000000000, 0.10000000000000001 },
+  { 1.5338490483665983, -0.50000000000000000, 0.20000000000000001 },
+  { 1.4715681939859637, -0.50000000000000000, 0.29999999999999999 },
+  { 1.4161679518465340, -0.50000000000000000, 0.40000000000000002 },
+  { 1.3664739530045971, -0.50000000000000000, 0.50000000000000000 },
+  { 1.3215740290190876, -0.50000000000000000, 0.59999999999999998 },
+  { 1.2807475181182502, -0.50000000000000000, 0.69999999999999996 },
+  { 1.2434165408189539, -0.50000000000000000, 0.80000000000000004 },
+  { 1.2091116095504744, -0.50000000000000000, 0.90000000000000002 },
+};
+
+// Test function for k=-0.50000000000000000.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data005[i].k), Tp(data005[i].nu));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002.
+testcase_comp_ellint_3<double> data006[] = {
+  { 1.6399998658645112, -0.40000000000000002, 0.0000000000000000 },
+  { 1.5620566886683604, -0.40000000000000002, 0.10000000000000001 },
+  { 1.4941414344266770, -0.40000000000000002, 0.20000000000000001 },
+  { 1.4342789859950078, -0.40000000000000002, 0.29999999999999999 },
+  { 1.3809986210732901, -0.40000000000000002, 0.40000000000000002 },
+  { 1.3331797176377398, -0.40000000000000002, 0.50000000000000000 },
+  { 1.2899514672527024, -0.40000000000000002, 0.59999999999999998 },
+  { 1.2506255923253344, -0.40000000000000002, 0.69999999999999996 },
+  { 1.2146499565727209, -0.40000000000000002, 0.80000000000000004 },
+  { 1.1815758115929846, -0.40000000000000002, 0.90000000000000002 },
+};
+
+// Test function for k=-0.40000000000000002.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data006[i].k), Tp(data006[i].nu));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004.
+testcase_comp_ellint_3<double> data007[] = {
+  { 1.6080486199305128, -0.30000000000000004, 0.0000000000000000 },
+  { 1.5323534693557528, -0.30000000000000004, 0.10000000000000001 },
+  { 1.4663658145259877, -0.30000000000000004, 0.20000000000000001 },
+  { 1.4081767433479091, -0.30000000000000004, 0.29999999999999999 },
+  { 1.3563643538969763, -0.30000000000000004, 0.40000000000000002 },
+  { 1.3098448759814962, -0.30000000000000004, 0.50000000000000000 },
+  { 1.2677758800420669, -0.30000000000000004, 0.59999999999999998 },
+  { 1.2294913236274982, -0.30000000000000004, 0.69999999999999996 },
+  { 1.1944567571590048, -0.30000000000000004, 0.80000000000000004 },
+  { 1.1622376896064914, -0.30000000000000004, 0.90000000000000002 },
+};
+
+// Test function for k=-0.30000000000000004.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data007[i].k), Tp(data007[i].nu));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996.
+testcase_comp_ellint_3<double> data008[] = {
+  { 1.5868678474541660, -0.19999999999999996, 0.0000000000000000 },
+  { 1.5126513474261087, -0.19999999999999996, 0.10000000000000001 },
+  { 1.4479323932249564, -0.19999999999999996, 0.20000000000000001 },
+  { 1.3908453514752477, -0.19999999999999996, 0.29999999999999999 },
+  { 1.3400002519661005, -0.19999999999999996, 0.40000000000000002 },
+  { 1.2943374404397372, -0.19999999999999996, 0.50000000000000000 },
+  { 1.2530330675914556, -0.19999999999999996, 0.59999999999999998 },
+  { 1.2154356555075863, -0.19999999999999996, 0.69999999999999996 },
+  { 1.1810223448909909, -0.19999999999999996, 0.80000000000000004 },
+  { 1.1493679916141861, -0.19999999999999996, 0.90000000000000002 },
+};
+
+// Test function for k=-0.19999999999999996.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data008[i].k), Tp(data008[i].nu));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978.
+testcase_comp_ellint_3<double> data009[] = {
+  { 1.5747455615173562, -0.099999999999999978, 0.0000000000000000 },
+  { 1.5013711111199950, -0.099999999999999978, 0.10000000000000001 },
+  { 1.4373749386463430, -0.099999999999999978, 0.20000000000000001 },
+  { 1.3809159606704959, -0.099999999999999978, 0.29999999999999999 },
+  { 1.3306223265207477, -0.099999999999999978, 0.40000000000000002 },
+  { 1.2854480708580160, -0.099999999999999978, 0.50000000000000000 },
+  { 1.2445798942989255, -0.099999999999999978, 0.59999999999999998 },
+  { 1.2073745911083185, -0.099999999999999978, 0.69999999999999996 },
+  { 1.1733158866987732, -0.099999999999999978, 0.80000000000000004 },
+  { 1.1419839485283374, -0.099999999999999978, 0.90000000000000002 },
+};
+
+// Test function for k=-0.099999999999999978.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data009[i].k), Tp(data009[i].nu));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000.
+testcase_comp_ellint_3<double> data010[] = {
+  { 1.5707963267948966, 0.0000000000000000, 0.0000000000000000 },
+  { 1.4976955329233277, 0.0000000000000000, 0.10000000000000001 },
+  { 1.4339343023863691, 0.0000000000000000, 0.20000000000000001 },
+  { 1.3776795151134889, 0.0000000000000000, 0.29999999999999999 },
+  { 1.3275651989026320, 0.0000000000000000, 0.40000000000000002 },
+  { 1.2825498301618641, 0.0000000000000000, 0.50000000000000000 },
+  { 1.2418235332245127, 0.0000000000000000, 0.59999999999999998 },
+  { 1.2047457872617382, 0.0000000000000000, 0.69999999999999996 },
+  { 1.1708024551734544, 0.0000000000000000, 0.80000000000000004 },
+  { 1.1395754288497419, 0.0000000000000000, 0.90000000000000002 },
+};
+
+// Test function for k=0.0000000000000000.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data010[i].k), Tp(data010[i].nu));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009.
+testcase_comp_ellint_3<double> data011[] = {
+  { 1.5747455615173562, 0.10000000000000009, 0.0000000000000000 },
+  { 1.5013711111199950, 0.10000000000000009, 0.10000000000000001 },
+  { 1.4373749386463430, 0.10000000000000009, 0.20000000000000001 },
+  { 1.3809159606704959, 0.10000000000000009, 0.29999999999999999 },
+  { 1.3306223265207477, 0.10000000000000009, 0.40000000000000002 },
+  { 1.2854480708580160, 0.10000000000000009, 0.50000000000000000 },
+  { 1.2445798942989255, 0.10000000000000009, 0.59999999999999998 },
+  { 1.2073745911083185, 0.10000000000000009, 0.69999999999999996 },
+  { 1.1733158866987732, 0.10000000000000009, 0.80000000000000004 },
+  { 1.1419839485283374, 0.10000000000000009, 0.90000000000000002 },
+};
+
+// Test function for k=0.10000000000000009.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data011[i].k), Tp(data011[i].nu));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996.
+testcase_comp_ellint_3<double> data012[] = {
+  { 1.5868678474541660, 0.19999999999999996, 0.0000000000000000 },
+  { 1.5126513474261087, 0.19999999999999996, 0.10000000000000001 },
+  { 1.4479323932249564, 0.19999999999999996, 0.20000000000000001 },
+  { 1.3908453514752477, 0.19999999999999996, 0.29999999999999999 },
+  { 1.3400002519661005, 0.19999999999999996, 0.40000000000000002 },
+  { 1.2943374404397372, 0.19999999999999996, 0.50000000000000000 },
+  { 1.2530330675914556, 0.19999999999999996, 0.59999999999999998 },
+  { 1.2154356555075863, 0.19999999999999996, 0.69999999999999996 },
+  { 1.1810223448909909, 0.19999999999999996, 0.80000000000000004 },
+  { 1.1493679916141861, 0.19999999999999996, 0.90000000000000002 },
+};
+
+// Test function for k=0.19999999999999996.
+template<typename Tp>
+  void
+  test012()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data012)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data012[i].k), Tp(data012[i].nu));
+	const Tp f0 = data012[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004.
+testcase_comp_ellint_3<double> data013[] = {
+  { 1.6080486199305128, 0.30000000000000004, 0.0000000000000000 },
+  { 1.5323534693557528, 0.30000000000000004, 0.10000000000000001 },
+  { 1.4663658145259877, 0.30000000000000004, 0.20000000000000001 },
+  { 1.4081767433479091, 0.30000000000000004, 0.29999999999999999 },
+  { 1.3563643538969763, 0.30000000000000004, 0.40000000000000002 },
+  { 1.3098448759814962, 0.30000000000000004, 0.50000000000000000 },
+  { 1.2677758800420669, 0.30000000000000004, 0.59999999999999998 },
+  { 1.2294913236274982, 0.30000000000000004, 0.69999999999999996 },
+  { 1.1944567571590048, 0.30000000000000004, 0.80000000000000004 },
+  { 1.1622376896064914, 0.30000000000000004, 0.90000000000000002 },
+};
+
+// Test function for k=0.30000000000000004.
+template<typename Tp>
+  void
+  test013()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data013)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data013[i].k), Tp(data013[i].nu));
+	const Tp f0 = data013[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991.
+testcase_comp_ellint_3<double> data014[] = {
+  { 1.6399998658645112, 0.39999999999999991, 0.0000000000000000 },
+  { 1.5620566886683604, 0.39999999999999991, 0.10000000000000001 },
+  { 1.4941414344266770, 0.39999999999999991, 0.20000000000000001 },
+  { 1.4342789859950078, 0.39999999999999991, 0.29999999999999999 },
+  { 1.3809986210732901, 0.39999999999999991, 0.40000000000000002 },
+  { 1.3331797176377398, 0.39999999999999991, 0.50000000000000000 },
+  { 1.2899514672527024, 0.39999999999999991, 0.59999999999999998 },
+  { 1.2506255923253344, 0.39999999999999991, 0.69999999999999996 },
+  { 1.2146499565727209, 0.39999999999999991, 0.80000000000000004 },
+  { 1.1815758115929846, 0.39999999999999991, 0.90000000000000002 },
+};
+
+// Test function for k=0.39999999999999991.
+template<typename Tp>
+  void
+  test014()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data014)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data014[i].k), Tp(data014[i].nu));
+	const Tp f0 = data014[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000.
+testcase_comp_ellint_3<double> data015[] = {
+  { 1.6857503548125963, 0.50000000000000000, 0.0000000000000000 },
+  { 1.6045524936084892, 0.50000000000000000, 0.10000000000000001 },
+  { 1.5338490483665983, 0.50000000000000000, 0.20000000000000001 },
+  { 1.4715681939859637, 0.50000000000000000, 0.29999999999999999 },
+  { 1.4161679518465340, 0.50000000000000000, 0.40000000000000002 },
+  { 1.3664739530045971, 0.50000000000000000, 0.50000000000000000 },
+  { 1.3215740290190876, 0.50000000000000000, 0.59999999999999998 },
+  { 1.2807475181182502, 0.50000000000000000, 0.69999999999999996 },
+  { 1.2434165408189539, 0.50000000000000000, 0.80000000000000004 },
+  { 1.2091116095504744, 0.50000000000000000, 0.90000000000000002 },
+};
+
+// Test function for k=0.50000000000000000.
+template<typename Tp>
+  void
+  test015()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data015)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data015[i].k), Tp(data015[i].nu));
+	const Tp f0 = data015[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009.
+testcase_comp_ellint_3<double> data016[] = {
+  { 1.7507538029157526, 0.60000000000000009, 0.0000000000000000 },
+  { 1.6648615773343014, 0.60000000000000009, 0.10000000000000001 },
+  { 1.5901418016279374, 0.60000000000000009, 0.20000000000000001 },
+  { 1.5243814243493585, 0.60000000000000009, 0.29999999999999999 },
+  { 1.4659345278069984, 0.60000000000000009, 0.40000000000000002 },
+  { 1.4135484285693078, 0.60000000000000009, 0.50000000000000000 },
+  { 1.3662507535812816, 0.60000000000000009, 0.59999999999999998 },
+  { 1.3232737468822813, 0.60000000000000009, 0.69999999999999996 },
+  { 1.2840021261752192, 0.60000000000000009, 0.80000000000000004 },
+  { 1.2479362973851873, 0.60000000000000009, 0.90000000000000002 },
+};
+
+// Test function for k=0.60000000000000009.
+template<typename Tp>
+  void
+  test016()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data016)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data016[i].k), Tp(data016[i].nu));
+	const Tp f0 = data016[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996.
+testcase_comp_ellint_3<double> data017[] = {
+  { 1.8456939983747236, 0.69999999999999996, 0.0000000000000000 },
+  { 1.7528050171757608, 0.69999999999999996, 0.10000000000000001 },
+  { 1.6721098780092145, 0.69999999999999996, 0.20000000000000001 },
+  { 1.6011813647733213, 0.69999999999999996, 0.29999999999999999 },
+  { 1.5382162002954762, 0.69999999999999996, 0.40000000000000002 },
+  { 1.4818433192178544, 0.69999999999999996, 0.50000000000000000 },
+  { 1.4309994736080540, 0.69999999999999996, 0.59999999999999998 },
+  { 1.3848459188329196, 0.69999999999999996, 0.69999999999999996 },
+  { 1.3427110650397531, 0.69999999999999996, 0.80000000000000004 },
+  { 1.3040500499695913, 0.69999999999999996, 0.90000000000000002 },
+};
+
+// Test function for k=0.69999999999999996.
+template<typename Tp>
+  void
+  test017()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data017)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data017[i].k), Tp(data017[i].nu));
+	const Tp f0 = data017[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004.
+testcase_comp_ellint_3<double> data018[] = {
+  { 1.9953027776647296, 0.80000000000000004, 0.0000000000000000 },
+  { 1.8910755418379521, 0.80000000000000004, 0.10000000000000001 },
+  { 1.8007226661734588, 0.80000000000000004, 0.20000000000000001 },
+  { 1.7214611048717301, 0.80000000000000004, 0.29999999999999999 },
+  { 1.6512267838651289, 0.80000000000000004, 0.40000000000000002 },
+  { 1.5884528947755532, 0.80000000000000004, 0.50000000000000000 },
+  { 1.5319262547427865, 0.80000000000000004, 0.59999999999999998 },
+  { 1.4806912324625332, 0.80000000000000004, 0.69999999999999996 },
+  { 1.4339837018309471, 0.80000000000000004, 0.80000000000000004 },
+  { 1.3911845406776222, 0.80000000000000004, 0.90000000000000002 },
+};
+
+// Test function for k=0.80000000000000004.
+template<typename Tp>
+  void
+  test018()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data018)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data018[i].k), Tp(data018[i].nu));
+	const Tp f0 = data018[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991.
+testcase_comp_ellint_3<double> data019[] = {
+  { 2.2805491384227703, 0.89999999999999991, 0.0000000000000000 },
+  { 2.1537868513875287, 0.89999999999999991, 0.10000000000000001 },
+  { 2.0443194576468895, 0.89999999999999991, 0.20000000000000001 },
+  { 1.9486280260314426, 0.89999999999999991, 0.29999999999999999 },
+  { 1.8641114227238351, 0.89999999999999991, 0.40000000000000002 },
+  { 1.7888013241937863, 0.89999999999999991, 0.50000000000000000 },
+  { 1.7211781128919525, 0.89999999999999991, 0.59999999999999998 },
+  { 1.6600480747670940, 0.89999999999999991, 0.69999999999999996 },
+  { 1.6044591960982202, 0.89999999999999991, 0.80000000000000004 },
+  { 1.5536420236310948, 0.89999999999999991, 0.90000000000000002 },
+};
+
+// Test function for k=0.89999999999999991.
+template<typename Tp>
+  void
+  test019()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data019)
+			   / sizeof(testcase_comp_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::comp_ellint_3(Tp(data019[i].k), Tp(data019[i].nu));
+	const Tp f0 = data019[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  test012<double>();
+  test013<double>();
+  test014<double>();
+  test015<double>();
+  test016<double>();
+  test017<double>();
+  test018<double>();
+  test019<double>();
+  return 0;
+}
Index: testsuite/special_functions/06_comp_ellint_3/compile.cc
===================================================================
--- testsuite/special_functions/06_comp_ellint_3/compile.cc	(revision 0)
+++ testsuite/special_functions/06_comp_ellint_3/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.6 comp_ellint_3
+
+#include <cmath>
+
+void
+test01()
+{
+  float kf = 0.5F, nuf = 0.5F;
+  double kd = 0.5, nud = 0.5;
+  long double kl = 0.5L, nul = 0.5L;
+
+  std::comp_ellint_3(kf, nuf);
+  std::comp_ellint_3f(kf, nuf);
+  std::comp_ellint_3(kd, nud);
+  std::comp_ellint_3(kl, nul);
+  std::comp_ellint_3l(kl, nul);
+
+  return;
+}
+
Index: testsuite/special_functions/06_comp_ellint_3/compile_2.cc
===================================================================
--- testsuite/special_functions/06_comp_ellint_3/compile_2.cc	(revision 0)
+++ testsuite/special_functions/06_comp_ellint_3/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.6 comp_ellint_3
+
+#include <math.h>
+
+void
+test01()
+{
+  float kf = 0.5F, nuf = 0.5F;
+  double kd = 0.5, nud = 0.5;
+  long double kl = 0.5L, nul = 0.5L;
+
+  comp_ellint_3(kf, nuf);
+  comp_ellint_3f(kf, nuf);
+  comp_ellint_3(kd, nud);
+  comp_ellint_3(kl, nul);
+  comp_ellint_3l(kl, nul);
+
+  return;
+}
+
Index: testsuite/special_functions/07_cyl_bessel_i/check_nan.cc
===================================================================
--- testsuite/special_functions/07_cyl_bessel_i/check_nan.cc	(revision 0)
+++ testsuite/special_functions/07_cyl_bessel_i/check_nan.cc	(working copy)
@@ -0,0 +1,88 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.7 cyl_bessel_i
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  float nuf = 0.0F;
+  double nud = 0.0;
+  long double nul = 0.0L;
+
+  float a = std::cyl_bessel_i(nuf, xf);
+  float b = std::cyl_bessel_if(nuf, xf);
+  double c = std::cyl_bessel_i(nud, xd);
+  long double d = std::cyl_bessel_i(nul, xl);
+  long double e = std::cyl_bessel_il(nul, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+void
+test02()
+{
+  float xf = 1.0F;
+  double xd = 1.0;
+  long double xl = 1.0L;
+
+  float nuf = std::numeric_limits<float>::quiet_NaN();
+  double nud = std::numeric_limits<double>::quiet_NaN();
+  long double nul = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::cyl_bessel_i(nuf, xf);
+  float b = std::cyl_bessel_if(nuf, xf);
+  double c = std::cyl_bessel_i(nud, xd);
+  long double d = std::cyl_bessel_i(nul, xl);
+  long double e = std::cyl_bessel_il(nul, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  return 0;
+}
+
Index: testsuite/special_functions/07_cyl_bessel_i/check_value.cc
===================================================================
--- testsuite/special_functions/07_cyl_bessel_i/check_value.cc	(revision 0)
+++ testsuite/special_functions/07_cyl_bessel_i/check_value.cc	(working copy)
@@ -0,0 +1,649 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  cyl_bessel_i
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for nu=0.0000000000000000.
+testcase_cyl_bessel_i<double> data001[] = {
+  { 1.0000000000000000, 0.0000000000000000, 0.0000000000000000 },
+  { 27.239871823604439, 0.0000000000000000, 5.0000000000000000 },
+  { 2815.7166284662558, 0.0000000000000000, 10.000000000000000 },
+  { 339649.37329791381, 0.0000000000000000, 15.000000000000000 },
+  { 43558282.559553474, 0.0000000000000000, 20.000000000000000 },
+  { 5774560606.4663124, 0.0000000000000000, 25.000000000000000 },
+  { 781672297823.97925, 0.0000000000000000, 30.000000000000000 },
+  { 107338818494514.42, 0.0000000000000000, 35.000000000000000 },
+  { 14894774793419918., 0.0000000000000000, 40.000000000000000 },
+  { 2.0834140751773164e+18, 0.0000000000000000, 45.000000000000000 },
+  { 2.9325537838493457e+20, 0.0000000000000000, 50.000000000000000 },
+  { 4.1487895607332160e+22, 0.0000000000000000, 55.000000000000000 },
+  { 5.8940770556098216e+24, 0.0000000000000000, 60.000000000000000 },
+  { 8.4030398456255596e+26, 0.0000000000000000, 65.000000000000000 },
+  { 1.2015889579125424e+29, 0.0000000000000000, 70.000000000000000 },
+  { 1.7226390780357976e+31, 0.0000000000000000, 75.000000000000000 },
+  { 2.4751784043341661e+33, 0.0000000000000000, 80.000000000000000 },
+  { 3.5634776304081403e+35, 0.0000000000000000, 85.000000000000000 },
+  { 5.1392383455086475e+37, 0.0000000000000000, 90.000000000000000 },
+  { 7.4233258618752072e+39, 0.0000000000000000, 95.000000000000000 },
+  { 1.0737517071310986e+42, 0.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data001[i].nu), Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+// Test data for nu=0.33333333333333331.
+testcase_cyl_bessel_i<double> data002[] = {
+  { 0.0000000000000000, 0.33333333333333331, 0.0000000000000000 },
+  { 26.897553069268362, 0.33333333333333331, 5.0000000000000000 },
+  { 2799.2396097056790, 0.33333333333333331, 10.000000000000000 },
+  { 338348.63146593666, 0.33333333333333331, 15.000000000000000 },
+  { 43434263.927938424, 0.33333333333333331, 20.000000000000000 },
+  { 5761474759.6213636, 0.33333333333333331, 25.000000000000000 },
+  { 780201111830.30237, 0.33333333333333331, 30.000000000000000 },
+  { 107166066959051.91, 0.33333333333333331, 35.000000000000000 },
+  { 14873836574083764., 0.33333333333333331, 40.000000000000000 },
+  { 2.0808143020217085e+18, 0.33333333333333331, 45.000000000000000 },
+  { 2.9292639365644226e+20, 0.33333333333333331, 50.000000000000000 },
+  { 4.1445621624120489e+22, 0.33333333333333331, 55.000000000000000 },
+  { 5.8885758374365916e+24, 0.33333333333333331, 60.000000000000000 },
+  { 8.3958047021083955e+26, 0.33333333333333331, 65.000000000000000 },
+  { 1.2006287819446431e+29, 0.33333333333333331, 70.000000000000000 },
+  { 1.7213548977150022e+31, 0.33333333333333331, 75.000000000000000 },
+  { 2.4734492458444449e+33, 0.33333333333333331, 80.000000000000000 },
+  { 3.5611354547857122e+35, 0.33333333333333331, 85.000000000000000 },
+  { 5.1360491295551848e+37, 0.33333333333333331, 90.000000000000000 },
+  { 7.4189629097600431e+39, 0.33333333333333331, 95.000000000000000 },
+  { 1.0731523308358370e+42, 0.33333333333333331, 100.00000000000000 },
+};
+
+// Test function for nu=0.33333333333333331.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data002[i].nu), Tp(data002[i].x));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for nu=0.50000000000000000.
+testcase_cyl_bessel_i<double> data003[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.0000000000000000 },
+  { 26.477547497559065, 0.50000000000000000, 5.0000000000000000 },
+  { 2778.7846038745711, 0.50000000000000000, 10.000000000000000 },
+  { 336729.88718706399, 0.50000000000000000, 15.000000000000000 },
+  { 43279746.272428922, 0.50000000000000000, 20.000000000000000 },
+  { 5745159748.3464680, 0.50000000000000000, 25.000000000000000 },
+  { 778366068840.44580, 0.50000000000000000, 30.000000000000000 },
+  { 106950522408567.66, 0.50000000000000000, 35.000000000000000 },
+  { 14847705549021962., 0.50000000000000000, 40.000000000000000 },
+  { 2.0775691824625661e+18, 0.50000000000000000, 45.000000000000000 },
+  { 2.9251568529912984e+20, 0.50000000000000000, 50.000000000000000 },
+  { 4.1392840094781220e+22, 0.50000000000000000, 55.000000000000000 },
+  { 5.8817065760751945e+24, 0.50000000000000000, 60.000000000000000 },
+  { 8.3867695787277258e+26, 0.50000000000000000, 65.000000000000000 },
+  { 1.1994296461653203e+29, 0.50000000000000000, 70.000000000000000 },
+  { 1.7197510246063334e+31, 0.50000000000000000, 75.000000000000000 },
+  { 2.4712895036230794e+33, 0.50000000000000000, 80.000000000000000 },
+  { 3.5582099086757769e+35, 0.50000000000000000, 85.000000000000000 },
+  { 5.1320654031231128e+37, 0.50000000000000000, 90.000000000000000 },
+  { 7.4135128383495239e+39, 0.50000000000000000, 95.000000000000000 },
+  { 1.0724035825423179e+42, 0.50000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data003[i].nu), Tp(data003[i].x));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for nu=0.66666666666666663.
+testcase_cyl_bessel_i<double> data004[] = {
+  { 0.0000000000000000, 0.66666666666666663, 0.0000000000000000 },
+  { 25.902310583215122, 0.66666666666666663, 5.0000000000000000 },
+  { 2750.4090423459315, 0.66666666666666663, 10.000000000000000 },
+  { 334476.98138574377, 0.66666666666666663, 15.000000000000000 },
+  { 43064361.686912313, 0.66666666666666663, 20.000000000000000 },
+  { 5722397441.9603882, 0.66666666666666663, 25.000000000000000 },
+  { 775804343498.02661, 0.66666666666666663, 30.000000000000000 },
+  { 106649495512800.88, 0.66666666666666663, 35.000000000000000 },
+  { 14811199896983756., 0.66666666666666663, 40.000000000000000 },
+  { 2.0730345814356961e+18, 0.66666666666666663, 45.000000000000000 },
+  { 2.9194166755257467e+20, 0.66666666666666663, 50.000000000000000 },
+  { 4.1319059569935374e+22, 0.66666666666666663, 55.000000000000000 },
+  { 5.8721031476386222e+24, 0.66666666666666663, 60.000000000000000 },
+  { 8.3741368248217844e+26, 0.66666666666666663, 65.000000000000000 },
+  { 1.1977528777008688e+29, 0.66666666666666663, 70.000000000000000 },
+  { 1.7175081240014333e+31, 0.66666666666666663, 75.000000000000000 },
+  { 2.4682690458513916e+33, 0.66666666666666663, 80.000000000000000 },
+  { 3.5541181975850724e+35, 0.66666666666666663, 85.000000000000000 },
+  { 5.1264933963228892e+37, 0.66666666666666663, 90.000000000000000 },
+  { 7.4058894880134064e+39, 0.66666666666666663, 95.000000000000000 },
+  { 1.0713562154788124e+42, 0.66666666666666663, 100.00000000000000 },
+};
+
+// Test function for nu=0.66666666666666663.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data004[i].nu), Tp(data004[i].x));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for nu=1.0000000000000000.
+testcase_cyl_bessel_i<double> data005[] = {
+  { 0.0000000000000000, 1.0000000000000000, 0.0000000000000000 },
+  { 24.335642142450524, 1.0000000000000000, 5.0000000000000000 },
+  { 2670.9883037012560, 1.0000000000000000, 10.000000000000000 },
+  { 328124.92197020649, 1.0000000000000000, 15.000000000000000 },
+  { 42454973.385127783, 1.0000000000000000, 20.000000000000000 },
+  { 5657865129.8787022, 1.0000000000000000, 25.000000000000000 },
+  { 768532038938.95667, 1.0000000000000000, 30.000000000000000 },
+  { 105794126051896.17, 1.0000000000000000, 35.000000000000000 },
+  { 14707396163259354., 1.0000000000000000, 40.000000000000000 },
+  { 2.0601334620815780e+18, 1.0000000000000000, 45.000000000000000 },
+  { 2.9030785901035638e+20, 1.0000000000000000, 50.000000000000000 },
+  { 4.1108986452992812e+22, 1.0000000000000000, 55.000000000000000 },
+  { 5.8447515883904527e+24, 1.0000000000000000, 60.000000000000000 },
+  { 8.3381485471501302e+26, 1.0000000000000000, 65.000000000000000 },
+  { 1.1929750788892366e+29, 1.0000000000000000, 70.000000000000000 },
+  { 1.7111160152965382e+31, 1.0000000000000000, 75.000000000000000 },
+  { 2.4596595795675343e+33, 1.0000000000000000, 80.000000000000000 },
+  { 3.5424536064404024e+35, 1.0000000000000000, 85.000000000000000 },
+  { 5.1106068152566129e+37, 1.0000000000000000, 90.000000000000000 },
+  { 7.3841518091360182e+39, 1.0000000000000000, 95.000000000000000 },
+  { 1.0683693903381569e+42, 1.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=1.0000000000000000.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data005[i].nu), Tp(data005[i].x));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for nu=2.0000000000000000.
+testcase_cyl_bessel_i<double> data006[] = {
+  { 0.0000000000000000, 2.0000000000000000, 0.0000000000000000 },
+  { 17.505614966624233, 2.0000000000000000, 5.0000000000000000 },
+  { 2281.5189677260046, 2.0000000000000000, 10.000000000000000 },
+  { 295899.38370188628, 2.0000000000000000, 15.000000000000000 },
+  { 39312785.221040756, 2.0000000000000000, 20.000000000000000 },
+  { 5321931396.0760155, 2.0000000000000000, 25.000000000000000 },
+  { 730436828561.38013, 2.0000000000000000, 30.000000000000000 },
+  { 101293439862977.19, 2.0000000000000000, 35.000000000000000 },
+  { 14159404985256922., 2.0000000000000000, 40.000000000000000 },
+  { 1.9918525879736883e+18, 2.0000000000000000, 45.000000000000000 },
+  { 2.8164306402451938e+20, 2.0000000000000000, 50.000000000000000 },
+  { 3.9993023372677540e+22, 2.0000000000000000, 55.000000000000000 },
+  { 5.6992520026634433e+24, 2.0000000000000000, 60.000000000000000 },
+  { 8.1464814287900378e+26, 2.0000000000000000, 65.000000000000000 },
+  { 1.1675039556585663e+29, 2.0000000000000000, 70.000000000000000 },
+  { 1.6770093176278926e+31, 2.0000000000000000, 75.000000000000000 },
+  { 2.4136869148449879e+33, 2.0000000000000000, 80.000000000000000 },
+  { 3.4801257808448186e+35, 2.0000000000000000, 85.000000000000000 },
+  { 5.0256693051696307e+37, 2.0000000000000000, 90.000000000000000 },
+  { 7.2678700343145818e+39, 2.0000000000000000, 95.000000000000000 },
+  { 1.0523843193243042e+42, 2.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=2.0000000000000000.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data006[i].nu), Tp(data006[i].x));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for nu=5.0000000000000000.
+testcase_cyl_bessel_i<double> data007[] = {
+  { 0.0000000000000000, 5.0000000000000000, 0.0000000000000000 },
+  { 2.1579745473225476, 5.0000000000000000, 5.0000000000000000 },
+  { 777.18828640326012, 5.0000000000000000, 10.000000000000000 },
+  { 144572.01120063409, 5.0000000000000000, 15.000000000000000 },
+  { 23018392.213413671, 5.0000000000000000, 20.000000000000000 },
+  { 3472466208.7419176, 5.0000000000000000, 25.000000000000000 },
+  { 512151465476.93494, 5.0000000000000000, 30.000000000000000 },
+  { 74756743552251.547, 5.0000000000000000, 35.000000000000000 },
+  { 10858318337624280., 5.0000000000000000, 40.000000000000000 },
+  { 1.5736087399245911e+18, 5.0000000000000000, 45.000000000000000 },
+  { 2.2785483079112825e+20, 5.0000000000000000, 50.000000000000000 },
+  { 3.2989391052963687e+22, 5.0000000000000000, 55.000000000000000 },
+  { 4.7777652072561732e+24, 5.0000000000000000, 60.000000000000000 },
+  { 6.9232165147172657e+26, 5.0000000000000000, 65.000000000000000 },
+  { 1.0038643002095155e+29, 5.0000000000000000, 70.000000000000000 },
+  { 1.4566328222327073e+31, 5.0000000000000000, 75.000000000000000 },
+  { 2.1151488565944835e+33, 5.0000000000000000, 80.000000000000000 },
+  { 3.0735883450768239e+35, 5.0000000000000000, 85.000000000000000 },
+  { 4.4694790189230327e+37, 5.0000000000000000, 90.000000000000000 },
+  { 6.5037505570430995e+39, 5.0000000000000000, 95.000000000000000 },
+  { 9.4700938730355882e+41, 5.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=5.0000000000000000.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data007[i].nu), Tp(data007[i].x));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=10.000000000000000.
+testcase_cyl_bessel_i<double> data008[] = {
+  { 0.0000000000000000, 10.000000000000000, 0.0000000000000000 },
+  { 0.0045800444191760525, 10.000000000000000, 5.0000000000000000 },
+  { 21.891706163723381, 10.000000000000000, 10.000000000000000 },
+  { 12267.475049806462, 10.000000000000000, 15.000000000000000 },
+  { 3540200.2090195213, 10.000000000000000, 20.000000000000000 },
+  { 771298871.17072666, 10.000000000000000, 25.000000000000000 },
+  { 145831809975.96710, 10.000000000000000, 30.000000000000000 },
+  { 25449470018534.777, 10.000000000000000, 35.000000000000000 },
+  { 4228469210516757.5, 10.000000000000000, 40.000000000000000 },
+  { 6.8049404557505165e+17, 10.000000000000000, 45.000000000000000 },
+  { 1.0715971594776370e+20, 10.000000000000000, 50.000000000000000 },
+  { 1.6618215752886714e+22, 10.000000000000000, 55.000000000000000 },
+  { 2.5486246072566784e+24, 10.000000000000000, 60.000000000000000 },
+  { 3.8764628702155481e+26, 10.000000000000000, 65.000000000000000 },
+  { 5.8592538145409686e+28, 10.000000000000000, 70.000000000000000 },
+  { 8.8135370711317444e+30, 10.000000000000000, 75.000000000000000 },
+  { 1.3207418268325279e+33, 10.000000000000000, 80.000000000000000 },
+  { 1.9732791360862190e+35, 10.000000000000000, 85.000000000000000 },
+  { 2.9411893748384672e+37, 10.000000000000000, 90.000000000000000 },
+  { 4.3754494922439984e+39, 10.000000000000000, 95.000000000000000 },
+  { 6.4989755247201446e+41, 10.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=10.000000000000000.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data008[i].nu), Tp(data008[i].x));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=20.000000000000000.
+testcase_cyl_bessel_i<double> data009[] = {
+  { 0.0000000000000000, 20.000000000000000, 0.0000000000000000 },
+  { 5.0242393579718066e-11, 20.000000000000000, 5.0000000000000000 },
+  { 0.00012507997356449481, 20.000000000000000, 10.000000000000000 },
+  { 1.6470152535015836, 20.000000000000000, 15.000000000000000 },
+  { 3188.7503288536154, 20.000000000000000, 20.000000000000000 },
+  { 2449840.5422952301, 20.000000000000000, 25.000000000000000 },
+  { 1126985104.4483771, 20.000000000000000, 30.000000000000000 },
+  { 379617876611.88580, 20.000000000000000, 35.000000000000000 },
+  { 104459633129479.89, 20.000000000000000, 40.000000000000000 },
+  { 25039579987216524., 20.000000000000000, 45.000000000000000 },
+  { 5.4420084027529984e+18, 20.000000000000000, 50.000000000000000 },
+  { 1.1007498584335495e+21, 20.000000000000000, 55.000000000000000 },
+  { 2.1091734863057236e+23, 20.000000000000000, 60.000000000000000 },
+  { 3.8763618091286899e+25, 20.000000000000000, 65.000000000000000 },
+  { 6.8946130527930870e+27, 20.000000000000000, 70.000000000000000 },
+  { 1.1946319948836447e+30, 20.000000000000000, 75.000000000000000 },
+  { 2.0265314377577587e+32, 20.000000000000000, 80.000000000000000 },
+  { 3.3784665214179985e+34, 20.000000000000000, 85.000000000000000 },
+  { 5.5516089411796646e+36, 20.000000000000000, 90.000000000000000 },
+  { 9.0129310795305151e+38, 20.000000000000000, 95.000000000000000 },
+  { 1.4483461256427176e+41, 20.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=20.000000000000000.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data009[i].nu), Tp(data009[i].x));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=50.000000000000000.
+testcase_cyl_bessel_i<double> data010[] = {
+  { 0.0000000000000000, 50.000000000000000, 0.0000000000000000 },
+  { 2.9314696468108517e-45, 50.000000000000000, 5.0000000000000000 },
+  { 4.7568945607268442e-30, 50.000000000000000, 10.000000000000000 },
+  { 5.5468372730667069e-21, 50.000000000000000, 15.000000000000000 },
+  { 2.2551205757604056e-14, 50.000000000000000, 20.000000000000000 },
+  { 4.5344251866130257e-09, 50.000000000000000, 25.000000000000000 },
+  { 0.00014590106916468940, 50.000000000000000, 30.000000000000000 },
+  { 1.3965549457254882, 50.000000000000000, 35.000000000000000 },
+  { 5726.8656631289896, 50.000000000000000, 40.000000000000000 },
+  { 12672593.113027781, 50.000000000000000, 45.000000000000000 },
+  { 17650802430.016712, 50.000000000000000, 50.000000000000000 },
+  { 17220231607789.926, 50.000000000000000, 55.000000000000000 },
+  { 12704607933652176., 50.000000000000000, 60.000000000000000 },
+  { 7.4989491942193725e+18, 50.000000000000000, 65.000000000000000 },
+  { 3.6944034898904922e+21, 50.000000000000000, 70.000000000000000 },
+  { 1.5691634774370186e+24, 50.000000000000000, 75.000000000000000 },
+  { 5.8927749458163587e+26, 50.000000000000000, 80.000000000000000 },
+  { 1.9958849054749339e+29, 50.000000000000000, 85.000000000000000 },
+  { 6.1946050361781500e+31, 50.000000000000000, 90.000000000000000 },
+  { 1.7845429728697119e+34, 50.000000000000000, 95.000000000000000 },
+  { 4.8219580855940819e+36, 50.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=50.000000000000000.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data010[i].nu), Tp(data010[i].x));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000029e-12));
+  }
+
+// Test data for nu=100.00000000000000.
+testcase_cyl_bessel_i<double> data011[] = {
+  { 0.0000000000000000, 100.00000000000000, 0.0000000000000000 },
+  { 7.0935514885313123e-119, 100.00000000000000, 5.0000000000000000 },
+  { 1.0823442017492018e-88, 100.00000000000000, 10.000000000000000 },
+  { 5.9887888536468904e-71, 100.00000000000000, 15.000000000000000 },
+  { 2.8703193216428771e-58, 100.00000000000000, 20.000000000000000 },
+  { 2.4426896913122370e-48, 100.00000000000000, 25.000000000000000 },
+  { 3.9476420053334271e-40, 100.00000000000000, 30.000000000000000 },
+  { 4.2836596180818780e-33, 100.00000000000000, 35.000000000000000 },
+  { 6.6249380222596129e-27, 100.00000000000000, 40.000000000000000 },
+  { 2.3702587262788900e-21, 100.00000000000000, 45.000000000000000 },
+  { 2.7278879470966917e-16, 100.00000000000000, 50.000000000000000 },
+  { 1.2763258878228082e-11, 100.00000000000000, 55.000000000000000 },
+  { 2.8832770906491972e-07, 100.00000000000000, 60.000000000000000 },
+  { 0.0035805902717061227, 100.00000000000000, 65.000000000000000 },
+  { 27.017219102595387, 100.00000000000000, 70.000000000000000 },
+  { 134001.44891209516, 100.00000000000000, 75.000000000000000 },
+  { 465194832.85060996, 100.00000000000000, 80.000000000000000 },
+  { 1189280653119.4814, 100.00000000000000, 85.000000000000000 },
+  { 2334119331258728.0, 100.00000000000000, 90.000000000000000 },
+  { 3.6399223078502436e+18, 100.00000000000000, 95.000000000000000 },
+  { 4.6415349416162005e+21, 100.00000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=100.00000000000000.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_cyl_bessel_i<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_i(Tp(data011[i].nu), Tp(data011[i].x));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  return 0;
+}
Index: testsuite/special_functions/07_cyl_bessel_i/compile.cc
===================================================================
--- testsuite/special_functions/07_cyl_bessel_i/compile.cc	(revision 0)
+++ testsuite/special_functions/07_cyl_bessel_i/compile.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.7 cyl_bessel_i
+
+#include <cmath>
+
+void
+test01()
+{
+
+  float nuf = 1.0F / 3.0F, xf = 0.5F;
+  double nud = 1.0 / 3.0, xd = 0.5;
+  long double nul = 1.0L / 3.0L, xl = 0.5L;
+
+  std::cyl_bessel_i(nuf, xf);
+  std::cyl_bessel_if(nuf, xf);
+  std::cyl_bessel_i(nud, xd);
+  std::cyl_bessel_i(nul, xl);
+  std::cyl_bessel_il(nul, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/07_cyl_bessel_i/compile_2.cc
===================================================================
--- testsuite/special_functions/07_cyl_bessel_i/compile_2.cc	(revision 0)
+++ testsuite/special_functions/07_cyl_bessel_i/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.7 cyl_bessel_i
+
+#include <math.h>
+
+void
+test01()
+{
+  float nuf = 1.0F / 3.0F, xf = 0.5F;
+  double nud = 1.0 / 3.0, xd = 0.5;
+  long double nul = 1.0L / 3.0L, xl = 0.5L;
+
+  cyl_bessel_i(nuf, xf);
+  cyl_bessel_if(nuf, xf);
+  cyl_bessel_i(nud, xd);
+  cyl_bessel_i(nul, xl);
+  cyl_bessel_il(nul, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/07_cyl_bessel_i/pr56216.cc
===================================================================
--- testsuite/special_functions/07_cyl_bessel_i/pr56216.cc	(revision 0)
+++ testsuite/special_functions/07_cyl_bessel_i/pr56216.cc	(working copy)
@@ -0,0 +1,44 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// PR libstdc++/56216 - Crash of Bessel functions at x==0!
+
+#include <testsuite_hooks.h>
+#include <cmath>
+
+void
+test01()
+{
+  double j0 = std::cyl_bessel_j(0.0, 0.0);
+  double i0 = std::cyl_bessel_i(0.0, 0.0);
+  double j1 = std::cyl_bessel_j(1.0, 0.0);
+  double i1 = std::cyl_bessel_i(1.0, 0.0);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(j0 == 1.0);
+  VERIFY(i0 == 1.0);
+  VERIFY(j1 == 0.0);
+  VERIFY(i1 == 0.0);
+}
+
+int
+main()
+{
+  test01();
+
+  return 0;
+}
Index: testsuite/special_functions/08_cyl_bessel_j/check_nan.cc
===================================================================
--- testsuite/special_functions/08_cyl_bessel_j/check_nan.cc	(revision 0)
+++ testsuite/special_functions/08_cyl_bessel_j/check_nan.cc	(working copy)
@@ -0,0 +1,88 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.8 cyl_bessel_j
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  float nuf = 0.0F;
+  double nud = 0.0;
+  long double nul = 0.0L;
+
+  float a = std::cyl_bessel_j(nuf, xf);
+  float b = std::cyl_bessel_jf(nuf, xf);
+  double c = std::cyl_bessel_j(nud, xd);
+  long double d = std::cyl_bessel_j(nul, xl);
+  long double e = std::cyl_bessel_jl(nul, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+void
+test02()
+{
+  float xf = 1.0F;
+  double xd = 1.0;
+  long double xl = 1.0L;
+
+  float nuf = std::numeric_limits<float>::quiet_NaN();
+  double nud = std::numeric_limits<double>::quiet_NaN();
+  long double nul = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::cyl_bessel_j(nuf, xf);
+  float b = std::cyl_bessel_jf(nuf, xf);
+  double c = std::cyl_bessel_j(nud, xd);
+  long double d = std::cyl_bessel_j(nul, xl);
+  long double e = std::cyl_bessel_jl(nul, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  return 0;
+}
+
Index: testsuite/special_functions/08_cyl_bessel_j/check_value.cc
===================================================================
--- testsuite/special_functions/08_cyl_bessel_j/check_value.cc	(revision 0)
+++ testsuite/special_functions/08_cyl_bessel_j/check_value.cc	(working copy)
@@ -0,0 +1,649 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  cyl_bessel_j
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for nu=0.0000000000000000.
+testcase_cyl_bessel_j<double> data001[] = {
+  { 1.0000000000000000, 0.0000000000000000, 0.0000000000000000 },
+  { -0.17759677131433835, 0.0000000000000000, 5.0000000000000000 },
+  { -0.24593576445134835, 0.0000000000000000, 10.000000000000000 },
+  { -0.014224472826780771, 0.0000000000000000, 15.000000000000000 },
+  { 0.16702466434058319, 0.0000000000000000, 20.000000000000000 },
+  { 0.096266783275958154, 0.0000000000000000, 25.000000000000000 },
+  { -0.086367983581040142, 0.0000000000000000, 30.000000000000000 },
+  { -0.12684568275631256, 0.0000000000000000, 35.000000000000000 },
+  { 0.0073668905842374085, 0.0000000000000000, 40.000000000000000 },
+  { 0.11581867067325631, 0.0000000000000000, 45.000000000000000 },
+  { 0.055812327669251746, 0.0000000000000000, 50.000000000000000 },
+  { -0.074548302648236808, 0.0000000000000000, 55.000000000000000 },
+  { -0.091471804089061859, 0.0000000000000000, 60.000000000000000 },
+  { 0.018687343227677979, 0.0000000000000000, 65.000000000000000 },
+  { 0.094908726483013545, 0.0000000000000000, 70.000000000000000 },
+  { 0.034643913805097008, 0.0000000000000000, 75.000000000000000 },
+  { -0.069742165512210033, 0.0000000000000000, 80.000000000000000 },
+  { -0.070940394796273273, 0.0000000000000000, 85.000000000000000 },
+  { 0.026630016699969526, 0.0000000000000000, 90.000000000000000 },
+  { 0.081811967783384135, 0.0000000000000000, 95.000000000000000 },
+  { 0.019985850304223170, 0.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data001[i].nu), Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for nu=0.33333333333333331.
+testcase_cyl_bessel_j<double> data002[] = {
+  { 0.0000000000000000, 0.33333333333333331, 0.0000000000000000 },
+  { -0.30642046380026405, 0.33333333333333331, 5.0000000000000000 },
+  { -0.18614516704869571, 0.33333333333333331, 10.000000000000000 },
+  { 0.089740004221152650, 0.33333333333333331, 15.000000000000000 },
+  { 0.17606058001293901, 0.33333333333333331, 20.000000000000000 },
+  { 0.020097162141383233, 0.33333333333333331, 25.000000000000000 },
+  { -0.13334053387426159, 0.33333333333333331, 30.000000000000000 },
+  { -0.087118009397765497, 0.33333333333333331, 35.000000000000000 },
+  { 0.069202942818858179, 0.33333333333333331, 40.000000000000000 },
+  { 0.11387616964518317, 0.33333333333333331, 45.000000000000000 },
+  { -0.00057226680771808045, 0.33333333333333331, 50.000000000000000 },
+  { -0.10331600929280822, 0.33333333333333331, 55.000000000000000 },
+  { -0.055618147270528003, 0.33333333333333331, 60.000000000000000 },
+  { 0.064711954014113948, 0.33333333333333331, 65.000000000000000 },
+  { 0.086879926462481605, 0.33333333333333331, 70.000000000000000 },
+  { -0.012614484229891068, 0.33333333333333331, 75.000000000000000 },
+  { -0.088199784400034537, 0.33333333333333331, 80.000000000000000 },
+  { -0.036703611076564523, 0.33333333333333331, 85.000000000000000 },
+  { 0.062916286828779547, 0.33333333333333331, 90.000000000000000 },
+  { 0.069465244416806030, 0.33333333333333331, 95.000000000000000 },
+  { -0.021271244853702364, 0.33333333333333331, 100.00000000000000 },
+};
+
+// Test function for nu=0.33333333333333331.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data002[i].nu), Tp(data002[i].x));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000017e-10));
+  }
+
+// Test data for nu=0.50000000000000000.
+testcase_cyl_bessel_j<double> data003[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.0000000000000000 },
+  { -0.34216798479816180, 0.50000000000000000, 5.0000000000000000 },
+  { -0.13726373575505049, 0.50000000000000000, 10.000000000000000 },
+  { 0.13396768882243937, 0.50000000000000000, 15.000000000000000 },
+  { 0.16288076385502984, 0.50000000000000000, 20.000000000000000 },
+  { -0.021120283599650493, 0.50000000000000000, 25.000000000000000 },
+  { -0.14392965337039987, 0.50000000000000000, 30.000000000000000 },
+  { -0.057747757589458777, 0.50000000000000000, 35.000000000000000 },
+  { 0.094000962389533649, 0.50000000000000000, 40.000000000000000 },
+  { 0.10120783324271411, 0.50000000000000000, 45.000000000000000 },
+  { -0.029605831888924641, 0.50000000000000000, 50.000000000000000 },
+  { -0.10756039213265806, 0.50000000000000000, 55.000000000000000 },
+  { -0.031397461182520438, 0.50000000000000000, 60.000000000000000 },
+  { 0.081827430775628554, 0.50000000000000000, 65.000000000000000 },
+  { 0.073802429539054554, 0.50000000000000000, 70.000000000000000 },
+  { -0.035727009681702615, 0.50000000000000000, 75.000000000000000 },
+  { -0.088661035811765460, 0.50000000000000000, 80.000000000000000 },
+  { -0.015238065106312516, 0.50000000000000000, 85.000000000000000 },
+  { 0.075189068550269425, 0.50000000000000000, 90.000000000000000 },
+  { 0.055932643481494133, 0.50000000000000000, 95.000000000000000 },
+  { -0.040402132716252127, 0.50000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data003[i].nu), Tp(data003[i].x));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for nu=0.66666666666666663.
+testcase_cyl_bessel_j<double> data004[] = {
+  { 0.0000000000000000, 0.66666666666666663, 0.0000000000000000 },
+  { -0.35712533549168868, 0.66666666666666663, 5.0000000000000000 },
+  { -0.080149603304315808, 0.66666666666666663, 10.000000000000000 },
+  { 0.16918875175798079, 0.66666666666666663, 15.000000000000000 },
+  { 0.13904826122116531, 0.66666666666666663, 20.000000000000000 },
+  { -0.060770629698497600, 0.66666666666666663, 25.000000000000000 },
+  { -0.14489851974205062, 0.66666666666666663, 30.000000000000000 },
+  { -0.024604880159644394, 0.66666666666666663, 35.000000000000000 },
+  { 0.11243936464912010, 0.66666666666666663, 40.000000000000000 },
+  { 0.081776275512525309, 0.66666666666666663, 45.000000000000000 },
+  { -0.056589908749367777, 0.66666666666666663, 50.000000000000000 },
+  { -0.10455814523765931, 0.66666666666666663, 55.000000000000000 },
+  { -0.0051030148548608456, 0.66666666666666663, 60.000000000000000 },
+  { 0.093398227061639236, 0.66666666666666663, 65.000000000000000 },
+  { 0.055763883611864913, 0.66666666666666663, 70.000000000000000 },
+  { -0.056395322915757364, 0.66666666666666663, 75.000000000000000 },
+  { -0.083131347805783087, 0.66666666666666663, 80.000000000000000 },
+  { 0.0072315397874096648, 0.66666666666666663, 85.000000000000000 },
+  { 0.082362798520905250, 0.66666666666666663, 90.000000000000000 },
+  { 0.038630504403446168, 0.66666666666666663, 95.000000000000000 },
+  { -0.056778819380529734, 0.66666666666666663, 100.00000000000000 },
+};
+
+// Test function for nu=0.66666666666666663.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data004[i].nu), Tp(data004[i].x));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000006e-10));
+  }
+
+// Test data for nu=1.0000000000000000.
+testcase_cyl_bessel_j<double> data005[] = {
+  { 0.0000000000000000, 1.0000000000000000, 0.0000000000000000 },
+  { -0.32757913759146529, 1.0000000000000000, 5.0000000000000000 },
+  { 0.043472746168861459, 1.0000000000000000, 10.000000000000000 },
+  { 0.20510403861352280, 1.0000000000000000, 15.000000000000000 },
+  { 0.066833124175850078, 1.0000000000000000, 20.000000000000000 },
+  { -0.12535024958028990, 1.0000000000000000, 25.000000000000000 },
+  { -0.11875106261662294, 1.0000000000000000, 30.000000000000000 },
+  { 0.043990942179625646, 1.0000000000000000, 35.000000000000000 },
+  { 0.12603831803758500, 1.0000000000000000, 40.000000000000000 },
+  { 0.028348854376424561, 1.0000000000000000, 45.000000000000000 },
+  { -0.097511828125175129, 1.0000000000000000, 50.000000000000000 },
+  { -0.078250038308684711, 1.0000000000000000, 55.000000000000000 },
+  { 0.046598383758166370, 1.0000000000000000, 60.000000000000000 },
+  { 0.097330172226126929, 1.0000000000000000, 65.000000000000000 },
+  { 0.0099877887848385128, 1.0000000000000000, 70.000000000000000 },
+  { -0.085139995044829081, 1.0000000000000000, 75.000000000000000 },
+  { -0.056057296675712555, 1.0000000000000000, 80.000000000000000 },
+  { 0.049151460334891130, 1.0000000000000000, 85.000000000000000 },
+  { 0.079925646708868092, 1.0000000000000000, 90.000000000000000 },
+  { -0.0023925612997269283, 1.0000000000000000, 95.000000000000000 },
+  { -0.077145352014112129, 1.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=1.0000000000000000.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data005[i].nu), Tp(data005[i].x));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000006e-10));
+  }
+
+// Test data for nu=2.0000000000000000.
+testcase_cyl_bessel_j<double> data006[] = {
+  { 0.0000000000000000, 2.0000000000000000, 0.0000000000000000 },
+  { 0.046565116277751971, 2.0000000000000000, 5.0000000000000000 },
+  { 0.25463031368512068, 2.0000000000000000, 10.000000000000000 },
+  { 0.041571677975250486, 2.0000000000000000, 15.000000000000000 },
+  { -0.16034135192299820, 2.0000000000000000, 20.000000000000000 },
+  { -0.10629480324238134, 2.0000000000000000, 25.000000000000000 },
+  { 0.078451246073265299, 2.0000000000000000, 30.000000000000000 },
+  { 0.12935945088086259, 2.0000000000000000, 35.000000000000000 },
+  { -0.0010649746823579794, 2.0000000000000000, 40.000000000000000 },
+  { -0.11455872158985966, 2.0000000000000000, 45.000000000000000 },
+  { -0.059712800794258863, 2.0000000000000000, 50.000000000000000 },
+  { 0.071702846709739240, 2.0000000000000000, 55.000000000000000 },
+  { 0.093025083547667420, 2.0000000000000000, 60.000000000000000 },
+  { -0.015692568697643128, 2.0000000000000000, 65.000000000000000 },
+  { -0.094623361089161029, 2.0000000000000000, 70.000000000000000 },
+  { -0.036914313672959179, 2.0000000000000000, 75.000000000000000 },
+  { 0.068340733095317172, 2.0000000000000000, 80.000000000000000 },
+  { 0.072096899745329540, 2.0000000000000000, 85.000000000000000 },
+  { -0.024853891217550248, 2.0000000000000000, 90.000000000000000 },
+  { -0.081862337494957332, 2.0000000000000000, 95.000000000000000 },
+  { -0.021528757344505364, 2.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=2.0000000000000000.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data006[i].nu), Tp(data006[i].x));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000017e-10));
+  }
+
+// Test data for nu=5.0000000000000000.
+testcase_cyl_bessel_j<double> data007[] = {
+  { 0.0000000000000000, 5.0000000000000000, 0.0000000000000000 },
+  { 0.26114054612017007, 5.0000000000000000, 5.0000000000000000 },
+  { -0.23406152818679371, 5.0000000000000000, 10.000000000000000 },
+  { 0.13045613456502966, 5.0000000000000000, 15.000000000000000 },
+  { 0.15116976798239498, 5.0000000000000000, 20.000000000000000 },
+  { -0.066007995398422933, 5.0000000000000000, 25.000000000000000 },
+  { -0.14324029551207709, 5.0000000000000000, 30.000000000000000 },
+  { -0.0015053072953907251, 5.0000000000000000, 35.000000000000000 },
+  { 0.12257346597711777, 5.0000000000000000, 40.000000000000000 },
+  { 0.057984499200954109, 5.0000000000000000, 45.000000000000000 },
+  { -0.081400247696569616, 5.0000000000000000, 50.000000000000000 },
+  { -0.092569895786432765, 5.0000000000000000, 55.000000000000000 },
+  { 0.027454744228344204, 5.0000000000000000, 60.000000000000000 },
+  { 0.099110527701539025, 5.0000000000000000, 65.000000000000000 },
+  { 0.026058129823895364, 5.0000000000000000, 70.000000000000000 },
+  { -0.078523977013751398, 5.0000000000000000, 75.000000000000000 },
+  { -0.065862349140031584, 5.0000000000000000, 80.000000000000000 },
+  { 0.038669072284680979, 5.0000000000000000, 85.000000000000000 },
+  { 0.082759319528415157, 5.0000000000000000, 90.000000000000000 },
+  { 0.0079423372702472871, 5.0000000000000000, 95.000000000000000 },
+  { -0.074195736964513898, 5.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=5.0000000000000000.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data007[i].nu), Tp(data007[i].x));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000028e-11));
+  }
+
+// Test data for nu=10.000000000000000.
+testcase_cyl_bessel_j<double> data008[] = {
+  { 0.0000000000000000, 10.000000000000000, 0.0000000000000000 },
+  { 0.0014678026473104744, 10.000000000000000, 5.0000000000000000 },
+  { 0.20748610663335865, 10.000000000000000, 10.000000000000000 },
+  { -0.090071811047659087, 10.000000000000000, 15.000000000000000 },
+  { 0.18648255802394512, 10.000000000000000, 20.000000000000000 },
+  { -0.075179843948523312, 10.000000000000000, 25.000000000000000 },
+  { -0.12987689399858882, 10.000000000000000, 30.000000000000000 },
+  { 0.063546391343962866, 10.000000000000000, 35.000000000000000 },
+  { 0.11938336278226094, 10.000000000000000, 40.000000000000000 },
+  { -0.026971402475010831, 10.000000000000000, 45.000000000000000 },
+  { -0.11384784914946940, 10.000000000000000, 50.000000000000000 },
+  { -0.015773790303746080, 10.000000000000000, 55.000000000000000 },
+  { 0.097177143328071064, 10.000000000000000, 60.000000000000000 },
+  { 0.054617389951112129, 10.000000000000000, 65.000000000000000 },
+  { -0.065870338561952013, 10.000000000000000, 70.000000000000000 },
+  { -0.080417867891894437, 10.000000000000000, 75.000000000000000 },
+  { 0.024043850978184747, 10.000000000000000, 80.000000000000000 },
+  { 0.086824832700067869, 10.000000000000000, 85.000000000000000 },
+  { 0.019554748856312299, 10.000000000000000, 90.000000000000000 },
+  { -0.072341598669443757, 10.000000000000000, 95.000000000000000 },
+  { -0.054732176935472096, 10.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=10.000000000000000.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data008[i].nu), Tp(data008[i].x));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for nu=20.000000000000000.
+testcase_cyl_bessel_j<double> data009[] = {
+  { 0.0000000000000000, 20.000000000000000, 0.0000000000000000 },
+  { 2.7703300521289426e-11, 20.000000000000000, 5.0000000000000000 },
+  { 1.1513369247813403e-05, 20.000000000000000, 10.000000000000000 },
+  { 0.0073602340792234934, 20.000000000000000, 15.000000000000000 },
+  { 0.16474777377532665, 20.000000000000000, 20.000000000000000 },
+  { 0.051994049228303307, 20.000000000000000, 25.000000000000000 },
+  { 0.0048310199934040923, 20.000000000000000, 30.000000000000000 },
+  { -0.10927417397178038, 20.000000000000000, 35.000000000000000 },
+  { 0.12779393355084889, 20.000000000000000, 40.000000000000000 },
+  { 0.0047633437900313621, 20.000000000000000, 45.000000000000000 },
+  { -0.11670435275957974, 20.000000000000000, 50.000000000000000 },
+  { 0.025389204574566639, 20.000000000000000, 55.000000000000000 },
+  { 0.10266020557876326, 20.000000000000000, 60.000000000000000 },
+  { -0.023138582263434154, 20.000000000000000, 65.000000000000000 },
+  { -0.096058573489952365, 20.000000000000000, 70.000000000000000 },
+  { 0.0068961047221522270, 20.000000000000000, 75.000000000000000 },
+  { 0.090565405489918357, 20.000000000000000, 80.000000000000000 },
+  { 0.015985497599497172, 20.000000000000000, 85.000000000000000 },
+  { -0.080345344044422534, 20.000000000000000, 90.000000000000000 },
+  { -0.040253075701614051, 20.000000000000000, 95.000000000000000 },
+  { 0.062217458498338672, 20.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=20.000000000000000.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data009[i].nu), Tp(data009[i].x));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000006e-10));
+  }
+
+// Test data for nu=50.000000000000000.
+testcase_cyl_bessel_j<double> data010[] = {
+  { 0.0000000000000000, 50.000000000000000, 0.0000000000000000 },
+  { 2.2942476159525415e-45, 50.000000000000000, 5.0000000000000000 },
+  { 1.7845136078715964e-30, 50.000000000000000, 10.000000000000000 },
+  { 6.1060519495338733e-22, 50.000000000000000, 15.000000000000000 },
+  { 4.4510392847006872e-16, 50.000000000000000, 20.000000000000000 },
+  { 9.7561594280229808e-12, 50.000000000000000, 25.000000000000000 },
+  { 2.0581656631564172e-08, 50.000000000000000, 30.000000000000000 },
+  { 7.6069951699272960e-06, 50.000000000000000, 35.000000000000000 },
+  { 0.00068185243531768309, 50.000000000000000, 40.000000000000000 },
+  { 0.017284343240791214, 50.000000000000000, 45.000000000000000 },
+  { 0.12140902189761507, 50.000000000000000, 50.000000000000000 },
+  { 0.13594720957176012, 50.000000000000000, 55.000000000000000 },
+  { -0.13798273148535209, 50.000000000000000, 60.000000000000000 },
+  { 0.12116217746619409, 50.000000000000000, 65.000000000000000 },
+  { -0.11394866738787145, 50.000000000000000, 70.000000000000000 },
+  { 0.094076799581573348, 50.000000000000000, 75.000000000000000 },
+  { -0.039457764590251347, 50.000000000000000, 80.000000000000000 },
+  { -0.040412060734136383, 50.000000000000000, 85.000000000000000 },
+  { 0.090802099838032266, 50.000000000000000, 90.000000000000000 },
+  { -0.055979156267280165, 50.000000000000000, 95.000000000000000 },
+  { -0.038698339728525440, 50.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=50.000000000000000.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data010[i].nu), Tp(data010[i].x));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000006e-11));
+  }
+
+// Test data for nu=100.00000000000000.
+testcase_cyl_bessel_j<double> data011[] = {
+  { 0.0000000000000000, 100.00000000000000, 0.0000000000000000 },
+  { 6.2677893955418763e-119, 100.00000000000000, 5.0000000000000000 },
+  { 6.5973160641553816e-89, 100.00000000000000, 10.000000000000000 },
+  { 1.9660095611249536e-71, 100.00000000000000, 15.000000000000000 },
+  { 3.9617550943362524e-59, 100.00000000000000, 20.000000000000000 },
+  { 1.1064482655301687e-49, 100.00000000000000, 25.000000000000000 },
+  { 4.5788015281752354e-42, 100.00000000000000, 30.000000000000000 },
+  { 9.9210206714732606e-36, 100.00000000000000, 35.000000000000000 },
+  { 2.3866062996027414e-30, 100.00000000000000, 40.000000000000000 },
+  { 1.0329791804565538e-25, 100.00000000000000, 45.000000000000000 },
+  { 1.1159273690838340e-21, 100.00000000000000, 50.000000000000000 },
+  { 3.7899753451900682e-18, 100.00000000000000, 55.000000000000000 },
+  { 4.7832744078781205e-15, 100.00000000000000, 60.000000000000000 },
+  { 2.5375564579490517e-12, 100.00000000000000, 65.000000000000000 },
+  { 6.1982452141641260e-10, 100.00000000000000, 70.000000000000000 },
+  { 7.4479005905904457e-08, 100.00000000000000, 75.000000000000000 },
+  { 4.6065530648234948e-06, 100.00000000000000, 80.000000000000000 },
+  { 0.00015043869999501765, 100.00000000000000, 85.000000000000000 },
+  { 0.0026021305819963472, 100.00000000000000, 90.000000000000000 },
+  { 0.023150768009428030, 100.00000000000000, 95.000000000000000 },
+  { 0.096366673295861571, 100.00000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=100.00000000000000.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_cyl_bessel_j<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_j(Tp(data011[i].nu), Tp(data011[i].x));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000006e-11));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  return 0;
+}
Index: testsuite/special_functions/08_cyl_bessel_j/compile.cc
===================================================================
--- testsuite/special_functions/08_cyl_bessel_j/compile.cc	(revision 0)
+++ testsuite/special_functions/08_cyl_bessel_j/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.8 cyl_bessel_j
+
+#include <cmath>
+
+void
+test01()
+{
+  float nuf = 1.0F / 3.0F, xf = 0.5F;
+  double nud = 1.0 / 3.0, xd = 0.5;
+  long double nul = 1.0L / 3.0L, xl = 0.5L;
+
+  std::cyl_bessel_j(nuf, xf);
+  std::cyl_bessel_jf(nuf, xf);
+  std::cyl_bessel_j(nud, xd);
+  std::cyl_bessel_j(nul, xl);
+  std::cyl_bessel_jl(nul, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/08_cyl_bessel_j/compile_2.cc
===================================================================
--- testsuite/special_functions/08_cyl_bessel_j/compile_2.cc	(revision 0)
+++ testsuite/special_functions/08_cyl_bessel_j/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.8 cyl_bessel_j
+
+#include <math.h>
+
+void
+test01()
+{
+  float nuf = 1.0F / 3.0F, xf = 0.5F;
+  double nud = 1.0 / 3.0, xd = 0.5;
+  long double nul = 1.0L / 3.0L, xl = 0.5L;
+
+  cyl_bessel_j(nuf, xf);
+  cyl_bessel_jf(nuf, xf);
+  cyl_bessel_j(nud, xd);
+  cyl_bessel_j(nul, xl);
+  cyl_bessel_jl(nul, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/09_cyl_bessel_k/check_nan.cc
===================================================================
--- testsuite/special_functions/09_cyl_bessel_k/check_nan.cc	(revision 0)
+++ testsuite/special_functions/09_cyl_bessel_k/check_nan.cc	(working copy)
@@ -0,0 +1,88 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.9 cyl_bessel_k
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  float nuf = 0.0F;
+  double nud = 0.0;
+  long double nul = 0.0L;
+
+  float a = std::cyl_bessel_k(nuf, xf);
+  float b = std::cyl_bessel_kf(nuf, xf);
+  double c = std::cyl_bessel_k(nud, xd);
+  long double d = std::cyl_bessel_k(nul, xl);
+  long double e = std::cyl_bessel_kl(nul, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+void
+test02()
+{
+  float xf = 1.0F;
+  double xd = 1.0;
+  long double xl = 1.0L;
+
+  float nuf = std::numeric_limits<float>::quiet_NaN();
+  double nud = std::numeric_limits<double>::quiet_NaN();
+  long double nul = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::cyl_bessel_k(nuf, xf);
+  float b = std::cyl_bessel_kf(nuf, xf);
+  double c = std::cyl_bessel_k(nud, xd);
+  long double d = std::cyl_bessel_k(nul, xl);
+  long double e = std::cyl_bessel_kl(nul, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  return 0;
+}
+
Index: testsuite/special_functions/09_cyl_bessel_k/check_value.cc
===================================================================
--- testsuite/special_functions/09_cyl_bessel_k/check_value.cc	(revision 0)
+++ testsuite/special_functions/09_cyl_bessel_k/check_value.cc	(working copy)
@@ -0,0 +1,638 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  cyl_bessel_k
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for nu=0.0000000000000000.
+testcase_cyl_bessel_k<double> data001[] = {
+  { 0.0036910983340425947, 0.0000000000000000, 5.0000000000000000 },
+  { 1.7780062316167650e-05, 0.0000000000000000, 10.000000000000000 },
+  { 9.8195364823964333e-08, 0.0000000000000000, 15.000000000000000 },
+  { 5.7412378153365238e-10, 0.0000000000000000, 20.000000000000000 },
+  { 3.4641615622131151e-12, 0.0000000000000000, 25.000000000000000 },
+  { 2.1324774964630566e-14, 0.0000000000000000, 30.000000000000000 },
+  { 1.3310351491429464e-16, 0.0000000000000000, 35.000000000000000 },
+  { 8.3928611000995700e-19, 0.0000000000000000, 40.000000000000000 },
+  { 5.3334561226187247e-21, 0.0000000000000000, 45.000000000000000 },
+  { 3.4101677497894956e-23, 0.0000000000000000, 50.000000000000000 },
+  { 2.1913102183534147e-25, 0.0000000000000000, 55.000000000000000 },
+  { 1.4138978405591074e-27, 0.0000000000000000, 60.000000000000000 },
+  { 9.1544673210030045e-30, 0.0000000000000000, 65.000000000000000 },
+  { 5.9446613372925013e-32, 0.0000000000000000, 70.000000000000000 },
+  { 3.8701170455869113e-34, 0.0000000000000000, 75.000000000000000 },
+  { 2.5251198425054723e-36, 0.0000000000000000, 80.000000000000000 },
+  { 1.6507623579783908e-38, 0.0000000000000000, 85.000000000000000 },
+  { 1.0810242556984256e-40, 0.0000000000000000, 90.000000000000000 },
+  { 7.0901249699001278e-43, 0.0000000000000000, 95.000000000000000 },
+  { 4.6566282291759032e-45, 0.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data001[i].nu), Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=0.33333333333333331.
+testcase_cyl_bessel_k<double> data002[] = {
+  { 0.0037288750960535887, 0.33333333333333331, 5.0000000000000000 },
+  { 1.7874608271055339e-05, 0.33333333333333331, 10.000000000000000 },
+  { 9.8548341568798317e-08, 0.33333333333333331, 15.000000000000000 },
+  { 5.7568278247790865e-10, 0.33333333333333331, 20.000000000000000 },
+  { 3.4717201424907059e-12, 0.33333333333333331, 25.000000000000000 },
+  { 2.1363664736611189e-14, 0.33333333333333331, 30.000000000000000 },
+  { 1.3331202314165813e-16, 0.33333333333333331, 35.000000000000000 },
+  { 8.4043837769480934e-19, 0.33333333333333331, 40.000000000000000 },
+  { 5.3399731261024948e-21, 0.33333333333333331, 45.000000000000000 },
+  { 3.4139217813583632e-23, 0.33333333333333331, 50.000000000000000 },
+  { 2.1935050179185627e-25, 0.33333333333333331, 55.000000000000000 },
+  { 1.4151968805623662e-27, 0.33333333333333331, 60.000000000000000 },
+  { 9.1622357217019043e-30, 0.33333333333333331, 65.000000000000000 },
+  { 5.9493479703461315e-32, 0.33333333333333331, 70.000000000000000 },
+  { 3.8729660011055947e-34, 0.33333333333333331, 75.000000000000000 },
+  { 2.5268631828013877e-36, 0.33333333333333331, 80.000000000000000 },
+  { 1.6518353676138867e-38, 0.33333333333333331, 85.000000000000000 },
+  { 1.0816880942511494e-40, 0.33333333333333331, 90.000000000000000 },
+  { 7.0942508599231512e-43, 0.33333333333333331, 95.000000000000000 },
+  { 4.6592031570213454e-45, 0.33333333333333331, 100.00000000000000 },
+};
+
+// Test function for nu=0.33333333333333331.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data002[i].nu), Tp(data002[i].x));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=0.50000000000000000.
+testcase_cyl_bessel_k<double> data003[] = {
+  { 0.0037766133746428825, 0.50000000000000000, 5.0000000000000000 },
+  { 1.7993478093705181e-05, 0.50000000000000000, 10.000000000000000 },
+  { 9.8991312032877236e-08, 0.50000000000000000, 15.000000000000000 },
+  { 5.7763739747074450e-10, 0.50000000000000000, 20.000000000000000 },
+  { 3.4811912768406949e-12, 0.50000000000000000, 25.000000000000000 },
+  { 2.1412375659560111e-14, 0.50000000000000000, 30.000000000000000 },
+  { 1.3357311366035824e-16, 0.50000000000000000, 35.000000000000000 },
+  { 8.4188091949489049e-19, 0.50000000000000000, 40.000000000000000 },
+  { 5.3481305002517408e-21, 0.50000000000000000, 45.000000000000000 },
+  { 3.4186200954570754e-23, 0.50000000000000000, 50.000000000000000 },
+  { 2.1962515908772453e-25, 0.50000000000000000, 55.000000000000000 },
+  { 1.4168223500353693e-27, 0.50000000000000000, 60.000000000000000 },
+  { 9.1719554473256892e-30, 0.50000000000000000, 65.000000000000000 },
+  { 5.9552114337788932e-32, 0.50000000000000000, 70.000000000000000 },
+  { 3.8765301321409432e-34, 0.50000000000000000, 75.000000000000000 },
+  { 2.5290440439442910e-36, 0.50000000000000000, 80.000000000000000 },
+  { 1.6531776067605980e-38, 0.50000000000000000, 85.000000000000000 },
+  { 1.0825184636529955e-40, 0.50000000000000000, 90.000000000000000 },
+  { 7.0994115873258822e-43, 0.50000000000000000, 95.000000000000000 },
+  { 4.6624238126346715e-45, 0.50000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data003[i].nu), Tp(data003[i].x));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=0.66666666666666663.
+testcase_cyl_bessel_k<double> data004[] = {
+  { 0.0038444246344968226, 0.66666666666666663, 5.0000000000000000 },
+  { 1.8161187569530204e-05, 0.66666666666666663, 10.000000000000000 },
+  { 9.9614751542305571e-08, 0.66666666666666663, 15.000000000000000 },
+  { 5.8038484271925811e-10, 0.66666666666666663, 20.000000000000000 },
+  { 3.4944937498488603e-12, 0.66666666666666663, 25.000000000000000 },
+  { 2.1480755645577720e-14, 0.66666666666666663, 30.000000000000000 },
+  { 1.3393949190152161e-16, 0.66666666666666663, 35.000000000000000 },
+  { 8.4390460553642992e-19, 0.66666666666666663, 40.000000000000000 },
+  { 5.3595716143622089e-21, 0.66666666666666663, 45.000000000000000 },
+  { 3.4252085301433749e-23, 0.66666666666666663, 50.000000000000000 },
+  { 2.2001025377982308e-25, 0.66666666666666663, 55.000000000000000 },
+  { 1.4191011274172078e-27, 0.66666666666666663, 60.000000000000000 },
+  { 9.1855803020269763e-30, 0.66666666666666663, 65.000000000000000 },
+  { 5.9634299472578764e-32, 0.66666666666666663, 70.000000000000000 },
+  { 3.8815254026478500e-34, 0.66666666666666663, 75.000000000000000 },
+  { 2.5321003991943851e-36, 0.66666666666666663, 80.000000000000000 },
+  { 1.6550585670593067e-38, 0.66666666666666663, 85.000000000000000 },
+  { 1.0836820479428605e-40, 0.66666666666666663, 90.000000000000000 },
+  { 7.1066428916285356e-43, 0.66666666666666663, 95.000000000000000 },
+  { 4.6669364587280465e-45, 0.66666666666666663, 100.00000000000000 },
+};
+
+// Test function for nu=0.66666666666666663.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data004[i].nu), Tp(data004[i].x));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=1.0000000000000000.
+testcase_cyl_bessel_k<double> data005[] = {
+  { 0.0040446134454521655, 1.0000000000000000, 5.0000000000000000 },
+  { 1.8648773453825582e-05, 1.0000000000000000, 10.000000000000000 },
+  { 1.0141729369762091e-07, 1.0000000000000000, 15.000000000000000 },
+  { 5.8830579695570384e-10, 1.0000000000000000, 20.000000000000000 },
+  { 3.5327780731999345e-12, 1.0000000000000000, 25.000000000000000 },
+  { 2.1677320018915498e-14, 1.0000000000000000, 30.000000000000000 },
+  { 1.3499178340011053e-16, 1.0000000000000000, 35.000000000000000 },
+  { 8.4971319548610435e-19, 1.0000000000000000, 40.000000000000000 },
+  { 5.3923945937225035e-21, 1.0000000000000000, 45.000000000000000 },
+  { 3.4441022267175555e-23, 1.0000000000000000, 50.000000000000000 },
+  { 2.2111422716117463e-25, 1.0000000000000000, 55.000000000000000 },
+  { 1.4256320265171041e-27, 1.0000000000000000, 60.000000000000000 },
+  { 9.2246195278906156e-30, 1.0000000000000000, 65.000000000000000 },
+  { 5.9869736739138550e-32, 1.0000000000000000, 70.000000000000000 },
+  { 3.8958329467421912e-34, 1.0000000000000000, 75.000000000000000 },
+  { 2.5408531275211708e-36, 1.0000000000000000, 80.000000000000000 },
+  { 1.6604444948567571e-38, 1.0000000000000000, 85.000000000000000 },
+  { 1.0870134457498335e-40, 1.0000000000000000, 90.000000000000000 },
+  { 7.1273442329907240e-43, 1.0000000000000000, 95.000000000000000 },
+  { 4.6798537356369101e-45, 1.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=1.0000000000000000.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data005[i].nu), Tp(data005[i].x));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=2.0000000000000000.
+testcase_cyl_bessel_k<double> data006[] = {
+  { 0.0053089437122234608, 2.0000000000000000, 5.0000000000000000 },
+  { 2.1509817006932767e-05, 2.0000000000000000, 10.000000000000000 },
+  { 1.1171767065031378e-07, 2.0000000000000000, 15.000000000000000 },
+  { 6.3295436122922281e-10, 2.0000000000000000, 20.000000000000000 },
+  { 3.7467838080691102e-12, 2.0000000000000000, 25.000000000000000 },
+  { 2.2769929632558265e-14, 2.0000000000000000, 30.000000000000000 },
+  { 1.4081733110858665e-16, 2.0000000000000000, 35.000000000000000 },
+  { 8.8177176978426223e-19, 2.0000000000000000, 40.000000000000000 },
+  { 5.5731181045619470e-21, 2.0000000000000000, 45.000000000000000 },
+  { 3.5479318388581979e-23, 2.0000000000000000, 50.000000000000000 },
+  { 2.2717153918665688e-25, 2.0000000000000000, 55.000000000000000 },
+  { 1.4614189081096777e-27, 2.0000000000000000, 60.000000000000000 },
+  { 9.4383017680150234e-30, 2.0000000000000000, 65.000000000000000 },
+  { 6.1157177279757537e-32, 2.0000000000000000, 70.000000000000000 },
+  { 3.9740059241667034e-34, 2.0000000000000000, 75.000000000000000 },
+  { 2.5886411706935015e-36, 2.0000000000000000, 80.000000000000000 },
+  { 1.6898316402103142e-38, 2.0000000000000000, 85.000000000000000 },
+  { 1.1051801100484218e-40, 2.0000000000000000, 90.000000000000000 },
+  { 7.2401743221736176e-43, 2.0000000000000000, 95.000000000000000 },
+  { 4.7502253038886413e-45, 2.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=2.0000000000000000.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data006[i].nu), Tp(data006[i].x));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=5.0000000000000000.
+testcase_cyl_bessel_k<double> data007[] = {
+  { 0.032706273712031865, 5.0000000000000000, 5.0000000000000000 },
+  { 5.7541849985312288e-05, 5.0000000000000000, 10.000000000000000 },
+  { 2.1878261369258224e-07, 5.0000000000000000, 15.000000000000000 },
+  { 1.0538660139974233e-09, 5.0000000000000000, 20.000000000000000 },
+  { 5.6485921365284157e-12, 5.0000000000000000, 25.000000000000000 },
+  { 3.2103335105890266e-14, 5.0000000000000000, 30.000000000000000 },
+  { 1.8919208406439644e-16, 5.0000000000000000, 35.000000000000000 },
+  { 1.1423814375953188e-18, 5.0000000000000000, 40.000000000000000 },
+  { 7.0181216822204101e-21, 5.0000000000000000, 45.000000000000000 },
+  { 4.3671822541009859e-23, 5.0000000000000000, 50.000000000000000 },
+  { 2.7444967640357869e-25, 5.0000000000000000, 55.000000000000000 },
+  { 1.7382232741886986e-27, 5.0000000000000000, 60.000000000000000 },
+  { 1.1078474298959669e-29, 5.0000000000000000, 65.000000000000000 },
+  { 7.0974537081794416e-32, 5.0000000000000000, 70.000000000000000 },
+  { 4.5667269500061064e-34, 5.0000000000000000, 75.000000000000000 },
+  { 2.9491764420206150e-36, 5.0000000000000000, 80.000000000000000 },
+  { 1.9105685973117463e-38, 5.0000000000000000, 85.000000000000000 },
+  { 1.2411034311592645e-40, 5.0000000000000000, 90.000000000000000 },
+  { 8.0814211331379146e-43, 5.0000000000000000, 95.000000000000000 },
+  { 5.2732561132929509e-45, 5.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=5.0000000000000000.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data007[i].nu), Tp(data007[i].x));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=10.000000000000000.
+testcase_cyl_bessel_k<double> data008[] = {
+  { 9.7585628291778121, 10.000000000000000, 5.0000000000000000 },
+  { 0.0016142553003906700, 10.000000000000000, 10.000000000000000 },
+  { 2.2605303776606435e-06, 10.000000000000000, 15.000000000000000 },
+  { 6.3162145283215804e-09, 10.000000000000000, 20.000000000000000 },
+  { 2.4076769602801233e-11, 10.000000000000000, 25.000000000000000 },
+  { 1.0842816942222975e-13, 10.000000000000000, 30.000000000000000 },
+  { 5.3976770429777191e-16, 10.000000000000000, 35.000000000000000 },
+  { 2.8680293113671932e-18, 10.000000000000000, 40.000000000000000 },
+  { 1.5939871900169600e-20, 10.000000000000000, 45.000000000000000 },
+  { 9.1509882099879962e-23, 10.000000000000000, 50.000000000000000 },
+  { 5.3823846249592858e-25, 10.000000000000000, 55.000000000000000 },
+  { 3.2253408700563144e-27, 10.000000000000000, 60.000000000000000 },
+  { 1.9613367530075138e-29, 10.000000000000000, 65.000000000000000 },
+  { 1.2068471495933484e-31, 10.000000000000000, 70.000000000000000 },
+  { 7.4979152649449644e-34, 10.000000000000000, 75.000000000000000 },
+  { 4.6957285830490538e-36, 10.000000000000000, 80.000000000000000 },
+  { 2.9606323347034079e-38, 10.000000000000000, 85.000000000000000 },
+  { 1.8773542561131613e-40, 10.000000000000000, 90.000000000000000 },
+  { 1.1962899527846350e-42, 10.000000000000000, 95.000000000000000 },
+  { 7.6554279773881018e-45, 10.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=10.000000000000000.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data008[i].nu), Tp(data008[i].x));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=20.000000000000000.
+testcase_cyl_bessel_k<double> data009[] = {
+  { 482700052.06214869, 20.000000000000000, 5.0000000000000000 },
+  { 178.74427820770546, 20.000000000000000, 10.000000000000000 },
+  { 0.012141257729731143, 20.000000000000000, 15.000000000000000 },
+  { 5.5431116361258155e-06, 20.000000000000000, 20.000000000000000 },
+  { 6.3744029330352113e-09, 20.000000000000000, 25.000000000000000 },
+  { 1.2304516475442478e-11, 20.000000000000000, 30.000000000000000 },
+  { 3.2673136479809018e-14, 20.000000000000000, 35.000000000000000 },
+  { 1.0703023799997383e-16, 20.000000000000000, 40.000000000000000 },
+  { 4.0549953175660457e-19, 20.000000000000000, 45.000000000000000 },
+  { 1.7061483797220349e-21, 20.000000000000000, 50.000000000000000 },
+  { 7.7617008115659413e-24, 20.000000000000000, 55.000000000000000 },
+  { 3.7482954006874720e-26, 20.000000000000000, 60.000000000000000 },
+  { 1.8966880763956576e-28, 20.000000000000000, 65.000000000000000 },
+  { 9.9615763479998864e-31, 20.000000000000000, 70.000000000000000 },
+  { 5.3921623063091066e-33, 20.000000000000000, 75.000000000000000 },
+  { 2.9920407657642272e-35, 20.000000000000000, 80.000000000000000 },
+  { 1.6948662723618255e-37, 20.000000000000000, 85.000000000000000 },
+  { 9.7689149642963042e-40, 20.000000000000000, 90.000000000000000 },
+  { 5.7143603019220823e-42, 20.000000000000000, 95.000000000000000 },
+  { 3.3852054148901700e-44, 20.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=20.000000000000000.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data009[i].nu), Tp(data009[i].x));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=50.000000000000000.
+testcase_cyl_bessel_k<double> data010[] = {
+  { 3.3943222434301628e+42, 50.000000000000000, 5.0000000000000000 },
+  { 2.0613737753892557e+27, 50.000000000000000, 10.000000000000000 },
+  { 1.7267736974519188e+18, 50.000000000000000, 15.000000000000000 },
+  { 411711209122.01788, 50.000000000000000, 20.000000000000000 },
+  { 1972478.7419813874, 50.000000000000000, 25.000000000000000 },
+  { 58.770686258007267, 50.000000000000000, 30.000000000000000 },
+  { 0.0058659391182535178, 50.000000000000000, 35.000000000000000 },
+  { 1.3634854128794101e-06, 50.000000000000000, 40.000000000000000 },
+  { 5.8652396362160819e-10, 50.000000000000000, 45.000000000000000 },
+  { 4.0060134766400893e-13, 50.000000000000000, 50.000000000000000 },
+  { 3.9062324485711016e-16, 50.000000000000000, 55.000000000000000 },
+  { 5.0389298085176510e-19, 50.000000000000000, 60.000000000000000 },
+  { 8.1305344250110424e-22, 50.000000000000000, 65.000000000000000 },
+  { 1.5732816234948991e-24, 50.000000000000000, 70.000000000000000 },
+  { 3.5349854993874412e-27, 50.000000000000000, 75.000000000000000 },
+  { 8.9940101003189485e-30, 50.000000000000000, 80.000000000000000 },
+  { 2.5403205503080723e-32, 50.000000000000000, 85.000000000000000 },
+  { 7.8397596486715721e-35, 50.000000000000000, 90.000000000000000 },
+  { 2.6098900651329542e-37, 50.000000000000000, 95.000000000000000 },
+  { 9.2745226536133258e-40, 50.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=50.000000000000000.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data010[i].nu), Tp(data010[i].x));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for nu=100.00000000000000.
+testcase_cyl_bessel_k<double> data011[] = {
+  { 7.0398601930616815e+115, 100.00000000000000, 5.0000000000000000 },
+  { 4.5966740842695238e+85, 100.00000000000000, 10.000000000000000 },
+  { 8.2565552242653946e+67, 100.00000000000000, 15.000000000000000 },
+  { 1.7081356456876041e+55, 100.00000000000000, 20.000000000000000 },
+  { 1.9858028128780610e+45, 100.00000000000000, 25.000000000000000 },
+  { 1.2131584253026677e+37, 100.00000000000000, 30.000000000000000 },
+  { 1.1016916354696688e+30, 100.00000000000000, 35.000000000000000 },
+  { 7.0074023297775712e+23, 100.00000000000000, 40.000000000000000 },
+  { 1.9236643958470894e+18, 100.00000000000000, 45.000000000000000 },
+  { 16394035276269.250, 100.00000000000000, 50.000000000000000 },
+  { 343254952.89495474, 100.00000000000000, 55.000000000000000 },
+  { 14870.012754946298, 100.00000000000000, 60.000000000000000 },
+  { 1.1708099078572216, 100.00000000000000, 65.000000000000000 },
+  { 0.00015161193930722313, 100.00000000000000, 70.000000000000000 },
+  { 2.9850234381623443e-08, 100.00000000000000, 75.000000000000000 },
+  { 8.3928710724649129e-12, 100.00000000000000, 80.000000000000000 },
+  { 3.2033435630927732e-15, 100.00000000000000, 85.000000000000000 },
+  { 1.5922281431788096e-18, 100.00000000000000, 90.000000000000000 },
+  { 9.9589454577674131e-22, 100.00000000000000, 95.000000000000000 },
+  { 7.6171296304940840e-25, 100.00000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=100.00000000000000.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_cyl_bessel_k<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_bessel_k(Tp(data011[i].nu), Tp(data011[i].x));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  return 0;
+}
Index: testsuite/special_functions/09_cyl_bessel_k/compile.cc
===================================================================
--- testsuite/special_functions/09_cyl_bessel_k/compile.cc	(revision 0)
+++ testsuite/special_functions/09_cyl_bessel_k/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.9 cyl_bessel_k
+
+#include <cmath>
+
+void
+test01()
+{
+  float nuf = 1.0F / 3.0F, xf = 0.5F;
+  double nud = 1.0 / 3.0, xd = 0.5;
+  long double nul = 1.0L / 3.0L, xl = 0.5L;
+
+  std::cyl_bessel_k(nuf, xf);
+  std::cyl_bessel_kf(nuf, xf);
+  std::cyl_bessel_k(nud, xd);
+  std::cyl_bessel_k(nul, xl);
+  std::cyl_bessel_kl(nul, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/09_cyl_bessel_k/compile_2.cc
===================================================================
--- testsuite/special_functions/09_cyl_bessel_k/compile_2.cc	(revision 0)
+++ testsuite/special_functions/09_cyl_bessel_k/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.9 cyl_bessel_k
+
+#include <math.h>
+
+void
+test01()
+{
+  float nuf = 1.0F / 3.0F, xf = 0.5F;
+  double nud = 1.0 / 3.0, xd = 0.5;
+  long double nul = 1.0L / 3.0L, xl = 0.5L;
+
+  cyl_bessel_k(nuf, xf);
+  cyl_bessel_kf(nuf, xf);
+  cyl_bessel_k(nud, xd);
+  cyl_bessel_k(nul, xl);
+  cyl_bessel_kl(nul, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/10_cyl_neumann/check_nan.cc
===================================================================
--- testsuite/special_functions/10_cyl_neumann/check_nan.cc	(revision 0)
+++ testsuite/special_functions/10_cyl_neumann/check_nan.cc	(working copy)
@@ -0,0 +1,88 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.10 cyl_neumann
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  float nuf = 0.0F;
+  double nud = 0.0;
+  long double nul = 0.0L;
+
+  float a = std::cyl_neumann(nuf, xf);
+  float b = std::cyl_neumannf(nuf, xf);
+  double c = std::cyl_neumann(nud, xd);
+  long double d = std::cyl_neumann(nul, xl);
+  long double e = std::cyl_neumannl(nul, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+void
+test02()
+{
+  float xf = 1.0F;
+  double xd = 1.0;
+  long double xl = 1.0L;
+
+  float nuf = std::numeric_limits<float>::quiet_NaN();
+  double nud = std::numeric_limits<double>::quiet_NaN();
+  long double nul = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::cyl_neumann(nuf, xf);
+  float b = std::cyl_neumannf(nuf, xf);
+  double c = std::cyl_neumann(nud, xd);
+  long double d = std::cyl_neumann(nul, xl);
+  long double e = std::cyl_neumannl(nul, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  return 0;
+}
+
Index: testsuite/special_functions/10_cyl_neumann/check_value.cc
===================================================================
--- testsuite/special_functions/10_cyl_neumann/check_value.cc	(revision 0)
+++ testsuite/special_functions/10_cyl_neumann/check_value.cc	(working copy)
@@ -0,0 +1,638 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  cyl_neumann
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for nu=0.0000000000000000.
+testcase_cyl_neumann<double> data001[] = {
+  { -0.30851762524903359, 0.0000000000000000, 5.0000000000000000 },
+  { 0.055671167283599457, 0.0000000000000000, 10.000000000000000 },
+  { 0.20546429603891822, 0.0000000000000000, 15.000000000000000 },
+  { 0.062640596809384053, 0.0000000000000000, 20.000000000000000 },
+  { -0.12724943226800617, 0.0000000000000000, 25.000000000000000 },
+  { -0.11729573168666413, 0.0000000000000000, 30.000000000000000 },
+  { 0.045797987195155689, 0.0000000000000000, 35.000000000000000 },
+  { 0.12593641705826092, 0.0000000000000000, 40.000000000000000 },
+  { 0.027060469763313333, 0.0000000000000000, 45.000000000000000 },
+  { -0.098064995470077118, 0.0000000000000000, 50.000000000000000 },
+  { -0.077569178730412594, 0.0000000000000000, 55.000000000000000 },
+  { 0.047358952209449426, 0.0000000000000000, 60.000000000000000 },
+  { 0.097183557740181920, 0.0000000000000000, 65.000000000000000 },
+  { 0.0093096664589409992, 0.0000000000000000, 70.000000000000000 },
+  { -0.085369047647775656, 0.0000000000000000, 75.000000000000000 },
+  { -0.055620339089770016, 0.0000000000000000, 80.000000000000000 },
+  { 0.049567884951494251, 0.0000000000000000, 85.000000000000000 },
+  { 0.079776475854877751, 0.0000000000000000, 90.000000000000000 },
+  { -0.0028230995861232107, 0.0000000000000000, 95.000000000000000 },
+  { -0.077244313365083153, 0.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data001[i].nu), Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000006e-10));
+  }
+
+// Test data for nu=0.33333333333333331.
+testcase_cyl_neumann<double> data002[] = {
+  { -0.18192321129343850, 0.33333333333333331, 5.0000000000000000 },
+  { 0.17020111788268760, 0.33333333333333331, 10.000000000000000 },
+  { 0.18540507541540796, 0.33333333333333331, 15.000000000000000 },
+  { -0.028777707635715043, 0.33333333333333331, 20.000000000000000 },
+  { -0.15829741864944163, 0.33333333333333331, 25.000000000000000 },
+  { -0.058645772316705209, 0.33333333333333331, 30.000000000000000 },
+  { 0.10294930308870617, 0.33333333333333331, 35.000000000000000 },
+  { 0.10547870367098922, 0.33333333333333331, 40.000000000000000 },
+  { -0.034334228816010816, 0.33333333333333331, 45.000000000000000 },
+  { -0.11283489933031279, 0.33333333333333331, 50.000000000000000 },
+  { -0.030007358986895105, 0.33333333333333331, 55.000000000000000 },
+  { 0.086699173295718121, 0.33333333333333331, 60.000000000000000 },
+  { 0.074875579668878658, 0.33333333333333331, 65.000000000000000 },
+  { -0.039323246374552680, 0.33333333333333331, 70.000000000000000 },
+  { -0.091263539574475236, 0.33333333333333331, 75.000000000000000 },
+  { -0.013358849535984318, 0.33333333333333331, 80.000000000000000 },
+  { 0.078373575537830198, 0.33333333333333331, 85.000000000000000 },
+  { 0.055812482883955940, 0.33333333333333331, 90.000000000000000 },
+  { -0.043310380106990683, 0.33333333333333331, 95.000000000000000 },
+  { -0.076900504962136559, 0.33333333333333331, 100.00000000000000 },
+};
+
+// Test function for nu=0.33333333333333331.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data002[i].nu), Tp(data002[i].x));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for nu=0.50000000000000000.
+testcase_cyl_neumann<double> data003[] = {
+  { -0.10121770918510846, 0.50000000000000000, 5.0000000000000000 },
+  { 0.21170886633139810, 0.50000000000000000, 10.000000000000000 },
+  { 0.15650551590730855, 0.50000000000000000, 15.000000000000000 },
+  { -0.072806904785061938, 0.50000000000000000, 20.000000000000000 },
+  { -0.15817308404205055, 0.50000000000000000, 25.000000000000000 },
+  { -0.022470290598831138, 0.50000000000000000, 30.000000000000000 },
+  { 0.12187835265849535, 0.50000000000000000, 35.000000000000000 },
+  { 0.084138655676395377, 0.50000000000000000, 40.000000000000000 },
+  { -0.062482641933003201, 0.50000000000000000, 45.000000000000000 },
+  { -0.10888475635053954, 0.50000000000000000, 50.000000000000000 },
+  { -0.0023805454010949376, 0.50000000000000000, 55.000000000000000 },
+  { 0.098104683735037918, 0.50000000000000000, 60.000000000000000 },
+  { 0.055663470218594434, 0.50000000000000000, 65.000000000000000 },
+  { -0.060396767883824871, 0.50000000000000000, 70.000000000000000 },
+  { -0.084922578922046868, 0.50000000000000000, 75.000000000000000 },
+  { 0.0098472271924441284, 0.50000000000000000, 80.000000000000000 },
+  { 0.085190643574343625, 0.50000000000000000, 85.000000000000000 },
+  { 0.037684970437156268, 0.50000000000000000, 90.000000000000000 },
+  { -0.059772904856097500, 0.50000000000000000, 95.000000000000000 },
+  { -0.068803091468728109, 0.50000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data003[i].nu), Tp(data003[i].x));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000028e-11));
+  }
+
+// Test data for nu=0.66666666666666663.
+testcase_cyl_neumann<double> data004[] = {
+  { -0.016050662643389627, 0.66666666666666663, 5.0000000000000000 },
+  { 0.23937232657540733, 0.66666666666666663, 10.000000000000000 },
+  { 0.11762106604241235, 0.66666666666666663, 15.000000000000000 },
+  { -0.11182254014899558, 0.66666666666666663, 20.000000000000000 },
+  { -0.14756582982938804, 0.66666666666666663, 25.000000000000000 },
+  { 0.015078692908077713, 0.66666666666666663, 30.000000000000000 },
+  { 0.13260911815705795, 0.66666666666666663, 35.000000000000000 },
+  { 0.057217565989652698, 0.66666666666666663, 40.000000000000000 },
+  { -0.086373755152382006, 0.66666666666666663, 45.000000000000000 },
+  { -0.097624139208051616, 0.66666666666666663, 50.000000000000000 },
+  { 0.025354902147023392, 0.66666666666666663, 55.000000000000000 },
+  { 0.10288136476351206, 0.66666666666666663, 60.000000000000000 },
+  { 0.032728379560128203, 0.66666666666666663, 65.000000000000000 },
+  { -0.077363672735747818, 0.66666666666666663, 70.000000000000000 },
+  { -0.072855870458293961, 0.66666666666666663, 75.000000000000000 },
+  { 0.032358106046953543, 0.66666666666666663, 80.000000000000000 },
+  { 0.086240651537394228, 0.66666666666666663, 85.000000000000000 },
+  { 0.017029601697285190, 0.66666666666666663, 90.000000000000000 },
+  { -0.072173520560584681, 0.66666666666666663, 95.000000000000000 },
+  { -0.056057339204073887, 0.66666666666666663, 100.00000000000000 },
+};
+
+// Test function for nu=0.66666666666666663.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data004[i].nu), Tp(data004[i].x));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for nu=1.0000000000000000.
+testcase_cyl_neumann<double> data005[] = {
+  { 0.14786314339122700, 1.0000000000000000, 5.0000000000000000 },
+  { 0.24901542420695386, 1.0000000000000000, 10.000000000000000 },
+  { 0.021073628036873522, 1.0000000000000000, 15.000000000000000 },
+  { -0.16551161436252115, 1.0000000000000000, 20.000000000000000 },
+  { -0.098829964783237412, 1.0000000000000000, 25.000000000000000 },
+  { 0.084425570661747135, 1.0000000000000000, 30.000000000000000 },
+  { 0.12751273354559009, 1.0000000000000000, 35.000000000000000 },
+  { -0.0057935058215497536, 1.0000000000000000, 40.000000000000000 },
+  { -0.11552517964639945, 1.0000000000000000, 45.000000000000000 },
+  { -0.056795668562014692, 1.0000000000000000, 50.000000000000000 },
+  { 0.073846265432577926, 1.0000000000000000, 55.000000000000000 },
+  { 0.091869609369866892, 1.0000000000000000, 60.000000000000000 },
+  { -0.017940374275377362, 1.0000000000000000, 65.000000000000000 },
+  { -0.094844652625716230, 1.0000000000000000, 70.000000000000000 },
+  { -0.035213785160580421, 1.0000000000000000, 75.000000000000000 },
+  { 0.069395913784588037, 1.0000000000000000, 80.000000000000000 },
+  { 0.071233187582749768, 1.0000000000000000, 85.000000000000000 },
+  { -0.026187238607768244, 1.0000000000000000, 90.000000000000000 },
+  { -0.081827958724501215, 1.0000000000000000, 95.000000000000000 },
+  { -0.020372312002759834, 1.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=1.0000000000000000.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data005[i].nu), Tp(data005[i].x));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for nu=2.0000000000000000.
+testcase_cyl_neumann<double> data006[] = {
+  { 0.36766288260552438, 2.0000000000000000, 5.0000000000000000 },
+  { -0.0058680824422086830, 2.0000000000000000, 10.000000000000000 },
+  { -0.20265447896733507, 2.0000000000000000, 15.000000000000000 },
+  { -0.079191758245636165, 2.0000000000000000, 20.000000000000000 },
+  { 0.11934303508534717, 2.0000000000000000, 25.000000000000000 },
+  { 0.12292410306411394, 2.0000000000000000, 30.000000000000000 },
+  { -0.038511545278264829, 2.0000000000000000, 35.000000000000000 },
+  { -0.12622609234933840, 2.0000000000000000, 40.000000000000000 },
+  { -0.032194922192042195, 2.0000000000000000, 45.000000000000000 },
+  { 0.095793168727596537, 2.0000000000000000, 50.000000000000000 },
+  { 0.080254497473415426, 2.0000000000000000, 55.000000000000000 },
+  { -0.044296631897120527, 2.0000000000000000, 60.000000000000000 },
+  { -0.097735569256347382, 2.0000000000000000, 65.000000000000000 },
+  { -0.012019513676818605, 2.0000000000000000, 70.000000000000000 },
+  { 0.084430013376826846, 2.0000000000000000, 75.000000000000000 },
+  { 0.057355236934384719, 2.0000000000000000, 80.000000000000000 },
+  { -0.047891809949547198, 2.0000000000000000, 85.000000000000000 },
+  { -0.080358414490605934, 2.0000000000000000, 90.000000000000000 },
+  { 0.0011004057182389746, 2.0000000000000000, 95.000000000000000 },
+  { 0.076836867125027963, 2.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=2.0000000000000000.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data006[i].nu), Tp(data006[i].x));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000017e-10));
+  }
+
+// Test data for nu=5.0000000000000000.
+testcase_cyl_neumann<double> data007[] = {
+  { -0.45369482249110193, 5.0000000000000000, 5.0000000000000000 },
+  { 0.13540304768936234, 5.0000000000000000, 10.000000000000000 },
+  { 0.16717271575940015, 5.0000000000000000, 15.000000000000000 },
+  { -0.10003576788953220, 5.0000000000000000, 20.000000000000000 },
+  { -0.14705799311372267, 5.0000000000000000, 25.000000000000000 },
+  { 0.031627359289264301, 5.0000000000000000, 30.000000000000000 },
+  { 0.13554781474770028, 5.0000000000000000, 35.000000000000000 },
+  { 0.031869448780850247, 5.0000000000000000, 40.000000000000000 },
+  { -0.10426932700176872, 5.0000000000000000, 45.000000000000000 },
+  { -0.078548413913081594, 5.0000000000000000, 50.000000000000000 },
+  { 0.055257033062858375, 5.0000000000000000, 55.000000000000000 },
+  { 0.099464632840450887, 5.0000000000000000, 60.000000000000000 },
+  { 0.00023860469499595305, 5.0000000000000000, 65.000000000000000 },
+  { -0.091861802216406052, 5.0000000000000000, 70.000000000000000 },
+  { -0.048383671296970042, 5.0000000000000000, 75.000000000000000 },
+  { 0.060293667104896316, 5.0000000000000000, 80.000000000000000 },
+  { 0.077506166682733996, 5.0000000000000000, 85.000000000000000 },
+  { -0.015338764062239767, 5.0000000000000000, 90.000000000000000 },
+  { -0.081531504045514361, 5.0000000000000000, 95.000000000000000 },
+  { -0.029480196281661937, 5.0000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=5.0000000000000000.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data007[i].nu), Tp(data007[i].x));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000013e-09));
+  }
+
+// Test data for nu=10.000000000000000.
+testcase_cyl_neumann<double> data008[] = {
+  { -25.129110095610095, 10.000000000000000, 5.0000000000000000 },
+  { -0.35981415218340279, 10.000000000000000, 10.000000000000000 },
+  { 0.21997141360195577, 10.000000000000000, 15.000000000000000 },
+  { -0.043894653515658105, 10.000000000000000, 20.000000000000000 },
+  { -0.14871839049980651, 10.000000000000000, 25.000000000000000 },
+  { 0.075056702122397012, 10.000000000000000, 30.000000000000000 },
+  { 0.12222473135000546, 10.000000000000000, 35.000000000000000 },
+  { -0.046723877232677985, 10.000000000000000, 40.000000000000000 },
+  { -0.11739339009322181, 10.000000000000000, 45.000000000000000 },
+  { 0.0057238971820535930, 10.000000000000000, 50.000000000000000 },
+  { 0.10733910125831631, 10.000000000000000, 55.000000000000000 },
+  { 0.036290350559545478, 10.000000000000000, 60.000000000000000 },
+  { -0.083239127691715667, 10.000000000000000, 65.000000000000000 },
+  { -0.069639384138314858, 10.000000000000000, 70.000000000000000 },
+  { 0.045798335061325066, 10.000000000000000, 75.000000000000000 },
+  { 0.086269195064844456, 10.000000000000000, 80.000000000000000 },
+  { -0.0018234674126248740, 10.000000000000000, 85.000000000000000 },
+  { -0.082067762371231284, 10.000000000000000, 90.000000000000000 },
+  { -0.038798074754578089, 10.000000000000000, 95.000000000000000 },
+  { 0.058331574236414913, 10.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=10.000000000000000.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data008[i].nu), Tp(data008[i].x));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000017e-10));
+  }
+
+// Test data for nu=20.000000000000000.
+testcase_cyl_neumann<double> data009[] = {
+  { -593396529.69143200, 20.000000000000000, 5.0000000000000000 },
+  { -1597.4838482696259, 20.000000000000000, 10.000000000000000 },
+  { -3.3087330924737621, 20.000000000000000, 15.000000000000000 },
+  { -0.28548945860020319, 20.000000000000000, 20.000000000000000 },
+  { 0.19804074776289243, 20.000000000000000, 25.000000000000000 },
+  { -0.16848153948742683, 20.000000000000000, 30.000000000000000 },
+  { 0.10102784152594022, 20.000000000000000, 35.000000000000000 },
+  { 0.045161820565805755, 20.000000000000000, 40.000000000000000 },
+  { -0.12556489308015448, 20.000000000000000, 45.000000000000000 },
+  { 0.016442633948115834, 20.000000000000000, 50.000000000000000 },
+  { 0.10853448778255181, 20.000000000000000, 55.000000000000000 },
+  { -0.026721408520664701, 20.000000000000000, 60.000000000000000 },
+  { -0.098780425256324175, 20.000000000000000, 65.000000000000000 },
+  { 0.016201957786018233, 20.000000000000000, 70.000000000000000 },
+  { 0.093591198265063721, 20.000000000000000, 75.000000000000000 },
+  { 0.0040484400737296200, 20.000000000000000, 80.000000000000000 },
+  { -0.086314929459920531, 20.000000000000000, 85.000000000000000 },
+  { -0.028274110097231530, 20.000000000000000, 90.000000000000000 },
+  { 0.072349520791638741, 20.000000000000000, 95.000000000000000 },
+  { 0.051247973076188474, 20.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=20.000000000000000.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data009[i].nu), Tp(data009[i].x));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000006e-10));
+  }
+
+// Test data for nu=50.000000000000000.
+testcase_cyl_neumann<double> data010[] = {
+  { -2.7888370175838930e+42, 50.000000000000000, 5.0000000000000000 },
+  { -3.6410665018007421e+27, 50.000000000000000, 10.000000000000000 },
+  { -1.0929732912175415e+19, 50.000000000000000, 15.000000000000000 },
+  { -15606426801663.734, 50.000000000000000, 20.000000000000000 },
+  { -753573251.44662738, 50.000000000000000, 25.000000000000000 },
+  { -386759.32602734759, 50.000000000000000, 30.000000000000000 },
+  { -1172.8690492895323, 50.000000000000000, 35.000000000000000 },
+  { -15.615608873419944, 50.000000000000000, 40.000000000000000 },
+  { -0.87058346204176895, 50.000000000000000, 45.000000000000000 },
+  { -0.21031655464397747, 50.000000000000000, 50.000000000000000 },
+  { 0.093048240412999389, 50.000000000000000, 55.000000000000000 },
+  { 0.0086417699626744754, 50.000000000000000, 60.000000000000000 },
+  { -0.025019788459222037, 50.000000000000000, 65.000000000000000 },
+  { -0.0014815155191909152, 50.000000000000000, 70.000000000000000 },
+  { 0.050335774732164121, 50.000000000000000, 75.000000000000000 },
+  { -0.092924250967987232, 50.000000000000000, 80.000000000000000 },
+  { 0.087332463030205698, 50.000000000000000, 85.000000000000000 },
+  { -0.016164237701651860, 50.000000000000000, 90.000000000000000 },
+  { -0.068897613820457934, 50.000000000000000, 95.000000000000000 },
+  { 0.076505263944803045, 50.000000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=50.000000000000000.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data010[i].nu), Tp(data010[i].x));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000017e-10));
+  }
+
+// Test data for nu=100.00000000000000.
+testcase_cyl_neumann<double> data011[] = {
+  { -5.0848639160196196e+115, 100.00000000000000, 5.0000000000000000 },
+  { -4.8491482711800252e+85, 100.00000000000000, 10.000000000000000 },
+  { -1.6375955323195320e+68, 100.00000000000000, 15.000000000000000 },
+  { -8.2002648144679126e+55, 100.00000000000000, 20.000000000000000 },
+  { -2.9712216432562368e+46, 100.00000000000000, 25.000000000000000 },
+  { -7.2875284708240751e+38, 100.00000000000000, 30.000000000000000 },
+  { -3.4251079902108953e+32, 100.00000000000000, 35.000000000000000 },
+  { -1.4552439438101802e+27, 100.00000000000000, 40.000000000000000 },
+  { -3.4506612476220073e+22, 100.00000000000000, 45.000000000000000 },
+  { -3.2938001882025953e+18, 100.00000000000000, 50.000000000000000 },
+  { -1005686182055527.4, 100.00000000000000, 55.000000000000000 },
+  { -831892881402.11377, 100.00000000000000, 60.000000000000000 },
+  { -1650863778.0598330, 100.00000000000000, 65.000000000000000 },
+  { -7192614.1976097794, 100.00000000000000, 70.000000000000000 },
+  { -64639.072261231595, 100.00000000000000, 75.000000000000000 },
+  { -1152.5905185698466, 100.00000000000000, 80.000000000000000 },
+  { -40.250761402101560, 100.00000000000000, 85.000000000000000 },
+  { -2.8307771387185459, 100.00000000000000, 90.000000000000000 },
+  { -0.45762200495904848, 100.00000000000000, 95.000000000000000 },
+  { -0.16692141141757652, 100.00000000000000, 100.00000000000000 },
+};
+
+// Test function for nu=100.00000000000000.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_cyl_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::cyl_neumann(Tp(data011[i].nu), Tp(data011[i].x));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000006e-11));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  return 0;
+}
Index: testsuite/special_functions/10_cyl_neumann/compile.cc
===================================================================
--- testsuite/special_functions/10_cyl_neumann/compile.cc	(revision 0)
+++ testsuite/special_functions/10_cyl_neumann/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.10 cyl_neumann
+
+#include <cmath>
+
+void
+test01()
+{
+  float nuf = 1.0F / 3.0F, xf = 0.5F;
+  double nud = 1.0 / 3.0, xd = 0.5;
+  long double nul = 1.0L / 3.0L, xl = 0.5L;
+
+  std::cyl_neumann(nuf, xf);
+  std::cyl_neumannf(nuf, xf);
+  std::cyl_neumann(nud, xd);
+  std::cyl_neumann(nul, xl);
+  std::cyl_neumannl(nul, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/10_cyl_neumann/compile_2.cc
===================================================================
--- testsuite/special_functions/10_cyl_neumann/compile_2.cc	(revision 0)
+++ testsuite/special_functions/10_cyl_neumann/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.10 cyl_neumann
+
+#include <math.h>
+
+void
+test01()
+{
+  float nuf = 1.0F / 3.0F, xf = 0.5F;
+  double nud = 1.0 / 3.0, xd = 0.5;
+  long double nul = 1.0L / 3.0L, xl = 0.5L;
+
+  cyl_neumann(nuf, xf);
+  cyl_neumannf(nuf, xf);
+  cyl_neumann(nud, xd);
+  cyl_neumann(nul, xl);
+  cyl_neumannl(nul, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/11_ellint_1/check_nan.cc
===================================================================
--- testsuite/special_functions/11_ellint_1/check_nan.cc	(revision 0)
+++ testsuite/special_functions/11_ellint_1/check_nan.cc	(working copy)
@@ -0,0 +1,88 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.11 ellint_1
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float kf = std::numeric_limits<float>::quiet_NaN();
+  double kd = std::numeric_limits<double>::quiet_NaN();
+  long double kl = std::numeric_limits<long double>::quiet_NaN();
+
+  float phif = std::atan2(1.0F, 1.0F);
+  double phid = std::atan2(1.0, 1.0);
+  long double phil = std::atan2(1.0L, 1.0L);
+
+  float a = std::ellint_1(kf, phif);
+  float b = std::ellint_1f(kf, phif);
+  double c = std::ellint_1(kd, phid);
+  long double d = std::ellint_1(kl, phil);
+  long double e = std::ellint_1l(kl, phil);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+void
+test02()
+{
+  float kf = 0.5F;
+  double kd = 0.5;
+  long double kl = 0.5L;
+
+  float phif = std::numeric_limits<float>::quiet_NaN();
+  double phid = std::numeric_limits<double>::quiet_NaN();
+  long double phil = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::ellint_1(kf, phif);
+  float b = std::ellint_1f(kf, phif);
+  double c = std::ellint_1(kd, phid);
+  long double d = std::ellint_1(kl, phil);
+  long double e = std::ellint_1l(kl, phil);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  return 0;
+}
+
Index: testsuite/special_functions/11_ellint_1/check_value.cc
===================================================================
--- testsuite/special_functions/11_ellint_1/check_value.cc	(revision 0)
+++ testsuite/special_functions/11_ellint_1/check_value.cc	(working copy)
@@ -0,0 +1,880 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  ellint_1
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for k=-0.90000000000000002.
+testcase_ellint_1<double> data001[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.0000000000000000 },
+  { 0.17525427376115024, -0.90000000000000002, 0.17453292519943295 },
+  { 0.35492464591297446, -0.90000000000000002, 0.34906585039886590 },
+  { 0.54388221416157112, -0.90000000000000002, 0.52359877559829882 },
+  { 0.74797400423532490, -0.90000000000000002, 0.69813170079773179 },
+  { 0.97463898451966458, -0.90000000000000002, 0.87266462599716477 },
+  { 1.2334463254523440, -0.90000000000000002, 1.0471975511965976 },
+  { 1.5355247765594913, -0.90000000000000002, 1.2217304763960306 },
+  { 1.8882928567775121, -0.90000000000000002, 1.3962634015954636 },
+  { 2.2805491384227703, -0.90000000000000002, 1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data001[i].k), Tp(data001[i].phi));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004.
+testcase_ellint_1<double> data002[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.0000000000000000 },
+  { 0.17510154241338899, -0.80000000000000004, 0.17453292519943295 },
+  { 0.35365068839779390, -0.80000000000000004, 0.34906585039886590 },
+  { 0.53926804409084550, -0.80000000000000004, 0.52359877559829882 },
+  { 0.73587926028070361, -0.80000000000000004, 0.69813170079773179 },
+  { 0.94770942970071170, -0.80000000000000004, 0.87266462599716477 },
+  { 1.1789022995388236, -0.80000000000000004, 1.0471975511965976 },
+  { 1.4323027881876009, -0.80000000000000004, 1.2217304763960306 },
+  { 1.7069629739121674, -0.80000000000000004, 1.3962634015954636 },
+  { 1.9953027776647296, -0.80000000000000004, 1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data002[i].k), Tp(data002[i].phi));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996.
+testcase_ellint_1<double> data003[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.0000000000000000 },
+  { 0.17496737466916723, -0.69999999999999996, 0.17453292519943295 },
+  { 0.35254687535677925, -0.69999999999999996, 0.34906585039886590 },
+  { 0.53536740275997119, -0.69999999999999996, 0.52359877559829882 },
+  { 0.72603797651684454, -0.69999999999999996, 0.69813170079773179 },
+  { 0.92698296348313458, -0.69999999999999996, 0.87266462599716477 },
+  { 1.1400447527693316, -0.69999999999999996, 1.0471975511965976 },
+  { 1.3657668117194073, -0.69999999999999996, 1.2217304763960306 },
+  { 1.6024686895959159, -0.69999999999999996, 1.3962634015954636 },
+  { 1.8456939983747236, -0.69999999999999996, 1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data003[i].k), Tp(data003[i].phi));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998.
+testcase_ellint_1<double> data004[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.0000000000000000 },
+  { 0.17485154362988359, -0.59999999999999998, 0.17453292519943295 },
+  { 0.35160509865544326, -0.59999999999999998, 0.34906585039886590 },
+  { 0.53210652578446138, -0.59999999999999998, 0.52359877559829882 },
+  { 0.71805304664485659, -0.59999999999999998, 0.69813170079773179 },
+  { 0.91082759030195970, -0.59999999999999998, 0.87266462599716477 },
+  { 1.1112333229323361, -0.59999999999999998, 1.0471975511965976 },
+  { 1.3191461190365270, -0.59999999999999998, 1.2217304763960306 },
+  { 1.5332022105084773, -0.59999999999999998, 1.3962634015954636 },
+  { 1.7507538029157526, -0.59999999999999998, 1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data004[i].k), Tp(data004[i].phi));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000.
+testcase_ellint_1<double> data005[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.0000000000000000 },
+  { 0.17475385514035785, -0.50000000000000000, 0.17453292519943295 },
+  { 0.35081868470101585, -0.50000000000000000, 0.34906585039886590 },
+  { 0.52942862705190574, -0.50000000000000000, 0.52359877559829882 },
+  { 0.71164727562630314, -0.50000000000000000, 0.69813170079773179 },
+  { 0.89824523594227768, -0.50000000000000000, 0.87266462599716477 },
+  { 1.0895506700518851, -0.50000000000000000, 1.0471975511965976 },
+  { 1.2853005857432931, -0.50000000000000000, 1.2217304763960306 },
+  { 1.4845545520549484, -0.50000000000000000, 1.3962634015954636 },
+  { 1.6857503548125963, -0.50000000000000000, 1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data005[i].k), Tp(data005[i].phi));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002.
+testcase_ellint_1<double> data006[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.0000000000000000 },
+  { 0.17467414669441528, -0.40000000000000002, 0.17453292519943295 },
+  { 0.35018222772483443, -0.40000000000000002, 0.34906585039886590 },
+  { 0.52729015917508737, -0.40000000000000002, 0.52359877559829882 },
+  { 0.70662374407341244, -0.40000000000000002, 0.69813170079773179 },
+  { 0.88859210497602170, -0.40000000000000002, 0.87266462599716477 },
+  { 1.0733136290471379, -0.40000000000000002, 1.0471975511965976 },
+  { 1.2605612170157061, -0.40000000000000002, 1.2217304763960306 },
+  { 1.4497513956433439, -0.40000000000000002, 1.3962634015954636 },
+  { 1.6399998658645112, -0.40000000000000002, 1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data006[i].k), Tp(data006[i].phi));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004.
+testcase_ellint_1<double> data007[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.0000000000000000 },
+  { 0.17461228653000099, -0.30000000000000004, 0.17453292519943295 },
+  { 0.34969146102798415, -0.30000000000000004, 0.34906585039886590 },
+  { 0.52565822873726320, -0.30000000000000004, 0.52359877559829882 },
+  { 0.70284226512408532, -0.30000000000000004, 0.69813170079773179 },
+  { 0.88144139195111182, -0.30000000000000004, 0.87266462599716477 },
+  { 1.0614897067260520, -0.30000000000000004, 1.0471975511965976 },
+  { 1.2428416824174218, -0.30000000000000004, 1.2217304763960306 },
+  { 1.4251795877015927, -0.30000000000000004, 1.3962634015954636 },
+  { 1.6080486199305128, -0.30000000000000004, 1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data007[i].k), Tp(data007[i].phi));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996.
+testcase_ellint_1<double> data008[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.0000000000000000 },
+  { 0.17456817290292809, -0.19999999999999996, 0.17453292519943295 },
+  { 0.34934315932086801, -0.19999999999999996, 0.34906585039886590 },
+  { 0.52450880529443988, -0.19999999999999996, 0.52359877559829882 },
+  { 0.70020491009844876, -0.19999999999999996, 0.69813170079773179 },
+  { 0.87651006649967955, -0.19999999999999996, 0.87266462599716477 },
+  { 1.0534305870298994, -0.19999999999999996, 1.0471975511965976 },
+  { 1.2308975521670784, -0.19999999999999996, 1.2217304763960306 },
+  { 1.4087733584990738, -0.19999999999999996, 1.3962634015954636 },
+  { 1.5868678474541660, -0.19999999999999996, 1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data008[i].k), Tp(data008[i].phi));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978.
+testcase_ellint_1<double> data009[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.0000000000000000 },
+  { 0.17454173353063659, -0.099999999999999978, 0.17453292519943295 },
+  { 0.34913506721468091, -0.099999999999999978, 0.34906585039886590 },
+  { 0.52382550016538942, -0.099999999999999978, 0.52359877559829882 },
+  { 0.69864700854177020, -0.099999999999999978, 0.69813170079773179 },
+  { 0.87361792586964870, -0.099999999999999978, 0.87266462599716477 },
+  { 1.0487386319621683, -0.099999999999999978, 1.0471975511965976 },
+  { 1.2239913752078757, -0.099999999999999978, 1.2217304763960306 },
+  { 1.3993423113684049, -0.099999999999999978, 1.3962634015954636 },
+  { 1.5747455615173562, -0.099999999999999978, 1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data009[i].k), Tp(data009[i].phi));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000.
+testcase_ellint_1<double> data010[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.0000000000000000 },
+  { 0.17453292519943292, 0.0000000000000000, 0.17453292519943295 },
+  { 0.34906585039886584, 0.0000000000000000, 0.34906585039886590 },
+  { 0.52359877559829870, 0.0000000000000000, 0.52359877559829882 },
+  { 0.69813170079773168, 0.0000000000000000, 0.69813170079773179 },
+  { 0.87266462599716477, 0.0000000000000000, 0.87266462599716477 },
+  { 1.0471975511965974, 0.0000000000000000, 1.0471975511965976 },
+  { 1.2217304763960304, 0.0000000000000000, 1.2217304763960306 },
+  { 1.3962634015954631, 0.0000000000000000, 1.3962634015954636 },
+  { 1.5707963267948966, 0.0000000000000000, 1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data010[i].k), Tp(data010[i].phi));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009.
+testcase_ellint_1<double> data011[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.0000000000000000 },
+  { 0.17454173353063659, 0.10000000000000009, 0.17453292519943295 },
+  { 0.34913506721468091, 0.10000000000000009, 0.34906585039886590 },
+  { 0.52382550016538942, 0.10000000000000009, 0.52359877559829882 },
+  { 0.69864700854177020, 0.10000000000000009, 0.69813170079773179 },
+  { 0.87361792586964870, 0.10000000000000009, 0.87266462599716477 },
+  { 1.0487386319621683, 0.10000000000000009, 1.0471975511965976 },
+  { 1.2239913752078757, 0.10000000000000009, 1.2217304763960306 },
+  { 1.3993423113684049, 0.10000000000000009, 1.3962634015954636 },
+  { 1.5747455615173562, 0.10000000000000009, 1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data011[i].k), Tp(data011[i].phi));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996.
+testcase_ellint_1<double> data012[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.0000000000000000 },
+  { 0.17456817290292809, 0.19999999999999996, 0.17453292519943295 },
+  { 0.34934315932086801, 0.19999999999999996, 0.34906585039886590 },
+  { 0.52450880529443988, 0.19999999999999996, 0.52359877559829882 },
+  { 0.70020491009844876, 0.19999999999999996, 0.69813170079773179 },
+  { 0.87651006649967955, 0.19999999999999996, 0.87266462599716477 },
+  { 1.0534305870298994, 0.19999999999999996, 1.0471975511965976 },
+  { 1.2308975521670784, 0.19999999999999996, 1.2217304763960306 },
+  { 1.4087733584990738, 0.19999999999999996, 1.3962634015954636 },
+  { 1.5868678474541660, 0.19999999999999996, 1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996.
+template<typename Tp>
+  void
+  test012()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data012)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data012[i].k), Tp(data012[i].phi));
+	const Tp f0 = data012[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004.
+testcase_ellint_1<double> data013[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.0000000000000000 },
+  { 0.17461228653000099, 0.30000000000000004, 0.17453292519943295 },
+  { 0.34969146102798415, 0.30000000000000004, 0.34906585039886590 },
+  { 0.52565822873726320, 0.30000000000000004, 0.52359877559829882 },
+  { 0.70284226512408532, 0.30000000000000004, 0.69813170079773179 },
+  { 0.88144139195111182, 0.30000000000000004, 0.87266462599716477 },
+  { 1.0614897067260520, 0.30000000000000004, 1.0471975511965976 },
+  { 1.2428416824174218, 0.30000000000000004, 1.2217304763960306 },
+  { 1.4251795877015927, 0.30000000000000004, 1.3962634015954636 },
+  { 1.6080486199305128, 0.30000000000000004, 1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004.
+template<typename Tp>
+  void
+  test013()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data013)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data013[i].k), Tp(data013[i].phi));
+	const Tp f0 = data013[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991.
+testcase_ellint_1<double> data014[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.0000000000000000 },
+  { 0.17467414669441528, 0.39999999999999991, 0.17453292519943295 },
+  { 0.35018222772483443, 0.39999999999999991, 0.34906585039886590 },
+  { 0.52729015917508737, 0.39999999999999991, 0.52359877559829882 },
+  { 0.70662374407341244, 0.39999999999999991, 0.69813170079773179 },
+  { 0.88859210497602170, 0.39999999999999991, 0.87266462599716477 },
+  { 1.0733136290471379, 0.39999999999999991, 1.0471975511965976 },
+  { 1.2605612170157061, 0.39999999999999991, 1.2217304763960306 },
+  { 1.4497513956433439, 0.39999999999999991, 1.3962634015954636 },
+  { 1.6399998658645112, 0.39999999999999991, 1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991.
+template<typename Tp>
+  void
+  test014()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data014)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data014[i].k), Tp(data014[i].phi));
+	const Tp f0 = data014[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000.
+testcase_ellint_1<double> data015[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.0000000000000000 },
+  { 0.17475385514035785, 0.50000000000000000, 0.17453292519943295 },
+  { 0.35081868470101585, 0.50000000000000000, 0.34906585039886590 },
+  { 0.52942862705190574, 0.50000000000000000, 0.52359877559829882 },
+  { 0.71164727562630314, 0.50000000000000000, 0.69813170079773179 },
+  { 0.89824523594227768, 0.50000000000000000, 0.87266462599716477 },
+  { 1.0895506700518851, 0.50000000000000000, 1.0471975511965976 },
+  { 1.2853005857432931, 0.50000000000000000, 1.2217304763960306 },
+  { 1.4845545520549484, 0.50000000000000000, 1.3962634015954636 },
+  { 1.6857503548125963, 0.50000000000000000, 1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000.
+template<typename Tp>
+  void
+  test015()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data015)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data015[i].k), Tp(data015[i].phi));
+	const Tp f0 = data015[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009.
+testcase_ellint_1<double> data016[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.0000000000000000 },
+  { 0.17485154362988359, 0.60000000000000009, 0.17453292519943295 },
+  { 0.35160509865544326, 0.60000000000000009, 0.34906585039886590 },
+  { 0.53210652578446138, 0.60000000000000009, 0.52359877559829882 },
+  { 0.71805304664485659, 0.60000000000000009, 0.69813170079773179 },
+  { 0.91082759030195970, 0.60000000000000009, 0.87266462599716477 },
+  { 1.1112333229323361, 0.60000000000000009, 1.0471975511965976 },
+  { 1.3191461190365270, 0.60000000000000009, 1.2217304763960306 },
+  { 1.5332022105084775, 0.60000000000000009, 1.3962634015954636 },
+  { 1.7507538029157526, 0.60000000000000009, 1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009.
+template<typename Tp>
+  void
+  test016()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data016)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data016[i].k), Tp(data016[i].phi));
+	const Tp f0 = data016[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996.
+testcase_ellint_1<double> data017[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.0000000000000000 },
+  { 0.17496737466916723, 0.69999999999999996, 0.17453292519943295 },
+  { 0.35254687535677925, 0.69999999999999996, 0.34906585039886590 },
+  { 0.53536740275997119, 0.69999999999999996, 0.52359877559829882 },
+  { 0.72603797651684454, 0.69999999999999996, 0.69813170079773179 },
+  { 0.92698296348313458, 0.69999999999999996, 0.87266462599716477 },
+  { 1.1400447527693316, 0.69999999999999996, 1.0471975511965976 },
+  { 1.3657668117194073, 0.69999999999999996, 1.2217304763960306 },
+  { 1.6024686895959159, 0.69999999999999996, 1.3962634015954636 },
+  { 1.8456939983747236, 0.69999999999999996, 1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996.
+template<typename Tp>
+  void
+  test017()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data017)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data017[i].k), Tp(data017[i].phi));
+	const Tp f0 = data017[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004.
+testcase_ellint_1<double> data018[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.0000000000000000 },
+  { 0.17510154241338899, 0.80000000000000004, 0.17453292519943295 },
+  { 0.35365068839779390, 0.80000000000000004, 0.34906585039886590 },
+  { 0.53926804409084550, 0.80000000000000004, 0.52359877559829882 },
+  { 0.73587926028070361, 0.80000000000000004, 0.69813170079773179 },
+  { 0.94770942970071170, 0.80000000000000004, 0.87266462599716477 },
+  { 1.1789022995388236, 0.80000000000000004, 1.0471975511965976 },
+  { 1.4323027881876009, 0.80000000000000004, 1.2217304763960306 },
+  { 1.7069629739121674, 0.80000000000000004, 1.3962634015954636 },
+  { 1.9953027776647296, 0.80000000000000004, 1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004.
+template<typename Tp>
+  void
+  test018()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data018)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data018[i].k), Tp(data018[i].phi));
+	const Tp f0 = data018[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991.
+testcase_ellint_1<double> data019[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.0000000000000000 },
+  { 0.17525427376115024, 0.89999999999999991, 0.17453292519943295 },
+  { 0.35492464591297446, 0.89999999999999991, 0.34906585039886590 },
+  { 0.54388221416157112, 0.89999999999999991, 0.52359877559829882 },
+  { 0.74797400423532490, 0.89999999999999991, 0.69813170079773179 },
+  { 0.97463898451966458, 0.89999999999999991, 0.87266462599716477 },
+  { 1.2334463254523440, 0.89999999999999991, 1.0471975511965976 },
+  { 1.5355247765594910, 0.89999999999999991, 1.2217304763960306 },
+  { 1.8882928567775117, 0.89999999999999991, 1.3962634015954636 },
+  { 2.2805491384227703, 0.89999999999999991, 1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991.
+template<typename Tp>
+  void
+  test019()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data019)
+			   / sizeof(testcase_ellint_1<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_1(Tp(data019[i].k), Tp(data019[i].phi));
+	const Tp f0 = data019[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  test012<double>();
+  test013<double>();
+  test014<double>();
+  test015<double>();
+  test016<double>();
+  test017<double>();
+  test018<double>();
+  test019<double>();
+  return 0;
+}
Index: testsuite/special_functions/11_ellint_1/compile.cc
===================================================================
--- testsuite/special_functions/11_ellint_1/compile.cc	(revision 0)
+++ testsuite/special_functions/11_ellint_1/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.11 ellint_1
+
+#include <cmath>
+
+void
+test01()
+{
+  float kf = 0.5F, phif = std::atan2(1.0F, 1.0F);
+  double kd = 0.5, phid = std::atan2(1.0, 1.0);
+  long double kl = 0.5L, phil = std::atan2(1.0L, 1.0L);
+
+  std::ellint_1(kf, phif);
+  std::ellint_1f(kf, phif);
+  std::ellint_1(kd, phid);
+  std::ellint_1(kl, phil);
+  std::ellint_1l(kl, phil);
+
+  return;
+}
+
Index: testsuite/special_functions/11_ellint_1/compile_2.cc
===================================================================
--- testsuite/special_functions/11_ellint_1/compile_2.cc	(revision 0)
+++ testsuite/special_functions/11_ellint_1/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.11 ellint_1
+
+#include <math.h>
+
+void
+test01()
+{
+  float kf = 0.5F, phif = atan2(1.0F, 1.0F);
+  double kd = 0.5, phid = atan2(1.0, 1.0);
+  long double kl = 0.5L, phil = atan2(1.0L, 1.0L);
+
+  ellint_1(kf, phif);
+  ellint_1f(kf, phif);
+  ellint_1(kd, phid);
+  ellint_1(kl, phil);
+  ellint_1l(kl, phil);
+
+  return;
+}
+
Index: testsuite/special_functions/12_ellint_2/check_nan.cc
===================================================================
--- testsuite/special_functions/12_ellint_2/check_nan.cc	(revision 0)
+++ testsuite/special_functions/12_ellint_2/check_nan.cc	(working copy)
@@ -0,0 +1,88 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.12 ellint_2
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float kf = std::numeric_limits<float>::quiet_NaN();
+  double kd = std::numeric_limits<double>::quiet_NaN();
+  long double kl = std::numeric_limits<long double>::quiet_NaN();
+
+  float phif = std::atan2(1.0F, 1.0F);
+  double phid = std::atan2(1.0, 1.0);
+  long double phil = std::atan2(1.0L, 1.0L);
+
+  float a = std::ellint_2(kf, phif);
+  float b = std::ellint_2f(kf, phif);
+  double c = std::ellint_2(kd, phid);
+  long double d = std::ellint_2(kl, phil);
+  long double e = std::ellint_2l(kl, phil);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+void
+test02()
+{
+  float kf = 0.5F;
+  double kd = 0.5;
+  long double kl = 0.5L;
+
+  float phif = std::numeric_limits<float>::quiet_NaN();
+  double phid = std::numeric_limits<double>::quiet_NaN();
+  long double phil = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::ellint_2(kf, phif);
+  float b = std::ellint_2f(kf, phif);
+  double c = std::ellint_2(kd, phid);
+  long double d = std::ellint_2(kl, phil);
+  long double e = std::ellint_2l(kl, phil);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  return 0;
+}
+
Index: testsuite/special_functions/12_ellint_2/check_value.cc
===================================================================
--- testsuite/special_functions/12_ellint_2/check_value.cc	(revision 0)
+++ testsuite/special_functions/12_ellint_2/check_value.cc	(working copy)
@@ -0,0 +1,880 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  ellint_2
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for k=-0.90000000000000002.
+testcase_ellint_2<double> data001[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.0000000000000000 },
+  { 0.17381690606167960, -0.90000000000000002, 0.17453292519943295 },
+  { 0.34337919186972055, -0.90000000000000002, 0.34906585039886590 },
+  { 0.50464268659856326, -0.90000000000000002, 0.52359877559829882 },
+  { 0.65400003842368570, -0.90000000000000002, 0.69813170079773179 },
+  { 0.78854928419904646, -0.90000000000000002, 0.87266462599716477 },
+  { 0.90645698626315396, -0.90000000000000002, 1.0471975511965976 },
+  { 1.0075154899135925, -0.90000000000000002, 1.2217304763960306 },
+  { 1.0940135583194068, -0.90000000000000002, 1.3962634015954636 },
+  { 1.1716970527816140, -0.90000000000000002, 1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data001[i].k), Tp(data001[i].phi));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004.
+testcase_ellint_2<double> data002[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.0000000000000000 },
+  { 0.17396762274534805, -0.80000000000000004, 0.17453292519943295 },
+  { 0.34458685226969316, -0.80000000000000004, 0.34906585039886590 },
+  { 0.50872923654502433, -0.80000000000000004, 0.52359877559829882 },
+  { 0.66372016539176215, -0.80000000000000004, 0.69813170079773179 },
+  { 0.80760344410167406, -0.80000000000000004, 0.87266462599716477 },
+  { 0.93945480372495049, -0.80000000000000004, 1.0471975511965976 },
+  { 1.0597473310395036, -0.80000000000000004, 1.2217304763960306 },
+  { 1.1706981862452361, -0.80000000000000004, 1.3962634015954636 },
+  { 1.2763499431699064, -0.80000000000000004, 1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data002[i].k), Tp(data002[i].phi));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996.
+testcase_ellint_2<double> data003[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.0000000000000000 },
+  { 0.17410041242702542, -0.69999999999999996, 0.17453292519943295 },
+  { 0.34564605085764760, -0.69999999999999996, 0.34906585039886590 },
+  { 0.51228495693314646, -0.69999999999999996, 0.52359877559829882 },
+  { 0.67207654098799530, -0.69999999999999996, 0.69813170079773179 },
+  { 0.82370932631556515, -0.69999999999999996, 0.87266462599716477 },
+  { 0.96672313309452795, -0.69999999999999996, 1.0471975511965976 },
+  { 1.1017090644949503, -0.69999999999999996, 1.2217304763960306 },
+  { 1.2304180097292914, -0.69999999999999996, 1.3962634015954636 },
+  { 1.3556611355719554, -0.69999999999999996, 1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data003[i].k), Tp(data003[i].phi));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998.
+testcase_ellint_2<double> data004[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.0000000000000000 },
+  { 0.17421534919599127, -0.59999999999999998, 0.17453292519943295 },
+  { 0.34655927787174101, -0.59999999999999998, 0.34906585039886590 },
+  { 0.51533034538432143, -0.59999999999999998, 0.52359877559829882 },
+  { 0.67916550597453018, -0.59999999999999998, 0.69813170079773179 },
+  { 0.83720218180349870, -0.59999999999999998, 0.87266462599716477 },
+  { 0.98922159354937755, -0.59999999999999998, 1.0471975511965976 },
+  { 1.1357478470419360, -0.59999999999999998, 1.2217304763960306 },
+  { 1.2780617372844056, -0.59999999999999998, 1.3962634015954636 },
+  { 1.4180833944487241, -0.59999999999999998, 1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data004[i].k), Tp(data004[i].phi));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000.
+testcase_ellint_2<double> data005[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.0000000000000000 },
+  { 0.17431249677315910, -0.50000000000000000, 0.17453292519943295 },
+  { 0.34732862537770803, -0.50000000000000000, 0.34906585039886590 },
+  { 0.51788193485993794, -0.50000000000000000, 0.52359877559829882 },
+  { 0.68506022954164536, -0.50000000000000000, 0.69813170079773179 },
+  { 0.84831662803347196, -0.50000000000000000, 0.87266462599716477 },
+  { 1.0075555551444717, -0.50000000000000000, 1.0471975511965976 },
+  { 1.1631768599287300, -0.50000000000000000, 1.2217304763960306 },
+  { 1.3160584048772543, -0.50000000000000000, 1.3962634015954636 },
+  { 1.4674622093394274, -0.50000000000000000, 1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data005[i].k), Tp(data005[i].phi));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002.
+testcase_ellint_2<double> data006[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.0000000000000000 },
+  { 0.17439190872481267, -0.40000000000000002, 0.17453292519943295 },
+  { 0.34795581767099210, -0.40000000000000002, 0.34906585039886590 },
+  { 0.51995290683804463, -0.40000000000000002, 0.52359877559829882 },
+  { 0.68981638464431538, -0.40000000000000002, 0.69813170079773179 },
+  { 0.85722088859936041, -0.40000000000000002, 0.87266462599716477 },
+  { 1.0221301327876993, -0.40000000000000002, 1.0471975511965976 },
+  { 1.1848138019818371, -0.40000000000000002, 1.2217304763960306 },
+  { 1.3458259266501533, -0.40000000000000002, 1.3962634015954636 },
+  { 1.5059416123600402, -0.40000000000000002, 1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data006[i].k), Tp(data006[i].phi));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004.
+testcase_ellint_2<double> data007[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.0000000000000000 },
+  { 0.17445362864048913, -0.30000000000000004, 0.17453292519943295 },
+  { 0.34844223535713464, -0.30000000000000004, 0.34906585039886590 },
+  { 0.52155353877411770, -0.30000000000000004, 0.52359877559829882 },
+  { 0.69347584418369879, -0.30000000000000004, 0.69813170079773179 },
+  { 0.86403609928237668, -0.30000000000000004, 0.87266462599716477 },
+  { 1.0332234514065408, -0.30000000000000004, 1.0471975511965976 },
+  { 1.2011943182068923, -0.30000000000000004, 1.2217304763960306 },
+  { 1.3682566113689623, -0.30000000000000004, 1.3962634015954636 },
+  { 1.5348334649232491, -0.30000000000000004, 1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data007[i].k), Tp(data007[i].phi));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996.
+testcase_ellint_2<double> data008[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.0000000000000000 },
+  { 0.17449769027652812, -0.19999999999999996, 0.17453292519943295 },
+  { 0.34878893400762095, -0.19999999999999996, 0.34906585039886590 },
+  { 0.52269152856057410, -0.19999999999999996, 0.52359877559829882 },
+  { 0.69606913360157563, -0.19999999999999996, 0.69813170079773179 },
+  { 0.86884782374863356, -0.19999999999999996, 0.87266462599716477 },
+  { 1.0410255369689567, -0.19999999999999996, 1.0471975511965976 },
+  { 1.2126730391631360, -0.19999999999999996, 1.2217304763960306 },
+  { 1.3839259540325153, -0.19999999999999996, 1.3962634015954636 },
+  { 1.5549685462425291, -0.19999999999999996, 1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data008[i].k), Tp(data008[i].phi));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978.
+testcase_ellint_2<double> data009[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.0000000000000000 },
+  { 0.17452411766649939, -0.099999999999999978, 0.17453292519943295 },
+  { 0.34899665805442404, -0.099999999999999978, 0.34906585039886590 },
+  { 0.52337222400508776, -0.099999999999999978, 0.52359877559829882 },
+  { 0.69761705217284864, -0.099999999999999978, 0.69813170079773179 },
+  { 0.87171309273007491, -0.099999999999999978, 0.87266462599716477 },
+  { 1.0456602197056326, -0.099999999999999978, 1.0471975511965976 },
+  { 1.2194762899272025, -0.099999999999999978, 1.2217304763960306 },
+  { 1.3931950229892744, -0.099999999999999978, 1.3962634015954636 },
+  { 1.5668619420216685, -0.099999999999999978, 1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data009[i].k), Tp(data009[i].phi));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000.
+testcase_ellint_2<double> data010[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.0000000000000000 },
+  { 0.17453292519943292, 0.0000000000000000, 0.17453292519943295 },
+  { 0.34906585039886584, 0.0000000000000000, 0.34906585039886590 },
+  { 0.52359877559829870, 0.0000000000000000, 0.52359877559829882 },
+  { 0.69813170079773168, 0.0000000000000000, 0.69813170079773179 },
+  { 0.87266462599716477, 0.0000000000000000, 0.87266462599716477 },
+  { 1.0471975511965974, 0.0000000000000000, 1.0471975511965976 },
+  { 1.2217304763960304, 0.0000000000000000, 1.2217304763960306 },
+  { 1.3962634015954631, 0.0000000000000000, 1.3962634015954636 },
+  { 1.5707963267948966, 0.0000000000000000, 1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data010[i].k), Tp(data010[i].phi));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009.
+testcase_ellint_2<double> data011[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.0000000000000000 },
+  { 0.17452411766649939, 0.10000000000000009, 0.17453292519943295 },
+  { 0.34899665805442404, 0.10000000000000009, 0.34906585039886590 },
+  { 0.52337222400508776, 0.10000000000000009, 0.52359877559829882 },
+  { 0.69761705217284864, 0.10000000000000009, 0.69813170079773179 },
+  { 0.87171309273007491, 0.10000000000000009, 0.87266462599716477 },
+  { 1.0456602197056326, 0.10000000000000009, 1.0471975511965976 },
+  { 1.2194762899272025, 0.10000000000000009, 1.2217304763960306 },
+  { 1.3931950229892744, 0.10000000000000009, 1.3962634015954636 },
+  { 1.5668619420216685, 0.10000000000000009, 1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data011[i].k), Tp(data011[i].phi));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996.
+testcase_ellint_2<double> data012[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.0000000000000000 },
+  { 0.17449769027652812, 0.19999999999999996, 0.17453292519943295 },
+  { 0.34878893400762095, 0.19999999999999996, 0.34906585039886590 },
+  { 0.52269152856057410, 0.19999999999999996, 0.52359877559829882 },
+  { 0.69606913360157563, 0.19999999999999996, 0.69813170079773179 },
+  { 0.86884782374863356, 0.19999999999999996, 0.87266462599716477 },
+  { 1.0410255369689567, 0.19999999999999996, 1.0471975511965976 },
+  { 1.2126730391631360, 0.19999999999999996, 1.2217304763960306 },
+  { 1.3839259540325153, 0.19999999999999996, 1.3962634015954636 },
+  { 1.5549685462425291, 0.19999999999999996, 1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996.
+template<typename Tp>
+  void
+  test012()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data012)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data012[i].k), Tp(data012[i].phi));
+	const Tp f0 = data012[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004.
+testcase_ellint_2<double> data013[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.0000000000000000 },
+  { 0.17445362864048913, 0.30000000000000004, 0.17453292519943295 },
+  { 0.34844223535713464, 0.30000000000000004, 0.34906585039886590 },
+  { 0.52155353877411770, 0.30000000000000004, 0.52359877559829882 },
+  { 0.69347584418369879, 0.30000000000000004, 0.69813170079773179 },
+  { 0.86403609928237668, 0.30000000000000004, 0.87266462599716477 },
+  { 1.0332234514065408, 0.30000000000000004, 1.0471975511965976 },
+  { 1.2011943182068923, 0.30000000000000004, 1.2217304763960306 },
+  { 1.3682566113689623, 0.30000000000000004, 1.3962634015954636 },
+  { 1.5348334649232491, 0.30000000000000004, 1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004.
+template<typename Tp>
+  void
+  test013()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data013)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data013[i].k), Tp(data013[i].phi));
+	const Tp f0 = data013[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991.
+testcase_ellint_2<double> data014[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.0000000000000000 },
+  { 0.17439190872481267, 0.39999999999999991, 0.17453292519943295 },
+  { 0.34795581767099210, 0.39999999999999991, 0.34906585039886590 },
+  { 0.51995290683804463, 0.39999999999999991, 0.52359877559829882 },
+  { 0.68981638464431538, 0.39999999999999991, 0.69813170079773179 },
+  { 0.85722088859936041, 0.39999999999999991, 0.87266462599716477 },
+  { 1.0221301327876993, 0.39999999999999991, 1.0471975511965976 },
+  { 1.1848138019818373, 0.39999999999999991, 1.2217304763960306 },
+  { 1.3458259266501533, 0.39999999999999991, 1.3962634015954636 },
+  { 1.5059416123600404, 0.39999999999999991, 1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991.
+template<typename Tp>
+  void
+  test014()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data014)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data014[i].k), Tp(data014[i].phi));
+	const Tp f0 = data014[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000.
+testcase_ellint_2<double> data015[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.0000000000000000 },
+  { 0.17431249677315910, 0.50000000000000000, 0.17453292519943295 },
+  { 0.34732862537770803, 0.50000000000000000, 0.34906585039886590 },
+  { 0.51788193485993794, 0.50000000000000000, 0.52359877559829882 },
+  { 0.68506022954164536, 0.50000000000000000, 0.69813170079773179 },
+  { 0.84831662803347196, 0.50000000000000000, 0.87266462599716477 },
+  { 1.0075555551444717, 0.50000000000000000, 1.0471975511965976 },
+  { 1.1631768599287300, 0.50000000000000000, 1.2217304763960306 },
+  { 1.3160584048772543, 0.50000000000000000, 1.3962634015954636 },
+  { 1.4674622093394274, 0.50000000000000000, 1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000.
+template<typename Tp>
+  void
+  test015()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data015)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data015[i].k), Tp(data015[i].phi));
+	const Tp f0 = data015[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009.
+testcase_ellint_2<double> data016[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.0000000000000000 },
+  { 0.17421534919599127, 0.60000000000000009, 0.17453292519943295 },
+  { 0.34655927787174101, 0.60000000000000009, 0.34906585039886590 },
+  { 0.51533034538432143, 0.60000000000000009, 0.52359877559829882 },
+  { 0.67916550597453018, 0.60000000000000009, 0.69813170079773179 },
+  { 0.83720218180349870, 0.60000000000000009, 0.87266462599716477 },
+  { 0.98922159354937744, 0.60000000000000009, 1.0471975511965976 },
+  { 1.1357478470419360, 0.60000000000000009, 1.2217304763960306 },
+  { 1.2780617372844056, 0.60000000000000009, 1.3962634015954636 },
+  { 1.4180833944487241, 0.60000000000000009, 1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009.
+template<typename Tp>
+  void
+  test016()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data016)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data016[i].k), Tp(data016[i].phi));
+	const Tp f0 = data016[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996.
+testcase_ellint_2<double> data017[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.0000000000000000 },
+  { 0.17410041242702542, 0.69999999999999996, 0.17453292519943295 },
+  { 0.34564605085764760, 0.69999999999999996, 0.34906585039886590 },
+  { 0.51228495693314646, 0.69999999999999996, 0.52359877559829882 },
+  { 0.67207654098799530, 0.69999999999999996, 0.69813170079773179 },
+  { 0.82370932631556515, 0.69999999999999996, 0.87266462599716477 },
+  { 0.96672313309452795, 0.69999999999999996, 1.0471975511965976 },
+  { 1.1017090644949503, 0.69999999999999996, 1.2217304763960306 },
+  { 1.2304180097292914, 0.69999999999999996, 1.3962634015954636 },
+  { 1.3556611355719554, 0.69999999999999996, 1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996.
+template<typename Tp>
+  void
+  test017()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data017)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data017[i].k), Tp(data017[i].phi));
+	const Tp f0 = data017[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004.
+testcase_ellint_2<double> data018[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.0000000000000000 },
+  { 0.17396762274534805, 0.80000000000000004, 0.17453292519943295 },
+  { 0.34458685226969316, 0.80000000000000004, 0.34906585039886590 },
+  { 0.50872923654502433, 0.80000000000000004, 0.52359877559829882 },
+  { 0.66372016539176215, 0.80000000000000004, 0.69813170079773179 },
+  { 0.80760344410167406, 0.80000000000000004, 0.87266462599716477 },
+  { 0.93945480372495049, 0.80000000000000004, 1.0471975511965976 },
+  { 1.0597473310395036, 0.80000000000000004, 1.2217304763960306 },
+  { 1.1706981862452361, 0.80000000000000004, 1.3962634015954636 },
+  { 1.2763499431699064, 0.80000000000000004, 1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004.
+template<typename Tp>
+  void
+  test018()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data018)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data018[i].k), Tp(data018[i].phi));
+	const Tp f0 = data018[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991.
+testcase_ellint_2<double> data019[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.0000000000000000 },
+  { 0.17381690606167960, 0.89999999999999991, 0.17453292519943295 },
+  { 0.34337919186972055, 0.89999999999999991, 0.34906585039886590 },
+  { 0.50464268659856326, 0.89999999999999991, 0.52359877559829882 },
+  { 0.65400003842368570, 0.89999999999999991, 0.69813170079773179 },
+  { 0.78854928419904657, 0.89999999999999991, 0.87266462599716477 },
+  { 0.90645698626315407, 0.89999999999999991, 1.0471975511965976 },
+  { 1.0075154899135930, 0.89999999999999991, 1.2217304763960306 },
+  { 1.0940135583194071, 0.89999999999999991, 1.3962634015954636 },
+  { 1.1716970527816144, 0.89999999999999991, 1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991.
+template<typename Tp>
+  void
+  test019()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data019)
+			   / sizeof(testcase_ellint_2<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::ellint_2(Tp(data019[i].k), Tp(data019[i].phi));
+	const Tp f0 = data019[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  test012<double>();
+  test013<double>();
+  test014<double>();
+  test015<double>();
+  test016<double>();
+  test017<double>();
+  test018<double>();
+  test019<double>();
+  return 0;
+}
Index: testsuite/special_functions/12_ellint_2/compile.cc
===================================================================
--- testsuite/special_functions/12_ellint_2/compile.cc	(revision 0)
+++ testsuite/special_functions/12_ellint_2/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.12 ellint_2
+
+#include <cmath>
+
+void
+test01()
+{
+  float kf = 0.5F, phif = std::atan2(1.0F, 1.0F);
+  double kd = 0.5, phid = std::atan2(1.0, 1.0);
+  long double kl = 0.5L, phil = std::atan2(1.0L, 1.0L);
+
+  std::ellint_2(kf, phif);
+  std::ellint_2f(kf, phif);
+  std::ellint_2(kd, phid);
+  std::ellint_2(kl, phil);
+  std::ellint_2l(kl, phil);
+
+  return;
+}
+
Index: testsuite/special_functions/12_ellint_2/compile_2.cc
===================================================================
--- testsuite/special_functions/12_ellint_2/compile_2.cc	(revision 0)
+++ testsuite/special_functions/12_ellint_2/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.12 ellint_2
+
+#include <math.h>
+
+void
+test01()
+{
+  float kf = 0.5F, phif = atan2(1.0F, 1.0F);
+  double kd = 0.5, phid = atan2(1.0, 1.0);
+  long double kl = 0.5L, phil = atan2(1.0L, 1.0L);
+
+  ellint_2(kf, phif);
+  ellint_2f(kf, phif);
+  ellint_2(kd, phid);
+  ellint_2(kl, phil);
+  ellint_2l(kl, phil);
+
+  return;
+}
+
Index: testsuite/special_functions/13_ellint_3/check_nan.cc
===================================================================
--- testsuite/special_functions/13_ellint_3/check_nan.cc	(revision 0)
+++ testsuite/special_functions/13_ellint_3/check_nan.cc	(working copy)
@@ -0,0 +1,131 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// 2007-01-10  Edward Smith-Rowland <3dw4rd@verizon.net>
+//
+// Copyright (C) 2007-2014 Free Software Foundation, Inc.
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.13 ellint_3
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float kf = std::numeric_limits<float>::quiet_NaN();
+  double kd = std::numeric_limits<double>::quiet_NaN();
+  long double kl = std::numeric_limits<long double>::quiet_NaN();
+
+  float nuf = 0.2F;
+  double nud = 0.2;
+  long double nul = 0.2L;
+
+  float phif = std::atan2(1.0F, 1.0F);
+  double phid = std::atan2(1.0, 1.0);
+  long double phil = std::atan2(1.0L, 1.0L);
+
+  float a = std::ellint_3(kf, nuf, phif);
+  float b = std::ellint_3f(kf, nuf, phif);
+  double c = std::ellint_3(kd, nud, phid);
+  long double d = std::ellint_3(kl, nul, phil);
+  long double e = std::ellint_3l(kl, nul, phil);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+void
+test02()
+{
+  float kf = 0.5F;
+  double kd = 0.5;
+  long double kl = 0.5L;
+
+  float nuf = std::numeric_limits<float>::quiet_NaN();
+  double nud = std::numeric_limits<double>::quiet_NaN();
+  long double nul = std::numeric_limits<long double>::quiet_NaN();
+
+  float phif = std::atan2(1.0F, 1.0F);
+  double phid = std::atan2(1.0, 1.0);
+  long double phil = std::atan2(1.0L, 1.0L);
+
+  float a = std::ellint_3(kf, nuf, phif);
+  float b = std::ellint_3f(kf, nuf, phif);
+  double c = std::ellint_3(kd, nud, phid);
+  long double d = std::ellint_3(kl, nul, phil);
+  long double e = std::ellint_3l(kl, nul, phil);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+void
+test03()
+{
+  float kf = 0.5F;
+  double kd = 0.5;
+  long double kl = 0.5L;
+
+  float nuf = 0.2F;
+  double nud = 0.2;
+  long double nul = 0.2L;
+
+  float phif = std::numeric_limits<float>::quiet_NaN();
+  double phid = std::numeric_limits<double>::quiet_NaN();
+  long double phil = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::ellint_3(kf, nuf, phif);
+  float b = std::ellint_3f(kf, nuf, phif);
+  double c = std::ellint_3(kd, nud, phid);
+  long double d = std::ellint_3(kl, nul, phil);
+  long double e = std::ellint_3l(kl, nul, phil);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  test02();
+  test03();
+  return 0;
+}
+
Index: testsuite/special_functions/13_ellint_3/check_value.cc
===================================================================
--- testsuite/special_functions/13_ellint_3/check_value.cc	(revision 0)
+++ testsuite/special_functions/13_ellint_3/check_value.cc	(working copy)
@@ -0,0 +1,10494 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  ellint_3
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for k=-0.90000000000000002, nu=0.0000000000000000.
+testcase_ellint_3<double> data001[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17525427376115024, -0.90000000000000002, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35492464591297446, -0.90000000000000002, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.54388221416157112, -0.90000000000000002, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.74797400423532490, -0.90000000000000002, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.97463898451966458, -0.90000000000000002, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.2334463254523440, -0.90000000000000002, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.5355247765594913, -0.90000000000000002, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.8882928567775121, -0.90000000000000002, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 2.2805491384227703, -0.90000000000000002, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data001[i].k), Tp(data001[i].nu),
+		     Tp(data001[i].phi));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.90000000000000002, nu=0.10000000000000001.
+testcase_ellint_3<double> data002[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17507714233254656, -0.90000000000000002, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.35350932904326521, -0.90000000000000002, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.53911129989870976, -0.90000000000000002, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.73666644254508395, -0.90000000000000002, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.95250736612100195, -0.90000000000000002, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.1950199550905594, -0.90000000000000002, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.4741687286340850, -0.90000000000000002, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.7968678183506057, -0.90000000000000002, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 2.1537868513875287, -0.90000000000000002, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data002[i].k), Tp(data002[i].nu),
+		     Tp(data002[i].phi));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.90000000000000002, nu=0.20000000000000001.
+testcase_ellint_3<double> data003[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17490065089140927, -0.90000000000000002, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.35211377590661436, -0.90000000000000002, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.53448220334204100, -0.90000000000000002, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.72591368943179579, -0.90000000000000002, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.93192539780038763, -0.90000000000000002, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.1600809679692683, -0.90000000000000002, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.4195407225882510, -0.90000000000000002, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.7168966476424525, -0.90000000000000002, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 2.0443194576468890, -0.90000000000000002, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data003[i].k), Tp(data003[i].nu),
+		     Tp(data003[i].phi));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.90000000000000002, nu=0.29999999999999999.
+testcase_ellint_3<double> data004[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17472479532647531, -0.90000000000000002, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.35073750187374114, -0.90000000000000002, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.52998766129466957, -0.90000000000000002, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.71566993548699553, -0.90000000000000002, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.91271517762560195, -0.90000000000000002, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 1.1281241199843370, -0.90000000000000002, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.3704929576917451, -0.90000000000000002, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.6461981511487713, -0.90000000000000002, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.9486280260314426, -0.90000000000000002, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data004[i].k), Tp(data004[i].nu),
+		     Tp(data004[i].phi));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.90000000000000002, nu=0.40000000000000002.
+testcase_ellint_3<double> data005[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17454957156468837, -0.90000000000000002, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34938003933330430, -0.90000000000000002, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.52562093533067433, -0.90000000000000002, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.70589461324915670, -0.90000000000000002, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.89472658511942849, -0.90000000000000002, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 1.0987419542323440, -0.90000000000000002, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.3261349565496303, -0.90000000000000002, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.5831293909853765, -0.90000000000000002, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.8641114227238349, -0.90000000000000002, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data005[i].k), Tp(data005[i].nu),
+		     Tp(data005[i].phi));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.90000000000000002, nu=0.50000000000000000.
+testcase_ellint_3<double> data006[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17437497557073334, -0.90000000000000002, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34804093691586013, -0.90000000000000002, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.52137576320372891, -0.90000000000000002, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.69655163996912262, -0.90000000000000002, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.87783188683054236, -0.90000000000000002, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 1.0716015959755185, -0.90000000000000002, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.2857636916026749, -0.90000000000000002, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.5264263913252363, -0.90000000000000002, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.7888013241937861, -0.90000000000000002, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data006[i].k), Tp(data006[i].nu),
+		     Tp(data006[i].phi));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.90000000000000002, nu=0.59999999999999998.
+testcase_ellint_3<double> data007[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17420100334657812, -0.90000000000000002, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34671975876122157, -0.90000000000000002, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.51724631570707946, -0.90000000000000002, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.68760879113743023, -0.90000000000000002, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.86192157779698364, -0.90000000000000002, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 1.0464279696166354, -0.90000000000000002, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.2488156247094007, -0.90000000000000002, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.4750988777188472, -0.90000000000000002, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.7211781128919523, -0.90000000000000002, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data007[i].k), Tp(data007[i].nu),
+		     Tp(data007[i].phi));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.90000000000000002, nu=0.69999999999999996.
+testcase_ellint_3<double> data008[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17402765093102207, -0.90000000000000002, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34541608382635131, -0.90000000000000002, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.51322715827061682, -0.90000000000000002, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.67903717872440272, -0.90000000000000002, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.84690113601682671, -0.90000000000000002, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 1.0229914311548418, -0.90000000000000002, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.2148329639709381, -0.90000000000000002, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.4283586501307803, -0.90000000000000002, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.6600480747670940, -0.90000000000000002, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data008[i].k), Tp(data008[i].nu),
+		     Tp(data008[i].phi));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.90000000000000002, nu=0.80000000000000004.
+testcase_ellint_3<double> data009[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17385491439925146, -0.90000000000000002, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.34412950523113928, -0.90000000000000002, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.50931321668729590, -0.90000000000000002, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.67081081392296327, -0.90000000000000002, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.83268846097293259, -0.90000000000000002, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 1.0010985015814027, -0.90000000000000002, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.1834394045489680, -0.90000000000000002, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.3855695891683186, -0.90000000000000002, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.6044591960982202, -0.90000000000000002, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data009[i].k), Tp(data009[i].nu),
+		     Tp(data009[i].phi));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.90000000000000002, nu=0.90000000000000002.
+testcase_ellint_3<double> data010[] = {
+  { 0.0000000000000000, -0.90000000000000002, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17368278986240135, -0.90000000000000002, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.34285962963961397, -0.90000000000000002, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.50549974644993312, -0.90000000000000002, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.66290623857720876, -0.90000000000000002, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.81921183128847175, -0.90000000000000002, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.98058481956066390, -0.90000000000000002, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 1.1543223520473569, -0.90000000000000002, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.3462119782292938, -0.90000000000000002, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.5536420236310946, -0.90000000000000002, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.90000000000000002, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data010[i].k), Tp(data010[i].nu),
+		     Tp(data010[i].phi));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004, nu=0.0000000000000000.
+testcase_ellint_3<double> data011[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17510154241338899, -0.80000000000000004, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35365068839779390, -0.80000000000000004, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.53926804409084550, -0.80000000000000004, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.73587926028070361, -0.80000000000000004, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.94770942970071170, -0.80000000000000004, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.1789022995388236, -0.80000000000000004, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.4323027881876009, -0.80000000000000004, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.7069629739121674, -0.80000000000000004, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.9953027776647296, -0.80000000000000004, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data011[i].k), Tp(data011[i].nu),
+		     Tp(data011[i].phi));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004, nu=0.10000000000000001.
+testcase_ellint_3<double> data012[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17492468824017163, -0.80000000000000004, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.35224443521476911, -0.80000000000000004, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.53456851853226950, -0.80000000000000004, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.72488875602364922, -0.80000000000000004, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.92661354274638952, -0.80000000000000004, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.1432651144499075, -0.80000000000000004, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.3774479927211429, -0.80000000000000004, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.6287092337196041, -0.80000000000000004, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.8910755418379521, -0.80000000000000004, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test012()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data012)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data012[i].k), Tp(data012[i].nu),
+		     Tp(data012[i].phi));
+	const Tp f0 = data012[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004, nu=0.20000000000000001.
+testcase_ellint_3<double> data013[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17474847286224940, -0.80000000000000004, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.35085779529084682, -0.80000000000000004, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.53000829263059146, -0.80000000000000004, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.71443466027453384, -0.80000000000000004, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.90698196872715420, -0.80000000000000004, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.1108198200558579, -0.80000000000000004, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.3284988909963957, -0.80000000000000004, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.5600369318140328, -0.80000000000000004, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.8007226661734588, -0.80000000000000004, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test013()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data013)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data013[i].k), Tp(data013[i].nu),
+		     Tp(data013[i].phi));
+	const Tp f0 = data013[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004, nu=0.29999999999999999.
+testcase_ellint_3<double> data014[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17457289217669889, -0.80000000000000004, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34949028801501258, -0.80000000000000004, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.52558024362769307, -0.80000000000000004, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.70447281740094891, -0.80000000000000004, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.88864745641528986, -0.80000000000000004, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 1.0811075819341462, -0.80000000000000004, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.2844589654082377, -0.80000000000000004, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.4991461361277847, -0.80000000000000004, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.7214611048717301, -0.80000000000000004, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test014()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data014)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data014[i].k), Tp(data014[i].nu),
+		     Tp(data014[i].phi));
+	const Tp f0 = data014[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004, nu=0.40000000000000002.
+testcase_ellint_3<double> data015[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17439794211872175, -0.80000000000000004, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34814144964568972, -0.80000000000000004, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.52127776285273064, -0.80000000000000004, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.69496411438966588, -0.80000000000000004, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.87146878427509589, -0.80000000000000004, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 1.0537579024937762, -0.80000000000000004, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.2445534387922637, -0.80000000000000004, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.4446769766361993, -0.80000000000000004, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.6512267838651289, -0.80000000000000004, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test015()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data015)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data015[i].k), Tp(data015[i].nu),
+		     Tp(data015[i].phi));
+	const Tp f0 = data015[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004, nu=0.50000000000000000.
+testcase_ellint_3<double> data016[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17422361866118044, -0.80000000000000004, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34681083254170475, -0.80000000000000004, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.51709470815494440, -0.80000000000000004, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.68587375344080237, -0.80000000000000004, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.85532571852810624, -0.80000000000000004, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 1.0284677391874903, -0.80000000000000004, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.2081693942686225, -0.80000000000000004, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.3955803006426311, -0.80000000000000004, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.5884528947755532, -0.80000000000000004, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test016()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data016)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data016[i].k), Tp(data016[i].nu),
+		     Tp(data016[i].phi));
+	const Tp f0 = data016[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004, nu=0.59999999999999998.
+testcase_ellint_3<double> data017[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17404991781414089, -0.80000000000000004, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34549800443625167, -0.80000000000000004, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.51302536167001545, -0.80000000000000004, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.67717065003912236, -0.80000000000000004, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.84011512421134416, -0.80000000000000004, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 1.0049863847088740, -0.80000000000000004, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.1748145941898920, -0.80000000000000004, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.3510319699755071, -0.80000000000000004, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.5319262547427865, -0.80000000000000004, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test017()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data017)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data017[i].k), Tp(data017[i].nu),
+		     Tp(data017[i].phi));
+	const Tp f0 = data017[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004, nu=0.69999999999999996.
+testcase_ellint_3<double> data018[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17387683562442199, -0.80000000000000004, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34420254775101611, -0.80000000000000004, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.50906439222143673, -0.80000000000000004, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.66882693152688422, -0.80000000000000004, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.82574792844091316, -0.80000000000000004, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.98310431309490931, -0.80000000000000004, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.1440884535113258, -0.80000000000000004, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.3103743938952537, -0.80000000000000004, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.4806912324625332, -0.80000000000000004, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test018()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data018)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data018[i].k), Tp(data018[i].nu),
+		     Tp(data018[i].phi));
+	const Tp f0 = data018[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004, nu=0.80000000000000004.
+testcase_ellint_3<double> data019[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17370436817515203, -0.80000000000000004, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.34292405894783395, -0.80000000000000004, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.50520682176250076, -0.80000000000000004, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.66081751679736178, -0.80000000000000004, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.81214672249355102, -0.80000000000000004, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.96264481387685552, -0.80000000000000004, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.1156611352656258, -0.80000000000000004, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.2730756225143889, -0.80000000000000004, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.4339837018309471, -0.80000000000000004, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test019()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data019)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data019[i].k), Tp(data019[i].nu),
+		     Tp(data019[i].phi));
+	const Tp f0 = data019[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.80000000000000004, nu=0.90000000000000002.
+testcase_ellint_3<double> data020[] = {
+  { 0.0000000000000000, -0.80000000000000004, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17353251158533151, -0.80000000000000004, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.34166214791545768, -0.80000000000000004, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.50144799535130569, -0.80000000000000004, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.65311976193814425, -0.80000000000000004, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.79924384892320866, -0.80000000000000004, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.94345762353365603, -0.80000000000000004, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 1.0892582069219161, -0.80000000000000004, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.2387000876610268, -0.80000000000000004, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.3911845406776222, -0.80000000000000004, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.80000000000000004, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test020()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data020)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data020[i].k), Tp(data020[i].nu),
+		     Tp(data020[i].phi));
+	const Tp f0 = data020[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996, nu=0.0000000000000000.
+testcase_ellint_3<double> data021[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17496737466916723, -0.69999999999999996, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35254687535677925, -0.69999999999999996, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.53536740275997119, -0.69999999999999996, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.72603797651684454, -0.69999999999999996, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.92698296348313458, -0.69999999999999996, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.1400447527693316, -0.69999999999999996, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.3657668117194073, -0.69999999999999996, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.6024686895959159, -0.69999999999999996, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.8456939983747236, -0.69999999999999996, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test021()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data021)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data021[i].k), Tp(data021[i].nu),
+		     Tp(data021[i].phi));
+	const Tp f0 = data021[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996, nu=0.10000000000000001.
+testcase_ellint_3<double> data022[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17479076384884684, -0.69999999999999996, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.35114844900396364, -0.69999999999999996, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.53072776947527001, -0.69999999999999996, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.71530198262386235, -0.69999999999999996, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.90666760677828306, -0.69999999999999996, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.1063366517438080, -0.69999999999999996, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.3149477243092149, -0.69999999999999996, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.5314886725038925, -0.69999999999999996, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.7528050171757608, -0.69999999999999996, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test022()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data022)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data022[i].k), Tp(data022[i].nu),
+		     Tp(data022[i].phi));
+	const Tp f0 = data022[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996, nu=0.20000000000000001.
+testcase_ellint_3<double> data023[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17461479077791475, -0.69999999999999996, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34976950621407538, -0.69999999999999996, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.52622533231350177, -0.69999999999999996, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.70508774017895215, -0.69999999999999996, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.88775302531730294, -0.69999999999999996, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.0756195476149006, -0.69999999999999996, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.2695349716654374, -0.69999999999999996, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.4690814617070540, -0.69999999999999996, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.6721098780092145, -0.69999999999999996, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test023()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data023)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data023[i].k), Tp(data023[i].nu),
+		     Tp(data023[i].phi));
+	const Tp f0 = data023[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996, nu=0.29999999999999999.
+testcase_ellint_3<double> data024[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17443945136076175, -0.69999999999999996, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34840956983535287, -0.69999999999999996, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.52185308551329168, -0.69999999999999996, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.69535240431168255, -0.69999999999999996, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.87007983473964923, -0.69999999999999996, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 1.0474657975577066, -0.69999999999999996, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.2286225419931891, -0.69999999999999996, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.4136490671013271, -0.69999999999999996, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.6011813647733213, -0.69999999999999996, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test024()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data024)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data024[i].k), Tp(data024[i].nu),
+		     Tp(data024[i].phi));
+	const Tp f0 = data024[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996, nu=0.40000000000000002.
+testcase_ellint_3<double> data025[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17426474153983229, -0.69999999999999996, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34706817945773732, -0.69999999999999996, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.51760452851738148, -0.69999999999999996, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.68605801534722755, -0.69999999999999996, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.85351339387296532, -0.69999999999999996, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 1.0215297967969539, -0.69999999999999996, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.1915051074460530, -0.69999999999999996, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.3639821911744707, -0.69999999999999996, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.5382162002954762, -0.69999999999999996, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test025()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data025)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data025[i].k), Tp(data025[i].nu),
+		     Tp(data025[i].phi));
+	const Tp f0 = data025[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996, nu=0.50000000000000000.
+testcase_ellint_3<double> data026[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17409065729516096, -0.69999999999999996, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34574489064986091, -0.69999999999999996, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.51347361925579782, -0.69999999999999996, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.67717079489579279, -0.69999999999999996, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.83793902055292280, -0.69999999999999996, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.99752863545289705, -0.69999999999999996, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.1576240080401501, -0.69999999999999996, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.3191464023923762, -0.69999999999999996, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.4818433192178544, -0.69999999999999996, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test026()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data026)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data026[i].k), Tp(data026[i].nu),
+		     Tp(data026[i].phi));
+	const Tp f0 = data026[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996, nu=0.59999999999999998.
+testcase_ellint_3<double> data027[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17391719464391614, -0.69999999999999996, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34443927423869031, -0.69999999999999996, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.50945473266486063, -0.69999999999999996, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.66866056326513812, -0.69999999999999996, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.82325830002337352, -0.69999999999999996, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.97522808245669368, -0.69999999999999996, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.1265300613705285, -0.69999999999999996, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.2784066076152001, -0.69999999999999996, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.4309994736080540, -0.69999999999999996, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test027()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data027)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data027[i].k), Tp(data027[i].nu),
+		     Tp(data027[i].phi));
+	const Tp f0 = data027[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996, nu=0.69999999999999996.
+testcase_ellint_3<double> data028[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17374434963995031, -0.69999999999999996, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34315091562900674, -0.69999999999999996, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.50554262375653347, -0.69999999999999996, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.66050025406305801, -0.69999999999999996, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.80938620118847404, -0.69999999999999996, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.95443223855852144, -0.69999999999999996, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0978573207128304, -0.69999999999999996, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.2411754575007123, -0.69999999999999996, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.3848459188329196, -0.69999999999999996, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test028()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data028)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data028[i].k), Tp(data028[i].nu),
+		     Tp(data028[i].phi));
+	const Tp f0 = data028[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996, nu=0.80000000000000004.
+testcase_ellint_3<double> data029[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17357211837335740, -0.69999999999999996, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.34187941416012108, -0.69999999999999996, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.50173239465478259, -0.69999999999999996, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.65266550725988315, -0.69999999999999996, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.79624879865249298, -0.69999999999999996, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.93497577043296920, -0.69999999999999996, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.0713041566930750, -0.69999999999999996, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.2069772023255654, -0.69999999999999996, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.3427110650397531, -0.69999999999999996, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test029()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data029)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data029[i].k), Tp(data029[i].nu),
+		     Tp(data029[i].phi));
+	const Tp f0 = data029[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.69999999999999996, nu=0.90000000000000002.
+testcase_ellint_3<double> data030[] = {
+  { 0.0000000000000000, -0.69999999999999996, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17340049697003637, -0.69999999999999996, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.34062438249741556, -0.69999999999999996, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.49801946510076867, -0.69999999999999996, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.64513432604750476, -0.69999999999999996, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.78378145487573758, -0.69999999999999996, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.91671799500854623, -0.69999999999999996, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 1.0466193579463123, -0.69999999999999996, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.1754218079199146, -0.69999999999999996, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.3040500499695913, -0.69999999999999996, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.69999999999999996, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test030()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data030)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data030[i].k), Tp(data030[i].nu),
+		     Tp(data030[i].phi));
+	const Tp f0 = data030[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998, nu=0.0000000000000000.
+testcase_ellint_3<double> data031[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17485154362988359, -0.59999999999999998, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35160509865544326, -0.59999999999999998, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.53210652578446138, -0.59999999999999998, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.71805304664485659, -0.59999999999999998, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.91082759030195970, -0.59999999999999998, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.1112333229323361, -0.59999999999999998, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.3191461190365270, -0.59999999999999998, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.5332022105084773, -0.59999999999999998, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.7507538029157526, -0.59999999999999998, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test031()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data031)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data031[i].k), Tp(data031[i].nu),
+		     Tp(data031[i].phi));
+	const Tp f0 = data031[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998, nu=0.10000000000000001.
+testcase_ellint_3<double> data032[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17467514275022011, -0.59999999999999998, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.35021333086258255, -0.59999999999999998, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.52751664092962691, -0.59999999999999998, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.70752126971957874, -0.59999999999999998, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.89111058756112871, -0.59999999999999998, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0789241202877768, -0.59999999999999998, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.2710800210399946, -0.59999999999999998, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.4669060574440276, -0.59999999999999998, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.6648615773343014, -0.59999999999999998, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test032()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data032)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data032[i].k), Tp(data032[i].nu),
+		     Tp(data032[i].phi));
+	const Tp f0 = data032[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998, nu=0.20000000000000001.
+testcase_ellint_3<double> data033[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17449937871800650, -0.59999999999999998, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34884093647346553, -0.59999999999999998, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.52306221119844087, -0.59999999999999998, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.69749955678982223, -0.59999999999999998, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.87274610682416853, -0.59999999999999998, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.0494620540750792, -0.59999999999999998, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.2280847305507339, -0.59999999999999998, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.4085436279696886, -0.59999999999999998, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.5901418016279374, -0.59999999999999998, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test033()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data033)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data033[i].k), Tp(data033[i].nu),
+		     Tp(data033[i].phi));
+	const Tp f0 = data033[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998, nu=0.29999999999999999.
+testcase_ellint_3<double> data034[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17432424744393932, -0.59999999999999998, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34748744127146447, -0.59999999999999998, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51873632743924825, -0.59999999999999998, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.68794610396313116, -0.59999999999999998, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.85558070175468726, -0.59999999999999998, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 1.0224416343605653, -0.59999999999999998, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1893144457936788, -0.59999999999999998, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.3566435377982575, -0.59999999999999998, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.5243814243493585, -0.59999999999999998, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test034()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data034)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data034[i].k), Tp(data034[i].nu),
+		     Tp(data034[i].phi));
+	const Tp f0 = data034[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998, nu=0.40000000000000002.
+testcase_ellint_3<double> data035[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17414974487670717, -0.59999999999999998, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34615238767335027, -0.59999999999999998, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.51453257838108557, -0.59999999999999998, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.67882386787534399, -0.59999999999999998, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.83948470233173578, -0.59999999999999998, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.99753496200073977, -0.59999999999999998, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.1541101404388487, -0.59999999999999998, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.3100911323398814, -0.59999999999999998, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.4659345278069984, -0.59999999999999998, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test035()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data035)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data035[i].k), Tp(data035[i].nu),
+		     Tp(data035[i].phi));
+	const Tp f0 = data035[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998, nu=0.50000000000000000.
+testcase_ellint_3<double> data036[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17397586700252807, -0.59999999999999998, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34483533397138516, -0.59999999999999998, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.51044500461706477, -0.59999999999999998, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.67009988034712664, -0.59999999999999998, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.82434762375735193, -0.59999999999999998, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.97447346702798998, -0.59999999999999998, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.1219494000522143, -0.59999999999999998, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.2680242605954484, -0.59999999999999998, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.4135484285693078, -0.59999999999999998, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test036()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data036)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data036[i].k), Tp(data036[i].nu),
+		     Tp(data036[i].phi));
+	const Tp f0 = data036[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998, nu=0.59999999999999998.
+testcase_ellint_3<double> data037[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17380260984469353, -0.59999999999999998, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34353585361777839, -0.59999999999999998, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.50646805774321380, -0.59999999999999998, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.66174468108625506, -0.59999999999999998, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.81007462280278408, -0.59999999999999998, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.95303466945718729, -0.59999999999999998, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0924118588677505, -0.59999999999999998, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.2297640574847937, -0.59999999999999998, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.3662507535812816, -0.59999999999999998, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test037()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data037)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data037[i].k), Tp(data037[i].nu),
+		     Tp(data037[i].phi));
+	const Tp f0 = data037[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998, nu=0.69999999999999996.
+testcase_ellint_3<double> data038[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17362996946312007, -0.59999999999999998, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34225353454870588, -0.59999999999999998, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.50259656397799524, -0.59999999999999998, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.65373184496628933, -0.59999999999999998, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.79658372884056439, -0.59999999999999998, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.93303240100245421, -0.59999999999999998, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0651547944716557, -0.59999999999999998, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1947676204853441, -0.59999999999999998, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.3232737468822813, -0.59999999999999998, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test038()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data038)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data038[i].k), Tp(data038[i].nu),
+		     Tp(data038[i].phi));
+	const Tp f0 = data038[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998, nu=0.80000000000000004.
+testcase_ellint_3<double> data039[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17345794195390685, -0.59999999999999998, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.34098797854531027, -0.59999999999999998, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49882569168826213, -0.59999999999999998, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.64603758566475511, -0.59999999999999998, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.78380365594769730, -0.59999999999999998, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.91430946255611190, -0.59999999999999998, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.0398955217270607, -0.59999999999999998, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.1625948314277679, -0.59999999999999998, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.2840021261752192, -0.59999999999999998, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test039()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data039)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data039[i].k), Tp(data039[i].nu),
+		     Tp(data039[i].phi));
+	const Tp f0 = data039[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.59999999999999998, nu=0.90000000000000002.
+testcase_ellint_3<double> data040[] = {
+  { 0.0000000000000000, -0.59999999999999998, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17328652344890030, -0.59999999999999998, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33973880062929018, -0.59999999999999998, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.49515092233122743, -0.59999999999999998, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.63864042139737043, -0.59999999999999998, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.77167205646538850, -0.59999999999999998, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.89673202848034383, -0.59999999999999998, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 1.0163984492661304, -0.59999999999999998, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.1328845785162431, -0.59999999999999998, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.2479362973851875, -0.59999999999999998, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.59999999999999998, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test040()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data040)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data040[i].k), Tp(data040[i].nu),
+		     Tp(data040[i].phi));
+	const Tp f0 = data040[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000, nu=0.0000000000000000.
+testcase_ellint_3<double> data041[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17475385514035785, -0.50000000000000000, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35081868470101585, -0.50000000000000000, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52942862705190574, -0.50000000000000000, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.71164727562630314, -0.50000000000000000, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.89824523594227768, -0.50000000000000000, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0895506700518851, -0.50000000000000000, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2853005857432931, -0.50000000000000000, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.4845545520549484, -0.50000000000000000, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.6857503548125963, -0.50000000000000000, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test041()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data041)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data041[i].k), Tp(data041[i].nu),
+		     Tp(data041[i].phi));
+	const Tp f0 = data041[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000, nu=0.10000000000000001.
+testcase_ellint_3<double> data042[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17457763120814676, -0.50000000000000000, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34943246340849154, -0.50000000000000000, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.52487937869610790, -0.50000000000000000, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.70127785096388384, -0.50000000000000000, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.87898815988624479, -0.50000000000000000, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0582764576094172, -0.50000000000000000, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.2391936844060205, -0.50000000000000000, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.4214793542995841, -0.50000000000000000, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.6045524936084892, -0.50000000000000000, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test042()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data042)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data042[i].k), Tp(data042[i].nu),
+		     Tp(data042[i].phi));
+	const Tp f0 = data042[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000, nu=0.20000000000000001.
+testcase_ellint_3<double> data043[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17440204336345433, -0.50000000000000000, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34806552388338824, -0.50000000000000000, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.52046416757129810, -0.50000000000000000, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.69140924550993865, -0.50000000000000000, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.86104678636125520, -0.50000000000000000, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.0297439459053981, -0.50000000000000000, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1979214112912033, -0.50000000000000000, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.3659033858648930, -0.50000000000000000, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.5338490483665983, -0.50000000000000000, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test043()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data043)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data043[i].k), Tp(data043[i].nu),
+		     Tp(data043[i].phi));
+	const Tp f0 = data043[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000, nu=0.29999999999999999.
+testcase_ellint_3<double> data044[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17422708752228896, -0.50000000000000000, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34671739434855858, -0.50000000000000000, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51617616305641878, -0.50000000000000000, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.68200047612545167, -0.50000000000000000, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.84427217869498372, -0.50000000000000000, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 1.0035637821389782, -0.50000000000000000, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1606800483933111, -0.50000000000000000, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.3164407134643459, -0.50000000000000000, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.4715681939859637, -0.50000000000000000, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test044()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data044)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data044[i].k), Tp(data044[i].nu),
+		     Tp(data044[i].phi));
+	const Tp f0 = data044[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000, nu=0.40000000000000002.
+testcase_ellint_3<double> data045[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17405275963859917, -0.50000000000000000, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34538761957029329, -0.50000000000000000, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.51200902646603907, -0.50000000000000000, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.67301522212868792, -0.50000000000000000, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.82853844466313320, -0.50000000000000000, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.97942097862681488, -0.50000000000000000, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.1268429801220614, -0.50000000000000000, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2720406704533922, -0.50000000000000000, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.4161679518465340, -0.50000000000000000, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test045()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data045)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data045[i].k), Tp(data045[i].nu),
+		     Tp(data045[i].phi));
+	const Tp f0 = data045[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000, nu=0.50000000000000000.
+testcase_ellint_3<double> data046[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17387905570381157, -0.50000000000000000, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34407576010465207, -0.50000000000000000, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50795686560160824, -0.50000000000000000, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.66442115453330164, -0.50000000000000000, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.81373829119355345, -0.50000000000000000, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.95705743313235825, -0.50000000000000000, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0959131991362554, -0.50000000000000000, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.2318900529754597, -0.50000000000000000, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.3664739530045971, -0.50000000000000000, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test046()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data046)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data046[i].k), Tp(data046[i].nu),
+		     Tp(data046[i].phi));
+	const Tp f0 = data046[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000, nu=0.59999999999999998.
+testcase_ellint_3<double> data047[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17370597174637581, -0.50000000000000000, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34278139158591414, -0.50000000000000000, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.50401419439302708, -0.50000000000000000, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.65618938076167210, -0.50000000000000000, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.79977959248855424, -0.50000000000000000, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.93625925190753545, -0.50000000000000000, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0674905658379708, -0.50000000000000000, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1953481298023050, -0.50000000000000000, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.3215740290190876, -0.50000000000000000, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test047()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data047)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data047[i].k), Tp(data047[i].nu),
+		     Tp(data047[i].phi));
+	const Tp f0 = data047[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000, nu=0.69999999999999996.
+testcase_ellint_3<double> data048[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17353350383131641, -0.50000000000000000, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34150410405436771, -0.50000000000000000, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.50017589696443487, -0.50000000000000000, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.64829398188419951, -0.50000000000000000, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.78658270782402073, -0.50000000000000000, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.91684738336675053, -0.50000000000000000, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0412486789555935, -0.50000000000000000, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1619021847612001, -0.50000000000000000, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2807475181182502, -0.50000000000000000, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test048()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data048)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data048[i].k), Tp(data048[i].nu),
+		     Tp(data048[i].phi));
+	const Tp f0 = data048[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000, nu=0.80000000000000004.
+testcase_ellint_3<double> data049[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17336164805979126, -0.50000000000000000, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.34024350132086773, -0.50000000000000000, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49643719555734073, -0.50000000000000000, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.64071162456976150, -0.50000000000000000, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.77407836177211908, -0.50000000000000000, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.89867058251905652, -0.50000000000000000, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.0169181822134910, -0.50000000000000000, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.1311363312779448, -0.50000000000000000, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.2434165408189539, -0.50000000000000000, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test049()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data049)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data049[i].k), Tp(data049[i].nu),
+		     Tp(data049[i].phi));
+	const Tp f0 = data049[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.50000000000000000, nu=0.90000000000000002.
+testcase_ellint_3<double> data050[] = {
+  { 0.0000000000000000, -0.50000000000000000, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17319040056865681, -0.50000000000000000, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33899920036578557, -0.50000000000000000, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.49279362182695174, -0.50000000000000000, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.63342123379746151, -0.50000000000000000, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.76220595179550321, -0.50000000000000000, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.88160004743532294, -0.50000000000000000, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.99427448642310123, -0.50000000000000000, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.1027091512470095, -0.50000000000000000, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.2091116095504744, -0.50000000000000000, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.50000000000000000, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test050()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data050)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data050[i].k), Tp(data050[i].nu),
+		     Tp(data050[i].phi));
+	const Tp f0 = data050[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002, nu=0.0000000000000000.
+testcase_ellint_3<double> data051[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17467414669441528, -0.40000000000000002, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35018222772483443, -0.40000000000000002, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52729015917508737, -0.40000000000000002, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.70662374407341244, -0.40000000000000002, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.88859210497602170, -0.40000000000000002, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0733136290471379, -0.40000000000000002, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2605612170157061, -0.40000000000000002, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.4497513956433439, -0.40000000000000002, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.6399998658645112, -0.40000000000000002, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test051()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data051)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data051[i].k), Tp(data051[i].nu),
+		     Tp(data051[i].phi));
+	const Tp f0 = data051[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002, nu=0.10000000000000001.
+testcase_ellint_3<double> data052[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17449806706684670, -0.40000000000000002, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34880048623856075, -0.40000000000000002, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.52277322065757392, -0.40000000000000002, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.69638072056918365, -0.40000000000000002, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.86968426619831540, -0.40000000000000002, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0428044206578095, -0.40000000000000002, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.2158651158274378, -0.40000000000000002, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.3889447129893324, -0.40000000000000002, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.5620566886683604, -0.40000000000000002, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test052()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data052)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data052[i].k), Tp(data052[i].nu),
+		     Tp(data052[i].phi));
+	const Tp f0 = data052[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002, nu=0.20000000000000001.
+testcase_ellint_3<double> data053[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17432262290723397, -0.40000000000000002, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34743795258968596, -0.40000000000000002, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.51838919472805101, -0.40000000000000002, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.68663134739057907, -0.40000000000000002, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.85206432981833979, -0.40000000000000002, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.0149595349004430, -0.40000000000000002, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1758349405464676, -0.40000000000000002, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.3353337673882637, -0.40000000000000002, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.4941414344266770, -0.40000000000000002, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test053()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data053)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data053[i].k), Tp(data053[i].nu),
+		     Tp(data053[i].phi));
+	const Tp f0 = data053[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002, nu=0.29999999999999999.
+testcase_ellint_3<double> data054[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17414781013591540, -0.40000000000000002, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34609415696777285, -0.40000000000000002, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51413131295862535, -0.40000000000000002, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.67733527622935630, -0.40000000000000002, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.83558675182733266, -0.40000000000000002, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 0.98940140808865906, -0.40000000000000002, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1396968797728058, -0.40000000000000002, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.2875920037865090, -0.40000000000000002, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.4342789859950078, -0.40000000000000002, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test054()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data054)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data054[i].k), Tp(data054[i].nu),
+		     Tp(data054[i].phi));
+	const Tp f0 = data054[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002, nu=0.40000000000000002.
+testcase_ellint_3<double> data055[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17397362471112707, -0.40000000000000002, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34476864603333196, -0.40000000000000002, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.50999329415379346, -0.40000000000000002, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.66845674551396006, -0.40000000000000002, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.82012848346231748, -0.40000000000000002, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.96582449258349057, -0.40000000000000002, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.1068473749476286, -0.40000000000000002, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2447132729159989, -0.40000000000000002, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.3809986210732901, -0.40000000000000002, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test055()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data055)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data055[i].k), Tp(data055[i].nu),
+		     Tp(data055[i].phi));
+	const Tp f0 = data055[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002, nu=0.50000000000000000.
+testcase_ellint_3<double> data056[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17380006262854136, -0.40000000000000002, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34346098216756610, -0.40000000000000002, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50596929935059420, -0.40000000000000002, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.65996392089131251, -0.40000000000000002, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.80558463511364786, -0.40000000000000002, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.94397834522857704, -0.40000000000000002, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0768075114108115, -0.40000000000000002, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.2059184624251333, -0.40000000000000002, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.3331797176377398, -0.40000000000000002, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test056()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data056)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data056[i].k), Tp(data056[i].nu),
+		     Tp(data056[i].phi));
+	const Tp f0 = data056[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002, nu=0.59999999999999998.
+testcase_ellint_3<double> data057[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17362711992081245, -0.40000000000000002, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34217074276403953, -0.40000000000000002, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.50205389185761606, -0.40000000000000002, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.65182834920372734, -0.40000000000000002, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.79186512820565136, -0.40000000000000002, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.92365535916287134, -0.40000000000000002, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0491915663957907, -0.40000000000000002, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1705934291745106, -0.40000000000000002, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.2899514672527024, -0.40000000000000002, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test057()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data057)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data057[i].k), Tp(data057[i].nu),
+		     Tp(data057[i].phi));
+	const Tp f0 = data057[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002, nu=0.69999999999999996.
+testcase_ellint_3<double> data058[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17345479265712868, -0.40000000000000002, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34089751955950354, -0.40000000000000002, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.49824200167361332, -0.40000000000000002, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.64402450341199402, -0.40000000000000002, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.77889207804122873, -0.40000000000000002, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.90468169720957992, -0.40000000000000002, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0236847823692916, -0.40000000000000002, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1382465247425166, -0.40000000000000002, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2506255923253344, -0.40000000000000002, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test058()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data058)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data058[i].k), Tp(data058[i].nu),
+		     Tp(data058[i].phi));
+	const Tp f0 = data058[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002, nu=0.80000000000000004.
+testcase_ellint_3<double> data059[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17328307694277154, -0.40000000000000002, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.33964091800132007, -0.40000000000000002, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49452889372467440, -0.40000000000000002, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.63652940095937316, -0.40000000000000002, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.76659772511159097, -0.40000000000000002, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.88691047977338111, -0.40000000000000002, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.0000273200611638, -0.40000000000000002, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.1084787902188009, -0.40000000000000002, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.2146499565727209, -0.40000000000000002, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test059()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data059)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data059[i].k), Tp(data059[i].nu),
+		     Tp(data059[i].phi));
+	const Tp f0 = data059[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.40000000000000002, nu=0.90000000000000002.
+testcase_ellint_3<double> data060[] = {
+  { 0.0000000000000000, -0.40000000000000002, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17311196891868127, -0.40000000000000002, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33840055664911906, -0.40000000000000002, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.49091013944075329, -0.40000000000000002, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.62932228186809580, -0.40000000000000002, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.75492278323019801, -0.40000000000000002, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.87021659043854294, -0.40000000000000002, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.97800245228239246, -0.40000000000000002, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.0809625773173697, -0.40000000000000002, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.1815758115929846, -0.40000000000000002, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.40000000000000002, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test060()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data060)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data060[i].k), Tp(data060[i].nu),
+		     Tp(data060[i].phi));
+	const Tp f0 = data060[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004, nu=0.0000000000000000.
+testcase_ellint_3<double> data061[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17461228653000099, -0.30000000000000004, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.34969146102798415, -0.30000000000000004, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52565822873726320, -0.30000000000000004, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.70284226512408532, -0.30000000000000004, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.88144139195111182, -0.30000000000000004, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0614897067260520, -0.30000000000000004, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2428416824174218, -0.30000000000000004, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.4251795877015927, -0.30000000000000004, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.6080486199305128, -0.30000000000000004, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test061()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data061)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data061[i].k), Tp(data061[i].nu),
+		     Tp(data061[i].phi));
+	const Tp f0 = data061[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004, nu=0.10000000000000001.
+testcase_ellint_3<double> data062[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17443631884814376, -0.30000000000000004, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34831316835124926, -0.30000000000000004, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.52116586276523857, -0.30000000000000004, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.69269385837910036, -0.30000000000000004, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.86279023163070856, -0.30000000000000004, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0315321461438263, -0.30000000000000004, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.1991449111869024, -0.30000000000000004, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.3659561780923213, -0.30000000000000004, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.5323534693557528, -0.30000000000000004, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test062()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data062)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data062[i].k), Tp(data062[i].nu),
+		     Tp(data062[i].phi));
+	const Tp f0 = data062[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004, nu=0.20000000000000001.
+testcase_ellint_3<double> data063[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17426098615372088, -0.30000000000000004, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34695402664689923, -0.30000000000000004, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.51680555567038933, -0.30000000000000004, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.68303375225260210, -0.30000000000000004, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.84540662891295026, -0.30000000000000004, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.0041834051646927, -0.30000000000000004, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1599952702345711, -0.30000000000000004, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.3137179520499165, -0.30000000000000004, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.4663658145259877, -0.30000000000000004, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test063()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data063)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data063[i].k), Tp(data063[i].nu),
+		     Tp(data063[i].phi));
+	const Tp f0 = data063[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004, nu=0.29999999999999999.
+testcase_ellint_3<double> data064[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17408628437042842, -0.30000000000000004, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34561356761638401, -0.30000000000000004, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51257058617875850, -0.30000000000000004, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.67382207124602878, -0.30000000000000004, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.82914751587825131, -0.30000000000000004, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 0.97907434814374938, -0.30000000000000004, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1246399297351584, -0.30000000000000004, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.2671793970398149, -0.30000000000000004, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.4081767433479091, -0.30000000000000004, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test064()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data064)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data064[i].k), Tp(data064[i].nu),
+		     Tp(data064[i].phi));
+	const Tp f0 = data064[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004, nu=0.40000000000000002.
+testcase_ellint_3<double> data065[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17391220945982727, -0.30000000000000004, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34429133937639689, -0.30000000000000004, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.50845471668581632, -0.30000000000000004, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.66502347027873854, -0.30000000000000004, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.81389191978012254, -0.30000000000000004, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.95590618002140570, -0.30000000000000004, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.0924915195213121, -0.30000000000000004, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2253651604038061, -0.30000000000000004, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.3563643538969763, -0.30000000000000004, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test065()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data065)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data065[i].k), Tp(data065[i].nu),
+		     Tp(data065[i].phi));
+	const Tp f0 = data065[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004, nu=0.50000000000000000.
+testcase_ellint_3<double> data066[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17373875742088232, -0.30000000000000004, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34298690571124157, -0.30000000000000004, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50445214859646936, -0.30000000000000004, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.65660648352418516, -0.30000000000000004, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.79953670639287289, -0.30000000000000004, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.93443393926588536, -0.30000000000000004, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0630838369016911, -0.30000000000000004, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.1875197325653029, -0.30000000000000004, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.3098448759814962, -0.30000000000000004, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test066()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data066)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data066[i].k), Tp(data066[i].nu),
+		     Tp(data066[i].phi));
+	const Tp f0 = data066[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004, nu=0.59999999999999998.
+testcase_ellint_3<double> data067[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17356592428950823, -0.30000000000000004, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34169984536697379, -0.30000000000000004, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.50055748266498457, -0.30000000000000004, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.64854298527106768, -0.30000000000000004, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.78599329284207431, -0.30000000000000004, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.91445452089128199, -0.30000000000000004, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0360412952290587, -0.30000000000000004, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1530473919778641, -0.30000000000000004, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.2677758800420669, -0.30000000000000004, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test067()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data067)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data067[i].k), Tp(data067[i].nu),
+		     Tp(data067[i].phi));
+	const Tp f0 = data067[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004, nu=0.69999999999999996.
+testcase_ellint_3<double> data068[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17339370613812224, -0.30000000000000004, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34042975138455933, -0.30000000000000004, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.49676568368075985, -0.30000000000000004, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.64080774055753720, -0.30000000000000004, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.77318507779667278, -0.30000000000000004, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.89579782346548609, -0.30000000000000004, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0110573286052202, -0.30000000000000004, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1214710972949635, -0.30000000000000004, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2294913236274982, -0.30000000000000004, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test068()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data068)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data068[i].k), Tp(data068[i].nu),
+		     Tp(data068[i].phi));
+	const Tp f0 = data068[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004, nu=0.80000000000000004.
+testcase_ellint_3<double> data069[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17322209907520358, -0.30000000000000004, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.33917623046949996, -0.30000000000000004, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49307204894329176, -0.30000000000000004, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.63337802830291734, -0.30000000000000004, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.76104540997689407, -0.30000000000000004, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.87832009635450714, -0.30000000000000004, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 0.98787879723171790, -0.30000000000000004, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.0924036340069339, -0.30000000000000004, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.1944567571590048, -0.30000000000000004, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test069()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data069)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data069[i].k), Tp(data069[i].nu),
+		     Tp(data069[i].phi));
+	const Tp f0 = data069[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.30000000000000004, nu=0.90000000000000002.
+testcase_ellint_3<double> data070[] = {
+  { 0.0000000000000000, -0.30000000000000004, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17305109924485945, -0.30000000000000004, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33793890239556984, -0.30000000000000004, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.48947218005089738, -0.30000000000000004, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.62623332340775151, -0.30000000000000004, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.74951596581511148, -0.30000000000000004, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.86189886597755994, -0.30000000000000004, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.96629451153092005, -0.30000000000000004, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.0655269133492682, -0.30000000000000004, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.1622376896064914, -0.30000000000000004, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.30000000000000004, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test070()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data070)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data070[i].k), Tp(data070[i].nu),
+		     Tp(data070[i].phi));
+	const Tp f0 = data070[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996, nu=0.0000000000000000.
+testcase_ellint_3<double> data071[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17456817290292809, -0.19999999999999996, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.34934315932086801, -0.19999999999999996, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52450880529443988, -0.19999999999999996, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.70020491009844876, -0.19999999999999996, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.87651006649967955, -0.19999999999999996, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0534305870298994, -0.19999999999999996, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2308975521670784, -0.19999999999999996, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.4087733584990738, -0.19999999999999996, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.5868678474541660, -0.19999999999999996, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test071()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data071)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data071[i].k), Tp(data071[i].nu),
+		     Tp(data071[i].phi));
+	const Tp f0 = data071[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996, nu=0.10000000000000001.
+testcase_ellint_3<double> data072[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17439228502691748, -0.19999999999999996, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34796731137565740, -0.19999999999999996, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.52003370294544848, -0.19999999999999996, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.69012222258631462, -0.19999999999999996, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.85803491465566772, -0.19999999999999996, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0238463961099364, -0.19999999999999996, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.1878691059202153, -0.19999999999999996, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.3505985031831940, -0.19999999999999996, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.5126513474261087, -0.19999999999999996, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test072()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data072)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data072[i].k), Tp(data072[i].nu),
+		     Tp(data072[i].phi));
+	const Tp f0 = data072[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996, nu=0.20000000000000001.
+testcase_ellint_3<double> data073[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17421703179583747, -0.19999999999999996, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34661057411998791, -0.19999999999999996, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.51569006052647393, -0.19999999999999996, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.68052412821107244, -0.19999999999999996, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.84081341263313825, -0.19999999999999996, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 0.99683359988842890, -0.19999999999999996, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1493086715118852, -0.19999999999999996, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.2992699693957541, -0.19999999999999996, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.4479323932249564, -0.19999999999999996, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test073()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data073)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data073[i].k), Tp(data073[i].nu),
+		     Tp(data073[i].phi));
+	const Tp f0 = data073[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996, nu=0.29999999999999999.
+testcase_ellint_3<double> data074[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17404240913577704, -0.19999999999999996, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34527248032587193, -0.19999999999999996, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51147118981668416, -0.19999999999999996, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.67137107867777601, -0.19999999999999996, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.82470418188668893, -0.19999999999999996, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 0.97202873223594299, -0.19999999999999996, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1144773569375266, -0.19999999999999996, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.2535292433701000, -0.19999999999999996, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.3908453514752477, -0.19999999999999996, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test074()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data074)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data074[i].k), Tp(data074[i].nu),
+		     Tp(data074[i].phi));
+	const Tp f0 = data074[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996, nu=0.40000000000000002.
+testcase_ellint_3<double> data075[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17386841301066674, -0.19999999999999996, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34395257914113253, -0.19999999999999996, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.50737088376869466, -0.19999999999999996, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.66262801717277631, -0.19999999999999996, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.80958766645079094, -0.19999999999999996, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.94913754236162040, -0.19999999999999996, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.0827985514222997, -0.19999999999999996, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2124212429050478, -0.19999999999999996, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.3400002519661005, -0.19999999999999996, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test075()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data075)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data075[i].k), Tp(data075[i].nu),
+		     Tp(data075[i].phi));
+	const Tp f0 = data075[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996, nu=0.50000000000000000.
+testcase_ellint_3<double> data076[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17369503942181799, -0.19999999999999996, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34265043534362660, -0.19999999999999996, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50338337208655415, -0.19999999999999996, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.65426373297163609, -0.19999999999999996, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.79536193036145808, -0.19999999999999996, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.92791875910061605, -0.19999999999999996, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0538145052725829, -0.19999999999999996, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.1752060022875899, -0.19999999999999996, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.2943374404397372, -0.19999999999999996, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test076()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data076)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data076[i].k), Tp(data076[i].nu),
+		     Tp(data076[i].phi));
+	const Tp f0 = data076[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996, nu=0.59999999999999998.
+testcase_ellint_3<double> data077[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17352228440746925, -0.19999999999999996, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34136562863713626, -0.19999999999999996, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.49950328177638481, -0.19999999999999996, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.64625032705690799, -0.19999999999999996, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.78193941198403083, -0.19999999999999996, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.90817230934317128, -0.19999999999999996, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0271563751276462, -0.19999999999999996, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1412999379040518, -0.19999999999999996, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.2530330675914556, -0.19999999999999996, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test077()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data077)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data077[i].k), Tp(data077[i].nu),
+		     Tp(data077[i].phi));
+	const Tp f0 = data077[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996, nu=0.69999999999999996.
+testcase_ellint_3<double> data078[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17335014404233895, -0.19999999999999996, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34009775298617811, -0.19999999999999996, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.49572560201923810, -0.19999999999999996, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.63856276669886503, -0.19999999999999996, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.76924438644867565, -0.19999999999999996, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.88973060843856466, -0.19999999999999996, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0025230471636377, -0.19999999999999996, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1102356376093103, -0.19999999999999996, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2154356555075863, -0.19999999999999996, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test078()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data078)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data078[i].k), Tp(data078[i].nu),
+		     Tp(data078[i].phi));
+	const Tp f0 = data078[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996, nu=0.80000000000000004.
+testcase_ellint_3<double> data079[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17317861443718538, -0.19999999999999996, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.33884641598718701, -0.19999999999999996, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49204565281259494, -0.19999999999999996, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.63117851188220320, -0.19999999999999996, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.75721095949544170, -0.19999999999999996, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.87245201443919118, -0.19999999999999996, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 0.97966584238831089, -0.19999999999999996, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.0816336325174360, -0.19999999999999996, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.1810223448909909, -0.19999999999999996, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test079()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data079)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data079[i].k), Tp(data079[i].nu),
+		     Tp(data079[i].phi));
+	const Tp f0 = data079[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.19999999999999996, nu=0.90000000000000002.
+testcase_ellint_3<double> data080[] = {
+  { 0.0000000000000000, -0.19999999999999996, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17300769173837277, -0.19999999999999996, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33761123827372508, -0.19999999999999996, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.48845905690769426, -0.19999999999999996, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.62407720017324952, -0.19999999999999996, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.74578146525124289, -0.19999999999999996, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.85621583540073076, -0.19999999999999996, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.95837725988001199, -0.19999999999999996, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.0551821412633928, -0.19999999999999996, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.1493679916141861, -0.19999999999999996, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.19999999999999996, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test080()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data080)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data080[i].k), Tp(data080[i].nu),
+		     Tp(data080[i].phi));
+	const Tp f0 = data080[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978, nu=0.0000000000000000.
+testcase_ellint_3<double> data081[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17454173353063659, -0.099999999999999978, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.34913506721468091, -0.099999999999999978, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52382550016538942, -0.099999999999999978, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.69864700854177020, -0.099999999999999978, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.87361792586964870, -0.099999999999999978, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0487386319621683, -0.099999999999999978, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2239913752078757, -0.099999999999999978, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.3993423113684049, -0.099999999999999978, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.5747455615173562, -0.099999999999999978, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test081()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data081)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data081[i].k), Tp(data081[i].nu),
+		     Tp(data081[i].phi));
+	const Tp f0 = data081[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978, nu=0.10000000000000001.
+testcase_ellint_3<double> data082[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17436589347616613, -0.099999999999999978, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34776067871237359, -0.099999999999999978, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.51936064354727796, -0.099999999999999978, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.68860303749364349, -0.099999999999999978, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.85524561882332051, -0.099999999999999978, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0193708301908335, -0.099999999999999978, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.1813474067123044, -0.099999999999999978, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.3417670770424983, -0.099999999999999978, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.5013711111199950, -0.099999999999999978, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test082()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data082)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data082[i].k), Tp(data082[i].nu),
+		     Tp(data082[i].phi));
+	const Tp f0 = data082[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978, nu=0.20000000000000001.
+testcase_ellint_3<double> data083[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17419068786141340, -0.099999999999999978, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34640537686230133, -0.099999999999999978, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.51502689171753946, -0.099999999999999978, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.67904147863672715, -0.099999999999999978, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.83811885126105179, -0.099999999999999978, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 0.99255278555742787, -0.099999999999999978, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1431260546194930, -0.099999999999999978, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.2909589656532101, -0.099999999999999978, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.4373749386463430, -0.099999999999999978, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test083()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data083)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data083[i].k), Tp(data083[i].nu),
+		     Tp(data083[i].phi));
+	const Tp f0 = data083[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978, nu=0.29999999999999999.
+testcase_ellint_3<double> data084[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17401611261390104, -0.099999999999999978, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34506869507511773, -0.099999999999999978, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51081757604259859, -0.099999999999999978, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.66992297597712303, -0.099999999999999978, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.82209722856174228, -0.099999999999999978, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 0.96792430487669590, -0.099999999999999978, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1085964108954092, -0.099999999999999978, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.2456748370836999, -0.099999999999999978, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.3809159606704959, -0.099999999999999978, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test084()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data084)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data084[i].k), Tp(data084[i].nu),
+		     Tp(data084[i].phi));
+	const Tp f0 = data084[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978, nu=0.40000000000000002.
+testcase_ellint_3<double> data085[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17384216369897931, -0.099999999999999978, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34375018311376787, -0.099999999999999978, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.50672650758380455, -0.099999999999999978, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.66121264213337616, -0.099999999999999978, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.80706202005774441, -0.099999999999999978, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.94519376138245870, -0.099999999999999978, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.0771880300759584, -0.099999999999999978, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2049711557188272, -0.099999999999999978, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.3306223265207477, -0.099999999999999978, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test085()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data085)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data085[i].k), Tp(data085[i].nu),
+		     Tp(data085[i].phi));
+	const Tp f0 = data085[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978, nu=0.50000000000000000.
+testcase_ellint_3<double> data086[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17366883711936548, -0.099999999999999978, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34244940634881882, -0.099999999999999978, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50274793281634367, -0.099999999999999978, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.65287941633275082, -0.099999999999999978, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.79291198790315398, -0.099999999999999978, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.92412201537880323, -0.099999999999999978, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0484480076799372, -0.099999999999999978, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.1681168130475206, -0.099999999999999978, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.2854480708580160, -0.099999999999999978, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test086()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data086)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data086[i].k), Tp(data086[i].nu),
+		     Tp(data086[i].phi));
+	const Tp f0 = data086[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978, nu=0.59999999999999998.
+testcase_ellint_3<double> data087[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17349612891469013, -0.099999999999999978, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34116594505539444, -0.099999999999999978, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.49887649430466674, -0.099999999999999978, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.64489553282165146, -0.099999999999999978, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.77956016553782437, -0.099999999999999978, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.90451074530096287, -0.099999999999999978, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0220113666961632, -0.099999999999999978, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1345351441065563, -0.099999999999999978, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.2445798942989255, -0.099999999999999978, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test087()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data087)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data087[i].k), Tp(data087[i].nu),
+		     Tp(data087[i].phi));
+	const Tp f0 = data087[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978, nu=0.69999999999999996.
+testcase_ellint_3<double> data088[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17332403516105047, -0.099999999999999978, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.33989939374896883, -0.099999999999999978, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.49510719568614070, -0.099999999999999978, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.63723607776354974, -0.099999999999999978, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.76693133887935327, -0.099999999999999978, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.88619382078823805, -0.099999999999999978, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 0.99758012018676490, -0.099999999999999978, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1037642270814410, -0.099999999999999978, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2073745911083185, -0.099999999999999978, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test088()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data088)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data088[i].k), Tp(data088[i].nu),
+		     Tp(data088[i].phi));
+	const Tp f0 = data088[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978, nu=0.80000000000000004.
+testcase_ellint_3<double> data089[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17315255197057014, -0.099999999999999978, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.33864936055747991, -0.099999999999999978, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49143537041117613, -0.099999999999999978, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.62987861760047492, -0.099999999999999978, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.75496005490917517, -0.099999999999999978, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.86903081862701881, -0.099999999999999978, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 0.97490814820725591, -0.099999999999999978, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.0754290107171083, -0.099999999999999978, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.1733158866987732, -0.099999999999999978, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test089()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data089)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data089[i].k), Tp(data089[i].nu),
+		     Tp(data089[i].phi));
+	const Tp f0 = data089[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=-0.099999999999999978, nu=0.90000000000000002.
+testcase_ellint_3<double> data090[] = {
+  { 0.0000000000000000, -0.099999999999999978, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17298167549096563, -0.099999999999999978, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33741546662741589, -0.099999999999999978, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.48785665376856868, -0.099999999999999978, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.62280288554518959, -0.099999999999999978, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.74358903115455188, -0.099999999999999978, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.85290207679298335, -0.099999999999999978, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.95379006645397379, -0.099999999999999978, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.0492213119872327, -0.099999999999999978, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.1419839485283374, -0.099999999999999978, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=-0.099999999999999978, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test090()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data090)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data090[i].k), Tp(data090[i].nu),
+		     Tp(data090[i].phi));
+	const Tp f0 = data090[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000, nu=0.0000000000000000.
+testcase_ellint_3<double> data091[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17453292519943292, 0.0000000000000000, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.34906585039886584, 0.0000000000000000, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52359877559829870, 0.0000000000000000, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.69813170079773168, 0.0000000000000000, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.87266462599716477, 0.0000000000000000, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0471975511965974, 0.0000000000000000, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2217304763960304, 0.0000000000000000, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.3962634015954631, 0.0000000000000000, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.5707963267948966, 0.0000000000000000, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test091()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data091)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data091[i].k), Tp(data091[i].nu),
+		     Tp(data091[i].phi));
+	const Tp f0 = data091[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000, nu=0.10000000000000001.
+testcase_ellint_3<double> data092[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17435710107516605, 0.0000000000000000, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34769194715329604, 0.0000000000000000, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.51913731575866107, 0.0000000000000000, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.68810051897078450, 0.0000000000000000, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.85432615661706823, 0.0000000000000000, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0179006647340794, 0.0000000000000000, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.1792120640746322, 0.0000000000000000, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.3388834245070498, 0.0000000000000000, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.4976955329233277, 0.0000000000000000, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test092()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data092)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data092[i].k), Tp(data092[i].nu),
+		     Tp(data092[i].phi));
+	const Tp f0 = data092[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000, nu=0.20000000000000001.
+testcase_ellint_3<double> data093[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17418191132226074, 0.0000000000000000, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34633712256943405, 0.0000000000000000, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.51480684302043700, 0.0000000000000000, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.67855102942481937, 0.0000000000000000, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.83723056090326253, 0.0000000000000000, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 0.99114645269578161, 0.0000000000000000, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1411014627915537, 0.0000000000000000, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.2882448138013969, 0.0000000000000000, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.4339343023863691, 0.0000000000000000, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test093()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data093)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data093[i].k), Tp(data093[i].nu),
+		     Tp(data093[i].phi));
+	const Tp f0 = data093[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000, nu=0.29999999999999999.
+testcase_ellint_3<double> data094[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17400735186871724, 0.0000000000000000, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34500091027020219, 0.0000000000000000, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51060069523901530, 0.0000000000000000, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.66944393961375448, 0.0000000000000000, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.82123776744538157, 0.0000000000000000, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 0.96657579245516501, 0.0000000000000000, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1066703663542414, 0.0000000000000000, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.2431094251944901, 0.0000000000000000, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.3776795151134889, 0.0000000000000000, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test094()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data094)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data094[i].k), Tp(data094[i].nu),
+		     Tp(data094[i].phi));
+	const Tp f0 = data094[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000, nu=0.40000000000000002.
+testcase_ellint_3<double> data095[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17383341868035862, 0.0000000000000000, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34368286022299821, 0.0000000000000000, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.50651268947499395, 0.0000000000000000, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.66074441806097539, 0.0000000000000000, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.80622931670113474, 0.0000000000000000, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.94389791565435210, 0.0000000000000000, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.0753503387899728, 0.0000000000000000, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2025374759127518, 0.0000000000000000, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.3275651989026320, 0.0000000000000000, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test095()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data095)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data095[i].k), Tp(data095[i].nu),
+		     Tp(data095[i].phi));
+	const Tp f0 = data095[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000, nu=0.50000000000000000.
+testcase_ellint_3<double> data096[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17366010776037044, 0.0000000000000000, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34238253799539309, 0.0000000000000000, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50253707775976397, 0.0000000000000000, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.65242145347295766, 0.0000000000000000, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.79210420018698058, 0.0000000000000000, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.92287437995632171, 0.0000000000000000, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0466900550798659, 0.0000000000000000, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.1658007366618623, 0.0000000000000000, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.2825498301618641, 0.0000000000000000, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test096()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data096)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data096[i].k), Tp(data096[i].nu),
+		     Tp(data096[i].phi));
+	const Tp f0 = data096[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000, nu=0.59999999999999998.
+testcase_ellint_3<double> data097[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17348741514884700, 0.0000000000000000, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34109952405241289, 0.0000000000000000, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.49866850781226285, 0.0000000000000000, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.64444732407062499, 0.0000000000000000, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.77877564686544720, 0.0000000000000000, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.90330743691883475, 0.0000000000000000, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0203257987604104, 0.0000000000000000, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1323247918768629, 0.0000000000000000, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.2418235332245127, 0.0000000000000000, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test097()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data097)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data097[i].k), Tp(data097[i].nu),
+		     Tp(data097[i].phi));
+	const Tp f0 = data097[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000, nu=0.69999999999999996.
+testcase_ellint_3<double> data098[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17331533692234474, 0.0000000000000000, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.33983341309265935, 0.0000000000000000, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.49490198805931979, 0.0000000000000000, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.63679715525145297, 0.0000000000000000, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.76616861049481944, 0.0000000000000000, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.88503143209004198, 0.0000000000000000, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 0.99596060249112173, 0.0000000000000000, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1016495050260424, 0.0000000000000000, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2047457872617382, 0.0000000000000000, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test098()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data098)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data098[i].k), Tp(data098[i].nu),
+		     Tp(data098[i].phi));
+	const Tp f0 = data098[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000, nu=0.80000000000000004.
+testcase_ellint_3<double> data099[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17314386919344210, 0.0000000000000000, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.33858381342073240, 0.0000000000000000, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49123285640844727, 0.0000000000000000, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.62944854858904509, 0.0000000000000000, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.75421778305499343, 0.0000000000000000, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.86790634112156617, 0.0000000000000000, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 0.97334918087427558, 0.0000000000000000, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.0734012615283985, 0.0000000000000000, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.1708024551734544, 0.0000000000000000, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test099()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data099)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data099[i].k), Tp(data099[i].nu),
+		     Tp(data099[i].phi));
+	const Tp f0 = data099[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.0000000000000000, nu=0.90000000000000002.
+testcase_ellint_3<double> data100[] = {
+  { 0.0000000000000000, 0.0000000000000000, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17297300811030597, 0.0000000000000000, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33735034635360817, 0.0000000000000000, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.48765675230233130, 0.0000000000000000, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.62238126886123568, 0.0000000000000000, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.74286600807269243, 0.0000000000000000, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.85181283909264949, 0.0000000000000000, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.95228683995371133, 0.0000000000000000, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.0472730487412552, 0.0000000000000000, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.1395754288497419, 0.0000000000000000, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.0000000000000000, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test100()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data100)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data100[i].k), Tp(data100[i].nu),
+		     Tp(data100[i].phi));
+	const Tp f0 = data100[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009, nu=0.0000000000000000.
+testcase_ellint_3<double> data101[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17454173353063659, 0.10000000000000009, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.34913506721468091, 0.10000000000000009, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52382550016538942, 0.10000000000000009, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.69864700854177020, 0.10000000000000009, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.87361792586964870, 0.10000000000000009, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0487386319621683, 0.10000000000000009, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2239913752078757, 0.10000000000000009, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.3993423113684049, 0.10000000000000009, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.5747455615173562, 0.10000000000000009, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test101()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data101)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data101[i].k), Tp(data101[i].nu),
+		     Tp(data101[i].phi));
+	const Tp f0 = data101[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009, nu=0.10000000000000001.
+testcase_ellint_3<double> data102[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17436589347616613, 0.10000000000000009, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34776067871237359, 0.10000000000000009, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.51936064354727796, 0.10000000000000009, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.68860303749364349, 0.10000000000000009, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.85524561882332051, 0.10000000000000009, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0193708301908335, 0.10000000000000009, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.1813474067123044, 0.10000000000000009, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.3417670770424983, 0.10000000000000009, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.5013711111199950, 0.10000000000000009, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test102()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data102)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data102[i].k), Tp(data102[i].nu),
+		     Tp(data102[i].phi));
+	const Tp f0 = data102[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009, nu=0.20000000000000001.
+testcase_ellint_3<double> data103[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17419068786141340, 0.10000000000000009, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34640537686230133, 0.10000000000000009, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.51502689171753946, 0.10000000000000009, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.67904147863672715, 0.10000000000000009, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.83811885126105179, 0.10000000000000009, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 0.99255278555742787, 0.10000000000000009, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1431260546194930, 0.10000000000000009, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.2909589656532101, 0.10000000000000009, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.4373749386463430, 0.10000000000000009, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test103()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data103)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data103[i].k), Tp(data103[i].nu),
+		     Tp(data103[i].phi));
+	const Tp f0 = data103[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009, nu=0.29999999999999999.
+testcase_ellint_3<double> data104[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17401611261390104, 0.10000000000000009, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34506869507511773, 0.10000000000000009, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51081757604259859, 0.10000000000000009, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.66992297597712303, 0.10000000000000009, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.82209722856174228, 0.10000000000000009, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 0.96792430487669590, 0.10000000000000009, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1085964108954092, 0.10000000000000009, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.2456748370836999, 0.10000000000000009, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.3809159606704959, 0.10000000000000009, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test104()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data104)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data104[i].k), Tp(data104[i].nu),
+		     Tp(data104[i].phi));
+	const Tp f0 = data104[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009, nu=0.40000000000000002.
+testcase_ellint_3<double> data105[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17384216369897931, 0.10000000000000009, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34375018311376787, 0.10000000000000009, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.50672650758380455, 0.10000000000000009, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.66121264213337616, 0.10000000000000009, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.80706202005774441, 0.10000000000000009, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.94519376138245870, 0.10000000000000009, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.0771880300759584, 0.10000000000000009, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2049711557188272, 0.10000000000000009, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.3306223265207477, 0.10000000000000009, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test105()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data105)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data105[i].k), Tp(data105[i].nu),
+		     Tp(data105[i].phi));
+	const Tp f0 = data105[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009, nu=0.50000000000000000.
+testcase_ellint_3<double> data106[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17366883711936548, 0.10000000000000009, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34244940634881882, 0.10000000000000009, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50274793281634367, 0.10000000000000009, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.65287941633275082, 0.10000000000000009, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.79291198790315398, 0.10000000000000009, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.92412201537880323, 0.10000000000000009, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0484480076799372, 0.10000000000000009, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.1681168130475206, 0.10000000000000009, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.2854480708580160, 0.10000000000000009, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test106()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data106)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data106[i].k), Tp(data106[i].nu),
+		     Tp(data106[i].phi));
+	const Tp f0 = data106[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009, nu=0.59999999999999998.
+testcase_ellint_3<double> data107[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17349612891469013, 0.10000000000000009, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34116594505539444, 0.10000000000000009, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.49887649430466674, 0.10000000000000009, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.64489553282165146, 0.10000000000000009, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.77956016553782437, 0.10000000000000009, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.90451074530096287, 0.10000000000000009, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0220113666961632, 0.10000000000000009, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1345351441065563, 0.10000000000000009, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.2445798942989255, 0.10000000000000009, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test107()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data107)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data107[i].k), Tp(data107[i].nu),
+		     Tp(data107[i].phi));
+	const Tp f0 = data107[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009, nu=0.69999999999999996.
+testcase_ellint_3<double> data108[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17332403516105047, 0.10000000000000009, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.33989939374896883, 0.10000000000000009, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.49510719568614070, 0.10000000000000009, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.63723607776354974, 0.10000000000000009, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.76693133887935327, 0.10000000000000009, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.88619382078823805, 0.10000000000000009, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 0.99758012018676490, 0.10000000000000009, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1037642270814410, 0.10000000000000009, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2073745911083185, 0.10000000000000009, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test108()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data108)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data108[i].k), Tp(data108[i].nu),
+		     Tp(data108[i].phi));
+	const Tp f0 = data108[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009, nu=0.80000000000000004.
+testcase_ellint_3<double> data109[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17315255197057014, 0.10000000000000009, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.33864936055747991, 0.10000000000000009, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49143537041117613, 0.10000000000000009, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.62987861760047492, 0.10000000000000009, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.75496005490917517, 0.10000000000000009, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.86903081862701881, 0.10000000000000009, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 0.97490814820725591, 0.10000000000000009, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.0754290107171083, 0.10000000000000009, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.1733158866987732, 0.10000000000000009, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test109()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data109)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data109[i].k), Tp(data109[i].nu),
+		     Tp(data109[i].phi));
+	const Tp f0 = data109[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.10000000000000009, nu=0.90000000000000002.
+testcase_ellint_3<double> data110[] = {
+  { 0.0000000000000000, 0.10000000000000009, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17298167549096563, 0.10000000000000009, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33741546662741589, 0.10000000000000009, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.48785665376856868, 0.10000000000000009, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.62280288554518959, 0.10000000000000009, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.74358903115455188, 0.10000000000000009, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.85290207679298335, 0.10000000000000009, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.95379006645397379, 0.10000000000000009, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.0492213119872327, 0.10000000000000009, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.1419839485283374, 0.10000000000000009, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.10000000000000009, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test110()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data110)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data110[i].k), Tp(data110[i].nu),
+		     Tp(data110[i].phi));
+	const Tp f0 = data110[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996, nu=0.0000000000000000.
+testcase_ellint_3<double> data111[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17456817290292809, 0.19999999999999996, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.34934315932086801, 0.19999999999999996, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52450880529443988, 0.19999999999999996, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.70020491009844876, 0.19999999999999996, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.87651006649967955, 0.19999999999999996, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0534305870298994, 0.19999999999999996, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2308975521670784, 0.19999999999999996, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.4087733584990738, 0.19999999999999996, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.5868678474541660, 0.19999999999999996, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test111()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data111)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data111[i].k), Tp(data111[i].nu),
+		     Tp(data111[i].phi));
+	const Tp f0 = data111[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996, nu=0.10000000000000001.
+testcase_ellint_3<double> data112[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17439228502691748, 0.19999999999999996, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34796731137565740, 0.19999999999999996, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.52003370294544848, 0.19999999999999996, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.69012222258631462, 0.19999999999999996, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.85803491465566772, 0.19999999999999996, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0238463961099364, 0.19999999999999996, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.1878691059202153, 0.19999999999999996, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.3505985031831940, 0.19999999999999996, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.5126513474261087, 0.19999999999999996, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test112()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data112)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data112[i].k), Tp(data112[i].nu),
+		     Tp(data112[i].phi));
+	const Tp f0 = data112[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996, nu=0.20000000000000001.
+testcase_ellint_3<double> data113[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17421703179583747, 0.19999999999999996, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34661057411998791, 0.19999999999999996, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.51569006052647393, 0.19999999999999996, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.68052412821107244, 0.19999999999999996, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.84081341263313825, 0.19999999999999996, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 0.99683359988842890, 0.19999999999999996, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1493086715118852, 0.19999999999999996, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.2992699693957541, 0.19999999999999996, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.4479323932249564, 0.19999999999999996, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test113()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data113)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data113[i].k), Tp(data113[i].nu),
+		     Tp(data113[i].phi));
+	const Tp f0 = data113[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996, nu=0.29999999999999999.
+testcase_ellint_3<double> data114[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17404240913577704, 0.19999999999999996, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34527248032587193, 0.19999999999999996, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51147118981668416, 0.19999999999999996, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.67137107867777601, 0.19999999999999996, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.82470418188668893, 0.19999999999999996, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 0.97202873223594299, 0.19999999999999996, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1144773569375266, 0.19999999999999996, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.2535292433701000, 0.19999999999999996, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.3908453514752477, 0.19999999999999996, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test114()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data114)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data114[i].k), Tp(data114[i].nu),
+		     Tp(data114[i].phi));
+	const Tp f0 = data114[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996, nu=0.40000000000000002.
+testcase_ellint_3<double> data115[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17386841301066674, 0.19999999999999996, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34395257914113253, 0.19999999999999996, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.50737088376869466, 0.19999999999999996, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.66262801717277631, 0.19999999999999996, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.80958766645079094, 0.19999999999999996, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.94913754236162040, 0.19999999999999996, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.0827985514222997, 0.19999999999999996, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2124212429050478, 0.19999999999999996, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.3400002519661005, 0.19999999999999996, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test115()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data115)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data115[i].k), Tp(data115[i].nu),
+		     Tp(data115[i].phi));
+	const Tp f0 = data115[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996, nu=0.50000000000000000.
+testcase_ellint_3<double> data116[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17369503942181799, 0.19999999999999996, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34265043534362660, 0.19999999999999996, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50338337208655415, 0.19999999999999996, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.65426373297163609, 0.19999999999999996, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.79536193036145808, 0.19999999999999996, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.92791875910061605, 0.19999999999999996, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0538145052725829, 0.19999999999999996, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.1752060022875899, 0.19999999999999996, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.2943374404397372, 0.19999999999999996, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test116()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data116)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data116[i].k), Tp(data116[i].nu),
+		     Tp(data116[i].phi));
+	const Tp f0 = data116[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996, nu=0.59999999999999998.
+testcase_ellint_3<double> data117[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17352228440746925, 0.19999999999999996, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34136562863713626, 0.19999999999999996, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.49950328177638481, 0.19999999999999996, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.64625032705690799, 0.19999999999999996, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.78193941198403083, 0.19999999999999996, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.90817230934317128, 0.19999999999999996, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0271563751276462, 0.19999999999999996, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1412999379040518, 0.19999999999999996, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.2530330675914556, 0.19999999999999996, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test117()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data117)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data117[i].k), Tp(data117[i].nu),
+		     Tp(data117[i].phi));
+	const Tp f0 = data117[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996, nu=0.69999999999999996.
+testcase_ellint_3<double> data118[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17335014404233895, 0.19999999999999996, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34009775298617811, 0.19999999999999996, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.49572560201923810, 0.19999999999999996, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.63856276669886503, 0.19999999999999996, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.76924438644867565, 0.19999999999999996, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.88973060843856466, 0.19999999999999996, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0025230471636377, 0.19999999999999996, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1102356376093103, 0.19999999999999996, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2154356555075863, 0.19999999999999996, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test118()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data118)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data118[i].k), Tp(data118[i].nu),
+		     Tp(data118[i].phi));
+	const Tp f0 = data118[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996, nu=0.80000000000000004.
+testcase_ellint_3<double> data119[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17317861443718538, 0.19999999999999996, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.33884641598718701, 0.19999999999999996, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49204565281259494, 0.19999999999999996, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.63117851188220320, 0.19999999999999996, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.75721095949544170, 0.19999999999999996, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.87245201443919118, 0.19999999999999996, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 0.97966584238831089, 0.19999999999999996, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.0816336325174360, 0.19999999999999996, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.1810223448909909, 0.19999999999999996, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test119()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data119)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data119[i].k), Tp(data119[i].nu),
+		     Tp(data119[i].phi));
+	const Tp f0 = data119[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.19999999999999996, nu=0.90000000000000002.
+testcase_ellint_3<double> data120[] = {
+  { 0.0000000000000000, 0.19999999999999996, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17300769173837277, 0.19999999999999996, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33761123827372508, 0.19999999999999996, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.48845905690769426, 0.19999999999999996, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.62407720017324952, 0.19999999999999996, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.74578146525124289, 0.19999999999999996, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.85621583540073076, 0.19999999999999996, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.95837725988001199, 0.19999999999999996, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.0551821412633928, 0.19999999999999996, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.1493679916141861, 0.19999999999999996, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.19999999999999996, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test120()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data120)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data120[i].k), Tp(data120[i].nu),
+		     Tp(data120[i].phi));
+	const Tp f0 = data120[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004, nu=0.0000000000000000.
+testcase_ellint_3<double> data121[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17461228653000099, 0.30000000000000004, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.34969146102798415, 0.30000000000000004, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52565822873726320, 0.30000000000000004, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.70284226512408532, 0.30000000000000004, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.88144139195111182, 0.30000000000000004, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0614897067260520, 0.30000000000000004, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2428416824174218, 0.30000000000000004, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.4251795877015927, 0.30000000000000004, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.6080486199305128, 0.30000000000000004, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test121()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data121)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data121[i].k), Tp(data121[i].nu),
+		     Tp(data121[i].phi));
+	const Tp f0 = data121[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004, nu=0.10000000000000001.
+testcase_ellint_3<double> data122[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17443631884814376, 0.30000000000000004, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34831316835124926, 0.30000000000000004, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.52116586276523857, 0.30000000000000004, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.69269385837910036, 0.30000000000000004, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.86279023163070856, 0.30000000000000004, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0315321461438263, 0.30000000000000004, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.1991449111869024, 0.30000000000000004, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.3659561780923213, 0.30000000000000004, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.5323534693557528, 0.30000000000000004, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test122()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data122)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data122[i].k), Tp(data122[i].nu),
+		     Tp(data122[i].phi));
+	const Tp f0 = data122[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004, nu=0.20000000000000001.
+testcase_ellint_3<double> data123[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17426098615372088, 0.30000000000000004, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34695402664689923, 0.30000000000000004, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.51680555567038933, 0.30000000000000004, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.68303375225260210, 0.30000000000000004, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.84540662891295026, 0.30000000000000004, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.0041834051646927, 0.30000000000000004, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1599952702345711, 0.30000000000000004, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.3137179520499165, 0.30000000000000004, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.4663658145259877, 0.30000000000000004, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test123()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data123)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data123[i].k), Tp(data123[i].nu),
+		     Tp(data123[i].phi));
+	const Tp f0 = data123[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004, nu=0.29999999999999999.
+testcase_ellint_3<double> data124[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17408628437042842, 0.30000000000000004, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34561356761638401, 0.30000000000000004, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51257058617875850, 0.30000000000000004, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.67382207124602878, 0.30000000000000004, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.82914751587825131, 0.30000000000000004, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 0.97907434814374938, 0.30000000000000004, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1246399297351584, 0.30000000000000004, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.2671793970398149, 0.30000000000000004, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.4081767433479091, 0.30000000000000004, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test124()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data124)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data124[i].k), Tp(data124[i].nu),
+		     Tp(data124[i].phi));
+	const Tp f0 = data124[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004, nu=0.40000000000000002.
+testcase_ellint_3<double> data125[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17391220945982727, 0.30000000000000004, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34429133937639689, 0.30000000000000004, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.50845471668581632, 0.30000000000000004, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.66502347027873854, 0.30000000000000004, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.81389191978012254, 0.30000000000000004, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.95590618002140570, 0.30000000000000004, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.0924915195213121, 0.30000000000000004, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2253651604038061, 0.30000000000000004, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.3563643538969763, 0.30000000000000004, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test125()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data125)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data125[i].k), Tp(data125[i].nu),
+		     Tp(data125[i].phi));
+	const Tp f0 = data125[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004, nu=0.50000000000000000.
+testcase_ellint_3<double> data126[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17373875742088232, 0.30000000000000004, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34298690571124157, 0.30000000000000004, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50445214859646936, 0.30000000000000004, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.65660648352418516, 0.30000000000000004, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.79953670639287289, 0.30000000000000004, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.93443393926588536, 0.30000000000000004, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0630838369016911, 0.30000000000000004, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.1875197325653029, 0.30000000000000004, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.3098448759814962, 0.30000000000000004, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test126()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data126)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data126[i].k), Tp(data126[i].nu),
+		     Tp(data126[i].phi));
+	const Tp f0 = data126[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004, nu=0.59999999999999998.
+testcase_ellint_3<double> data127[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17356592428950823, 0.30000000000000004, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34169984536697379, 0.30000000000000004, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.50055748266498457, 0.30000000000000004, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.64854298527106768, 0.30000000000000004, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.78599329284207431, 0.30000000000000004, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.91445452089128199, 0.30000000000000004, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0360412952290587, 0.30000000000000004, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1530473919778641, 0.30000000000000004, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.2677758800420669, 0.30000000000000004, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test127()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data127)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data127[i].k), Tp(data127[i].nu),
+		     Tp(data127[i].phi));
+	const Tp f0 = data127[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004, nu=0.69999999999999996.
+testcase_ellint_3<double> data128[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17339370613812224, 0.30000000000000004, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34042975138455933, 0.30000000000000004, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.49676568368075985, 0.30000000000000004, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.64080774055753720, 0.30000000000000004, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.77318507779667278, 0.30000000000000004, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.89579782346548609, 0.30000000000000004, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0110573286052202, 0.30000000000000004, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1214710972949635, 0.30000000000000004, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2294913236274982, 0.30000000000000004, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test128()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data128)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data128[i].k), Tp(data128[i].nu),
+		     Tp(data128[i].phi));
+	const Tp f0 = data128[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004, nu=0.80000000000000004.
+testcase_ellint_3<double> data129[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17322209907520358, 0.30000000000000004, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.33917623046949996, 0.30000000000000004, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49307204894329176, 0.30000000000000004, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.63337802830291734, 0.30000000000000004, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.76104540997689407, 0.30000000000000004, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.87832009635450714, 0.30000000000000004, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 0.98787879723171790, 0.30000000000000004, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.0924036340069339, 0.30000000000000004, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.1944567571590048, 0.30000000000000004, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test129()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data129)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data129[i].k), Tp(data129[i].nu),
+		     Tp(data129[i].phi));
+	const Tp f0 = data129[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.30000000000000004, nu=0.90000000000000002.
+testcase_ellint_3<double> data130[] = {
+  { 0.0000000000000000, 0.30000000000000004, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17305109924485945, 0.30000000000000004, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33793890239556984, 0.30000000000000004, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.48947218005089738, 0.30000000000000004, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.62623332340775151, 0.30000000000000004, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.74951596581511148, 0.30000000000000004, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.86189886597755994, 0.30000000000000004, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.96629451153092005, 0.30000000000000004, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.0655269133492682, 0.30000000000000004, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.1622376896064914, 0.30000000000000004, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.30000000000000004, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test130()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data130)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data130[i].k), Tp(data130[i].nu),
+		     Tp(data130[i].phi));
+	const Tp f0 = data130[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991, nu=0.0000000000000000.
+testcase_ellint_3<double> data131[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17467414669441528, 0.39999999999999991, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35018222772483443, 0.39999999999999991, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52729015917508737, 0.39999999999999991, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.70662374407341244, 0.39999999999999991, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.88859210497602170, 0.39999999999999991, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0733136290471379, 0.39999999999999991, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2605612170157061, 0.39999999999999991, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.4497513956433439, 0.39999999999999991, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.6399998658645112, 0.39999999999999991, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test131()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data131)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data131[i].k), Tp(data131[i].nu),
+		     Tp(data131[i].phi));
+	const Tp f0 = data131[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991, nu=0.10000000000000001.
+testcase_ellint_3<double> data132[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17449806706684670, 0.39999999999999991, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34880048623856075, 0.39999999999999991, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.52277322065757392, 0.39999999999999991, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.69638072056918365, 0.39999999999999991, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.86968426619831540, 0.39999999999999991, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0428044206578095, 0.39999999999999991, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.2158651158274378, 0.39999999999999991, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.3889447129893324, 0.39999999999999991, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.5620566886683604, 0.39999999999999991, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test132()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data132)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data132[i].k), Tp(data132[i].nu),
+		     Tp(data132[i].phi));
+	const Tp f0 = data132[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991, nu=0.20000000000000001.
+testcase_ellint_3<double> data133[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17432262290723397, 0.39999999999999991, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34743795258968596, 0.39999999999999991, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.51838919472805112, 0.39999999999999991, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.68663134739057907, 0.39999999999999991, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.85206432981833979, 0.39999999999999991, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.0149595349004430, 0.39999999999999991, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1758349405464676, 0.39999999999999991, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.3353337673882637, 0.39999999999999991, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.4941414344266770, 0.39999999999999991, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test133()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data133)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data133[i].k), Tp(data133[i].nu),
+		     Tp(data133[i].phi));
+	const Tp f0 = data133[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991, nu=0.29999999999999999.
+testcase_ellint_3<double> data134[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17414781013591540, 0.39999999999999991, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34609415696777285, 0.39999999999999991, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51413131295862535, 0.39999999999999991, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.67733527622935630, 0.39999999999999991, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.83558675182733266, 0.39999999999999991, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 0.98940140808865906, 0.39999999999999991, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1396968797728058, 0.39999999999999991, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.2875920037865090, 0.39999999999999991, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.4342789859950078, 0.39999999999999991, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test134()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data134)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data134[i].k), Tp(data134[i].nu),
+		     Tp(data134[i].phi));
+	const Tp f0 = data134[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991, nu=0.40000000000000002.
+testcase_ellint_3<double> data135[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17397362471112707, 0.39999999999999991, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34476864603333196, 0.39999999999999991, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.50999329415379346, 0.39999999999999991, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.66845674551396006, 0.39999999999999991, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.82012848346231748, 0.39999999999999991, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.96582449258349057, 0.39999999999999991, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.1068473749476286, 0.39999999999999991, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2447132729159989, 0.39999999999999991, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.3809986210732901, 0.39999999999999991, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test135()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data135)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data135[i].k), Tp(data135[i].nu),
+		     Tp(data135[i].phi));
+	const Tp f0 = data135[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991, nu=0.50000000000000000.
+testcase_ellint_3<double> data136[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17380006262854136, 0.39999999999999991, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34346098216756610, 0.39999999999999991, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50596929935059420, 0.39999999999999991, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.65996392089131251, 0.39999999999999991, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.80558463511364786, 0.39999999999999991, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.94397834522857704, 0.39999999999999991, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0768075114108115, 0.39999999999999991, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.2059184624251333, 0.39999999999999991, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.3331797176377398, 0.39999999999999991, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test136()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data136)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data136[i].k), Tp(data136[i].nu),
+		     Tp(data136[i].phi));
+	const Tp f0 = data136[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991, nu=0.59999999999999998.
+testcase_ellint_3<double> data137[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17362711992081245, 0.39999999999999991, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34217074276403953, 0.39999999999999991, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.50205389185761606, 0.39999999999999991, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.65182834920372734, 0.39999999999999991, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.79186512820565136, 0.39999999999999991, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.92365535916287134, 0.39999999999999991, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0491915663957907, 0.39999999999999991, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1705934291745106, 0.39999999999999991, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.2899514672527024, 0.39999999999999991, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test137()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data137)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data137[i].k), Tp(data137[i].nu),
+		     Tp(data137[i].phi));
+	const Tp f0 = data137[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991, nu=0.69999999999999996.
+testcase_ellint_3<double> data138[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17345479265712868, 0.39999999999999991, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34089751955950354, 0.39999999999999991, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.49824200167361332, 0.39999999999999991, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.64402450341199402, 0.39999999999999991, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.77889207804122873, 0.39999999999999991, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.90468169720957992, 0.39999999999999991, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0236847823692916, 0.39999999999999991, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1382465247425166, 0.39999999999999991, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2506255923253344, 0.39999999999999991, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test138()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data138)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data138[i].k), Tp(data138[i].nu),
+		     Tp(data138[i].phi));
+	const Tp f0 = data138[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991, nu=0.80000000000000004.
+testcase_ellint_3<double> data139[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17328307694277154, 0.39999999999999991, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.33964091800132007, 0.39999999999999991, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49452889372467440, 0.39999999999999991, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.63652940095937316, 0.39999999999999991, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.76659772511159097, 0.39999999999999991, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.88691047977338111, 0.39999999999999991, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.0000273200611638, 0.39999999999999991, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.1084787902188009, 0.39999999999999991, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.2146499565727209, 0.39999999999999991, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test139()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data139)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data139[i].k), Tp(data139[i].nu),
+		     Tp(data139[i].phi));
+	const Tp f0 = data139[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.39999999999999991, nu=0.90000000000000002.
+testcase_ellint_3<double> data140[] = {
+  { 0.0000000000000000, 0.39999999999999991, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17311196891868127, 0.39999999999999991, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33840055664911906, 0.39999999999999991, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.49091013944075329, 0.39999999999999991, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.62932228186809580, 0.39999999999999991, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.75492278323019801, 0.39999999999999991, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.87021659043854294, 0.39999999999999991, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.97800245228239246, 0.39999999999999991, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.0809625773173697, 0.39999999999999991, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.1815758115929846, 0.39999999999999991, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.39999999999999991, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test140()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data140)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data140[i].k), Tp(data140[i].nu),
+		     Tp(data140[i].phi));
+	const Tp f0 = data140[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000, nu=0.0000000000000000.
+testcase_ellint_3<double> data141[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17475385514035785, 0.50000000000000000, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35081868470101585, 0.50000000000000000, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.52942862705190574, 0.50000000000000000, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.71164727562630314, 0.50000000000000000, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.89824523594227768, 0.50000000000000000, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.0895506700518851, 0.50000000000000000, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.2853005857432931, 0.50000000000000000, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.4845545520549484, 0.50000000000000000, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.6857503548125963, 0.50000000000000000, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test141()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data141)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data141[i].k), Tp(data141[i].nu),
+		     Tp(data141[i].phi));
+	const Tp f0 = data141[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000, nu=0.10000000000000001.
+testcase_ellint_3<double> data142[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17457763120814676, 0.50000000000000000, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.34943246340849154, 0.50000000000000000, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.52487937869610790, 0.50000000000000000, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.70127785096388384, 0.50000000000000000, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.87898815988624479, 0.50000000000000000, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0582764576094172, 0.50000000000000000, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.2391936844060205, 0.50000000000000000, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.4214793542995841, 0.50000000000000000, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.6045524936084892, 0.50000000000000000, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test142()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data142)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data142[i].k), Tp(data142[i].nu),
+		     Tp(data142[i].phi));
+	const Tp f0 = data142[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000, nu=0.20000000000000001.
+testcase_ellint_3<double> data143[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17440204336345433, 0.50000000000000000, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34806552388338824, 0.50000000000000000, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.52046416757129810, 0.50000000000000000, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.69140924550993865, 0.50000000000000000, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.86104678636125520, 0.50000000000000000, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.0297439459053981, 0.50000000000000000, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.1979214112912033, 0.50000000000000000, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.3659033858648930, 0.50000000000000000, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.5338490483665983, 0.50000000000000000, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test143()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data143)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data143[i].k), Tp(data143[i].nu),
+		     Tp(data143[i].phi));
+	const Tp f0 = data143[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000, nu=0.29999999999999999.
+testcase_ellint_3<double> data144[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17422708752228896, 0.50000000000000000, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34671739434855858, 0.50000000000000000, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51617616305641878, 0.50000000000000000, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.68200047612545167, 0.50000000000000000, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.84427217869498372, 0.50000000000000000, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 1.0035637821389782, 0.50000000000000000, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1606800483933111, 0.50000000000000000, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.3164407134643459, 0.50000000000000000, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.4715681939859637, 0.50000000000000000, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test144()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data144)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data144[i].k), Tp(data144[i].nu),
+		     Tp(data144[i].phi));
+	const Tp f0 = data144[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000, nu=0.40000000000000002.
+testcase_ellint_3<double> data145[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17405275963859917, 0.50000000000000000, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34538761957029329, 0.50000000000000000, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.51200902646603907, 0.50000000000000000, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.67301522212868792, 0.50000000000000000, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.82853844466313320, 0.50000000000000000, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.97942097862681488, 0.50000000000000000, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.1268429801220614, 0.50000000000000000, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.2720406704533922, 0.50000000000000000, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.4161679518465340, 0.50000000000000000, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test145()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data145)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data145[i].k), Tp(data145[i].nu),
+		     Tp(data145[i].phi));
+	const Tp f0 = data145[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000, nu=0.50000000000000000.
+testcase_ellint_3<double> data146[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17387905570381157, 0.50000000000000000, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34407576010465207, 0.50000000000000000, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.50795686560160824, 0.50000000000000000, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.66442115453330164, 0.50000000000000000, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.81373829119355345, 0.50000000000000000, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.95705743313235825, 0.50000000000000000, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.0959131991362554, 0.50000000000000000, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.2318900529754597, 0.50000000000000000, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.3664739530045971, 0.50000000000000000, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test146()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data146)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data146[i].k), Tp(data146[i].nu),
+		     Tp(data146[i].phi));
+	const Tp f0 = data146[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000, nu=0.59999999999999998.
+testcase_ellint_3<double> data147[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17370597174637581, 0.50000000000000000, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34278139158591414, 0.50000000000000000, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.50401419439302708, 0.50000000000000000, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.65618938076167210, 0.50000000000000000, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.79977959248855424, 0.50000000000000000, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.93625925190753545, 0.50000000000000000, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0674905658379708, 0.50000000000000000, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.1953481298023050, 0.50000000000000000, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.3215740290190876, 0.50000000000000000, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test147()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data147)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data147[i].k), Tp(data147[i].nu),
+		     Tp(data147[i].phi));
+	const Tp f0 = data147[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000, nu=0.69999999999999996.
+testcase_ellint_3<double> data148[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17353350383131641, 0.50000000000000000, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34150410405436771, 0.50000000000000000, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.50017589696443487, 0.50000000000000000, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.64829398188419951, 0.50000000000000000, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.78658270782402073, 0.50000000000000000, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.91684738336675053, 0.50000000000000000, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0412486789555935, 0.50000000000000000, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1619021847612001, 0.50000000000000000, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.2807475181182502, 0.50000000000000000, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test148()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data148)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data148[i].k), Tp(data148[i].nu),
+		     Tp(data148[i].phi));
+	const Tp f0 = data148[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000, nu=0.80000000000000004.
+testcase_ellint_3<double> data149[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17336164805979126, 0.50000000000000000, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.34024350132086773, 0.50000000000000000, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49643719555734073, 0.50000000000000000, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.64071162456976150, 0.50000000000000000, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.77407836177211908, 0.50000000000000000, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.89867058251905652, 0.50000000000000000, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.0169181822134910, 0.50000000000000000, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.1311363312779448, 0.50000000000000000, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.2434165408189539, 0.50000000000000000, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test149()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data149)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data149[i].k), Tp(data149[i].nu),
+		     Tp(data149[i].phi));
+	const Tp f0 = data149[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.50000000000000000, nu=0.90000000000000002.
+testcase_ellint_3<double> data150[] = {
+  { 0.0000000000000000, 0.50000000000000000, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17319040056865681, 0.50000000000000000, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33899920036578557, 0.50000000000000000, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.49279362182695174, 0.50000000000000000, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.63342123379746151, 0.50000000000000000, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.76220595179550321, 0.50000000000000000, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.88160004743532294, 0.50000000000000000, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 0.99427448642310123, 0.50000000000000000, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.1027091512470095, 0.50000000000000000, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.2091116095504744, 0.50000000000000000, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.50000000000000000, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test150()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data150)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data150[i].k), Tp(data150[i].nu),
+		     Tp(data150[i].phi));
+	const Tp f0 = data150[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009, nu=0.0000000000000000.
+testcase_ellint_3<double> data151[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17485154362988359, 0.60000000000000009, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35160509865544326, 0.60000000000000009, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.53210652578446138, 0.60000000000000009, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.71805304664485659, 0.60000000000000009, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.91082759030195970, 0.60000000000000009, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.1112333229323361, 0.60000000000000009, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.3191461190365270, 0.60000000000000009, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.5332022105084775, 0.60000000000000009, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.7507538029157526, 0.60000000000000009, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test151()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data151)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data151[i].k), Tp(data151[i].nu),
+		     Tp(data151[i].phi));
+	const Tp f0 = data151[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009, nu=0.10000000000000001.
+testcase_ellint_3<double> data152[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17467514275022011, 0.60000000000000009, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.35021333086258255, 0.60000000000000009, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.52751664092962691, 0.60000000000000009, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.70752126971957874, 0.60000000000000009, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.89111058756112871, 0.60000000000000009, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.0789241202877768, 0.60000000000000009, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.2710800210399946, 0.60000000000000009, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.4669060574440276, 0.60000000000000009, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.6648615773343014, 0.60000000000000009, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test152()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data152)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data152[i].k), Tp(data152[i].nu),
+		     Tp(data152[i].phi));
+	const Tp f0 = data152[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009, nu=0.20000000000000001.
+testcase_ellint_3<double> data153[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17449937871800650, 0.60000000000000009, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34884093647346553, 0.60000000000000009, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.52306221119844087, 0.60000000000000009, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.69749955678982223, 0.60000000000000009, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.87274610682416853, 0.60000000000000009, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.0494620540750792, 0.60000000000000009, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.2280847305507339, 0.60000000000000009, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.4085436279696888, 0.60000000000000009, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.5901418016279374, 0.60000000000000009, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test153()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data153)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data153[i].k), Tp(data153[i].nu),
+		     Tp(data153[i].phi));
+	const Tp f0 = data153[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009, nu=0.29999999999999999.
+testcase_ellint_3<double> data154[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17432424744393932, 0.60000000000000009, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34748744127146447, 0.60000000000000009, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.51873632743924825, 0.60000000000000009, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.68794610396313116, 0.60000000000000009, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.85558070175468726, 0.60000000000000009, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 1.0224416343605653, 0.60000000000000009, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.1893144457936788, 0.60000000000000009, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.3566435377982575, 0.60000000000000009, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.5243814243493585, 0.60000000000000009, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test154()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data154)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data154[i].k), Tp(data154[i].nu),
+		     Tp(data154[i].phi));
+	const Tp f0 = data154[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009, nu=0.40000000000000002.
+testcase_ellint_3<double> data155[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17414974487670717, 0.60000000000000009, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34615238767335027, 0.60000000000000009, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.51453257838108557, 0.60000000000000009, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.67882386787534399, 0.60000000000000009, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.83948470233173578, 0.60000000000000009, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 0.99753496200073977, 0.60000000000000009, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.1541101404388487, 0.60000000000000009, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.3100911323398816, 0.60000000000000009, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.4659345278069984, 0.60000000000000009, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test155()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data155)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data155[i].k), Tp(data155[i].nu),
+		     Tp(data155[i].phi));
+	const Tp f0 = data155[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009, nu=0.50000000000000000.
+testcase_ellint_3<double> data156[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17397586700252807, 0.60000000000000009, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34483533397138516, 0.60000000000000009, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.51044500461706477, 0.60000000000000009, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.67009988034712664, 0.60000000000000009, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.82434762375735193, 0.60000000000000009, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.97447346702798998, 0.60000000000000009, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.1219494000522143, 0.60000000000000009, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.2680242605954486, 0.60000000000000009, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.4135484285693078, 0.60000000000000009, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test156()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data156)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data156[i].k), Tp(data156[i].nu),
+		     Tp(data156[i].phi));
+	const Tp f0 = data156[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009, nu=0.59999999999999998.
+testcase_ellint_3<double> data157[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17380260984469353, 0.60000000000000009, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34353585361777839, 0.60000000000000009, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.50646805774321380, 0.60000000000000009, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.66174468108625506, 0.60000000000000009, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.81007462280278408, 0.60000000000000009, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.95303466945718729, 0.60000000000000009, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.0924118588677505, 0.60000000000000009, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.2297640574847937, 0.60000000000000009, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.3662507535812816, 0.60000000000000009, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test157()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data157)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data157[i].k), Tp(data157[i].nu),
+		     Tp(data157[i].phi));
+	const Tp f0 = data157[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009, nu=0.69999999999999996.
+testcase_ellint_3<double> data158[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17362996946312007, 0.60000000000000009, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34225353454870588, 0.60000000000000009, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.50259656397799524, 0.60000000000000009, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.65373184496628933, 0.60000000000000009, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.79658372884056439, 0.60000000000000009, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.93303240100245421, 0.60000000000000009, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0651547944716557, 0.60000000000000009, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.1947676204853441, 0.60000000000000009, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.3232737468822813, 0.60000000000000009, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test158()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data158)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data158[i].k), Tp(data158[i].nu),
+		     Tp(data158[i].phi));
+	const Tp f0 = data158[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009, nu=0.80000000000000004.
+testcase_ellint_3<double> data159[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17345794195390685, 0.60000000000000009, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.34098797854531027, 0.60000000000000009, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.49882569168826213, 0.60000000000000009, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.64603758566475511, 0.60000000000000009, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.78380365594769730, 0.60000000000000009, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.91430946255611190, 0.60000000000000009, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.0398955217270607, 0.60000000000000009, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.1625948314277679, 0.60000000000000009, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.2840021261752192, 0.60000000000000009, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test159()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data159)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data159[i].k), Tp(data159[i].nu),
+		     Tp(data159[i].phi));
+	const Tp f0 = data159[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.60000000000000009, nu=0.90000000000000002.
+testcase_ellint_3<double> data160[] = {
+  { 0.0000000000000000, 0.60000000000000009, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17328652344890030, 0.60000000000000009, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.33973880062929018, 0.60000000000000009, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.49515092233122743, 0.60000000000000009, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.63864042139737043, 0.60000000000000009, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.77167205646538850, 0.60000000000000009, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.89673202848034383, 0.60000000000000009, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 1.0163984492661304, 0.60000000000000009, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.1328845785162431, 0.60000000000000009, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.2479362973851873, 0.60000000000000009, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.60000000000000009, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test160()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data160)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data160[i].k), Tp(data160[i].nu),
+		     Tp(data160[i].phi));
+	const Tp f0 = data160[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996, nu=0.0000000000000000.
+testcase_ellint_3<double> data161[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17496737466916723, 0.69999999999999996, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35254687535677925, 0.69999999999999996, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.53536740275997119, 0.69999999999999996, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.72603797651684454, 0.69999999999999996, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.92698296348313458, 0.69999999999999996, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.1400447527693316, 0.69999999999999996, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.3657668117194073, 0.69999999999999996, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.6024686895959159, 0.69999999999999996, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.8456939983747236, 0.69999999999999996, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test161()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data161)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data161[i].k), Tp(data161[i].nu),
+		     Tp(data161[i].phi));
+	const Tp f0 = data161[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996, nu=0.10000000000000001.
+testcase_ellint_3<double> data162[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17479076384884684, 0.69999999999999996, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.35114844900396364, 0.69999999999999996, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.53072776947527001, 0.69999999999999996, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.71530198262386235, 0.69999999999999996, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.90666760677828306, 0.69999999999999996, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.1063366517438080, 0.69999999999999996, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.3149477243092149, 0.69999999999999996, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.5314886725038925, 0.69999999999999996, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.7528050171757608, 0.69999999999999996, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test162()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data162)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data162[i].k), Tp(data162[i].nu),
+		     Tp(data162[i].phi));
+	const Tp f0 = data162[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996, nu=0.20000000000000001.
+testcase_ellint_3<double> data163[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17461479077791475, 0.69999999999999996, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.34976950621407538, 0.69999999999999996, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.52622533231350177, 0.69999999999999996, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.70508774017895215, 0.69999999999999996, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.88775302531730294, 0.69999999999999996, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.0756195476149006, 0.69999999999999996, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.2695349716654374, 0.69999999999999996, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.4690814617070540, 0.69999999999999996, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.6721098780092145, 0.69999999999999996, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test163()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data163)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data163[i].k), Tp(data163[i].nu),
+		     Tp(data163[i].phi));
+	const Tp f0 = data163[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996, nu=0.29999999999999999.
+testcase_ellint_3<double> data164[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17443945136076175, 0.69999999999999996, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34840956983535287, 0.69999999999999996, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.52185308551329168, 0.69999999999999996, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.69535240431168255, 0.69999999999999996, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.87007983473964923, 0.69999999999999996, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 1.0474657975577066, 0.69999999999999996, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.2286225419931891, 0.69999999999999996, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.4136490671013271, 0.69999999999999996, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.6011813647733213, 0.69999999999999996, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test164()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data164)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data164[i].k), Tp(data164[i].nu),
+		     Tp(data164[i].phi));
+	const Tp f0 = data164[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996, nu=0.40000000000000002.
+testcase_ellint_3<double> data165[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17426474153983229, 0.69999999999999996, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34706817945773732, 0.69999999999999996, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.51760452851738148, 0.69999999999999996, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.68605801534722755, 0.69999999999999996, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.85351339387296532, 0.69999999999999996, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 1.0215297967969539, 0.69999999999999996, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.1915051074460530, 0.69999999999999996, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.3639821911744707, 0.69999999999999996, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.5382162002954762, 0.69999999999999996, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test165()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data165)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data165[i].k), Tp(data165[i].nu),
+		     Tp(data165[i].phi));
+	const Tp f0 = data165[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996, nu=0.50000000000000000.
+testcase_ellint_3<double> data166[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17409065729516096, 0.69999999999999996, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34574489064986091, 0.69999999999999996, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.51347361925579782, 0.69999999999999996, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.67717079489579279, 0.69999999999999996, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.83793902055292280, 0.69999999999999996, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 0.99752863545289705, 0.69999999999999996, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.1576240080401501, 0.69999999999999996, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.3191464023923762, 0.69999999999999996, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.4818433192178544, 0.69999999999999996, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test166()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data166)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data166[i].k), Tp(data166[i].nu),
+		     Tp(data166[i].phi));
+	const Tp f0 = data166[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996, nu=0.59999999999999998.
+testcase_ellint_3<double> data167[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17391719464391614, 0.69999999999999996, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34443927423869031, 0.69999999999999996, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.50945473266486063, 0.69999999999999996, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.66866056326513812, 0.69999999999999996, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.82325830002337352, 0.69999999999999996, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 0.97522808245669368, 0.69999999999999996, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.1265300613705285, 0.69999999999999996, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.2784066076152001, 0.69999999999999996, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.4309994736080540, 0.69999999999999996, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test167()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data167)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data167[i].k), Tp(data167[i].nu),
+		     Tp(data167[i].phi));
+	const Tp f0 = data167[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996, nu=0.69999999999999996.
+testcase_ellint_3<double> data168[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17374434963995031, 0.69999999999999996, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34315091562900674, 0.69999999999999996, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.50554262375653347, 0.69999999999999996, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.66050025406305801, 0.69999999999999996, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.80938620118847404, 0.69999999999999996, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.95443223855852144, 0.69999999999999996, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.0978573207128304, 0.69999999999999996, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.2411754575007123, 0.69999999999999996, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.3848459188329196, 0.69999999999999996, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test168()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data168)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data168[i].k), Tp(data168[i].nu),
+		     Tp(data168[i].phi));
+	const Tp f0 = data168[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996, nu=0.80000000000000004.
+testcase_ellint_3<double> data169[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17357211837335740, 0.69999999999999996, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.34187941416012108, 0.69999999999999996, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.50173239465478259, 0.69999999999999996, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.65266550725988315, 0.69999999999999996, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.79624879865249298, 0.69999999999999996, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.93497577043296920, 0.69999999999999996, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.0713041566930750, 0.69999999999999996, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.2069772023255654, 0.69999999999999996, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.3427110650397531, 0.69999999999999996, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test169()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data169)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data169[i].k), Tp(data169[i].nu),
+		     Tp(data169[i].phi));
+	const Tp f0 = data169[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.69999999999999996, nu=0.90000000000000002.
+testcase_ellint_3<double> data170[] = {
+  { 0.0000000000000000, 0.69999999999999996, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17340049697003637, 0.69999999999999996, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.34062438249741556, 0.69999999999999996, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.49801946510076867, 0.69999999999999996, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.64513432604750476, 0.69999999999999996, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.78378145487573758, 0.69999999999999996, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.91671799500854623, 0.69999999999999996, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 1.0466193579463123, 0.69999999999999996, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.1754218079199146, 0.69999999999999996, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.3040500499695913, 0.69999999999999996, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.69999999999999996, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test170()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data170)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data170[i].k), Tp(data170[i].nu),
+		     Tp(data170[i].phi));
+	const Tp f0 = data170[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004, nu=0.0000000000000000.
+testcase_ellint_3<double> data171[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17510154241338899, 0.80000000000000004, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35365068839779390, 0.80000000000000004, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.53926804409084550, 0.80000000000000004, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.73587926028070361, 0.80000000000000004, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.94770942970071170, 0.80000000000000004, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.1789022995388236, 0.80000000000000004, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.4323027881876009, 0.80000000000000004, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.7069629739121674, 0.80000000000000004, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 1.9953027776647296, 0.80000000000000004, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test171()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data171)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data171[i].k), Tp(data171[i].nu),
+		     Tp(data171[i].phi));
+	const Tp f0 = data171[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004, nu=0.10000000000000001.
+testcase_ellint_3<double> data172[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17492468824017163, 0.80000000000000004, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.35224443521476911, 0.80000000000000004, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.53456851853226950, 0.80000000000000004, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.72488875602364922, 0.80000000000000004, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.92661354274638952, 0.80000000000000004, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.1432651144499075, 0.80000000000000004, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.3774479927211429, 0.80000000000000004, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.6287092337196041, 0.80000000000000004, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 1.8910755418379521, 0.80000000000000004, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test172()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data172)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data172[i].k), Tp(data172[i].nu),
+		     Tp(data172[i].phi));
+	const Tp f0 = data172[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004, nu=0.20000000000000001.
+testcase_ellint_3<double> data173[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17474847286224940, 0.80000000000000004, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.35085779529084682, 0.80000000000000004, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.53000829263059146, 0.80000000000000004, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.71443466027453384, 0.80000000000000004, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.90698196872715420, 0.80000000000000004, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.1108198200558579, 0.80000000000000004, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.3284988909963957, 0.80000000000000004, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.5600369318140328, 0.80000000000000004, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 1.8007226661734588, 0.80000000000000004, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test173()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data173)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data173[i].k), Tp(data173[i].nu),
+		     Tp(data173[i].phi));
+	const Tp f0 = data173[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004, nu=0.29999999999999999.
+testcase_ellint_3<double> data174[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17457289217669889, 0.80000000000000004, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.34949028801501258, 0.80000000000000004, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.52558024362769307, 0.80000000000000004, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.70447281740094891, 0.80000000000000004, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.88864745641528986, 0.80000000000000004, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 1.0811075819341462, 0.80000000000000004, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.2844589654082377, 0.80000000000000004, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.4991461361277847, 0.80000000000000004, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.7214611048717301, 0.80000000000000004, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test174()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data174)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data174[i].k), Tp(data174[i].nu),
+		     Tp(data174[i].phi));
+	const Tp f0 = data174[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004, nu=0.40000000000000002.
+testcase_ellint_3<double> data175[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17439794211872175, 0.80000000000000004, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34814144964568972, 0.80000000000000004, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.52127776285273064, 0.80000000000000004, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.69496411438966588, 0.80000000000000004, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.87146878427509589, 0.80000000000000004, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 1.0537579024937762, 0.80000000000000004, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.2445534387922637, 0.80000000000000004, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.4446769766361993, 0.80000000000000004, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.6512267838651289, 0.80000000000000004, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test175()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data175)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data175[i].k), Tp(data175[i].nu),
+		     Tp(data175[i].phi));
+	const Tp f0 = data175[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004, nu=0.50000000000000000.
+testcase_ellint_3<double> data176[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17422361866118044, 0.80000000000000004, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34681083254170475, 0.80000000000000004, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.51709470815494440, 0.80000000000000004, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.68587375344080237, 0.80000000000000004, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.85532571852810624, 0.80000000000000004, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 1.0284677391874903, 0.80000000000000004, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.2081693942686225, 0.80000000000000004, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.3955803006426311, 0.80000000000000004, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.5884528947755532, 0.80000000000000004, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test176()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data176)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data176[i].k), Tp(data176[i].nu),
+		     Tp(data176[i].phi));
+	const Tp f0 = data176[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004, nu=0.59999999999999998.
+testcase_ellint_3<double> data177[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17404991781414089, 0.80000000000000004, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34549800443625167, 0.80000000000000004, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.51302536167001545, 0.80000000000000004, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.67717065003912236, 0.80000000000000004, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.84011512421134416, 0.80000000000000004, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 1.0049863847088740, 0.80000000000000004, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.1748145941898920, 0.80000000000000004, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.3510319699755071, 0.80000000000000004, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.5319262547427865, 0.80000000000000004, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test177()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data177)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data177[i].k), Tp(data177[i].nu),
+		     Tp(data177[i].phi));
+	const Tp f0 = data177[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004, nu=0.69999999999999996.
+testcase_ellint_3<double> data178[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17387683562442199, 0.80000000000000004, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34420254775101611, 0.80000000000000004, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.50906439222143673, 0.80000000000000004, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.66882693152688422, 0.80000000000000004, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.82574792844091316, 0.80000000000000004, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 0.98310431309490931, 0.80000000000000004, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.1440884535113258, 0.80000000000000004, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.3103743938952537, 0.80000000000000004, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.4806912324625332, 0.80000000000000004, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test178()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data178)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data178[i].k), Tp(data178[i].nu),
+		     Tp(data178[i].phi));
+	const Tp f0 = data178[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004, nu=0.80000000000000004.
+testcase_ellint_3<double> data179[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17370436817515203, 0.80000000000000004, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.34292405894783395, 0.80000000000000004, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.50520682176250076, 0.80000000000000004, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.66081751679736178, 0.80000000000000004, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.81214672249355102, 0.80000000000000004, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 0.96264481387685552, 0.80000000000000004, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.1156611352656258, 0.80000000000000004, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.2730756225143889, 0.80000000000000004, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.4339837018309471, 0.80000000000000004, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test179()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data179)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data179[i].k), Tp(data179[i].nu),
+		     Tp(data179[i].phi));
+	const Tp f0 = data179[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.80000000000000004, nu=0.90000000000000002.
+testcase_ellint_3<double> data180[] = {
+  { 0.0000000000000000, 0.80000000000000004, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17353251158533151, 0.80000000000000004, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.34166214791545768, 0.80000000000000004, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.50144799535130569, 0.80000000000000004, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.65311976193814425, 0.80000000000000004, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.79924384892320866, 0.80000000000000004, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.94345762353365603, 0.80000000000000004, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 1.0892582069219161, 0.80000000000000004, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.2387000876610268, 0.80000000000000004, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.3911845406776222, 0.80000000000000004, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.80000000000000004, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test180()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data180)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data180[i].k), Tp(data180[i].nu),
+		     Tp(data180[i].phi));
+	const Tp f0 = data180[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991, nu=0.0000000000000000.
+testcase_ellint_3<double> data181[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.0000000000000000, 
+	  0.0000000000000000 },
+  { 0.17525427376115024, 0.89999999999999991, 0.0000000000000000, 
+	  0.17453292519943295 },
+  { 0.35492464591297446, 0.89999999999999991, 0.0000000000000000, 
+	  0.34906585039886590 },
+  { 0.54388221416157112, 0.89999999999999991, 0.0000000000000000, 
+	  0.52359877559829882 },
+  { 0.74797400423532490, 0.89999999999999991, 0.0000000000000000, 
+	  0.69813170079773179 },
+  { 0.97463898451966458, 0.89999999999999991, 0.0000000000000000, 
+	  0.87266462599716477 },
+  { 1.2334463254523440, 0.89999999999999991, 0.0000000000000000, 
+	  1.0471975511965976 },
+  { 1.5355247765594910, 0.89999999999999991, 0.0000000000000000, 
+	  1.2217304763960306 },
+  { 1.8882928567775117, 0.89999999999999991, 0.0000000000000000, 
+	  1.3962634015954636 },
+  { 2.2805491384227703, 0.89999999999999991, 0.0000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991, nu=0.0000000000000000.
+template<typename Tp>
+  void
+  test181()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data181)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data181[i].k), Tp(data181[i].nu),
+		     Tp(data181[i].phi));
+	const Tp f0 = data181[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991, nu=0.10000000000000001.
+testcase_ellint_3<double> data182[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.10000000000000001, 
+	  0.0000000000000000 },
+  { 0.17507714233254656, 0.89999999999999991, 0.10000000000000001, 
+	  0.17453292519943295 },
+  { 0.35350932904326521, 0.89999999999999991, 0.10000000000000001, 
+	  0.34906585039886590 },
+  { 0.53911129989870976, 0.89999999999999991, 0.10000000000000001, 
+	  0.52359877559829882 },
+  { 0.73666644254508395, 0.89999999999999991, 0.10000000000000001, 
+	  0.69813170079773179 },
+  { 0.95250736612100195, 0.89999999999999991, 0.10000000000000001, 
+	  0.87266462599716477 },
+  { 1.1950199550905594, 0.89999999999999991, 0.10000000000000001, 
+	  1.0471975511965976 },
+  { 1.4741687286340848, 0.89999999999999991, 0.10000000000000001, 
+	  1.2217304763960306 },
+  { 1.7968678183506053, 0.89999999999999991, 0.10000000000000001, 
+	  1.3962634015954636 },
+  { 2.1537868513875287, 0.89999999999999991, 0.10000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991, nu=0.10000000000000001.
+template<typename Tp>
+  void
+  test182()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data182)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data182[i].k), Tp(data182[i].nu),
+		     Tp(data182[i].phi));
+	const Tp f0 = data182[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991, nu=0.20000000000000001.
+testcase_ellint_3<double> data183[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.20000000000000001, 
+	  0.0000000000000000 },
+  { 0.17490065089140927, 0.89999999999999991, 0.20000000000000001, 
+	  0.17453292519943295 },
+  { 0.35211377590661436, 0.89999999999999991, 0.20000000000000001, 
+	  0.34906585039886590 },
+  { 0.53448220334204100, 0.89999999999999991, 0.20000000000000001, 
+	  0.52359877559829882 },
+  { 0.72591368943179579, 0.89999999999999991, 0.20000000000000001, 
+	  0.69813170079773179 },
+  { 0.93192539780038763, 0.89999999999999991, 0.20000000000000001, 
+	  0.87266462599716477 },
+  { 1.1600809679692683, 0.89999999999999991, 0.20000000000000001, 
+	  1.0471975511965976 },
+  { 1.4195407225882508, 0.89999999999999991, 0.20000000000000001, 
+	  1.2217304763960306 },
+  { 1.7168966476424521, 0.89999999999999991, 0.20000000000000001, 
+	  1.3962634015954636 },
+  { 2.0443194576468895, 0.89999999999999991, 0.20000000000000001, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991, nu=0.20000000000000001.
+template<typename Tp>
+  void
+  test183()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data183)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data183[i].k), Tp(data183[i].nu),
+		     Tp(data183[i].phi));
+	const Tp f0 = data183[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991, nu=0.29999999999999999.
+testcase_ellint_3<double> data184[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.29999999999999999, 
+	  0.0000000000000000 },
+  { 0.17472479532647531, 0.89999999999999991, 0.29999999999999999, 
+	  0.17453292519943295 },
+  { 0.35073750187374114, 0.89999999999999991, 0.29999999999999999, 
+	  0.34906585039886590 },
+  { 0.52998766129466957, 0.89999999999999991, 0.29999999999999999, 
+	  0.52359877559829882 },
+  { 0.71566993548699553, 0.89999999999999991, 0.29999999999999999, 
+	  0.69813170079773179 },
+  { 0.91271517762560195, 0.89999999999999991, 0.29999999999999999, 
+	  0.87266462599716477 },
+  { 1.1281241199843370, 0.89999999999999991, 0.29999999999999999, 
+	  1.0471975511965976 },
+  { 1.3704929576917448, 0.89999999999999991, 0.29999999999999999, 
+	  1.2217304763960306 },
+  { 1.6461981511487711, 0.89999999999999991, 0.29999999999999999, 
+	  1.3962634015954636 },
+  { 1.9486280260314426, 0.89999999999999991, 0.29999999999999999, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991, nu=0.29999999999999999.
+template<typename Tp>
+  void
+  test184()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data184)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data184[i].k), Tp(data184[i].nu),
+		     Tp(data184[i].phi));
+	const Tp f0 = data184[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991, nu=0.40000000000000002.
+testcase_ellint_3<double> data185[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.40000000000000002, 
+	  0.0000000000000000 },
+  { 0.17454957156468837, 0.89999999999999991, 0.40000000000000002, 
+	  0.17453292519943295 },
+  { 0.34938003933330430, 0.89999999999999991, 0.40000000000000002, 
+	  0.34906585039886590 },
+  { 0.52562093533067433, 0.89999999999999991, 0.40000000000000002, 
+	  0.52359877559829882 },
+  { 0.70589461324915670, 0.89999999999999991, 0.40000000000000002, 
+	  0.69813170079773179 },
+  { 0.89472658511942849, 0.89999999999999991, 0.40000000000000002, 
+	  0.87266462599716477 },
+  { 1.0987419542323440, 0.89999999999999991, 0.40000000000000002, 
+	  1.0471975511965976 },
+  { 1.3261349565496301, 0.89999999999999991, 0.40000000000000002, 
+	  1.2217304763960306 },
+  { 1.5831293909853763, 0.89999999999999991, 0.40000000000000002, 
+	  1.3962634015954636 },
+  { 1.8641114227238351, 0.89999999999999991, 0.40000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991, nu=0.40000000000000002.
+template<typename Tp>
+  void
+  test185()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data185)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data185[i].k), Tp(data185[i].nu),
+		     Tp(data185[i].phi));
+	const Tp f0 = data185[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991, nu=0.50000000000000000.
+testcase_ellint_3<double> data186[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.50000000000000000, 
+	  0.0000000000000000 },
+  { 0.17437497557073334, 0.89999999999999991, 0.50000000000000000, 
+	  0.17453292519943295 },
+  { 0.34804093691586013, 0.89999999999999991, 0.50000000000000000, 
+	  0.34906585039886590 },
+  { 0.52137576320372891, 0.89999999999999991, 0.50000000000000000, 
+	  0.52359877559829882 },
+  { 0.69655163996912262, 0.89999999999999991, 0.50000000000000000, 
+	  0.69813170079773179 },
+  { 0.87783188683054236, 0.89999999999999991, 0.50000000000000000, 
+	  0.87266462599716477 },
+  { 1.0716015959755185, 0.89999999999999991, 0.50000000000000000, 
+	  1.0471975511965976 },
+  { 1.2857636916026749, 0.89999999999999991, 0.50000000000000000, 
+	  1.2217304763960306 },
+  { 1.5264263913252358, 0.89999999999999991, 0.50000000000000000, 
+	  1.3962634015954636 },
+  { 1.7888013241937863, 0.89999999999999991, 0.50000000000000000, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991, nu=0.50000000000000000.
+template<typename Tp>
+  void
+  test186()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data186)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data186[i].k), Tp(data186[i].nu),
+		     Tp(data186[i].phi));
+	const Tp f0 = data186[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991, nu=0.59999999999999998.
+testcase_ellint_3<double> data187[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.59999999999999998, 
+	  0.0000000000000000 },
+  { 0.17420100334657812, 0.89999999999999991, 0.59999999999999998, 
+	  0.17453292519943295 },
+  { 0.34671975876122157, 0.89999999999999991, 0.59999999999999998, 
+	  0.34906585039886590 },
+  { 0.51724631570707946, 0.89999999999999991, 0.59999999999999998, 
+	  0.52359877559829882 },
+  { 0.68760879113743023, 0.89999999999999991, 0.59999999999999998, 
+	  0.69813170079773179 },
+  { 0.86192157779698364, 0.89999999999999991, 0.59999999999999998, 
+	  0.87266462599716477 },
+  { 1.0464279696166354, 0.89999999999999991, 0.59999999999999998, 
+	  1.0471975511965976 },
+  { 1.2488156247094004, 0.89999999999999991, 0.59999999999999998, 
+	  1.2217304763960306 },
+  { 1.4750988777188470, 0.89999999999999991, 0.59999999999999998, 
+	  1.3962634015954636 },
+  { 1.7211781128919525, 0.89999999999999991, 0.59999999999999998, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991, nu=0.59999999999999998.
+template<typename Tp>
+  void
+  test187()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data187)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data187[i].k), Tp(data187[i].nu),
+		     Tp(data187[i].phi));
+	const Tp f0 = data187[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991, nu=0.69999999999999996.
+testcase_ellint_3<double> data188[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.69999999999999996, 
+	  0.0000000000000000 },
+  { 0.17402765093102207, 0.89999999999999991, 0.69999999999999996, 
+	  0.17453292519943295 },
+  { 0.34541608382635131, 0.89999999999999991, 0.69999999999999996, 
+	  0.34906585039886590 },
+  { 0.51322715827061682, 0.89999999999999991, 0.69999999999999996, 
+	  0.52359877559829882 },
+  { 0.67903717872440272, 0.89999999999999991, 0.69999999999999996, 
+	  0.69813170079773179 },
+  { 0.84690113601682671, 0.89999999999999991, 0.69999999999999996, 
+	  0.87266462599716477 },
+  { 1.0229914311548418, 0.89999999999999991, 0.69999999999999996, 
+	  1.0471975511965976 },
+  { 1.2148329639709381, 0.89999999999999991, 0.69999999999999996, 
+	  1.2217304763960306 },
+  { 1.4283586501307799, 0.89999999999999991, 0.69999999999999996, 
+	  1.3962634015954636 },
+  { 1.6600480747670940, 0.89999999999999991, 0.69999999999999996, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991, nu=0.69999999999999996.
+template<typename Tp>
+  void
+  test188()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data188)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data188[i].k), Tp(data188[i].nu),
+		     Tp(data188[i].phi));
+	const Tp f0 = data188[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991, nu=0.80000000000000004.
+testcase_ellint_3<double> data189[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.80000000000000004, 
+	  0.0000000000000000 },
+  { 0.17385491439925146, 0.89999999999999991, 0.80000000000000004, 
+	  0.17453292519943295 },
+  { 0.34412950523113928, 0.89999999999999991, 0.80000000000000004, 
+	  0.34906585039886590 },
+  { 0.50931321668729590, 0.89999999999999991, 0.80000000000000004, 
+	  0.52359877559829882 },
+  { 0.67081081392296327, 0.89999999999999991, 0.80000000000000004, 
+	  0.69813170079773179 },
+  { 0.83268846097293259, 0.89999999999999991, 0.80000000000000004, 
+	  0.87266462599716477 },
+  { 1.0010985015814027, 0.89999999999999991, 0.80000000000000004, 
+	  1.0471975511965976 },
+  { 1.1834394045489678, 0.89999999999999991, 0.80000000000000004, 
+	  1.2217304763960306 },
+  { 1.3855695891683182, 0.89999999999999991, 0.80000000000000004, 
+	  1.3962634015954636 },
+  { 1.6044591960982202, 0.89999999999999991, 0.80000000000000004, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991, nu=0.80000000000000004.
+template<typename Tp>
+  void
+  test189()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data189)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data189[i].k), Tp(data189[i].nu),
+		     Tp(data189[i].phi));
+	const Tp f0 = data189[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for k=0.89999999999999991, nu=0.90000000000000002.
+testcase_ellint_3<double> data190[] = {
+  { 0.0000000000000000, 0.89999999999999991, 0.90000000000000002, 
+	  0.0000000000000000 },
+  { 0.17368278986240135, 0.89999999999999991, 0.90000000000000002, 
+	  0.17453292519943295 },
+  { 0.34285962963961397, 0.89999999999999991, 0.90000000000000002, 
+	  0.34906585039886590 },
+  { 0.50549974644993312, 0.89999999999999991, 0.90000000000000002, 
+	  0.52359877559829882 },
+  { 0.66290623857720876, 0.89999999999999991, 0.90000000000000002, 
+	  0.69813170079773179 },
+  { 0.81921183128847175, 0.89999999999999991, 0.90000000000000002, 
+	  0.87266462599716477 },
+  { 0.98058481956066390, 0.89999999999999991, 0.90000000000000002, 
+	  1.0471975511965976 },
+  { 1.1543223520473569, 0.89999999999999991, 0.90000000000000002, 
+	  1.2217304763960306 },
+  { 1.3462119782292934, 0.89999999999999991, 0.90000000000000002, 
+	  1.3962634015954636 },
+  { 1.5536420236310948, 0.89999999999999991, 0.90000000000000002, 
+	  1.5707963267948966 },
+};
+
+// Test function for k=0.89999999999999991, nu=0.90000000000000002.
+template<typename Tp>
+  void
+  test190()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data190)
+			   / sizeof(testcase_ellint_3<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::ellint_3(Tp(data190[i].k), Tp(data190[i].nu),
+		     Tp(data190[i].phi));
+	const Tp f0 = data190[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  test012<double>();
+  test013<double>();
+  test014<double>();
+  test015<double>();
+  test016<double>();
+  test017<double>();
+  test018<double>();
+  test019<double>();
+  test020<double>();
+  test021<double>();
+  test022<double>();
+  test023<double>();
+  test024<double>();
+  test025<double>();
+  test026<double>();
+  test027<double>();
+  test028<double>();
+  test029<double>();
+  test030<double>();
+  test031<double>();
+  test032<double>();
+  test033<double>();
+  test034<double>();
+  test035<double>();
+  test036<double>();
+  test037<double>();
+  test038<double>();
+  test039<double>();
+  test040<double>();
+  test041<double>();
+  test042<double>();
+  test043<double>();
+  test044<double>();
+  test045<double>();
+  test046<double>();
+  test047<double>();
+  test048<double>();
+  test049<double>();
+  test050<double>();
+  test051<double>();
+  test052<double>();
+  test053<double>();
+  test054<double>();
+  test055<double>();
+  test056<double>();
+  test057<double>();
+  test058<double>();
+  test059<double>();
+  test060<double>();
+  test061<double>();
+  test062<double>();
+  test063<double>();
+  test064<double>();
+  test065<double>();
+  test066<double>();
+  test067<double>();
+  test068<double>();
+  test069<double>();
+  test070<double>();
+  test071<double>();
+  test072<double>();
+  test073<double>();
+  test074<double>();
+  test075<double>();
+  test076<double>();
+  test077<double>();
+  test078<double>();
+  test079<double>();
+  test080<double>();
+  test081<double>();
+  test082<double>();
+  test083<double>();
+  test084<double>();
+  test085<double>();
+  test086<double>();
+  test087<double>();
+  test088<double>();
+  test089<double>();
+  test090<double>();
+  test091<double>();
+  test092<double>();
+  test093<double>();
+  test094<double>();
+  test095<double>();
+  test096<double>();
+  test097<double>();
+  test098<double>();
+  test099<double>();
+  test100<double>();
+  test101<double>();
+  test102<double>();
+  test103<double>();
+  test104<double>();
+  test105<double>();
+  test106<double>();
+  test107<double>();
+  test108<double>();
+  test109<double>();
+  test110<double>();
+  test111<double>();
+  test112<double>();
+  test113<double>();
+  test114<double>();
+  test115<double>();
+  test116<double>();
+  test117<double>();
+  test118<double>();
+  test119<double>();
+  test120<double>();
+  test121<double>();
+  test122<double>();
+  test123<double>();
+  test124<double>();
+  test125<double>();
+  test126<double>();
+  test127<double>();
+  test128<double>();
+  test129<double>();
+  test130<double>();
+  test131<double>();
+  test132<double>();
+  test133<double>();
+  test134<double>();
+  test135<double>();
+  test136<double>();
+  test137<double>();
+  test138<double>();
+  test139<double>();
+  test140<double>();
+  test141<double>();
+  test142<double>();
+  test143<double>();
+  test144<double>();
+  test145<double>();
+  test146<double>();
+  test147<double>();
+  test148<double>();
+  test149<double>();
+  test150<double>();
+  test151<double>();
+  test152<double>();
+  test153<double>();
+  test154<double>();
+  test155<double>();
+  test156<double>();
+  test157<double>();
+  test158<double>();
+  test159<double>();
+  test160<double>();
+  test161<double>();
+  test162<double>();
+  test163<double>();
+  test164<double>();
+  test165<double>();
+  test166<double>();
+  test167<double>();
+  test168<double>();
+  test169<double>();
+  test170<double>();
+  test171<double>();
+  test172<double>();
+  test173<double>();
+  test174<double>();
+  test175<double>();
+  test176<double>();
+  test177<double>();
+  test178<double>();
+  test179<double>();
+  test180<double>();
+  test181<double>();
+  test182<double>();
+  test183<double>();
+  test184<double>();
+  test185<double>();
+  test186<double>();
+  test187<double>();
+  test188<double>();
+  test189<double>();
+  test190<double>();
+  return 0;
+}
Index: testsuite/special_functions/13_ellint_3/compile.cc
===================================================================
--- testsuite/special_functions/13_ellint_3/compile.cc	(revision 0)
+++ testsuite/special_functions/13_ellint_3/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.13 ellint_3
+
+#include <cmath>
+
+void
+test01()
+{
+  float kf = 0.5F, nuf = 0.2F, phif = std::atan2(1.0F, 1.0F);
+  double kd = 0.5, nud = 0.2, phid = std::atan2(1.0, 1.0);
+  long double kl = 0.5L, nul = 0.2L, phil = std::atan2(1.0L, 1.0L);
+
+  std::ellint_3(kf, nuf, phif);
+  std::ellint_3f(kf, nuf, phif);
+  std::ellint_3(kd, nud, phid);
+  std::ellint_3(kl, nul, phil);
+  std::ellint_3l(kl, nul, phil);
+
+  return;
+}
+
Index: testsuite/special_functions/13_ellint_3/compile_2.cc
===================================================================
--- testsuite/special_functions/13_ellint_3/compile_2.cc	(revision 0)
+++ testsuite/special_functions/13_ellint_3/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.13 ellint_3
+
+#include <math.h>
+
+void
+test01()
+{
+  float kf = 0.5F, nuf = 0.2F, phif = atan2(1.0F, 1.0F);
+  double kd = 0.5, nud = 0.2, phid = atan2(1.0, 1.0);
+  long double kl = 0.5L, nul = 0.2L, phil = atan2(1.0L, 1.0L);
+
+  ellint_3(kf, nuf, phif);
+  ellint_3f(kf, nuf, phif);
+  ellint_3(kd, nud, phid);
+  ellint_3(kl, nul, phil);
+  ellint_3l(kl, nul, phil);
+
+  return;
+}
+
Index: testsuite/special_functions/14_expint/check_nan.cc
===================================================================
--- testsuite/special_functions/14_expint/check_nan.cc	(revision 0)
+++ testsuite/special_functions/14_expint/check_nan.cc	(working copy)
@@ -0,0 +1,56 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.14 expint
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::expint(xf);
+  float b = std::expintf(xf);
+  double c = std::expint(xd);
+  long double d = std::expint(xl);
+  long double e = std::expintl(xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/14_expint/check_value_neg.cc
===================================================================
--- testsuite/special_functions/14_expint/check_value_neg.cc	(revision 0)
+++ testsuite/special_functions/14_expint/check_value_neg.cc	(working copy)
@@ -0,0 +1,128 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  expint
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data.
+testcase_expint<double> data001[] = {
+  { -3.7832640295504591e-24, -50.000000000000000 },
+  { -1.0489811642368024e-23, -49.000000000000000 },
+  { -2.9096641904058423e-23, -48.000000000000000 },
+  { -8.0741978427258127e-23, -47.000000000000000 },
+  { -2.2415317597442998e-22, -46.000000000000000 },
+  { -6.2256908094623848e-22, -45.000000000000000 },
+  { -1.7299598742816476e-21, -44.000000000000000 },
+  { -4.8094965569500181e-21, -43.000000000000000 },
+  { -1.3377908810011775e-20, -42.000000000000000 },
+  { -3.7231667764599780e-20, -41.000000000000000 },
+  { -1.0367732614516570e-19, -40.000000000000000 },
+  { -2.8887793015227007e-19, -39.000000000000000 },
+  { -8.0541069142907499e-19, -38.000000000000000 },
+  { -2.2470206975885714e-18, -37.000000000000000 },
+  { -6.2733390097622421e-18, -36.000000000000000 },
+  { -1.7527059389947371e-17, -35.000000000000000 },
+  { -4.9006761183927874e-17, -34.000000000000000 },
+  { -1.3713843484487468e-16, -33.000000000000000 },
+  { -3.8409618012250671e-16, -32.000000000000000 },
+  { -1.0767670386162383e-15, -31.000000000000000 },
+  { -3.0215520106888124e-15, -30.000000000000000 },
+  { -8.4877597783535634e-15, -29.000000000000000 },
+  { -2.3869415119337330e-14, -28.000000000000000 },
+  { -6.7206374352620390e-14, -27.000000000000000 },
+  { -1.8946858856749785e-13, -26.000000000000000 },
+  { -5.3488997553402167e-13, -25.000000000000000 },
+  { -1.5123058939997059e-12, -24.000000000000000 },
+  { -4.2826847956656722e-12, -23.000000000000000 },
+  { -1.2149378956204371e-11, -22.000000000000000 },
+  { -3.4532012671467559e-11, -21.000000000000000 },
+  { -9.8355252906498815e-11, -20.000000000000000 },
+  { -2.8078290970607954e-10, -19.000000000000000 },
+  { -8.0360903448286769e-10, -18.000000000000000 },
+  { -2.3064319898216547e-09, -17.000000000000000 },
+  { -6.6404872494410427e-09, -16.000000000000000 },
+  { -1.9186278921478670e-08, -15.000000000000000 },
+  { -5.5656311111451816e-08, -14.000000000000000 },
+  { -1.6218662188014328e-07, -13.000000000000000 },
+  { -4.7510818246724931e-07, -12.000000000000000 },
+  { -1.4003003042474418e-06, -11.000000000000000 },
+  { -4.1569689296853246e-06, -10.000000000000000 },
+  { -1.2447354178006272e-05, -9.0000000000000000 },
+  { -3.7665622843924906e-05, -8.0000000000000000 },
+  { -0.00011548173161033820, -7.0000000000000000 },
+  { -0.00036008245216265862, -6.0000000000000000 },
+  { -0.0011482955912753257, -5.0000000000000000 },
+  { -0.0037793524098489058, -4.0000000000000000 },
+  { -0.013048381094197037, -3.0000000000000000 },
+  { -0.048900510708061125, -2.0000000000000000 },
+  { -0.21938393439552029, -1.0000000000000000 },
+};
+
+// Test function.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_expint<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::expint(Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  return 0;
+}
Index: testsuite/special_functions/14_expint/check_value_pos.cc
===================================================================
--- testsuite/special_functions/14_expint/check_value_pos.cc	(revision 0)
+++ testsuite/special_functions/14_expint/check_value_pos.cc	(working copy)
@@ -0,0 +1,128 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  expint
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data.
+testcase_expint<double> data001[] = {
+  { 1.8951178163559366, 1.0000000000000000 },
+  { 4.9542343560018907, 2.0000000000000000 },
+  { 9.9338325706254160, 3.0000000000000000 },
+  { 19.630874470056217, 4.0000000000000000 },
+  { 40.185275355803178, 5.0000000000000000 },
+  { 85.989762142439204, 6.0000000000000000 },
+  { 191.50474333550136, 7.0000000000000000 },
+  { 440.37989953483833, 8.0000000000000000 },
+  { 1037.8782907170896, 9.0000000000000000 },
+  { 2492.2289762418782, 10.000000000000000 },
+  { 6071.4063740986112, 11.000000000000000 },
+  { 14959.532666397528, 12.000000000000000 },
+  { 37197.688490689041, 13.000000000000000 },
+  { 93192.513633965369, 14.000000000000000 },
+  { 234955.85249076830, 15.000000000000000 },
+  { 595560.99867083691, 16.000000000000000 },
+  { 1516637.8940425171, 17.000000000000000 },
+  { 3877904.3305974435, 18.000000000000000 },
+  { 9950907.2510468438, 19.000000000000000 },
+  { 25615652.664056588, 20.000000000000000 },
+  { 66127186.355484925, 21.000000000000000 },
+  { 171144671.30036369, 22.000000000000000 },
+  { 443966369.83027124, 23.000000000000000 },
+  { 1154115391.8491828, 24.000000000000000 },
+  { 3005950906.5255494, 25.000000000000000 },
+  { 7842940991.8981876, 26.000000000000000 },
+  { 20496497119.880810, 27.000000000000000 },
+  { 53645118592.314682, 28.000000000000000 },
+  { 140599195758.40689, 29.000000000000000 },
+  { 368973209407.27417, 30.000000000000000 },
+  { 969455575968.39392, 31.000000000000000 },
+  { 2550043566357.7871, 32.000000000000000 },
+  { 6714640184076.4971, 33.000000000000000 },
+  { 17698037244116.266, 34.000000000000000 },
+  { 46690550144661.602, 35.000000000000000 },
+  { 123285207991209.75, 36.000000000000000 },
+  { 325798899867226.50, 37.000000000000000 },
+  { 861638819996578.75, 38.000000000000000 },
+  { 2280446200301902.5, 39.000000000000000 },
+  { 6039718263611242.0, 40.000000000000000 },
+  { 16006649143245042., 41.000000000000000 },
+  { 42447960921368504., 42.000000000000000 },
+  { 1.1263482901669666e+17, 43.000000000000000 },
+  { 2.9904447186323366e+17, 44.000000000000000 },
+  { 7.9439160357044531e+17, 45.000000000000000 },
+  { 2.1113423886478239e+18, 46.000000000000000 },
+  { 5.6143296808103424e+18, 47.000000000000000 },
+  { 1.4936302131129930e+19, 48.000000000000000 },
+  { 3.9754427479037444e+19, 49.000000000000000 },
+  { 1.0585636897131690e+20, 50.000000000000000 },
+};
+
+// Test function.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_expint<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::expint(Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  return 0;
+}
Index: testsuite/special_functions/14_expint/compile.cc
===================================================================
--- testsuite/special_functions/14_expint/compile.cc	(revision 0)
+++ testsuite/special_functions/14_expint/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.14 expint
+
+#include <cmath>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+
+  std::expint(xf);
+  std::expintf(xf);
+  std::expint(xd);
+  std::expint(xl);
+  std::expintl(xl);
+
+  return;
+}
+
Index: testsuite/special_functions/14_expint/compile_2.cc
===================================================================
--- testsuite/special_functions/14_expint/compile_2.cc	(revision 0)
+++ testsuite/special_functions/14_expint/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.14 expint
+
+#include <math.h>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+
+  expint(xf);
+  expintf(xf);
+  expint(xd);
+  expint(xl);
+  expintl(xl);
+
+  return;
+}
+
Index: testsuite/special_functions/15_hermite/check_nan.cc
===================================================================
--- testsuite/special_functions/15_hermite/check_nan.cc	(revision 0)
+++ testsuite/special_functions/15_hermite/check_nan.cc	(working copy)
@@ -0,0 +1,58 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.15 hermite
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  unsigned int n = 5;
+
+  float a = std::hermite(n, xf);
+  float b = std::hermitef(n, xf);
+  double c = std::hermite(n, xd);
+  long double d = std::hermite(n, xl);
+  long double e = std::hermitel(n, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/15_hermite/compile.cc
===================================================================
--- testsuite/special_functions/15_hermite/compile.cc	(revision 0)
+++ testsuite/special_functions/15_hermite/compile.cc	(working copy)
@@ -0,0 +1,42 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.15 hermite
+
+#include <cmath>
+
+void
+test01()
+{
+  float xf = 2.5F;
+  double xd = 2.5;
+  long double xl = 2.5L;
+
+  unsigned int n = 5;
+
+  std::hermite(n, xf);
+  std::hermitef(n, xf);
+  std::hermite(n, xd);
+  std::hermite(n, xl);
+  std::hermitel(n, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/15_hermite/compile_2.cc
===================================================================
--- testsuite/special_functions/15_hermite/compile_2.cc	(revision 0)
+++ testsuite/special_functions/15_hermite/compile_2.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.15 hermite
+
+#include <math.h>
+
+void
+test01()
+{
+  float xf = 2.5F;
+  double xd = 2.5;
+  long double xl = 2.5L;
+  unsigned int n = 5;
+
+  hermite(n, xf);
+  hermitef(n, xf);
+  hermite(n, xd);
+  hermite(n, xl);
+  hermitel(n, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/16_laguerre/check_nan.cc
===================================================================
--- testsuite/special_functions/16_laguerre/check_nan.cc	(revision 0)
+++ testsuite/special_functions/16_laguerre/check_nan.cc	(working copy)
@@ -0,0 +1,58 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.16 laguerre
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  unsigned int n = 2;
+
+  float a = std::laguerre(n, xf);
+  float b = std::laguerref(n, xf);
+  double c = std::laguerre(n, xd);
+  long double d = std::laguerre(n, xl);
+  long double e = std::laguerrel(n, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/16_laguerre/check_value.cc
===================================================================
--- testsuite/special_functions/16_laguerre/check_value.cc	(revision 0)
+++ testsuite/special_functions/16_laguerre/check_value.cc	(working copy)
@@ -0,0 +1,484 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  laguerre
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for n=0.
+testcase_laguerre<double> data001[] = {
+  { 1.0000000000000000, 0, 0.0000000000000000 },
+  { 1.0000000000000000, 0, 5.0000000000000000 },
+  { 1.0000000000000000, 0, 10.000000000000000 },
+  { 1.0000000000000000, 0, 15.000000000000000 },
+  { 1.0000000000000000, 0, 20.000000000000000 },
+  { 1.0000000000000000, 0, 25.000000000000000 },
+  { 1.0000000000000000, 0, 30.000000000000000 },
+  { 1.0000000000000000, 0, 35.000000000000000 },
+  { 1.0000000000000000, 0, 40.000000000000000 },
+  { 1.0000000000000000, 0, 45.000000000000000 },
+  { 1.0000000000000000, 0, 50.000000000000000 },
+  { 1.0000000000000000, 0, 55.000000000000000 },
+  { 1.0000000000000000, 0, 60.000000000000000 },
+  { 1.0000000000000000, 0, 65.000000000000000 },
+  { 1.0000000000000000, 0, 70.000000000000000 },
+  { 1.0000000000000000, 0, 75.000000000000000 },
+  { 1.0000000000000000, 0, 80.000000000000000 },
+  { 1.0000000000000000, 0, 85.000000000000000 },
+  { 1.0000000000000000, 0, 90.000000000000000 },
+  { 1.0000000000000000, 0, 95.000000000000000 },
+  { 1.0000000000000000, 0, 100.00000000000000 },
+};
+
+// Test function for n=0.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::laguerre(Tp(data001[i].n), Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=1.
+testcase_laguerre<double> data002[] = {
+  { 1.0000000000000000, 1, 0.0000000000000000 },
+  { -4.0000000000000000, 1, 5.0000000000000000 },
+  { -9.0000000000000000, 1, 10.000000000000000 },
+  { -14.000000000000000, 1, 15.000000000000000 },
+  { -19.000000000000000, 1, 20.000000000000000 },
+  { -24.000000000000000, 1, 25.000000000000000 },
+  { -29.000000000000000, 1, 30.000000000000000 },
+  { -34.000000000000000, 1, 35.000000000000000 },
+  { -39.000000000000000, 1, 40.000000000000000 },
+  { -44.000000000000000, 1, 45.000000000000000 },
+  { -49.000000000000000, 1, 50.000000000000000 },
+  { -54.000000000000000, 1, 55.000000000000000 },
+  { -59.000000000000000, 1, 60.000000000000000 },
+  { -64.000000000000000, 1, 65.000000000000000 },
+  { -69.000000000000000, 1, 70.000000000000000 },
+  { -74.000000000000000, 1, 75.000000000000000 },
+  { -79.000000000000000, 1, 80.000000000000000 },
+  { -84.000000000000000, 1, 85.000000000000000 },
+  { -89.000000000000000, 1, 90.000000000000000 },
+  { -94.000000000000000, 1, 95.000000000000000 },
+  { -99.000000000000000, 1, 100.00000000000000 },
+};
+
+// Test function for n=1.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::laguerre(Tp(data002[i].n), Tp(data002[i].x));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=2.
+testcase_laguerre<double> data003[] = {
+  { 1.0000000000000000, 2, 0.0000000000000000 },
+  { 3.5000000000000000, 2, 5.0000000000000000 },
+  { 31.000000000000000, 2, 10.000000000000000 },
+  { 83.500000000000000, 2, 15.000000000000000 },
+  { 161.00000000000000, 2, 20.000000000000000 },
+  { 263.50000000000000, 2, 25.000000000000000 },
+  { 391.00000000000000, 2, 30.000000000000000 },
+  { 543.50000000000000, 2, 35.000000000000000 },
+  { 721.00000000000000, 2, 40.000000000000000 },
+  { 923.50000000000000, 2, 45.000000000000000 },
+  { 1151.0000000000000, 2, 50.000000000000000 },
+  { 1403.5000000000000, 2, 55.000000000000000 },
+  { 1681.0000000000000, 2, 60.000000000000000 },
+  { 1983.5000000000000, 2, 65.000000000000000 },
+  { 2311.0000000000000, 2, 70.000000000000000 },
+  { 2663.5000000000000, 2, 75.000000000000000 },
+  { 3041.0000000000000, 2, 80.000000000000000 },
+  { 3443.5000000000000, 2, 85.000000000000000 },
+  { 3871.0000000000000, 2, 90.000000000000000 },
+  { 4323.5000000000000, 2, 95.000000000000000 },
+  { 4801.0000000000000, 2, 100.00000000000000 },
+};
+
+// Test function for n=2.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::laguerre(Tp(data003[i].n), Tp(data003[i].x));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=5.
+testcase_laguerre<double> data004[] = {
+  { 1.0000000000000000, 5, 0.0000000000000000 },
+  { -3.1666666666666665, 5, 5.0000000000000000 },
+  { 34.333333333333329, 5, 10.000000000000000 },
+  { -355.25000000000000, 5, 15.000000000000000 },
+  { -4765.6666666666670, 5, 20.000000000000000 },
+  { -23040.666666666664, 5, 25.000000000000000 },
+  { -74399.000000000000, 5, 30.000000000000000 },
+  { -190559.41666666663, 5, 35.000000000000000 },
+  { -418865.66666666663, 5, 40.000000000000000 },
+  { -825411.50000000000, 5, 45.000000000000000 },
+  { -1498165.6666666665, 5, 50.000000000000000 },
+  { -2550096.9166666670, 5, 55.000000000000000 },
+  { -4122299.0000000000, 5, 60.000000000000000 },
+  { -6387115.6666666670, 5, 65.000000000000000 },
+  { -9551265.6666666679, 5, 70.000000000000000 },
+  { -13858967.750000000, 5, 75.000000000000000 },
+  { -19595065.666666664, 5, 80.000000000000000 },
+  { -27088153.166666668, 5, 85.000000000000000 },
+  { -36713699.000000000, 5, 90.000000000000000 },
+  { -48897171.916666657, 5, 95.000000000000000 },
+  { -64117165.666666664, 5, 100.00000000000000 },
+};
+
+// Test function for n=5.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::laguerre(Tp(data004[i].n), Tp(data004[i].x));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=10.
+testcase_laguerre<double> data005[] = {
+  { 1.0000000000000000, 10, 0.0000000000000000 },
+  { 1.7562761794532631, 10, 5.0000000000000000 },
+  { 27.984126984126977, 10, 10.000000000000000 },
+  { -237.51841517857147, 10, 15.000000000000000 },
+  { 3227.8077601410932, 10, 20.000000000000000 },
+  { -45786.199797453693, 10, 25.000000000000000 },
+  { 15129.571428571455, 10, 30.000000000000000 },
+  { 7764800.8179494590, 10, 35.000000000000000 },
+  { 79724066.608465582, 10, 40.000000000000000 },
+  { 469865425.65122765, 10, 45.000000000000000 },
+  { 2037190065.3738980, 10, 50.000000000000000 },
+  { 7187828002.9825764, 10, 55.000000000000000 },
+  { 21804200401.000000, 10, 60.000000000000000 },
+  { 58854343015.616211, 10, 65.000000000000000 },
+  { 144688291819.51855, 10, 70.000000000000000 },
+  { 329425241736.70038, 10, 75.000000000000000 },
+  { 703324772760.08276, 10, 80.000000000000000 },
+  { 1421627560118.6157, 10, 85.000000000000000 },
+  { 2741055412243.8569, 10, 90.000000000000000 },
+  { 5071986977681.8652, 10, 95.000000000000000 },
+  { 9051283795429.5723, 10, 100.00000000000000 },
+};
+
+// Test function for n=10.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::laguerre(Tp(data005[i].n), Tp(data005[i].x));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=20.
+testcase_laguerre<double> data006[] = {
+  { 1.0000000000000000, 20, 0.0000000000000000 },
+  { 2.0202257444769134, 20, 5.0000000000000000 },
+  { -11.961333867812119, 20, 10.000000000000000 },
+  { -50.151037960139455, 20, 15.000000000000000 },
+  { 2829.4728613531743, 20, 20.000000000000000 },
+  { -11583.947899113540, 20, 25.000000000000000 },
+  { -18439.424502520938, 20, 30.000000000000000 },
+  { -38838.223606979285, 20, 35.000000000000000 },
+  { 24799805.877530713, 20, 40.000000000000000 },
+  { -673953823.59913278, 20, 45.000000000000000 },
+  { 7551960453.7672548, 20, 50.000000000000000 },
+  { 31286508510.614746, 20, 55.000000000000000 },
+  { -1379223608444.9155, 20, 60.000000000000000 },
+  { -6692517968212.9717, 20, 65.000000000000000 },
+  { 165423821874449.94, 20, 70.000000000000000 },
+  { 3082390018008546.5, 20, 75.000000000000000 },
+  { 29500368536981676., 20, 80.000000000000000 },
+  { 2.0353526354974186e+17, 20, 85.000000000000000 },
+  { 1.1292309514432901e+18, 20, 90.000000000000000 },
+  { 5.3239262855563100e+18, 20, 95.000000000000000 },
+  { 2.2061882785931735e+19, 20, 100.00000000000000 },
+};
+
+// Test function for n=20.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::laguerre(Tp(data006[i].n), Tp(data006[i].x));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for n=50.
+testcase_laguerre<double> data007[] = {
+  { 1.0000000000000000, 50, 0.0000000000000000 },
+  { 1.4735258819430543, 50, 5.0000000000000000 },
+  { 17.534183446338233, 50, 10.000000000000000 },
+  { -195.62436619077380, 50, 15.000000000000000 },
+  { 980.26961889791028, 50, 20.000000000000000 },
+  { 24812.277673870878, 50, 25.000000000000000 },
+  { 293000.50735962362, 50, 30.000000000000000 },
+  { 2316195.5013375278, 50, 35.000000000000000 },
+  { -14896937.968694873, 50, 40.000000000000000 },
+  { -502066598.00813466, 50, 45.000000000000000 },
+  { 2513677852.6916871, 50, 50.000000000000000 },
+  { 45129675503.538910, 50, 55.000000000000000 },
+  { -883876565337.99219, 50, 60.000000000000000 },
+  { 9361319947203.8418, 50, 65.000000000000000 },
+  { -80967880733583.234, 50, 70.000000000000000 },
+  { 717391079438942.62, 50, 75.000000000000000 },
+  { -8217471769564841.0, 50, 80.000000000000000 },
+  { 1.2595276229009978e+17, 50, 85.000000000000000 },
+  { -2.1140031308048891e+18, 50, 90.000000000000000 },
+  { 3.2438187475835134e+19, 50, 95.000000000000000 },
+  { -3.9710103487094692e+20, 50, 100.00000000000000 },
+};
+
+// Test function for n=50.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::laguerre(Tp(data007[i].n), Tp(data007[i].x));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for n=100.
+testcase_laguerre<double> data008[] = {
+  { 1.0000000000000000, 100, 0.0000000000000000 },
+  { 1.4555271625328801, 100, 5.0000000000000000 },
+  { 13.277662844303450, 100, 10.000000000000000 },
+  { 91.737038454342454, 100, 15.000000000000000 },
+  { 1854.0367283243388, 100, 20.000000000000000 },
+  { -11281.698886837261, 100, 25.000000000000000 },
+  { 170141.86987046551, 100, 30.000000000000000 },
+  { -2950092.7025822806, 100, 35.000000000000000 },
+  { -7272442.3156006960, 100, 40.000000000000000 },
+  { 295697471.90876162, 100, 45.000000000000000 },
+  { 4847420871.2690506, 100, 50.000000000000000 },
+  { 59406998102.392288, 100, 55.000000000000000 },
+  { 693492765740.29688, 100, 60.000000000000000 },
+  { 6606192010150.3154, 100, 65.000000000000000 },
+  { 17125518672239.770, 100, 70.000000000000000 },
+  { -870493767065150.12, 100, 75.000000000000000 },
+  { -13763178176383768., 100, 80.000000000000000 },
+  { 30667078414479584., 100, 85.000000000000000 },
+  { 2.1307220490380173e+18, 100, 90.000000000000000 },
+  { -7.2706523009007821e+18, 100, 95.000000000000000 },
+  { -2.6292260693068916e+20, 100, 100.00000000000000 },
+};
+
+// Test function for n=100.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_laguerre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::laguerre(Tp(data008[i].n), Tp(data008[i].x));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  return 0;
+}
Index: testsuite/special_functions/16_laguerre/compile.cc
===================================================================
--- testsuite/special_functions/16_laguerre/compile.cc	(revision 0)
+++ testsuite/special_functions/16_laguerre/compile.cc	(working copy)
@@ -0,0 +1,42 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.16 laguerre
+
+#include <cmath>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+
+  unsigned int n = 2;
+
+  std::laguerre(n, xf);
+  std::laguerref(n, xf);
+  std::laguerre(n, xd);
+  std::laguerre(n, xl);
+  std::laguerrel(n, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/16_laguerre/compile_2.cc
===================================================================
--- testsuite/special_functions/16_laguerre/compile_2.cc	(revision 0)
+++ testsuite/special_functions/16_laguerre/compile_2.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.16 laguerre
+
+#include <math.h>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+  unsigned int n = 2;
+
+  laguerre(n, xf);
+  laguerref(n, xf);
+  laguerre(n, xd);
+  laguerre(n, xl);
+  laguerrel(n, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/17_legendre/check_nan.cc
===================================================================
--- testsuite/special_functions/17_legendre/check_nan.cc	(revision 0)
+++ testsuite/special_functions/17_legendre/check_nan.cc	(working copy)
@@ -0,0 +1,59 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.17 legendre
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  unsigned int l = 2;
+
+  float a = std::legendre(l, xf);
+  float b = std::legendref(l, xf);
+  double c = std::legendre(l, xd);
+  long double d = std::legendre(l, xl);
+  long double e = std::legendrel(l, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/17_legendre/check_value.cc
===================================================================
--- testsuite/special_functions/17_legendre/check_value.cc	(revision 0)
+++ testsuite/special_functions/17_legendre/check_value.cc	(working copy)
@@ -0,0 +1,484 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  legendre
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for l=0.
+testcase_legendre<double> data001[] = {
+  { 1.0000000000000000, 0, -1.0000000000000000 },
+  { 1.0000000000000000, 0, -0.90000000000000002 },
+  { 1.0000000000000000, 0, -0.80000000000000004 },
+  { 1.0000000000000000, 0, -0.69999999999999996 },
+  { 1.0000000000000000, 0, -0.59999999999999998 },
+  { 1.0000000000000000, 0, -0.50000000000000000 },
+  { 1.0000000000000000, 0, -0.40000000000000002 },
+  { 1.0000000000000000, 0, -0.30000000000000004 },
+  { 1.0000000000000000, 0, -0.19999999999999996 },
+  { 1.0000000000000000, 0, -0.099999999999999978 },
+  { 1.0000000000000000, 0, 0.0000000000000000 },
+  { 1.0000000000000000, 0, 0.10000000000000009 },
+  { 1.0000000000000000, 0, 0.19999999999999996 },
+  { 1.0000000000000000, 0, 0.30000000000000004 },
+  { 1.0000000000000000, 0, 0.39999999999999991 },
+  { 1.0000000000000000, 0, 0.50000000000000000 },
+  { 1.0000000000000000, 0, 0.60000000000000009 },
+  { 1.0000000000000000, 0, 0.69999999999999996 },
+  { 1.0000000000000000, 0, 0.80000000000000004 },
+  { 1.0000000000000000, 0, 0.89999999999999991 },
+  { 1.0000000000000000, 0, 1.0000000000000000 },
+};
+
+// Test function for l=0.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::legendre(Tp(data001[i].l), Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=1.
+testcase_legendre<double> data002[] = {
+  { -1.0000000000000000, 1, -1.0000000000000000 },
+  { -0.90000000000000002, 1, -0.90000000000000002 },
+  { -0.80000000000000004, 1, -0.80000000000000004 },
+  { -0.69999999999999996, 1, -0.69999999999999996 },
+  { -0.59999999999999998, 1, -0.59999999999999998 },
+  { -0.50000000000000000, 1, -0.50000000000000000 },
+  { -0.40000000000000002, 1, -0.40000000000000002 },
+  { -0.30000000000000004, 1, -0.30000000000000004 },
+  { -0.19999999999999996, 1, -0.19999999999999996 },
+  { -0.099999999999999978, 1, -0.099999999999999978 },
+  { 0.0000000000000000, 1, 0.0000000000000000 },
+  { 0.10000000000000009, 1, 0.10000000000000009 },
+  { 0.19999999999999996, 1, 0.19999999999999996 },
+  { 0.30000000000000004, 1, 0.30000000000000004 },
+  { 0.39999999999999991, 1, 0.39999999999999991 },
+  { 0.50000000000000000, 1, 0.50000000000000000 },
+  { 0.60000000000000009, 1, 0.60000000000000009 },
+  { 0.69999999999999996, 1, 0.69999999999999996 },
+  { 0.80000000000000004, 1, 0.80000000000000004 },
+  { 0.89999999999999991, 1, 0.89999999999999991 },
+  { 1.0000000000000000, 1, 1.0000000000000000 },
+};
+
+// Test function for l=1.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::legendre(Tp(data002[i].l), Tp(data002[i].x));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=2.
+testcase_legendre<double> data003[] = {
+  { 1.0000000000000000, 2, -1.0000000000000000 },
+  { 0.71500000000000008, 2, -0.90000000000000002 },
+  { 0.46000000000000019, 2, -0.80000000000000004 },
+  { 0.23499999999999988, 2, -0.69999999999999996 },
+  { 0.039999999999999925, 2, -0.59999999999999998 },
+  { -0.12500000000000000, 2, -0.50000000000000000 },
+  { -0.25999999999999995, 2, -0.40000000000000002 },
+  { -0.36499999999999999, 2, -0.30000000000000004 },
+  { -0.44000000000000006, 2, -0.19999999999999996 },
+  { -0.48499999999999999, 2, -0.099999999999999978 },
+  { -0.50000000000000000, 2, 0.0000000000000000 },
+  { -0.48499999999999999, 2, 0.10000000000000009 },
+  { -0.44000000000000006, 2, 0.19999999999999996 },
+  { -0.36499999999999999, 2, 0.30000000000000004 },
+  { -0.26000000000000012, 2, 0.39999999999999991 },
+  { -0.12500000000000000, 2, 0.50000000000000000 },
+  { 0.040000000000000147, 2, 0.60000000000000009 },
+  { 0.23499999999999988, 2, 0.69999999999999996 },
+  { 0.46000000000000019, 2, 0.80000000000000004 },
+  { 0.71499999999999986, 2, 0.89999999999999991 },
+  { 1.0000000000000000, 2, 1.0000000000000000 },
+};
+
+// Test function for l=2.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::legendre(Tp(data003[i].l), Tp(data003[i].x));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=5.
+testcase_legendre<double> data004[] = {
+  { -1.0000000000000000, 5, -1.0000000000000000 },
+  { 0.041141250000000087, 5, -0.90000000000000002 },
+  { 0.39951999999999993, 5, -0.80000000000000004 },
+  { 0.36519874999999991, 5, -0.69999999999999996 },
+  { 0.15263999999999994, 5, -0.59999999999999998 },
+  { -0.089843750000000000, 5, -0.50000000000000000 },
+  { -0.27063999999999994, 5, -0.40000000000000002 },
+  { -0.34538625000000001, 5, -0.30000000000000004 },
+  { -0.30751999999999996, 5, -0.19999999999999996 },
+  { -0.17882874999999995, 5, -0.099999999999999978 },
+  { 0.0000000000000000, 5, 0.0000000000000000 },
+  { 0.17882875000000015, 5, 0.10000000000000009 },
+  { 0.30751999999999996, 5, 0.19999999999999996 },
+  { 0.34538625000000001, 5, 0.30000000000000004 },
+  { 0.27064000000000010, 5, 0.39999999999999991 },
+  { 0.089843750000000000, 5, 0.50000000000000000 },
+  { -0.15264000000000016, 5, 0.60000000000000009 },
+  { -0.36519874999999991, 5, 0.69999999999999996 },
+  { -0.39951999999999993, 5, 0.80000000000000004 },
+  { -0.041141250000000261, 5, 0.89999999999999991 },
+  { 1.0000000000000000, 5, 1.0000000000000000 },
+};
+
+// Test function for l=5.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::legendre(Tp(data004[i].l), Tp(data004[i].x));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10.
+testcase_legendre<double> data005[] = {
+  { 1.0000000000000000, 10, -1.0000000000000000 },
+  { -0.26314561785585960, 10, -0.90000000000000002 },
+  { 0.30052979560000004, 10, -0.80000000000000004 },
+  { 0.085805795531640333, 10, -0.69999999999999996 },
+  { -0.24366274560000001, 10, -0.59999999999999998 },
+  { -0.18822860717773438, 10, -0.50000000000000000 },
+  { 0.096839064399999925, 10, -0.40000000000000002 },
+  { 0.25147634951601561, 10, -0.30000000000000004 },
+  { 0.12907202559999983, 10, -0.19999999999999996 },
+  { -0.12212499738710943, 10, -0.099999999999999978 },
+  { -0.24609375000000000, 10, 0.0000000000000000 },
+  { -0.12212499738710922, 10, 0.10000000000000009 },
+  { 0.12907202559999983, 10, 0.19999999999999996 },
+  { 0.25147634951601561, 10, 0.30000000000000004 },
+  { 0.096839064400000258, 10, 0.39999999999999991 },
+  { -0.18822860717773438, 10, 0.50000000000000000 },
+  { -0.24366274559999984, 10, 0.60000000000000009 },
+  { 0.085805795531640333, 10, 0.69999999999999996 },
+  { 0.30052979560000004, 10, 0.80000000000000004 },
+  { -0.26314561785585899, 10, 0.89999999999999991 },
+  { 1.0000000000000000, 10, 1.0000000000000000 },
+};
+
+// Test function for l=10.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::legendre(Tp(data005[i].l), Tp(data005[i].x));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=20.
+testcase_legendre<double> data006[] = {
+  { 1.0000000000000000, 20, -1.0000000000000000 },
+  { -0.14930823530984835, 20, -0.90000000000000002 },
+  { 0.22420460541741347, 20, -0.80000000000000004 },
+  { -0.20457394463834172, 20, -0.69999999999999996 },
+  { 0.15916752910098109, 20, -0.59999999999999998 },
+  { -0.048358381067373557, 20, -0.50000000000000000 },
+  { -0.10159261558628156, 20, -0.40000000000000002 },
+  { 0.18028715947998042, 20, -0.30000000000000004 },
+  { -0.098042194344594796, 20, -0.19999999999999996 },
+  { -0.082077130944527663, 20, -0.099999999999999978 },
+  { 0.17619705200195312, 20, 0.0000000000000000 },
+  { -0.082077130944528023, 20, 0.10000000000000009 },
+  { -0.098042194344594796, 20, 0.19999999999999996 },
+  { 0.18028715947998042, 20, 0.30000000000000004 },
+  { -0.10159261558628112, 20, 0.39999999999999991 },
+  { -0.048358381067373557, 20, 0.50000000000000000 },
+  { 0.15916752910098075, 20, 0.60000000000000009 },
+  { -0.20457394463834172, 20, 0.69999999999999996 },
+  { 0.22420460541741347, 20, 0.80000000000000004 },
+  { -0.14930823530984924, 20, 0.89999999999999991 },
+  { 1.0000000000000000, 20, 1.0000000000000000 },
+};
+
+// Test function for l=20.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::legendre(Tp(data006[i].l), Tp(data006[i].x));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=50.
+testcase_legendre<double> data007[] = {
+  { 1.0000000000000000, 50, -1.0000000000000000 },
+  { -0.17003765994383671, 50, -0.90000000000000002 },
+  { 0.13879737345093113, 50, -0.80000000000000004 },
+  { -0.014572731645892852, 50, -0.69999999999999996 },
+  { -0.058860798844002096, 50, -0.59999999999999998 },
+  { -0.031059099239609811, 50, -0.50000000000000000 },
+  { 0.041569033381825375, 50, -0.40000000000000002 },
+  { 0.10911051574714797, 50, -0.30000000000000004 },
+  { 0.083432272204197494, 50, -0.19999999999999996 },
+  { -0.038205812661313600, 50, -0.099999999999999978 },
+  { -0.11227517265921705, 50, 0.0000000000000000 },
+  { -0.038205812661314155, 50, 0.10000000000000009 },
+  { 0.083432272204197494, 50, 0.19999999999999996 },
+  { 0.10911051574714797, 50, 0.30000000000000004 },
+  { 0.041569033381824674, 50, 0.39999999999999991 },
+  { -0.031059099239609811, 50, 0.50000000000000000 },
+  { -0.058860798844001430, 50, 0.60000000000000009 },
+  { -0.014572731645892852, 50, 0.69999999999999996 },
+  { 0.13879737345093113, 50, 0.80000000000000004 },
+  { -0.17003765994383657, 50, 0.89999999999999991 },
+  { 1.0000000000000000, 50, 1.0000000000000000 },
+};
+
+// Test function for l=50.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::legendre(Tp(data007[i].l), Tp(data007[i].x));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=100.
+testcase_legendre<double> data008[] = {
+  { 1.0000000000000000, 100, -1.0000000000000000 },
+  { 0.10226582055871893, 100, -0.90000000000000002 },
+  { 0.050861167913584228, 100, -0.80000000000000004 },
+  { -0.077132507199778641, 100, -0.69999999999999996 },
+  { -0.023747023905133141, 100, -0.59999999999999998 },
+  { -0.060518025961861198, 100, -0.50000000000000000 },
+  { -0.072258202125684470, 100, -0.40000000000000002 },
+  { 0.057127392202801566, 100, -0.30000000000000004 },
+  { 0.014681835355659706, 100, -0.19999999999999996 },
+  { -0.063895098434750205, 100, -0.099999999999999978 },
+  { 0.079589237387178727, 100, 0.0000000000000000 },
+  { -0.063895098434749761, 100, 0.10000000000000009 },
+  { 0.014681835355659706, 100, 0.19999999999999996 },
+  { 0.057127392202801566, 100, 0.30000000000000004 },
+  { -0.072258202125685025, 100, 0.39999999999999991 },
+  { -0.060518025961861198, 100, 0.50000000000000000 },
+  { -0.023747023905134217, 100, 0.60000000000000009 },
+  { -0.077132507199778641, 100, 0.69999999999999996 },
+  { 0.050861167913584228, 100, 0.80000000000000004 },
+  { 0.10226582055871711, 100, 0.89999999999999991 },
+  { 1.0000000000000000, 100, 1.0000000000000000 },
+};
+
+// Test function for l=100.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::legendre(Tp(data008[i].l), Tp(data008[i].x));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  return 0;
+}
Index: testsuite/special_functions/17_legendre/compile.cc
===================================================================
--- testsuite/special_functions/17_legendre/compile.cc	(revision 0)
+++ testsuite/special_functions/17_legendre/compile.cc	(working copy)
@@ -0,0 +1,42 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.17 legendre
+
+#include <cmath>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+
+  unsigned int l = 2;
+
+  std::legendre(l, xf);
+  std::legendref(l, xf);
+  std::legendre(l, xd);
+  std::legendre(l, xl);
+  std::legendrel(l, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/17_legendre/compile_2.cc
===================================================================
--- testsuite/special_functions/17_legendre/compile_2.cc	(revision 0)
+++ testsuite/special_functions/17_legendre/compile_2.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.17 legendre
+
+#include <math.h>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+  unsigned int l = 2;
+
+  legendre(l, xf);
+  legendref(l, xf);
+  legendre(l, xd);
+  legendre(l, xl);
+  legendrel(l, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/18_riemann_zeta/check_nan.cc
===================================================================
--- testsuite/special_functions/18_riemann_zeta/check_nan.cc	(revision 0)
+++ testsuite/special_functions/18_riemann_zeta/check_nan.cc	(working copy)
@@ -0,0 +1,56 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.18 riemann_zeta
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  float a = std::riemann_zeta(xf);
+  float b = std::riemann_zetaf(xf);
+  double c = std::riemann_zeta(xd);
+  long double d = std::riemann_zeta(xl);
+  long double e = std::riemann_zetal(xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/18_riemann_zeta/check_value_neg.cc
===================================================================
--- testsuite/special_functions/18_riemann_zeta/check_value_neg.cc	(revision 0)
+++ testsuite/special_functions/18_riemann_zeta/check_value_neg.cc	(working copy)
@@ -0,0 +1,139 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  riemann_zeta
+// This can take long on simulators, timing out the test.
+// { dg-options "-DMAX_ITERATIONS=5" { target simulator } }
+
+#ifndef MAX_ITERATIONS
+#define MAX_ITERATIONS (sizeof(data001) / sizeof(testcase_riemann_zeta<double>))
+#endif
+
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data.
+testcase_riemann_zeta<double> data001[] = {
+  { 0.0000000000000000, -10.000000000000000 },
+  { -0.0033669820451019579, -9.8000000000000007 },
+  { -0.0058129517767319039, -9.5999999999999996 },
+  { -0.0072908732290557004, -9.4000000000000004 },
+  { -0.0078420910654484442, -9.1999999999999993 },
+  { -0.0075757575757575803, -9.0000000000000000 },
+  { -0.0066476555677551898, -8.8000000000000007 },
+  { -0.0052400095350859429, -8.5999999999999996 },
+  { -0.0035434308017674959, -8.4000000000000004 },
+  { -0.0017417330388368585, -8.1999999999999993 },
+  { 0.0000000000000000, -8.0000000000000000 },
+  { 0.0015440036789213961, -7.7999999999999998 },
+  { 0.0027852131086497423, -7.5999999999999996 },
+  { 0.0036537321227995880, -7.4000000000000004 },
+  { 0.0041147930817053468, -7.2000000000000002 },
+  { 0.0041666666666666683, -7.0000000000000000 },
+  { 0.0038369975032738366, -6.7999999999999998 },
+  { 0.0031780270571782981, -6.5999999999999996 },
+  { 0.0022611282027338573, -6.4000000000000004 },
+  { 0.0011710237049390511, -6.2000000000000002 },
+  { 0.0000000000000000, -6.0000000000000000 },
+  { -0.0011576366649881879, -5.7999999999999998 },
+  { -0.0022106784318564345, -5.5999999999999996 },
+  { -0.0030755853460586891, -5.4000000000000004 },
+  { -0.0036804380477934787, -5.2000000000000002 },
+  { -0.0039682539682539698, -5.0000000000000000 },
+  { -0.0038996891301999797, -4.7999999999999998 },
+  { -0.0034551830834302711, -4.5999999999999996 },
+  { -0.0026366345018725115, -4.4000000000000004 },
+  { -0.0014687209305056974, -4.2000000000000002 },
+  { 0.0000000000000000, -4.0000000000000000 },
+  { 0.0016960463875825202, -3.7999999999999998 },
+  { 0.0035198355903356747, -3.5999999999999996 },
+  { 0.0053441503206513421, -3.4000000000000004 },
+  { 0.0070119720770910540, -3.2000000000000002 },
+  { 0.0083333333333333350, -3.0000000000000000 },
+  { 0.0090807294856852811, -2.7999999999999998 },
+  { 0.0089824623788396681, -2.5999999999999996 },
+  { 0.0077130239874243630, -2.4000000000000004 },
+  { 0.0048792123593036068, -2.2000000000000002 },
+  { 0.0000000000000000, -2.0000000000000000 },
+  { -0.0075229347765968010, -1.8000000000000007 },
+  { -0.018448986678963775, -1.5999999999999996 },
+  { -0.033764987694047593, -1.4000000000000004 },
+  { -0.054788441243880631, -1.1999999999999993 },
+  { -0.083333333333333398, -1.0000000000000000 },
+  { -0.12198707766977103, -0.80000000000000071 },
+  { -0.17459571193801401, -0.59999999999999964 },
+  { -0.24716546083171492, -0.40000000000000036 },
+  { -0.34966628059831484, -0.19999999999999929 },
+  { -0.49999999999999994, 0.0000000000000000 },
+  { -0.73392092489633953, 0.19999999999999929 },
+  { -1.1347977838669825, 0.40000000000000036 },
+  { -1.9526614482239983, 0.59999999999999964 },
+  { -4.4375384158955677, 0.80000000000000071 },
+};
+
+// Test function.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = MAX_ITERATIONS;
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::riemann_zeta(Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(0.025000000000000001));
+  }
+
+int
+main()
+{
+  test001<double>();
+  return 0;
+}
Index: testsuite/special_functions/18_riemann_zeta/check_value_pos.cc
===================================================================
--- testsuite/special_functions/18_riemann_zeta/check_value_pos.cc	(revision 0)
+++ testsuite/special_functions/18_riemann_zeta/check_value_pos.cc	(working copy)
@@ -0,0 +1,229 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  riemann_zeta
+// This can take long on simulators, timing out the test.
+// { dg-options "-DMAX_ITERATIONS=5" { target simulator } }
+
+#ifndef MAX_ITERATIONS
+#define MAX_ITERATIONS (sizeof(data001) / sizeof(testcase_riemann_zeta<double>))
+#endif
+
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data.
+testcase_riemann_zeta<double> data001[] = {
+  { 5.5915824411777502, 1.2000000000000000 },
+  { 3.1055472779775792, 1.3999999999999999 },
+  { 2.2857656656801324, 1.6000000000000001 },
+  { 1.8822296181028220, 1.8000000000000000 },
+  { 1.6449340668482275, 2.0000000000000000 },
+  { 1.4905432565068937, 2.2000000000000002 },
+  { 1.3833428588407359, 2.3999999999999999 },
+  { 1.3054778090727803, 2.6000000000000001 },
+  { 1.2470314223172541, 2.7999999999999998 },
+  { 1.2020569031595945, 3.0000000000000000 },
+  { 1.1667733709844674, 3.2000000000000002 },
+  { 1.1386637757280420, 3.3999999999999999 },
+  { 1.1159890791233376, 3.6000000000000001 },
+  { 1.0975105764590047, 3.7999999999999998 },
+  { 1.0823232337111381, 4.0000000000000000 },
+  { 1.0697514772338095, 4.2000000000000002 },
+  { 1.0592817259798355, 4.4000000000000004 },
+  { 1.0505173825665735, 4.5999999999999996 },
+  { 1.0431480133351789, 4.7999999999999998 },
+  { 1.0369277551433700, 5.0000000000000000 },
+  { 1.0316598766779168, 5.2000000000000002 },
+  { 1.0271855389203537, 5.4000000000000004 },
+  { 1.0233754792270300, 5.5999999999999996 },
+  { 1.0201237683883446, 5.7999999999999998 },
+  { 1.0173430619844492, 6.0000000000000000 },
+  { 1.0149609451852233, 6.2000000000000002 },
+  { 1.0129170887121841, 6.4000000000000004 },
+  { 1.0111610141542708, 6.5999999999999996 },
+  { 1.0096503223447120, 6.7999999999999998 },
+  { 1.0083492773819229, 7.0000000000000000 },
+  { 1.0072276664807169, 7.2000000000000002 },
+  { 1.0062598756930512, 7.4000000000000004 },
+  { 1.0054241359879634, 7.5999999999999996 },
+  { 1.0047019048164696, 7.7999999999999998 },
+  { 1.0040773561979444, 8.0000000000000000 },
+  { 1.0035369583062013, 8.1999999999999993 },
+  { 1.0030691220374448, 8.4000000000000004 },
+  { 1.0026639074861505, 8.5999999999999996 },
+  { 1.0023127779098220, 8.8000000000000007 },
+  { 1.0020083928260823, 9.0000000000000000 },
+  { 1.0017444334995897, 9.1999999999999993 },
+  { 1.0015154553480514, 9.4000000000000004 },
+  { 1.0013167628052648, 9.5999999999999996 },
+  { 1.0011443029840295, 9.8000000000000007 },
+  { 1.0009945751278182, 10.000000000000000 },
+  { 1.0008645533615086, 10.199999999999999 },
+  { 1.0007516206744649, 10.400000000000000 },
+  { 1.0006535124140847, 10.600000000000000 },
+  { 1.0005682678503411, 10.800000000000001 },
+  { 1.0004941886041194, 11.000000000000000 },
+  { 1.0004298029239944, 11.199999999999999 },
+  { 1.0003738349551168, 11.400000000000000 },
+  { 1.0003251782761946, 11.600000000000000 },
+  { 1.0002828730909989, 11.800000000000001 },
+  { 1.0002460865533080, 12.000000000000000 },
+  { 1.0002140957818750, 12.199999999999999 },
+  { 1.0001862731874056, 12.400000000000000 },
+  { 1.0001620737887460, 12.600000000000000 },
+  { 1.0001410242422089, 12.800000000000001 },
+  { 1.0001227133475783, 13.000000000000000 },
+  { 1.0001067838280169, 13.199999999999999 },
+  { 1.0000929252097515, 13.400000000000000 },
+  { 1.0000808676518718, 13.600000000000000 },
+  { 1.0000703765974504, 13.800000000000001 },
+  { 1.0000612481350588, 14.000000000000000 },
+  { 1.0000533049750668, 14.199999999999999 },
+  { 1.0000463929582293, 14.400000000000000 },
+  { 1.0000403780253397, 14.600000000000000 },
+  { 1.0000351435864272, 14.800000000000001 },
+  { 1.0000305882363070, 15.000000000000000 },
+  { 1.0000266237704787, 15.199999999999999 },
+  { 1.0000231734615617, 15.400000000000000 },
+  { 1.0000201705617975, 15.600000000000000 },
+  { 1.0000175570017611, 15.800000000000001 },
+  { 1.0000152822594086, 16.000000000000000 },
+  { 1.0000133023770337, 16.199999999999999 },
+  { 1.0000115791066830, 16.399999999999999 },
+  { 1.0000100791671644, 16.600000000000001 },
+  { 1.0000087735980010, 16.800000000000001 },
+  { 1.0000076371976379, 17.000000000000000 },
+  { 1.0000066480348633, 17.199999999999999 },
+  { 1.0000057870238734, 17.399999999999999 },
+  { 1.0000050375546607, 17.600000000000001 },
+  { 1.0000043851715013, 17.800000000000001 },
+  { 1.0000038172932648, 18.000000000000000 },
+  { 1.0000033229700953, 18.199999999999999 },
+  { 1.0000028926717153, 18.399999999999999 },
+  { 1.0000025181032419, 18.600000000000001 },
+  { 1.0000021920449287, 18.800000000000001 },
+  { 1.0000019082127167, 19.000000000000000 },
+  { 1.0000016611368951, 19.199999999999999 },
+  { 1.0000014460565094, 19.399999999999999 },
+  { 1.0000012588274738, 19.600000000000001 },
+  { 1.0000010958426055, 19.800000000000001 },
+  { 1.0000009539620338, 20.000000000000000 },
+  { 1.0000008304526344, 20.199999999999999 },
+  { 1.0000007229353187, 20.399999999999999 },
+  { 1.0000006293391575, 20.600000000000001 },
+  { 1.0000005478614529, 20.800000000000001 },
+  { 1.0000004769329869, 21.000000000000000 },
+  { 1.0000004151877719, 21.199999999999999 },
+  { 1.0000003614367254, 21.399999999999999 },
+  { 1.0000003146447527, 21.600000000000001 },
+  { 1.0000002739108020, 21.800000000000001 },
+  { 1.0000002384505029, 22.000000000000000 },
+  { 1.0000002075810521, 22.199999999999999 },
+  { 1.0000001807080625, 22.399999999999999 },
+  { 1.0000001573141093, 22.600000000000001 },
+  { 1.0000001369487659, 22.800000000000001 },
+  { 1.0000001192199262, 23.000000000000000 },
+  { 1.0000001037862520, 23.199999999999999 },
+  { 1.0000000903506006, 23.399999999999999 },
+  { 1.0000000786543011, 23.600000000000001 },
+  { 1.0000000684721728, 23.800000000000001 },
+  { 1.0000000596081891, 24.000000000000000 },
+  { 1.0000000518917020, 24.199999999999999 },
+  { 1.0000000451741575, 24.399999999999999 },
+  { 1.0000000393262332, 24.600000000000001 },
+  { 1.0000000342353501, 24.800000000000001 },
+  { 1.0000000298035037, 25.000000000000000 },
+  { 1.0000000259453767, 25.199999999999999 },
+  { 1.0000000225866978, 25.399999999999999 },
+  { 1.0000000196628109, 25.600000000000001 },
+  { 1.0000000171174297, 25.800000000000001 },
+  { 1.0000000149015549, 26.000000000000000 },
+  { 1.0000000129725304, 26.199999999999999 },
+  { 1.0000000112932221, 26.399999999999999 },
+  { 1.0000000098313035, 26.600000000000001 },
+  { 1.0000000085586331, 26.800000000000001 },
+  { 1.0000000074507118, 27.000000000000000 },
+  { 1.0000000064862125, 27.199999999999999 },
+  { 1.0000000056465688, 27.399999999999999 },
+  { 1.0000000049156179, 27.600000000000001 },
+  { 1.0000000042792894, 27.800000000000001 },
+  { 1.0000000037253340, 28.000000000000000 },
+  { 1.0000000032430887, 28.199999999999999 },
+  { 1.0000000028232703, 28.399999999999999 },
+  { 1.0000000024577977, 28.600000000000001 },
+  { 1.0000000021396356, 28.800000000000001 },
+  { 1.0000000018626598, 29.000000000000000 },
+  { 1.0000000016215385, 29.199999999999999 },
+  { 1.0000000014116306, 29.399999999999999 },
+  { 1.0000000012288952, 29.600000000000001 },
+  { 1.0000000010698147, 29.800000000000001 },
+  { 1.0000000009313275, 30.000000000000000 },
+};
+
+// Test function.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = MAX_ITERATIONS;
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::riemann_zeta(Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(0.025000000000000001));
+  }
+
+int
+main()
+{
+  test001<double>();
+  return 0;
+}
Index: testsuite/special_functions/18_riemann_zeta/compile.cc
===================================================================
--- testsuite/special_functions/18_riemann_zeta/compile.cc	(revision 0)
+++ testsuite/special_functions/18_riemann_zeta/compile.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.18 riemann_zeta
+
+#include <cmath>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+
+  std::riemann_zeta(xf);
+  std::riemann_zetaf(xf);
+  std::riemann_zeta(xd);
+  std::riemann_zeta(xl);
+  std::riemann_zetal(xl);
+
+  return;
+}
+
Index: testsuite/special_functions/18_riemann_zeta/compile_2.cc
===================================================================
--- testsuite/special_functions/18_riemann_zeta/compile_2.cc	(revision 0)
+++ testsuite/special_functions/18_riemann_zeta/compile_2.cc	(working copy)
@@ -0,0 +1,40 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.18 riemann_zeta
+
+#include <math.h>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+
+  riemann_zeta(xf);
+  riemann_zetaf(xf);
+  riemann_zeta(xd);
+  riemann_zeta(xl);
+  riemann_zetal(xl);
+
+  return;
+}
+
Index: testsuite/special_functions/19_sph_bessel/check_nan.cc
===================================================================
--- testsuite/special_functions/19_sph_bessel/check_nan.cc	(revision 0)
+++ testsuite/special_functions/19_sph_bessel/check_nan.cc	(working copy)
@@ -0,0 +1,58 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.19 sph_bessel
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  unsigned int n = 0;
+
+  float a = std::sph_bessel(n, xf);
+  float b = std::sph_besself(n, xf);
+  double c = std::sph_bessel(n, xd);
+  long double d = std::sph_bessel(n, xl);
+  long double e = std::sph_bessell(n, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/19_sph_bessel/check_value.cc
===================================================================
--- testsuite/special_functions/19_sph_bessel/check_value.cc	(revision 0)
+++ testsuite/special_functions/19_sph_bessel/check_value.cc	(working copy)
@@ -0,0 +1,484 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  sph_bessel
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for n=0.
+testcase_sph_bessel<double> data001[] = {
+  { 1.0000000000000000, 0, 0.0000000000000000 },
+  { -0.19178485493262770, 0, 5.0000000000000000 },
+  { -0.054402111088936979, 0, 10.000000000000000 },
+  { 0.043352522677141132, 0, 15.000000000000000 },
+  { 0.045647262536381385, 0, 20.000000000000000 },
+  { -0.0052940700039109216, 0, 25.000000000000000 },
+  { -0.032934387469762058, 0, 30.000000000000000 },
+  { -0.012233790557032885, 0, 35.000000000000000 },
+  { 0.018627829011983722, 0, 40.000000000000000 },
+  { 0.018908967211869299, 0, 45.000000000000000 },
+  { -0.0052474970740785751, 0, 50.000000000000000 },
+  { -0.018177366788338544, 0, 55.000000000000000 },
+  { -0.0050801770183702783, 0, 60.000000000000000 },
+  { 0.012720441222924669, 0, 65.000000000000000 },
+  { 0.011055581165112701, 0, 70.000000000000000 },
+  { -0.0051704218054590724, 0, 75.000000000000000 },
+  { -0.012423608174042190, 0, 80.000000000000000 },
+  { -0.0020714778817480834, 0, 85.000000000000000 },
+  { 0.0099332962622284207, 0, 90.000000000000000 },
+  { 0.0071922285761696946, 0, 95.000000000000000 },
+  { -0.0050636564110975880, 0, 100.00000000000000 },
+};
+
+// Test function for n=0.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_sph_bessel<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_bessel(Tp(data001[i].n), Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for n=1.
+testcase_sph_bessel<double> data002[] = {
+  { 0.0000000000000000, 1, 0.0000000000000000 },
+  { -0.095089408079170795, 1, 5.0000000000000000 },
+  { 0.078466941798751549, 1, 10.000000000000000 },
+  { 0.053536029035730827, 1, 15.000000000000000 },
+  { -0.018121739963850528, 1, 20.000000000000000 },
+  { -0.039859875274695380, 1, 25.000000000000000 },
+  { -0.0062395279119115375, 1, 30.000000000000000 },
+  { 0.025470240415270681, 1, 35.000000000000000 },
+  { 0.017139147266606137, 1, 40.000000000000000 },
+  { -0.011253622702352454, 1, 45.000000000000000 },
+  { -0.019404270511323839, 1, 50.000000000000000 },
+  { -0.00073280223727807778, 1, 55.000000000000000 },
+  { 0.015788880056613101, 1, 60.000000000000000 },
+  { 0.0088488352686322581, 1, 65.000000000000000 },
+  { -0.0088894803131598157, 1, 70.000000000000000 },
+  { -0.012358955887069445, 1, 75.000000000000000 },
+  { 0.0012245454458125670, 1, 80.000000000000000 },
+  { 0.011556531358968161, 1, 85.000000000000000 },
+  { 0.0050889656932377623, 1, 90.000000000000000 },
+  { -0.0076103298149331573, 1, 95.000000000000000 },
+  { -0.0086738252869878168, 1, 100.00000000000000 },
+};
+
+// Test function for n=1.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_sph_bessel<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_bessel(Tp(data002[i].n), Tp(data002[i].x));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000028e-11));
+  }
+
+// Test data for n=2.
+testcase_sph_bessel<double> data003[] = {
+  { 0.0000000000000000, 2, 0.0000000000000000 },
+  { 0.13473121008512520, 2, 5.0000000000000000 },
+  { 0.077942193628562445, 2, 10.000000000000000 },
+  { -0.032645316869994966, 2, 15.000000000000000 },
+  { -0.048365523530958965, 2, 20.000000000000000 },
+  { 0.00051088497094747614, 2, 25.000000000000000 },
+  { 0.032310434678570907, 2, 30.000000000000000 },
+  { 0.014416954021198941, 2, 35.000000000000000 },
+  { -0.017342392966988262, 2, 40.000000000000000 },
+  { -0.019659208725359461, 2, 45.000000000000000 },
+  { 0.0040832408433991458, 2, 50.000000000000000 },
+  { 0.018137395757214285, 2, 55.000000000000000 },
+  { 0.0058696210212009327, 2, 60.000000000000000 },
+  { -0.012312033441295490, 2, 65.000000000000000 },
+  { -0.011436558892819550, 2, 70.000000000000000 },
+  { 0.0046760635699762939, 2, 75.000000000000000 },
+  { 0.012469528628260161, 2, 80.000000000000000 },
+  { 0.0024793554591234306, 2, 85.000000000000000 },
+  { -0.0097636640724538277, 2, 90.000000000000000 },
+  { -0.0074325547808517939, 2, 95.000000000000000 },
+  { 0.0048034416524879537, 2, 100.00000000000000 },
+};
+
+// Test function for n=2.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_sph_bessel<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_bessel(Tp(data003[i].n), Tp(data003[i].x));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for n=5.
+testcase_sph_bessel<double> data004[] = {
+  { 0.0000000000000000, 5, 0.0000000000000000 },
+  { 0.10681116145650453, 5, 5.0000000000000000 },
+  { -0.055534511621452155, 5, 10.000000000000000 },
+  { 0.065968007076521951, 5, 15.000000000000000 },
+  { 0.016683908063095682, 5, 20.000000000000000 },
+  { -0.036117795989722382, 5, 25.000000000000000 },
+  { -0.020504008736827489, 5, 30.000000000000000 },
+  { 0.018499481206814560, 5, 35.000000000000000 },
+  { 0.022448773791044995, 5, 40.000000000000000 },
+  { -0.0048552694845020138, 5, 45.000000000000000 },
+  { -0.020048300563664877, 5, 50.000000000000000 },
+  { -0.0052999924455565742, 5, 55.000000000000000 },
+  { 0.014151556281331407, 5, 60.000000000000000 },
+  { 0.011354588594416780, 5, 65.000000000000000 },
+  { -0.0064983781785323573, 5, 70.000000000000000 },
+  { -0.013089909320064257, 5, 75.000000000000000 },
+  { -0.00096200450071302446, 5, 80.000000000000000 },
+  { 0.011048668899130202, 5, 85.000000000000000 },
+  { 0.0065639581708136037, 5, 90.000000000000000 },
+  { -0.0064646119368202771, 5, 95.000000000000000 },
+  { -0.0092901489349075730, 5, 100.00000000000000 },
+};
+
+// Test function for n=5.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_sph_bessel<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_bessel(Tp(data004[i].n), Tp(data004[i].x));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000028e-11));
+  }
+
+// Test data for n=10.
+testcase_sph_bessel<double> data005[] = {
+  { 0.0000000000000000, 10, 0.0000000000000000 },
+  { 0.00040734424424946052, 10, 5.0000000000000000 },
+  { 0.064605154492564265, 10, 10.000000000000000 },
+  { 0.0018969790010883577, 10, 15.000000000000000 },
+  { 0.039686698644626366, 10, 20.000000000000000 },
+  { -0.036253285601128581, 10, 25.000000000000000 },
+  { -0.014529646403897799, 10, 30.000000000000000 },
+  { 0.026281264603993857, 10, 35.000000000000000 },
+  { 0.013124803182748323, 10, 40.000000000000000 },
+  { -0.017600831383728983, 10, 45.000000000000000 },
+  { -0.015039221463465955, 10, 50.000000000000000 },
+  { 0.0095256289349167390, 10, 55.000000000000000 },
+  { 0.015822719394008339, 10, 60.000000000000000 },
+  { -0.0019391391708249756, 10, 65.000000000000000 },
+  { -0.014293389028395012, 10, 70.000000000000000 },
+  { -0.0044210285031696227, 10, 75.000000000000000 },
+  { 0.010516146958338813, 10, 80.000000000000000 },
+  { 0.0086736275131325726, 10, 85.000000000000000 },
+  { -0.0052905066357239322, 10, 90.000000000000000 },
+  { -0.010258326955210768, 10, 95.000000000000000 },
+  { -0.00019565785971342419, 10, 100.00000000000000 },
+};
+
+// Test function for n=10.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_sph_bessel<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_bessel(Tp(data005[i].n), Tp(data005[i].x));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000017e-10));
+  }
+
+// Test data for n=20.
+testcase_sph_bessel<double> data006[] = {
+  { 0.0000000000000000, 20, 0.0000000000000000 },
+  { 5.4277267607932098e-12, 20, 5.0000000000000000 },
+  { 2.3083719613194670e-06, 20, 10.000000000000000 },
+  { 0.0015467058510412498, 20, 15.000000000000000 },
+  { 0.038324851639805160, 20, 20.000000000000000 },
+  { 0.028500071484154645, 20, 25.000000000000000 },
+  { -0.014711593353429081, 20, 30.000000000000000 },
+  { -0.010797653070264229, 20, 35.000000000000000 },
+  { 0.026535391837540293, 20, 40.000000000000000 },
+  { -0.011582959134716393, 20, 45.000000000000000 },
+  { -0.015785029898269291, 20, 50.000000000000000 },
+  { 0.013885519185862741, 20, 55.000000000000000 },
+  { 0.011112458964023273, 20, 60.000000000000000 },
+  { -0.011938384963927570, 20, 65.000000000000000 },
+  { -0.010117695207156904, 20, 70.000000000000000 },
+  { 0.0089871214102383232, 20, 75.000000000000000 },
+  { 0.010400578884991936, 20, 80.000000000000000 },
+  { -0.0055359020656326700, 20, 85.000000000000000 },
+  { -0.010639343320787521, 20, 90.000000000000000 },
+  { 0.0018051661455979529, 20, 95.000000000000000 },
+  { 0.010107671283873056, 20, 100.00000000000000 },
+};
+
+// Test function for n=20.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_sph_bessel<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_bessel(Tp(data006[i].n), Tp(data006[i].x));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for n=50.
+testcase_sph_bessel<double> data007[] = {
+  { 0.0000000000000000, 50, 0.0000000000000000 },
+  { 2.8574793504401511e-46, 50, 5.0000000000000000 },
+  { 2.2306960232186471e-31, 50, 10.000000000000000 },
+  { 7.6804716640080804e-23, 50, 15.000000000000000 },
+  { 5.6500807918725220e-17, 50, 20.000000000000000 },
+  { 1.2540416973758975e-12, 50, 25.000000000000000 },
+  { 2.6901637185735326e-09, 50, 30.000000000000000 },
+  { 1.0167148174422245e-06, 50, 35.000000000000000 },
+  { 9.3949174038179069e-05, 50, 40.000000000000000 },
+  { 0.0024888927213794561, 50, 45.000000000000000 },
+  { 0.018829107369282647, 50, 50.000000000000000 },
+  { 0.026373198438145489, 50, 55.000000000000000 },
+  { -0.021230978268739001, 50, 60.000000000000000 },
+  { 0.016539881802291313, 50, 65.000000000000000 },
+  { -0.015985416061436664, 50, 70.000000000000000 },
+  { 0.015462548984405590, 50, 75.000000000000000 },
+  { -0.010638570118081819, 50, 80.000000000000000 },
+  { 0.00046961239784540793, 50, 85.000000000000000 },
+  { 0.0096065882189920251, 50, 90.000000000000000 },
+  { -0.010613873910261154, 50, 95.000000000000000 },
+  { 0.00057971408822774949, 50, 100.00000000000000 },
+};
+
+// Test function for n=50.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_sph_bessel<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_bessel(Tp(data007[i].n), Tp(data007[i].x));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000017e-10));
+  }
+
+// Test data for n=100.
+testcase_sph_bessel<double> data008[] = {
+  { 0.0000000000000000, 100, 0.0000000000000000 },
+  { 5.5356503033889938e-120, 100, 5.0000000000000000 },
+  { 5.8320401820058771e-90, 100, 10.000000000000000 },
+  { 1.7406387750766626e-72, 100, 15.000000000000000 },
+  { 3.5152711125317012e-60, 100, 20.000000000000000 },
+  { 9.8455459353815965e-51, 100, 25.000000000000000 },
+  { 4.0888596744301583e-43, 100, 30.000000000000000 },
+  { 8.8975854911133939e-37, 100, 35.000000000000000 },
+  { 2.1513492547733828e-31, 100, 40.000000000000000 },
+  { 9.3673586994539108e-27, 100, 45.000000000000000 },
+  { 1.0190122629310471e-22, 100, 50.000000000000000 },
+  { 3.4887804977690388e-19, 100, 55.000000000000000 },
+  { 4.4442883425555593e-16, 100, 60.000000000000000 },
+  { 2.3832619568710728e-13, 100, 65.000000000000000 },
+  { 5.8948384175607987e-11, 100, 70.000000000000000 },
+  { 7.1884446357022277e-09, 100, 75.000000000000000 },
+  { 4.5247964400095002e-07, 100, 80.000000000000000 },
+  { 1.5096093228779032e-05, 100, 85.000000000000000 },
+  { 0.00026825172647807507, 100, 90.000000000000000 },
+  { 0.0024744308520581117, 100, 95.000000000000000 },
+  { 0.010880477011438352, 100, 100.00000000000000 },
+};
+
+// Test function for n=100.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_sph_bessel<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_bessel(Tp(data008[i].n), Tp(data008[i].x));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000029e-12));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  return 0;
+}
Index: testsuite/special_functions/19_sph_bessel/compile.cc
===================================================================
--- testsuite/special_functions/19_sph_bessel/compile.cc	(revision 0)
+++ testsuite/special_functions/19_sph_bessel/compile.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.19 sph_bessel
+
+#include <cmath>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+  unsigned int n = 0;
+
+  std::sph_bessel(n, xf);
+  std::sph_besself(n, xf);
+  std::sph_bessel(n, xd);
+  std::sph_bessel(n, xl);
+  std::sph_bessell(n, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/19_sph_bessel/compile_2.cc
===================================================================
--- testsuite/special_functions/19_sph_bessel/compile_2.cc	(revision 0)
+++ testsuite/special_functions/19_sph_bessel/compile_2.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.19 sph_bessel
+
+#include <math.h>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+  unsigned int n = 0;
+
+  sph_bessel(n, xf);
+  sph_besself(n, xf);
+  sph_bessel(n, xd);
+  sph_bessel(n, xl);
+  sph_bessell(n, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/20_sph_legendre/check_nan.cc
===================================================================
--- testsuite/special_functions/20_sph_legendre/check_nan.cc	(revision 0)
+++ testsuite/special_functions/20_sph_legendre/check_nan.cc	(working copy)
@@ -0,0 +1,58 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.20 sph_legendre
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+
+  float thetaf = std::numeric_limits<float>::quiet_NaN();
+  double thetad = std::numeric_limits<double>::quiet_NaN();
+  long double thetal = std::numeric_limits<long double>::quiet_NaN();
+  unsigned int l = 2, m = 1;
+
+  float a = std::sph_legendre(l, m, thetaf);
+  float b = std::sph_legendref(l, m, thetaf);
+  double c = std::sph_legendre(l, m, thetad);
+  long double d = std::sph_legendre(l, m, thetal);
+  long double e = std::sph_legendrel(l, m, thetal);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/20_sph_legendre/check_value.cc
===================================================================
--- testsuite/special_functions/20_sph_legendre/check_value.cc	(revision 0)
+++ testsuite/special_functions/20_sph_legendre/check_value.cc	(working copy)
@@ -0,0 +1,2816 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  sph_legendre
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for l=0, m=0.
+testcase_sph_legendre<double> data001[] = {
+  { 0.28209479177387814, 0, 0, 
+	  0.0000000000000000 },
+  { 0.28209479177387814, 0, 0, 
+	  0.15707963267948966 },
+  { 0.28209479177387814, 0, 0, 
+	  0.31415926535897931 },
+  { 0.28209479177387814, 0, 0, 
+	  0.47123889803846897 },
+  { 0.28209479177387814, 0, 0, 
+	  0.62831853071795862 },
+  { 0.28209479177387814, 0, 0, 
+	  0.78539816339744828 },
+  { 0.28209479177387814, 0, 0, 
+	  0.94247779607693793 },
+  { 0.28209479177387814, 0, 0, 
+	  1.0995574287564276 },
+  { 0.28209479177387814, 0, 0, 
+	  1.2566370614359172 },
+  { 0.28209479177387814, 0, 0, 
+	  1.4137166941154069 },
+  { 0.28209479177387814, 0, 0, 
+	  1.5707963267948966 },
+  { 0.28209479177387814, 0, 0, 
+	  1.7278759594743860 },
+  { 0.28209479177387814, 0, 0, 
+	  1.8849555921538759 },
+  { 0.28209479177387814, 0, 0, 
+	  2.0420352248333655 },
+  { 0.28209479177387814, 0, 0, 
+	  2.1991148575128552 },
+  { 0.28209479177387814, 0, 0, 
+	  2.3561944901923448 },
+  { 0.28209479177387814, 0, 0, 
+	  2.5132741228718345 },
+  { 0.28209479177387814, 0, 0, 
+	  2.6703537555513241 },
+  { 0.28209479177387814, 0, 0, 
+	  2.8274333882308138 },
+  { 0.28209479177387814, 0, 0, 
+	  2.9845130209103035 },
+  { 0.28209479177387814, 0, 0, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=0, m=0.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data001[i].l), Tp(data001[i].m),
+		     Tp(data001[i].theta));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=1, m=0.
+testcase_sph_legendre<double> data002[] = {
+  { 0.48860251190291992, 1, 0, 
+	  0.0000000000000000 },
+  { 0.48258700419201100, 1, 0, 
+	  0.15707963267948966 },
+  { 0.46468860282345231, 1, 0, 
+	  0.31415926535897931 },
+  { 0.43534802584032634, 1, 0, 
+	  0.47123889803846897 },
+  { 0.39528773562374975, 1, 0, 
+	  0.62831853071795862 },
+  { 0.34549414947133550, 1, 0, 
+	  0.78539816339744828 },
+  { 0.28719335072959390, 1, 0, 
+	  0.94247779607693793 },
+  { 0.22182089855280449, 1, 0, 
+	  1.0995574287564276 },
+  { 0.15098647967228981, 1, 0, 
+	  1.2566370614359172 },
+  { 0.076434272566846345, 1, 0, 
+	  1.4137166941154069 },
+  { 2.9918275112863369e-17, 1, 0, 
+	  1.5707963267948966 },
+  { -0.076434272566846179, 1, 0, 
+	  1.7278759594743860 },
+  { -0.15098647967228976, 1, 0, 
+	  1.8849555921538759 },
+  { -0.22182089855280443, 1, 0, 
+	  2.0420352248333655 },
+  { -0.28719335072959384, 1, 0, 
+	  2.1991148575128552 },
+  { -0.34549414947133544, 1, 0, 
+	  2.3561944901923448 },
+  { -0.39528773562374969, 1, 0, 
+	  2.5132741228718345 },
+  { -0.43534802584032628, 1, 0, 
+	  2.6703537555513241 },
+  { -0.46468860282345231, 1, 0, 
+	  2.8274333882308138 },
+  { -0.48258700419201095, 1, 0, 
+	  2.9845130209103035 },
+  { -0.48860251190291992, 1, 0, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=1, m=0.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data002[i].l), Tp(data002[i].m),
+		     Tp(data002[i].theta));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=1, m=1.
+testcase_sph_legendre<double> data003[] = {
+  { 0.0000000000000000, 1, 1, 
+	  0.0000000000000000 },
+  { -0.054047192447077917, 1, 1, 
+	  0.15707963267948966 },
+  { -0.10676356364376104, 1, 1, 
+	  0.31415926535897931 },
+  { -0.15685106157558129, 1, 1, 
+	  0.47123889803846897 },
+  { -0.20307636581258243, 1, 1, 
+	  0.62831853071795862 },
+  { -0.24430125595146007, 1, 1, 
+	  0.78539816339744828 },
+  { -0.27951063837942880, 1, 1, 
+	  0.94247779607693793 },
+  { -0.30783754124787122, 1, 1, 
+	  1.0995574287564276 },
+  { -0.32858446219656556, 1, 1, 
+	  1.2566370614359172 },
+  { -0.34124054317667202, 1, 1, 
+	  1.4137166941154069 },
+  { -0.34549414947133567, 1, 1, 
+	  1.5707963267948966 },
+  { -0.34124054317667202, 1, 1, 
+	  1.7278759594743860 },
+  { -0.32858446219656556, 1, 1, 
+	  1.8849555921538759 },
+  { -0.30783754124787127, 1, 1, 
+	  2.0420352248333655 },
+  { -0.27951063837942880, 1, 1, 
+	  2.1991148575128552 },
+  { -0.24430125595146013, 1, 1, 
+	  2.3561944901923448 },
+  { -0.20307636581258248, 1, 1, 
+	  2.5132741228718345 },
+  { -0.15685106157558140, 1, 1, 
+	  2.6703537555513241 },
+  { -0.10676356364376104, 1, 1, 
+	  2.8274333882308138 },
+  { -0.054047192447078167, 1, 1, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 1, 1, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=1, m=1.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data003[i].l), Tp(data003[i].m),
+		     Tp(data003[i].theta));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=2, m=0.
+testcase_sph_legendre<double> data004[] = {
+  { 0.63078313050504009, 2, 0, 
+	  0.0000000000000000 },
+  { 0.60762858760316607, 2, 0, 
+	  0.15707963267948966 },
+  { 0.54043148688396569, 2, 0, 
+	  0.31415926535897931 },
+  { 0.43576954875556589, 2, 0, 
+	  0.47123889803846897 },
+  { 0.30388781294457579, 2, 0, 
+	  0.62831853071795862 },
+  { 0.15769578262626011, 2, 0, 
+	  0.78539816339744828 },
+  { 0.011503752307944235, 2, 0, 
+	  0.94247779607693793 },
+  { -0.12037798350304570, 2, 0, 
+	  1.0995574287564276 },
+  { -0.22503992163144576, 2, 0, 
+	  1.2566370614359172 },
+  { -0.29223702235064597, 2, 0, 
+	  1.4137166941154069 },
+  { -0.31539156525252005, 2, 0, 
+	  1.5707963267948966 },
+  { -0.29223702235064608, 2, 0, 
+	  1.7278759594743860 },
+  { -0.22503992163144584, 2, 0, 
+	  1.8849555921538759 },
+  { -0.12037798350304584, 2, 0, 
+	  2.0420352248333655 },
+  { 0.011503752307944164, 2, 0, 
+	  2.1991148575128552 },
+  { 0.15769578262625994, 2, 0, 
+	  2.3561944901923448 },
+  { 0.30388781294457567, 2, 0, 
+	  2.5132741228718345 },
+  { 0.43576954875556562, 2, 0, 
+	  2.6703537555513241 },
+  { 0.54043148688396569, 2, 0, 
+	  2.8274333882308138 },
+  { 0.60762858760316585, 2, 0, 
+	  2.9845130209103035 },
+  { 0.63078313050504009, 2, 0, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=2, m=0.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data004[i].l), Tp(data004[i].m),
+		     Tp(data004[i].theta));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=2, m=1.
+testcase_sph_legendre<double> data005[] = {
+  { 0.0000000000000000, 2, 1, 
+	  0.0000000000000000 },
+  { -0.11936529291378727, 2, 1, 
+	  0.15707963267948966 },
+  { -0.22704627929027449, 2, 1, 
+	  0.31415926535897931 },
+  { -0.31250239392538215, 2, 1, 
+	  0.47123889803846897 },
+  { -0.36736859691086526, 2, 1, 
+	  0.62831853071795862 },
+  { -0.38627420202318979, 2, 1, 
+	  0.78539816339744828 },
+  { -0.36736859691086526, 2, 1, 
+	  0.94247779607693793 },
+  { -0.31250239392538226, 2, 1, 
+	  1.0995574287564276 },
+  { -0.22704627929027438, 2, 1, 
+	  1.2566370614359172 },
+  { -0.11936529291378740, 2, 1, 
+	  1.4137166941154069 },
+  { -4.7304946510089748e-17, 2, 1, 
+	  1.5707963267948966 },
+  { 0.11936529291378714, 2, 1, 
+	  1.7278759594743860 },
+  { 0.22704627929027429, 2, 1, 
+	  1.8849555921538759 },
+  { 0.31250239392538220, 2, 1, 
+	  2.0420352248333655 },
+  { 0.36736859691086521, 2, 1, 
+	  2.1991148575128552 },
+  { 0.38627420202318979, 2, 1, 
+	  2.3561944901923448 },
+  { 0.36736859691086526, 2, 1, 
+	  2.5132741228718345 },
+  { 0.31250239392538232, 2, 1, 
+	  2.6703537555513241 },
+  { 0.22704627929027449, 2, 1, 
+	  2.8274333882308138 },
+  { 0.11936529291378781, 2, 1, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 2, 1, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=2, m=1.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data005[i].l), Tp(data005[i].m),
+		     Tp(data005[i].theta));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=2, m=2.
+testcase_sph_legendre<double> data006[] = {
+  { 0.0000000000000000, 2, 2, 
+	  0.0000000000000000 },
+  { 0.0094528025561622549, 2, 2, 
+	  0.15707963267948966 },
+  { 0.036885904048903795, 2, 2, 
+	  0.31415926535897931 },
+  { 0.079613961366457681, 2, 2, 
+	  0.47123889803846897 },
+  { 0.13345445455470123, 2, 2, 
+	  0.62831853071795862 },
+  { 0.19313710101159484, 2, 2, 
+	  0.78539816339744828 },
+  { 0.25281974746848851, 2, 2, 
+	  0.94247779607693793 },
+  { 0.30666024065673209, 2, 2, 
+	  1.0995574287564276 },
+  { 0.34938829797428600, 2, 2, 
+	  1.2566370614359172 },
+  { 0.37682139946702747, 2, 2, 
+	  1.4137166941154069 },
+  { 0.38627420202318979, 2, 2, 
+	  1.5707963267948966 },
+  { 0.37682139946702753, 2, 2, 
+	  1.7278759594743860 },
+  { 0.34938829797428606, 2, 2, 
+	  1.8849555921538759 },
+  { 0.30666024065673209, 2, 2, 
+	  2.0420352248333655 },
+  { 0.25281974746848856, 2, 2, 
+	  2.1991148575128552 },
+  { 0.19313710101159492, 2, 2, 
+	  2.3561944901923448 },
+  { 0.13345445455470126, 2, 2, 
+	  2.5132741228718345 },
+  { 0.079613961366457764, 2, 2, 
+	  2.6703537555513241 },
+  { 0.036885904048903795, 2, 2, 
+	  2.8274333882308138 },
+  { 0.0094528025561623433, 2, 2, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 2, 2, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=2, m=2.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data006[i].l), Tp(data006[i].m),
+		     Tp(data006[i].theta));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=5, m=0.
+testcase_sph_legendre<double> data007[] = {
+  { 0.93560257962738880, 5, 0, 
+	  0.0000000000000000 },
+  { 0.77014422942079963, 5, 0, 
+	  0.15707963267948966 },
+  { 0.35892185032365165, 5, 0, 
+	  0.31415926535897931 },
+  { -0.090214932090594294, 5, 0, 
+	  0.47123889803846897 },
+  { -0.36214460396518883, 5, 0, 
+	  0.62831853071795862 },
+  { -0.35145955579226906, 5, 0, 
+	  0.78539816339744828 },
+  { -0.11441703594725168, 5, 0, 
+	  0.94247779607693793 },
+  { 0.17248966720808107, 5, 0, 
+	  1.0995574287564276 },
+  { 0.32128384287200523, 5, 0, 
+	  1.2566370614359172 },
+  { 0.24377632246714948, 5, 0, 
+	  1.4137166941154069 },
+  { 1.0741712853887702e-16, 5, 0, 
+	  1.5707963267948966 },
+  { -0.24377632246714911, 5, 0, 
+	  1.7278759594743860 },
+  { -0.32128384287200534, 5, 0, 
+	  1.8849555921538759 },
+  { -0.17248966720808132, 5, 0, 
+	  2.0420352248333655 },
+  { 0.11441703594725151, 5, 0, 
+	  2.1991148575128552 },
+  { 0.35145955579226895, 5, 0, 
+	  2.3561944901923448 },
+  { 0.36214460396518905, 5, 0, 
+	  2.5132741228718345 },
+  { 0.090214932090594752, 5, 0, 
+	  2.6703537555513241 },
+  { -0.35892185032365165, 5, 0, 
+	  2.8274333882308138 },
+  { -0.77014422942079852, 5, 0, 
+	  2.9845130209103035 },
+  { -0.93560257962738880, 5, 0, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=5, m=0.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data007[i].l), Tp(data007[i].m),
+		     Tp(data007[i].theta));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=5, m=1.
+testcase_sph_legendre<double> data008[] = {
+  { 0.0000000000000000, 5, 1, 
+	  0.0000000000000000 },
+  { -0.36712373713318258, 5, 1, 
+	  0.15707963267948966 },
+  { -0.54610329010534753, 5, 1, 
+	  0.31415926535897931 },
+  { -0.45381991493631763, 5, 1, 
+	  0.47123889803846897 },
+  { -0.15679720635769961, 5, 1, 
+	  0.62831853071795862 },
+  { 0.16985499419838601, 5, 1, 
+	  0.78539816339744828 },
+  { 0.34468004499725180, 5, 1, 
+	  0.94247779607693793 },
+  { 0.28349471119605985, 5, 1, 
+	  1.0995574287564276 },
+  { 0.044286619339675815, 5, 1, 
+	  1.2566370614359172 },
+  { -0.21193784177193470, 5, 1, 
+	  1.4137166941154069 },
+  { -0.32028164857621527, 5, 1, 
+	  1.5707963267948966 },
+  { -0.21193784177193514, 5, 1, 
+	  1.7278759594743860 },
+  { 0.044286619339675592, 5, 1, 
+	  1.8849555921538759 },
+  { 0.28349471119605968, 5, 1, 
+	  2.0420352248333655 },
+  { 0.34468004499725174, 5, 1, 
+	  2.1991148575128552 },
+  { 0.16985499419838640, 5, 1, 
+	  2.3561944901923448 },
+  { -0.15679720635769906, 5, 1, 
+	  2.5132741228718345 },
+  { -0.45381991493631768, 5, 1, 
+	  2.6703537555513241 },
+  { -0.54610329010534753, 5, 1, 
+	  2.8274333882308138 },
+  { -0.36712373713318402, 5, 1, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 5, 1, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=5, m=1.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data008[i].l), Tp(data008[i].m),
+		     Tp(data008[i].theta));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=5, m=2.
+testcase_sph_legendre<double> data009[] = {
+  { 0.0000000000000000, 5, 2, 
+	  0.0000000000000000 },
+  { 0.078919441745546146, 5, 2, 
+	  0.15707963267948966 },
+  { 0.26373799140437987, 5, 2, 
+	  0.31415926535897931 },
+  { 0.43002359842080096, 5, 2, 
+	  0.47123889803846897 },
+  { 0.45642486439050983, 5, 2, 
+	  0.62831853071795862 },
+  { 0.29959604906083293, 5, 2, 
+	  0.78539816339744828 },
+  { 0.023781239849532215, 5, 2, 
+	  0.94247779607693793 },
+  { -0.23313989334673826, 5, 2, 
+	  1.0995574287564276 },
+  { -0.33799912776303714, 5, 2, 
+	  1.2566370614359172 },
+  { -0.23964508489529743, 5, 2, 
+	  1.4137166941154069 },
+  { -1.0377480524338170e-16, 5, 2, 
+	  1.5707963267948966 },
+  { 0.23964508489529704, 5, 2, 
+	  1.7278759594743860 },
+  { 0.33799912776303714, 5, 2, 
+	  1.8849555921538759 },
+  { 0.23313989334673843, 5, 2, 
+	  2.0420352248333655 },
+  { -0.023781239849531916, 5, 2, 
+	  2.1991148575128552 },
+  { -0.29959604906083276, 5, 2, 
+	  2.3561944901923448 },
+  { -0.45642486439050983, 5, 2, 
+	  2.5132741228718345 },
+  { -0.43002359842080118, 5, 2, 
+	  2.6703537555513241 },
+  { -0.26373799140437987, 5, 2, 
+	  2.8274333882308138 },
+  { -0.078919441745546867, 5, 2, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 5, 2, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=5, m=2.
+template<typename Tp>
+  void
+  test009()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data009)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data009[i].l), Tp(data009[i].m),
+		     Tp(data009[i].theta));
+	const Tp f0 = data009[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=5, m=5.
+testcase_sph_legendre<double> data010[] = {
+  { 0.0000000000000000, 5, 5, 
+	  0.0000000000000000 },
+  { -4.3481439097909148e-05, 5, 5, 
+	  0.15707963267948966 },
+  { -0.0013078367086431812, 5, 5, 
+	  0.31415926535897931 },
+  { -0.0089510818191922761, 5, 5, 
+	  0.47123889803846897 },
+  { -0.032563803777573896, 5, 5, 
+	  0.62831853071795862 },
+  { -0.082047757105021241, 5, 5, 
+	  0.78539816339744828 },
+  { -0.16085328164143814, 5, 5, 
+	  0.94247779607693793 },
+  { -0.26064303436645381, 5, 5, 
+	  1.0995574287564276 },
+  { -0.36113811790820571, 5, 5, 
+	  1.2566370614359172 },
+  { -0.43625592459446139, 5, 5, 
+	  1.4137166941154069 },
+  { -0.46413220344085809, 5, 5, 
+	  1.5707963267948966 },
+  { -0.43625592459446155, 5, 5, 
+	  1.7278759594743860 },
+  { -0.36113811790820577, 5, 5, 
+	  1.8849555921538759 },
+  { -0.26064303436645386, 5, 5, 
+	  2.0420352248333655 },
+  { -0.16085328164143822, 5, 5, 
+	  2.1991148575128552 },
+  { -0.082047757105021310, 5, 5, 
+	  2.3561944901923448 },
+  { -0.032563803777573910, 5, 5, 
+	  2.5132741228718345 },
+  { -0.0089510818191923004, 5, 5, 
+	  2.6703537555513241 },
+  { -0.0013078367086431812, 5, 5, 
+	  2.8274333882308138 },
+  { -4.3481439097910151e-05, 5, 5, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 5, 5, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=5, m=5.
+template<typename Tp>
+  void
+  test010()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data010)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data010[i].l), Tp(data010[i].m),
+		     Tp(data010[i].theta));
+	const Tp f0 = data010[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10, m=0.
+testcase_sph_legendre<double> data011[] = {
+  { 1.2927207364566027, 10, 0, 
+	  0.0000000000000000 },
+  { 0.55288895150522555, 10, 0, 
+	  0.15707963267948966 },
+  { -0.44874428379711545, 10, 0, 
+	  0.31415926535897931 },
+  { -0.25532095827149687, 10, 0, 
+	  0.47123889803846897 },
+  { 0.36625249688013961, 10, 0, 
+	  0.62831853071795862 },
+  { 0.14880806329084206, 10, 0, 
+	  0.78539816339744828 },
+  { -0.33533356797848757, 10, 0, 
+	  0.94247779607693793 },
+  { -0.080639967662335665, 10, 0, 
+	  1.0995574287564276 },
+  { 0.32197986450174521, 10, 0, 
+	  1.2566370614359172 },
+  { 0.025713542103667848, 10, 0, 
+	  1.4137166941154069 },
+  { -0.31813049373736707, 10, 0, 
+	  1.5707963267948966 },
+  { 0.025713542103666699, 10, 0, 
+	  1.7278759594743860 },
+  { 0.32197986450174543, 10, 0, 
+	  1.8849555921538759 },
+  { -0.080639967662335096, 10, 0, 
+	  2.0420352248333655 },
+  { -0.33533356797848757, 10, 0, 
+	  2.1991148575128552 },
+  { 0.14880806329084156, 10, 0, 
+	  2.3561944901923448 },
+  { 0.36625249688013994, 10, 0, 
+	  2.5132741228718345 },
+  { -0.25532095827149576, 10, 0, 
+	  2.6703537555513241 },
+  { -0.44874428379711545, 10, 0, 
+	  2.8274333882308138 },
+  { 0.55288895150522011, 10, 0, 
+	  2.9845130209103035 },
+  { 1.2927207364566027, 10, 0, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=10, m=0.
+template<typename Tp>
+  void
+  test011()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data011)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data011[i].l), Tp(data011[i].m),
+		     Tp(data011[i].theta));
+	const Tp f0 = data011[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10, m=1.
+testcase_sph_legendre<double> data012[] = {
+  { 0.0000000000000000, 10, 1, 
+	  0.0000000000000000 },
+  { -0.74373723919063894, 10, 1, 
+	  0.15707963267948966 },
+  { -0.29035110456209601, 10, 1, 
+	  0.31415926535897931 },
+  { 0.42219282075271530, 10, 1, 
+	  0.47123889803846897 },
+  { 0.17109256898931269, 10, 1, 
+	  0.62831853071795862 },
+  { -0.35583574648544281, 10, 1, 
+	  0.78539816339744828 },
+  { -0.10089212303543979, 10, 1, 
+	  0.94247779607693793 },
+  { 0.32997652649321085, 10, 1, 
+	  1.0995574287564276 },
+  { 0.047416376890032939, 10, 1, 
+	  1.2566370614359172 },
+  { -0.31999356750295660, 10, 1, 
+	  1.4137166941154069 },
+  { -2.0430664782290766e-16, 10, 1, 
+	  1.5707963267948966 },
+  { 0.31999356750295660, 10, 1, 
+	  1.7278759594743860 },
+  { -0.047416376890032544, 10, 1, 
+	  1.8849555921538759 },
+  { -0.32997652649321091, 10, 1, 
+	  2.0420352248333655 },
+  { 0.10089212303543935, 10, 1, 
+	  2.1991148575128552 },
+  { 0.35583574648544292, 10, 1, 
+	  2.3561944901923448 },
+  { -0.17109256898931161, 10, 1, 
+	  2.5132741228718345 },
+  { -0.42219282075271569, 10, 1, 
+	  2.6703537555513241 },
+  { 0.29035110456209601, 10, 1, 
+	  2.8274333882308138 },
+  { 0.74373723919064050, 10, 1, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 10, 1, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=10, m=1.
+template<typename Tp>
+  void
+  test012()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data012)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data012[i].l), Tp(data012[i].m),
+		     Tp(data012[i].theta));
+	const Tp f0 = data012[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10, m=2.
+testcase_sph_legendre<double> data013[] = {
+  { 0.0000000000000000, 10, 2, 
+	  0.0000000000000000 },
+  { 0.34571695599980246, 10, 2, 
+	  0.15707963267948966 },
+  { 0.62485535978198059, 10, 2, 
+	  0.31415926535897931 },
+  { 0.098210039644716252, 10, 2, 
+	  0.47123889803846897 },
+  { -0.41494799233049684, 10, 2, 
+	  0.62831853071795862 },
+  { -0.081698973831472732, 10, 2, 
+	  0.78539816339744828 },
+  { 0.35253132222271277, 10, 2, 
+	  0.94247779607693793 },
+  { 0.049026298555980979, 10, 2, 
+	  1.0995574287564276 },
+  { -0.32791246874130792, 10, 2, 
+	  1.2566370614359172 },
+  { -0.016196782433946885, 10, 2, 
+	  1.4137166941154069 },
+  { 0.32106263400438328, 10, 2, 
+	  1.5707963267948966 },
+  { -0.016196782433945761, 10, 2, 
+	  1.7278759594743860 },
+  { -0.32791246874130803, 10, 2, 
+	  1.8849555921538759 },
+  { 0.049026298555980424, 10, 2, 
+	  2.0420352248333655 },
+  { 0.35253132222271266, 10, 2, 
+	  2.1991148575128552 },
+  { -0.081698973831472121, 10, 2, 
+	  2.3561944901923448 },
+  { -0.41494799233049695, 10, 2, 
+	  2.5132741228718345 },
+  { 0.098210039644715197, 10, 2, 
+	  2.6703537555513241 },
+  { 0.62485535978198059, 10, 2, 
+	  2.8274333882308138 },
+  { 0.34571695599980545, 10, 2, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 10, 2, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=10, m=2.
+template<typename Tp>
+  void
+  test013()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data013)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data013[i].l), Tp(data013[i].m),
+		     Tp(data013[i].theta));
+	const Tp f0 = data013[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10, m=5.
+testcase_sph_legendre<double> data014[] = {
+  { 0.0000000000000000, 10, 5, 
+	  0.0000000000000000 },
+  { -0.0030300124052750196, 10, 5, 
+	  0.15707963267948966 },
+  { -0.070348585248056802, 10, 5, 
+	  0.31415926535897931 },
+  { -0.30055029290703639, 10, 5, 
+	  0.47123889803846897 },
+  { -0.49987818144009155, 10, 5, 
+	  0.62831853071795862 },
+  { -0.28108771757150108, 10, 5, 
+	  0.78539816339744828 },
+  { 0.22068081187249292, 10, 5, 
+	  0.94247779607693793 },
+  { 0.33689502212592121, 10, 5, 
+	  1.0995574287564276 },
+  { -0.086095515520764110, 10, 5, 
+	  1.2566370614359172 },
+  { -0.33935827318511558, 10, 5, 
+	  1.4137166941154069 },
+  { -1.9213014340664578e-16, 10, 5, 
+	  1.5707963267948966 },
+  { 0.33935827318511552, 10, 5, 
+	  1.7278759594743860 },
+  { 0.086095515520764512, 10, 5, 
+	  1.8849555921538759 },
+  { -0.33689502212592087, 10, 5, 
+	  2.0420352248333655 },
+  { -0.22068081187249344, 10, 5, 
+	  2.1991148575128552 },
+  { 0.28108771757150064, 10, 5, 
+	  2.3561944901923448 },
+  { 0.49987818144009138, 10, 5, 
+	  2.5132741228718345 },
+  { 0.30055029290703672, 10, 5, 
+	  2.6703537555513241 },
+  { 0.070348585248056802, 10, 5, 
+	  2.8274333882308138 },
+  { 0.0030300124052750873, 10, 5, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 10, 5, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=10, m=5.
+template<typename Tp>
+  void
+  test014()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data014)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data014[i].l), Tp(data014[i].m),
+		     Tp(data014[i].theta));
+	const Tp f0 = data014[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=10, m=10.
+testcase_sph_legendre<double> data015[] = {
+  { 0.0000000000000000, 10, 10, 
+	  0.0000000000000000 },
+  { 4.7624282733343473e-09, 10, 10, 
+	  0.15707963267948966 },
+  { 4.3085156534549772e-06, 10, 10, 
+	  0.31415926535897931 },
+  { 0.00020182347649472387, 10, 10, 
+	  0.47123889803846897 },
+  { 0.0026711045506511684, 10, 10, 
+	  0.62831853071795862 },
+  { 0.016957196623256909, 10, 10, 
+	  0.78539816339744828 },
+  { 0.065174916004990341, 10, 10, 
+	  0.94247779607693793 },
+  { 0.17112476903017845, 10, 10, 
+	  1.0995574287564276 },
+  { 0.32852414199733554, 10, 10, 
+	  1.2566370614359172 },
+  { 0.47940582314838287, 10, 10, 
+	  1.4137166941154069 },
+  { 0.54263029194422152, 10, 10, 
+	  1.5707963267948966 },
+  { 0.47940582314838309, 10, 10, 
+	  1.7278759594743860 },
+  { 0.32852414199733571, 10, 10, 
+	  1.8849555921538759 },
+  { 0.17112476903017856, 10, 10, 
+	  2.0420352248333655 },
+  { 0.065174916004990410, 10, 10, 
+	  2.1991148575128552 },
+  { 0.016957196623256943, 10, 10, 
+	  2.3561944901923448 },
+  { 0.0026711045506511706, 10, 10, 
+	  2.5132741228718345 },
+  { 0.00020182347649472493, 10, 10, 
+	  2.6703537555513241 },
+  { 4.3085156534549772e-06, 10, 10, 
+	  2.8274333882308138 },
+  { 4.7624282733345673e-09, 10, 10, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 10, 10, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=10, m=10.
+template<typename Tp>
+  void
+  test015()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data015)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data015[i].l), Tp(data015[i].m),
+		     Tp(data015[i].theta));
+	const Tp f0 = data015[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=20, m=0.
+testcase_sph_legendre<double> data016[] = {
+  { 1.8062879984608917, 20, 0, 
+	  0.0000000000000000 },
+  { -0.58906549291415933, 20, 0, 
+	  0.15707963267948966 },
+  { 0.45624611402342408, 20, 0, 
+	  0.31415926535897931 },
+  { -0.39955402700466724, 20, 0, 
+	  0.47123889803846897 },
+  { 0.36818552901640772, 20, 0, 
+	  0.62831853071795862 },
+  { -0.34873131330857743, 20, 0, 
+	  0.78539816339744828 },
+  { 0.33600882829186507, 20, 0, 
+	  0.94247779607693793 },
+  { -0.32759286308122931, 20, 0, 
+	  1.0995574287564276 },
+  { 0.32222458068091325, 20, 0, 
+	  1.2566370614359172 },
+  { -0.31922731037135965, 20, 0, 
+	  1.4137166941154069 },
+  { 0.31826262039531755, 20, 0, 
+	  1.5707963267948966 },
+  { -0.31922731037135987, 20, 0, 
+	  1.7278759594743860 },
+  { 0.32222458068091342, 20, 0, 
+	  1.8849555921538759 },
+  { -0.32759286308122942, 20, 0, 
+	  2.0420352248333655 },
+  { 0.33600882829186518, 20, 0, 
+	  2.1991148575128552 },
+  { -0.34873131330857782, 20, 0, 
+	  2.3561944901923448 },
+  { 0.36818552901640805, 20, 0, 
+	  2.5132741228718345 },
+  { -0.39955402700466824, 20, 0, 
+	  2.6703537555513241 },
+  { 0.45624611402342408, 20, 0, 
+	  2.8274333882308138 },
+  { -0.58906549291416732, 20, 0, 
+	  2.9845130209103035 },
+  { 1.8062879984608917, 20, 0, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=20, m=0.
+template<typename Tp>
+  void
+  test016()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data016)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data016[i].l), Tp(data016[i].m),
+		     Tp(data016[i].theta));
+	const Tp f0 = data016[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=20, m=1.
+testcase_sph_legendre<double> data017[] = {
+  { 0.0000000000000000, 20, 1, 
+	  0.0000000000000000 },
+  { -0.45905213045060256, 20, 1, 
+	  0.15707963267948966 },
+  { 0.31166370423309253, 20, 1, 
+	  0.31415926535897931 },
+  { -0.23278757741246778, 20, 1, 
+	  0.47123889803846897 },
+  { 0.17937240823504172, 20, 1, 
+	  0.62831853071795862 },
+  { -0.13857299972299839, 20, 1, 
+	  0.78539816339744828 },
+  { 0.10495324841927722, 20, 1, 
+	  0.94247779607693793 },
+  { -0.075707774352163665, 20, 1, 
+	  1.0995574287564276 },
+  { 0.049168697683476224, 20, 1, 
+	  1.2566370614359172 },
+  { -0.024216050551253303, 20, 1, 
+	  1.4137166941154069 },
+  { 3.9938443510694349e-16, 20, 1, 
+	  1.5707963267948966 },
+  { 0.024216050551250919, 20, 1, 
+	  1.7278759594743860 },
+  { -0.049168697683475482, 20, 1, 
+	  1.8849555921538759 },
+  { 0.075707774352163068, 20, 1, 
+	  2.0420352248333655 },
+  { -0.10495324841927638, 20, 1, 
+	  2.1991148575128552 },
+  { 0.13857299972299741, 20, 1, 
+	  2.3561944901923448 },
+  { -0.17937240823503983, 20, 1, 
+	  2.5132741228718345 },
+  { 0.23278757741246703, 20, 1, 
+	  2.6703537555513241 },
+  { -0.31166370423309253, 20, 1, 
+	  2.8274333882308138 },
+  { 0.45905213045059046, 20, 1, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 20, 1, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=20, m=1.
+template<typename Tp>
+  void
+  test017()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data017)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data017[i].l), Tp(data017[i].m),
+		     Tp(data017[i].theta));
+	const Tp f0 = data017[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for l=20, m=2.
+testcase_sph_legendre<double> data018[] = {
+  { 0.0000000000000000, 20, 2, 
+	  0.0000000000000000 },
+  { 0.87399805141574394, 20, 2, 
+	  0.15707963267948966 },
+  { -0.55116854080895061, 20, 2, 
+	  0.31415926535897931 },
+  { 0.44520137308557572, 20, 2, 
+	  0.47123889803846897 },
+  { -0.39321637877908228, 20, 2, 
+	  0.62831853071795862 },
+  { 0.36312025711350937, 20, 2, 
+	  0.78539816339744828 },
+  { -0.34427103004873116, 20, 2, 
+	  0.94247779607693793 },
+  { 0.33214917638387642, 20, 2, 
+	  1.0995574287564276 },
+  { -0.32455734448839091, 20, 2, 
+	  1.2566370614359172 },
+  { 0.32036529628513238, 20, 2, 
+	  1.4137166941154069 },
+  { -0.31902310563819986, 20, 2, 
+	  1.5707963267948966 },
+  { 0.32036529628513266, 20, 2, 
+	  1.7278759594743860 },
+  { -0.32455734448839102, 20, 2, 
+	  1.8849555921538759 },
+  { 0.33214917638387659, 20, 2, 
+	  2.0420352248333655 },
+  { -0.34427103004873105, 20, 2, 
+	  2.1991148575128552 },
+  { 0.36312025711350981, 20, 2, 
+	  2.3561944901923448 },
+  { -0.39321637877908278, 20, 2, 
+	  2.5132741228718345 },
+  { 0.44520137308557650, 20, 2, 
+	  2.6703537555513241 },
+  { -0.55116854080895061, 20, 2, 
+	  2.8274333882308138 },
+  { 0.87399805141574527, 20, 2, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 20, 2, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=20, m=2.
+template<typename Tp>
+  void
+  test018()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data018)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data018[i].l), Tp(data018[i].m),
+		     Tp(data018[i].theta));
+	const Tp f0 = data018[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=20, m=5.
+testcase_sph_legendre<double> data019[] = {
+  { 0.0000000000000000, 20, 5, 
+	  0.0000000000000000 },
+  { -0.10024848623504863, 20, 5, 
+	  0.15707963267948966 },
+  { -0.68115361075940484, 20, 5, 
+	  0.31415926535897931 },
+  { 0.31774532551156298, 20, 5, 
+	  0.47123889803846897 },
+  { -0.16011868165390544, 20, 5, 
+	  0.62831853071795862 },
+  { 0.085844143304115578, 20, 5, 
+	  0.78539816339744828 },
+  { -0.047467540840864568, 20, 5, 
+	  0.94247779607693793 },
+  { 0.026283575189471796, 20, 5, 
+	  1.0995574287564276 },
+  { -0.013891104052597688, 20, 5, 
+	  1.2566370614359172 },
+  { 0.0059873308239496957, 20, 5, 
+	  1.4137166941154069 },
+  { 3.9355286582083095e-16, 20, 5, 
+	  1.5707963267948966 },
+  { -0.0059873308239519014, 20, 5, 
+	  1.7278759594743860 },
+  { 0.013891104052598547, 20, 5, 
+	  1.8849555921538759 },
+  { -0.026283575189472864, 20, 5, 
+	  2.0420352248333655 },
+  { 0.047467540840865928, 20, 5, 
+	  2.1991148575128552 },
+  { -0.085844143304117007, 20, 5, 
+	  2.3561944901923448 },
+  { 0.16011868165390658, 20, 5, 
+	  2.5132741228718345 },
+  { -0.31774532551156381, 20, 5, 
+	  2.6703537555513241 },
+  { 0.68115361075940484, 20, 5, 
+	  2.8274333882308138 },
+  { 0.10024848623505046, 20, 5, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 20, 5, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=20, m=5.
+template<typename Tp>
+  void
+  test019()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data019)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data019[i].l), Tp(data019[i].m),
+		     Tp(data019[i].theta));
+	const Tp f0 = data019[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for l=20, m=10.
+testcase_sph_legendre<double> data020[] = {
+  { 0.0000000000000000, 20, 10, 
+	  0.0000000000000000 },
+  { 3.0595797603706485e-05, 20, 10, 
+	  0.15707963267948966 },
+  { 0.015924453916397002, 20, 10, 
+	  0.31415926535897931 },
+  { 0.26588079118745744, 20, 10, 
+	  0.47123889803846897 },
+  { 0.54045081420686869, 20, 10, 
+	  0.62831853071795862 },
+  { -0.28215279394285531, 20, 10, 
+	  0.78539816339744828 },
+  { 0.0085297337582245884, 20, 10, 
+	  0.94247779607693793 },
+  { 0.16930127953533738, 20, 10, 
+	  1.0995574287564276 },
+  { -0.27215134048018325, 20, 10, 
+	  1.2566370614359172 },
+  { 0.32456597088029526, 20, 10, 
+	  1.4137166941154069 },
+  { -0.34057893241353715, 20, 10, 
+	  1.5707963267948966 },
+  { 0.32456597088029449, 20, 10, 
+	  1.7278759594743860 },
+  { -0.27215134048018291, 20, 10, 
+	  1.8849555921538759 },
+  { 0.16930127953533675, 20, 10, 
+	  2.0420352248333655 },
+  { 0.0085297337582257438, 20, 10, 
+	  2.1991148575128552 },
+  { -0.28215279394285619, 20, 10, 
+	  2.3561944901923448 },
+  { 0.54045081420686736, 20, 10, 
+	  2.5132741228718345 },
+  { 0.26588079118745828, 20, 10, 
+	  2.6703537555513241 },
+  { 0.015924453916397002, 20, 10, 
+	  2.8274333882308138 },
+  { 3.0595797603707888e-05, 20, 10, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 20, 10, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=20, m=10.
+template<typename Tp>
+  void
+  test020()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data020)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data020[i].l), Tp(data020[i].m),
+		     Tp(data020[i].theta));
+	const Tp f0 = data020[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+// Test data for l=20, m=20.
+testcase_sph_legendre<double> data021[] = {
+  { 0.0000000000000000, 20, 20, 
+	  0.0000000000000000 },
+  { 4.9264471419246231e-17, 20, 20, 
+	  0.15707963267948966 },
+  { 4.0321091681531780e-11, 20, 20, 
+	  0.31415926535897931 },
+  { 8.8474944184471664e-08, 20, 20, 
+	  0.47123889803846897 },
+  { 1.5497395129387764e-05, 20, 20, 
+	  0.62831853071795862 },
+  { 0.00062457564282984495, 20, 20, 
+	  0.78539816339744828 },
+  { 0.0092265192458967568, 20, 20, 
+	  0.94247779607693793 },
+  { 0.063606673236323297, 20, 20, 
+	  1.0995574287564276 },
+  { 0.23442909509776316, 20, 20, 
+	  1.2566370614359172 },
+  { 0.49921030481087009, 20, 20, 
+	  1.4137166941154069 },
+  { 0.63956545825776223, 20, 20, 
+	  1.5707963267948966 },
+  { 0.49921030481087064, 20, 20, 
+	  1.7278759594743860 },
+  { 0.23442909509776336, 20, 20, 
+	  1.8849555921538759 },
+  { 0.063606673236323380, 20, 20, 
+	  2.0420352248333655 },
+  { 0.0092265192458967742, 20, 20, 
+	  2.1991148575128552 },
+  { 0.00062457564282984766, 20, 20, 
+	  2.3561944901923448 },
+  { 1.5497395129387791e-05, 20, 20, 
+	  2.5132741228718345 },
+  { 8.8474944184472617e-08, 20, 20, 
+	  2.6703537555513241 },
+  { 4.0321091681531780e-11, 20, 20, 
+	  2.8274333882308138 },
+  { 4.9264471419250786e-17, 20, 20, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 20, 20, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=20, m=20.
+template<typename Tp>
+  void
+  test021()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data021)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data021[i].l), Tp(data021[i].m),
+		     Tp(data021[i].theta));
+	const Tp f0 = data021[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=50, m=0.
+testcase_sph_legendre<double> data022[] = {
+  { 2.8350175706934717, 50, 0, 
+	  0.0000000000000000 },
+  { 0.53157537495174900, 50, 0, 
+	  0.15707963267948966 },
+  { -0.46056183476301255, 50, 0, 
+	  0.31415926535897931 },
+  { -0.24876032079677909, 50, 0, 
+	  0.47123889803846897 },
+  { 0.36926172901532522, 50, 0, 
+	  0.62831853071795862 },
+  { 0.14571730283563575, 50, 0, 
+	  0.78539816339744828 },
+  { -0.33636199170850806, 50, 0, 
+	  0.94247779607693793 },
+  { -0.079132716267091507, 50, 0, 
+	  1.0995574287564276 },
+  { 0.32232921941301451, 50, 0, 
+	  1.2566370614359172 },
+  { 0.025253991969481544, 50, 0, 
+	  1.4137166941154069 },
+  { -0.31830208724152359, 50, 0, 
+	  1.5707963267948966 },
+  { 0.025253991969476332, 50, 0, 
+	  1.7278759594743860 },
+  { 0.32232921941301479, 50, 0, 
+	  1.8849555921538759 },
+  { -0.079132716267088510, 50, 0, 
+	  2.0420352248333655 },
+  { -0.33636199170850883, 50, 0, 
+	  2.1991148575128552 },
+  { 0.14571730283563347, 50, 0, 
+	  2.3561944901923448 },
+  { 0.36926172901532667, 50, 0, 
+	  2.5132741228718345 },
+  { -0.24876032079677354, 50, 0, 
+	  2.6703537555513241 },
+  { -0.46056183476301255, 50, 0, 
+	  2.8274333882308138 },
+  { 0.53157537495172758, 50, 0, 
+	  2.9845130209103035 },
+  { 2.8350175706934717, 50, 0, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=50, m=0.
+template<typename Tp>
+  void
+  test022()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data022)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data022[i].l), Tp(data022[i].m),
+		     Tp(data022[i].theta));
+	const Tp f0 = data022[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for l=50, m=1.
+testcase_sph_legendre<double> data023[] = {
+  { 0.0000000000000000, 50, 1, 
+	  0.0000000000000000 },
+  { -0.63751752155226260, 50, 1, 
+	  0.15707963267948966 },
+  { -0.32616619317604606, 50, 1, 
+	  0.31415926535897931 },
+  { 0.40649930826162850, 50, 1, 
+	  0.47123889803846897 },
+  { 0.18473991408344057, 50, 1, 
+	  0.62831853071795862 },
+  { -0.35083930302013117, 50, 1, 
+	  0.78539816339744828 },
+  { -0.10755382110947125, 50, 1, 
+	  0.94247779607693793 },
+  { 0.32822568316499900, 50, 1, 
+	  1.0995574287564276 },
+  { 0.050286056609797389, 50, 1, 
+	  1.2566370614359172 },
+  { -0.31935368562159644, 50, 1, 
+	  1.4137166941154069 },
+  { -9.8421602686195941e-16, 50, 1, 
+	  1.5707963267948966 },
+  { 0.31935368562159716, 50, 1, 
+	  1.7278759594743860 },
+  { -0.050286056609795446, 50, 1, 
+	  1.8849555921538759 },
+  { -0.32822568316499912, 50, 1, 
+	  2.0420352248333655 },
+  { 0.10755382110946902, 50, 1, 
+	  2.1991148575128552 },
+  { 0.35083930302013205, 50, 1, 
+	  2.3561944901923448 },
+  { -0.18473991408343635, 50, 1, 
+	  2.5132741228718345 },
+  { -0.40649930826163011, 50, 1, 
+	  2.6703537555513241 },
+  { 0.32616619317604606, 50, 1, 
+	  2.8274333882308138 },
+  { 0.63751752155228247, 50, 1, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 50, 1, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=50, m=1.
+template<typename Tp>
+  void
+  test023()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data023)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data023[i].l), Tp(data023[i].m),
+		     Tp(data023[i].theta));
+	const Tp f0 = data023[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for l=50, m=2.
+testcase_sph_legendre<double> data024[] = {
+  { 0.0000000000000000, 50, 2, 
+	  0.0000000000000000 },
+  { -0.37230261163838724, 50, 2, 
+	  0.15707963267948966 },
+  { 0.50051599680316194, 50, 2, 
+	  0.31415926535897931 },
+  { 0.21724795180329495, 50, 2, 
+	  0.47123889803846897 },
+  { -0.37948127307610924, 50, 2, 
+	  0.62831853071795862 },
+  { -0.13187372121003396, 50, 2, 
+	  0.78539816339744828 },
+  { 0.33959009162400228, 50, 2, 
+	  0.94247779607693793 },
+  { 0.072537503112489563, 50, 2, 
+	  1.0995574287564276 },
+  { -0.32310306941855266, 50, 2, 
+	  1.2566370614359172 },
+  { -0.023259822816436588, 50, 2, 
+	  1.4137166941154069 },
+  { 0.31842698506357275, 50, 2, 
+	  1.5707963267948966 },
+  { -0.023259822816431196, 50, 2, 
+	  1.7278759594743860 },
+  { -0.32310306941855316, 50, 2, 
+	  1.8849555921538759 },
+  { 0.072537503112487453, 50, 2, 
+	  2.0420352248333655 },
+  { 0.33959009162400267, 50, 2, 
+	  2.1991148575128552 },
+  { -0.13187372121003124, 50, 2, 
+	  2.3561944901923448 },
+  { -0.37948127307611107, 50, 2, 
+	  2.5132741228718345 },
+  { 0.21724795180329090, 50, 2, 
+	  2.6703537555513241 },
+  { 0.50051599680316194, 50, 2, 
+	  2.8274333882308138 },
+  { -0.37230261163837081, 50, 2, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 50, 2, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=50, m=2.
+template<typename Tp>
+  void
+  test024()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data024)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data024[i].l), Tp(data024[i].m),
+		     Tp(data024[i].theta));
+	const Tp f0 = data024[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+// Test data for l=50, m=5.
+testcase_sph_legendre<double> data025[] = {
+  { 0.0000000000000000, 50, 5, 
+	  0.0000000000000000 },
+  { -0.57750385903193124, 50, 5, 
+	  0.15707963267948966 },
+  { 0.077360497065588632, 50, 5, 
+	  0.31415926535897931 },
+  { 0.47707267400540226, 50, 5, 
+	  0.47123889803846897 },
+  { 0.055370615126630517, 50, 5, 
+	  0.62831853071795862 },
+  { -0.37629451847202833, 50, 5, 
+	  0.78539816339744828 },
+  { -0.048042277801960784, 50, 5, 
+	  0.94247779607693793 },
+  { 0.33619379362228718, 50, 5, 
+	  1.0995574287564276 },
+  { 0.025265227185718764, 50, 5, 
+	  1.2566370614359172 },
+  { -0.32083679430964535, 50, 5, 
+	  1.4137166941154069 },
+  { -9.8189201019751884e-16, 50, 5, 
+	  1.5707963267948966 },
+  { 0.32083679430964579, 50, 5, 
+	  1.7278759594743860 },
+  { -0.025265227185716790, 50, 5, 
+	  1.8849555921538759 },
+  { -0.33619379362228752, 50, 5, 
+	  2.0420352248333655 },
+  { 0.048042277801958064, 50, 5, 
+	  2.1991148575128552 },
+  { 0.37629451847202872, 50, 5, 
+	  2.3561944901923448 },
+  { -0.055370615126626811, 50, 5, 
+	  2.5132741228718345 },
+  { -0.47707267400540176, 50, 5, 
+	  2.6703537555513241 },
+  { -0.077360497065588632, 50, 5, 
+	  2.8274333882308138 },
+  { 0.57750385903191603, 50, 5, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 50, 5, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=50, m=5.
+template<typename Tp>
+  void
+  test025()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data025)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data025[i].l), Tp(data025[i].m),
+		     Tp(data025[i].theta));
+	const Tp f0 = data025[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for l=50, m=10.
+testcase_sph_legendre<double> data026[] = {
+  { 0.0000000000000000, 50, 10, 
+	  0.0000000000000000 },
+  { 0.15606941844800776, 50, 10, 
+	  0.15707963267948966 },
+  { -0.53748868836814501, 50, 10, 
+	  0.31415926535897931 },
+  { -0.49304919025183969, 50, 10, 
+	  0.47123889803846897 },
+  { -0.26267582750428364, 50, 10, 
+	  0.62831853071795862 },
+  { 0.22058983666314153, 50, 10, 
+	  0.78539816339744828 },
+  { 0.32936725160671754, 50, 10, 
+	  0.94247779607693793 },
+  { -0.092053311559447959, 50, 10, 
+	  1.0995574287564276 },
+  { -0.32542913495935522, 50, 10, 
+	  1.2566370614359172 },
+  { 0.025673223789103351, 50, 10, 
+	  1.4137166941154069 },
+  { 0.32150019350255743, 50, 10, 
+	  1.5707963267948966 },
+  { 0.025673223789108836, 50, 10, 
+	  1.7278759594743860 },
+  { -0.32542913495935510, 50, 10, 
+	  1.8849555921538759 },
+  { -0.092053311559449819, 50, 10, 
+	  2.0420352248333655 },
+  { 0.32936725160671687, 50, 10, 
+	  2.1991148575128552 },
+  { 0.22058983666314380, 50, 10, 
+	  2.3561944901923448 },
+  { -0.26267582750427920, 50, 10, 
+	  2.5132741228718345 },
+  { -0.49304919025184135, 50, 10, 
+	  2.6703537555513241 },
+  { -0.53748868836814501, 50, 10, 
+	  2.8274333882308138 },
+  { 0.15606941844801256, 50, 10, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 50, 10, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=50, m=10.
+template<typename Tp>
+  void
+  test026()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data026)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data026[i].l), Tp(data026[i].m),
+		     Tp(data026[i].theta));
+	const Tp f0 = data026[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for l=50, m=20.
+testcase_sph_legendre<double> data027[] = {
+  { 0.0000000000000000, 50, 20, 
+	  0.0000000000000000 },
+  { 3.0409598712833246e-07, 50, 20, 
+	  0.15707963267948966 },
+  { 0.030940518122882274, 50, 20, 
+	  0.31415926535897931 },
+  { 0.64134588721659802, 50, 20, 
+	  0.47123889803846897 },
+  { 0.29895244392136405, 50, 20, 
+	  0.62831853071795862 },
+  { 0.25309324781873871, 50, 20, 
+	  0.78539816339744828 },
+  { 0.34368634714931717, 50, 20, 
+	  0.94247779607693793 },
+  { 0.33996764360663945, 50, 20, 
+	  1.0995574287564276 },
+  { 0.12866267745104024, 50, 20, 
+	  1.2566370614359172 },
+  { -0.18201114398922874, 50, 20, 
+	  1.4137166941154069 },
+  { -0.33216683431510857, 50, 20, 
+	  1.5707963267948966 },
+  { -0.18201114398923302, 50, 20, 
+	  1.7278759594743860 },
+  { 0.12866267745103857, 50, 20, 
+	  1.8849555921538759 },
+  { 0.33996764360663895, 50, 20, 
+	  2.0420352248333655 },
+  { 0.34368634714931812, 50, 20, 
+	  2.1991148575128552 },
+  { 0.25309324781874126, 50, 20, 
+	  2.3561944901923448 },
+  { 0.29895244392136594, 50, 20, 
+	  2.5132741228718345 },
+  { 0.64134588721659869, 50, 20, 
+	  2.6703537555513241 },
+  { 0.030940518122882274, 50, 20, 
+	  2.8274333882308138 },
+  { 3.0409598712835887e-07, 50, 20, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 50, 20, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=50, m=20.
+template<typename Tp>
+  void
+  test027()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data027)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data027[i].l), Tp(data027[i].m),
+		     Tp(data027[i].theta));
+	const Tp f0 = data027[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for l=50, m=50.
+testcase_sph_legendre<double> data028[] = {
+  { 0.0000000000000000, 50, 50, 
+	  0.0000000000000000 },
+  { 4.1649039898151844e-41, 50, 50, 
+	  0.15707963267948966 },
+  { 2.5240684647724192e-26, 50, 50, 
+	  0.31415926535897931 },
+  { 5.6927376423967334e-18, 50, 50, 
+	  0.47123889803846897 },
+  { 2.3116239814797057e-12, 50, 50, 
+	  0.62831853071795862 },
+  { 2.3835981241325056e-08, 50, 50, 
+	  0.78539816339744828 },
+  { 1.9992410287270356e-05, 50, 50, 
+	  0.94247779607693793 },
+  { 0.0024947505670829834, 50, 50, 
+	  1.0995574287564276 },
+  { 0.065057774647971231, 50, 50, 
+	  1.2566370614359172 },
+  { 0.43050607056732243, 50, 50, 
+	  1.4137166941154069 },
+  { 0.79980281171531975, 50, 50, 
+	  1.5707963267948966 },
+  { 0.43050607056732360, 50, 50, 
+	  1.7278759594743860 },
+  { 0.065057774647971398, 50, 50, 
+	  1.8849555921538759 },
+  { 0.0024947505670829899, 50, 50, 
+	  2.0420352248333655 },
+  { 1.9992410287270427e-05, 50, 50, 
+	  2.1991148575128552 },
+  { 2.3835981241325311e-08, 50, 50, 
+	  2.3561944901923448 },
+  { 2.3116239814797222e-12, 50, 50, 
+	  2.5132741228718345 },
+  { 5.6927376423968952e-18, 50, 50, 
+	  2.6703537555513241 },
+  { 2.5240684647724192e-26, 50, 50, 
+	  2.8274333882308138 },
+  { 4.1649039898161316e-41, 50, 50, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 50, 50, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=50, m=50.
+template<typename Tp>
+  void
+  test028()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data028)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data028[i].l), Tp(data028[i].m),
+		     Tp(data028[i].theta));
+	const Tp f0 = data028[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for l=100, m=0.
+testcase_sph_legendre<double> data029[] = {
+  { 3.9993839251484076, 100, 0, 
+	  0.0000000000000000 },
+  { -0.60770160285935426, 100, 0, 
+	  0.15707963267948966 },
+  { 0.46193027883955923, 100, 0, 
+	  0.31415926535897931 },
+  { -0.40218718869815234, 100, 0, 
+	  0.47123889803846897 },
+  { 0.36960201406910725, 100, 0, 
+	  0.62831853071795862 },
+  { -0.34953726547378389, 100, 0, 
+	  0.78539816339744828 },
+  { 0.33646959352497829, 100, 0, 
+	  0.94247779607693793 },
+  { -0.32784733067663224, 100, 0, 
+	  1.0995574287564276 },
+  { 0.32235624474047969, 100, 0, 
+	  1.2566370614359172 },
+  { -0.31929330706601350, 100, 0, 
+	  1.4137166941154069 },
+  { 0.31830791662110325, 100, 0, 
+	  1.5707963267948966 },
+  { -0.31929330706601405, 100, 0, 
+	  1.7278759594743860 },
+  { 0.32235624474048036, 100, 0, 
+	  1.8849555921538759 },
+  { -0.32784733067663357, 100, 0, 
+	  2.0420352248333655 },
+  { 0.33646959352498013, 100, 0, 
+	  2.1991148575128552 },
+  { -0.34953726547378589, 100, 0, 
+	  2.3561944901923448 },
+  { 0.36960201406911097, 100, 0, 
+	  2.5132741228718345 },
+  { -0.40218718869815723, 100, 0, 
+	  2.6703537555513241 },
+  { 0.46193027883955923, 100, 0, 
+	  2.8274333882308138 },
+  { -0.60770160285939456, 100, 0, 
+	  2.9845130209103035 },
+  { 3.9993839251484076, 100, 0, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=100, m=0.
+template<typename Tp>
+  void
+  test029()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data029)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data029[i].l), Tp(data029[i].m),
+		     Tp(data029[i].theta));
+	const Tp f0 = data029[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for l=100, m=1.
+testcase_sph_legendre<double> data030[] = {
+  { 0.0000000000000000, 100, 1, 
+	  0.0000000000000000 },
+  { -0.50851949013719866, 100, 1, 
+	  0.15707963267948966 },
+  { 0.33129641402221749, 100, 1, 
+	  0.31415926535897931 },
+  { -0.24390405750942512, 100, 1, 
+	  0.47123889803846897 },
+  { 0.18659755088414104, 100, 1, 
+	  0.62831853071795862 },
+  { -0.14355908970517178, 100, 1, 
+	  0.78539816339744828 },
+  { 0.10844906813251107, 100, 1, 
+	  0.94247779607693793 },
+  { -0.078100088690857675, 100, 1, 
+	  1.0995574287564276 },
+  { 0.050670002998302717, 100, 1, 
+	  1.2566370614359172 },
+  { -0.024941251747138900, 100, 1, 
+	  1.4137166941154069 },
+  { 1.9587949830851623e-15, 100, 1, 
+	  1.5707963267948966 },
+  { 0.024941251747127875, 100, 1, 
+	  1.7278759594743860 },
+  { -0.050670002998298824, 100, 1, 
+	  1.8849555921538759 },
+  { 0.078100088690853664, 100, 1, 
+	  2.0420352248333655 },
+  { -0.10844906813250622, 100, 1, 
+	  2.1991148575128552 },
+  { 0.14355908970516626, 100, 1, 
+	  2.3561944901923448 },
+  { -0.18659755088413388, 100, 1, 
+	  2.5132741228718345 },
+  { 0.24390405750941679, 100, 1, 
+	  2.6703537555513241 },
+  { -0.33129641402221749, 100, 1, 
+	  2.8274333882308138 },
+  { 0.50851949013714159, 100, 1, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 100, 1, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=100, m=1.
+template<typename Tp>
+  void
+  test030()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data030)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data030[i].l), Tp(data030[i].m),
+		     Tp(data030[i].theta));
+	const Tp f0 = data030[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for l=100, m=2.
+testcase_sph_legendre<double> data031[] = {
+  { 0.0000000000000000, 100, 2, 
+	  0.0000000000000000 },
+  { 0.67166274297193962, 100, 2, 
+	  0.15707963267948966 },
+  { -0.48226933687995360, 100, 2, 
+	  0.31415926535897931 },
+  { 0.41175421895715525, 100, 2, 
+	  0.47123889803846897 },
+  { -0.37475021787822438, 100, 2, 
+	  0.62831853071795862 },
+  { 0.35242909383605225, 100, 2, 
+	  0.78539816339744828 },
+  { -0.33807110409160063, 100, 2, 
+	  0.94247779607693793 },
+  { 0.32867180390710077, 100, 2, 
+	  1.0995574287564276 },
+  { -0.32271583790278502, 100, 2, 
+	  1.2566370614359172 },
+  { 0.31940354677687444, 100, 2, 
+	  1.4137166941154069 },
+  { -0.31833943693772526, 100, 2, 
+	  1.5707963267948966 },
+  { 0.31940354677687555, 100, 2, 
+	  1.7278759594743860 },
+  { -0.32271583790278552, 100, 2, 
+	  1.8849555921538759 },
+  { 0.32867180390710193, 100, 2, 
+	  2.0420352248333655 },
+  { -0.33807110409160157, 100, 2, 
+	  2.1991148575128552 },
+  { 0.35242909383605503, 100, 2, 
+	  2.3561944901923448 },
+  { -0.37475021787822776, 100, 2, 
+	  2.5132741228718345 },
+  { 0.41175421895716052, 100, 2, 
+	  2.6703537555513241 },
+  { -0.48226933687995360, 100, 2, 
+	  2.8274333882308138 },
+  { 0.67166274297196660, 100, 2, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 100, 2, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=100, m=2.
+template<typename Tp>
+  void
+  test031()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data031)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data031[i].l), Tp(data031[i].m),
+		     Tp(data031[i].theta));
+	const Tp f0 = data031[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for l=100, m=5.
+testcase_sph_legendre<double> data032[] = {
+  { 0.0000000000000000, 100, 5, 
+	  0.0000000000000000 },
+  { 0.062564361105902272, 100, 5, 
+	  0.15707963267948966 },
+  { 0.14179554455879767, 100, 5, 
+	  0.31415926535897931 },
+  { -0.14356866942905960, 100, 5, 
+	  0.47123889803846897 },
+  { 0.12355483388448550, 100, 5, 
+	  0.62831853071795862 },
+  { -0.10090029999681642, 100, 5, 
+	  0.78539816339744828 },
+  { 0.078905134460230675, 100, 5, 
+	  0.94247779607693793 },
+  { -0.058040182398185071, 100, 5, 
+	  1.0995574287564276 },
+  { 0.038142759389482424, 100, 5, 
+	  1.2566370614359172 },
+  { -0.018906264170660478, 100, 5, 
+	  1.4137166941154069 },
+  { 1.9576303042914544e-15, 100, 5, 
+	  1.5707963267948966 },
+  { 0.018906264170649455, 100, 5, 
+	  1.7278759594743860 },
+  { -0.038142759389478365, 100, 5, 
+	  1.8849555921538759 },
+  { 0.058040182398180429, 100, 5, 
+	  2.0420352248333655 },
+  { -0.078905134460225707, 100, 5, 
+	  2.1991148575128552 },
+  { 0.10090029999681013, 100, 5, 
+	  2.3561944901923448 },
+  { -0.12355483388447824, 100, 5, 
+	  2.5132741228718345 },
+  { 0.14356866942904906, 100, 5, 
+	  2.6703537555513241 },
+  { -0.14179554455879767, 100, 5, 
+	  2.8274333882308138 },
+  { -0.062564361105954577, 100, 5, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 100, 5, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=100, m=5.
+template<typename Tp>
+  void
+  test032()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data032)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data032[i].l), Tp(data032[i].m),
+		     Tp(data032[i].theta));
+	const Tp f0 = data032[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000039e-13));
+  }
+
+// Test data for l=100, m=10.
+testcase_sph_legendre<double> data033[] = {
+  { 0.0000000000000000, 100, 10, 
+	  0.0000000000000000 },
+  { -0.75366545187996004, 100, 10, 
+	  0.15707963267948966 },
+  { -0.35914570017276798, 100, 10, 
+	  0.31415926535897931 },
+  { 0.43480692911578295, 100, 10, 
+	  0.47123889803846897 },
+  { -0.40862111080315755, 100, 10, 
+	  0.62831853071795862 },
+  { 0.37832688692909411, 100, 10, 
+	  0.78539816339744828 },
+  { -0.35484056194773445, 100, 10, 
+	  0.94247779607693793 },
+  { 0.33821981171196341, 100, 10, 
+	  1.0995574287564276 },
+  { -0.32729120767830594, 100, 10, 
+	  1.2566370614359172 },
+  { 0.32110336937091438, 100, 10, 
+	  1.4137166941154069 },
+  { -0.31910064020036194, 100, 10, 
+	  1.5707963267948966 },
+  { 0.32110336937091460, 100, 10, 
+	  1.7278759594743860 },
+  { -0.32729120767830605, 100, 10, 
+	  1.8849555921538759 },
+  { 0.33821981171196341, 100, 10, 
+	  2.0420352248333655 },
+  { -0.35484056194773461, 100, 10, 
+	  2.1991148575128552 },
+  { 0.37832688692909372, 100, 10, 
+	  2.3561944901923448 },
+  { -0.40862111080315500, 100, 10, 
+	  2.5132741228718345 },
+  { 0.43480692911577751, 100, 10, 
+	  2.6703537555513241 },
+  { -0.35914570017276798, 100, 10, 
+	  2.8274333882308138 },
+  { -0.75366545187997991, 100, 10, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 100, 10, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=100, m=10.
+template<typename Tp>
+  void
+  test033()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data033)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data033[i].l), Tp(data033[i].m),
+		     Tp(data033[i].theta));
+	const Tp f0 = data033[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000020e-13));
+  }
+
+// Test data for l=100, m=20.
+testcase_sph_legendre<double> data034[] = {
+  { 0.0000000000000000, 100, 20, 
+	  0.0000000000000000 },
+  { 0.053569660841553700, 100, 20, 
+	  0.15707963267948966 },
+  { 0.57154926874732348, 100, 20, 
+	  0.31415926535897931 },
+  { 0.47536909969585633, 100, 20, 
+	  0.47123889803846897 },
+  { -0.28882554564109075, 100, 20, 
+	  0.62831853071795862 },
+  { 0.020116179014043743, 100, 20, 
+	  0.78539816339744828 },
+  { 0.14752195931706563, 100, 20, 
+	  0.94247779607693793 },
+  { -0.24069428588868366, 100, 20, 
+	  1.0995574287564276 },
+  { 0.29031796025014306, 100, 20, 
+	  1.2566370614359172 },
+  { -0.31437256851143458, 100, 20, 
+	  1.4137166941154069 },
+  { 0.32153954851141792, 100, 20, 
+	  1.5707963267948966 },
+  { -0.31437256851143169, 100, 20, 
+	  1.7278759594743860 },
+  { 0.29031796025014139, 100, 20, 
+	  1.8849555921538759 },
+  { -0.24069428588868083, 100, 20, 
+	  2.0420352248333655 },
+  { 0.14752195931706186, 100, 20, 
+	  2.1991148575128552 },
+  { 0.020116179014049562, 100, 20, 
+	  2.3561944901923448 },
+  { -0.28882554564109575, 100, 20, 
+	  2.5132741228718345 },
+  { 0.47536909969585545, 100, 20, 
+	  2.6703537555513241 },
+  { 0.57154926874732348, 100, 20, 
+	  2.8274333882308138 },
+  { 0.053569660841557079, 100, 20, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 100, 20, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=100, m=20.
+template<typename Tp>
+  void
+  test034()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data034)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data034[i].l), Tp(data034[i].m),
+		     Tp(data034[i].theta));
+	const Tp f0 = data034[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+// Test data for l=100, m=50.
+testcase_sph_legendre<double> data035[] = {
+  { 0.0000000000000000, 100, 50, 
+	  0.0000000000000000 },
+  { 3.3047910392590615e-21, 100, 50, 
+	  0.15707963267948966 },
+  { 1.0592655372554981e-07, 100, 50, 
+	  0.31415926535897931 },
+  { 0.080418744223952773, 100, 50, 
+	  0.47123889803846897 },
+  { -0.56450600580393095, 100, 50, 
+	  0.62831853071795862 },
+  { 0.33338739844742110, 100, 50, 
+	  0.78539816339744828 },
+  { 0.39741714816514706, 100, 50, 
+	  0.94247779607693793 },
+  { 0.35223993750972243, 100, 50, 
+	  1.0995574287564276 },
+  { 0.17885891940721577, 100, 50, 
+	  1.2566370614359172 },
+  { -0.15341660126461967, 100, 50, 
+	  1.4137166941154069 },
+  { -0.34175924303503102, 100, 50, 
+	  1.5707963267948966 },
+  { -0.15341660126462869, 100, 50, 
+	  1.7278759594743860 },
+  { 0.17885891940721302, 100, 50, 
+	  1.8849555921538759 },
+  { 0.35223993750972105, 100, 50, 
+	  2.0420352248333655 },
+  { 0.39741714816514595, 100, 50, 
+	  2.1991148575128552 },
+  { 0.33338739844741666, 100, 50, 
+	  2.3561944901923448 },
+  { -0.56450600580392973, 100, 50, 
+	  2.5132741228718345 },
+  { 0.080418744223953911, 100, 50, 
+	  2.6703537555513241 },
+  { 1.0592655372554981e-07, 100, 50, 
+	  2.8274333882308138 },
+  { 3.3047910392597822e-21, 100, 50, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 100, 50, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=100, m=50.
+template<typename Tp>
+  void
+  test035()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data035)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data035[i].l), Tp(data035[i].m),
+		     Tp(data035[i].theta));
+	const Tp f0 = data035[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000008e-12));
+  }
+
+// Test data for l=100, m=100.
+testcase_sph_legendre<double> data036[] = {
+  { 0.0000000000000000, 100, 100, 
+	  0.0000000000000000 },
+  { 2.5744136608862186e-81, 100, 100, 
+	  0.15707963267948966 },
+  { 9.4551974868956498e-52, 100, 100, 
+	  0.31415926535897931 },
+  { 4.8096190703397596e-35, 100, 100, 
+	  0.47123889803846897 },
+  { 7.9305393636342891e-24, 100, 100, 
+	  0.62831853071795862 },
+  { 8.4320740610944858e-16, 100, 100, 
+	  0.78539816339744828 },
+  { 5.9319660146027522e-10, 100, 100, 
+	  0.94247779607693793 },
+  { 9.2368225946797243e-06, 100, 100, 
+	  1.0995574287564276 },
+  { 0.0062815489742044095, 100, 100, 
+	  1.2566370614359172 },
+  { 0.27505966018176986, 100, 100, 
+	  1.4137166941154069 },
+  { 0.94936713998764621, 100, 100, 
+	  1.5707963267948966 },
+  { 0.27505966018177130, 100, 100, 
+	  1.7278759594743860 },
+  { 0.0062815489742044433, 100, 100, 
+	  1.8849555921538759 },
+  { 9.2368225946797734e-06, 100, 100, 
+	  2.0420352248333655 },
+  { 5.9319660146027946e-10, 100, 100, 
+	  2.1991148575128552 },
+  { 8.4320740610946652e-16, 100, 100, 
+	  2.3561944901923448 },
+  { 7.9305393636344023e-24, 100, 100, 
+	  2.5132741228718345 },
+  { 4.8096190703400333e-35, 100, 100, 
+	  2.6703537555513241 },
+  { 9.4551974868956498e-52, 100, 100, 
+	  2.8274333882308138 },
+  { 2.5744136608873895e-81, 100, 100, 
+	  2.9845130209103035 },
+  { 0.0000000000000000, 100, 100, 
+	  3.1415926535897931 },
+};
+
+// Test function for l=100, m=100.
+template<typename Tp>
+  void
+  test036()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data036)
+			   / sizeof(testcase_sph_legendre<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+  	 {
+	const Tp f = std::sph_legendre(Tp(data036[i].l), Tp(data036[i].m),
+		     Tp(data036[i].theta));
+	const Tp f0 = data036[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  test009<double>();
+  test010<double>();
+  test011<double>();
+  test012<double>();
+  test013<double>();
+  test014<double>();
+  test015<double>();
+  test016<double>();
+  test017<double>();
+  test018<double>();
+  test019<double>();
+  test020<double>();
+  test021<double>();
+  test022<double>();
+  test023<double>();
+  test024<double>();
+  test025<double>();
+  test026<double>();
+  test027<double>();
+  test028<double>();
+  test029<double>();
+  test030<double>();
+  test031<double>();
+  test032<double>();
+  test033<double>();
+  test034<double>();
+  test035<double>();
+  test036<double>();
+  return 0;
+}
Index: testsuite/special_functions/20_sph_legendre/compile.cc
===================================================================
--- testsuite/special_functions/20_sph_legendre/compile.cc	(revision 0)
+++ testsuite/special_functions/20_sph_legendre/compile.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.20 sph_legendre
+
+#include <cmath>
+
+void
+test01()
+{
+  float thetaf = 0.5F;
+  double thetad = 0.5;
+  long double thetal = 0.5L;
+  unsigned int l = 2, m = 1;
+
+  std::sph_legendre(l, m, thetaf);
+  std::sph_legendref(l, m, thetaf);
+  std::sph_legendre(l, m, thetad);
+  std::sph_legendre(l, m, thetal);
+  std::sph_legendrel(l, m, thetal);
+
+  return;
+}
+
Index: testsuite/special_functions/20_sph_legendre/compile_2.cc
===================================================================
--- testsuite/special_functions/20_sph_legendre/compile_2.cc	(revision 0)
+++ testsuite/special_functions/20_sph_legendre/compile_2.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.20 sph_legendre
+
+#include <math.h>
+
+void
+test01()
+{
+  float thetaf = 0.5F;
+  double thetad = 0.5;
+  long double thetal = 0.5L;
+  unsigned int l = 2, m = 1;
+
+  sph_legendre(l, m, thetaf);
+  sph_legendref(l, m, thetaf);
+  sph_legendre(l, m, thetad);
+  sph_legendre(l, m, thetal);
+  sph_legendrel(l, m, thetal);
+
+  return;
+}
+
Index: testsuite/special_functions/21_sph_neumann/check_nan.cc
===================================================================
--- testsuite/special_functions/21_sph_neumann/check_nan.cc	(revision 0)
+++ testsuite/special_functions/21_sph_neumann/check_nan.cc	(working copy)
@@ -0,0 +1,58 @@
+// { dg-require-c-std "" }
+// { dg-add-options ieee }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.21 sph_neumann
+
+#include <cmath>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+  float xf = std::numeric_limits<float>::quiet_NaN();
+  double xd = std::numeric_limits<double>::quiet_NaN();
+  long double xl = std::numeric_limits<long double>::quiet_NaN();
+
+  unsigned int n = 0;
+
+  float a = std::sph_neumann(n, xf);
+  float b = std::sph_neumannf(n, xf);
+  double c = std::sph_neumann(n, xd);
+  long double d = std::sph_neumann(n, xl);
+  long double e = std::sph_neumannl(n, xl);
+
+  bool test [[gnu::unused]] = true;
+  VERIFY(std::isnan(a));
+  VERIFY(std::isnan(b));
+  VERIFY(std::isnan(c));
+  VERIFY(std::isnan(d));
+  VERIFY(std::isnan(e));
+
+  return;
+}
+
+int
+main()
+{
+  test01();
+  return 0;
+}
+
Index: testsuite/special_functions/21_sph_neumann/check_value.cc
===================================================================
--- testsuite/special_functions/21_sph_neumann/check_value.cc	(revision 0)
+++ testsuite/special_functions/21_sph_neumann/check_value.cc	(working copy)
@@ -0,0 +1,476 @@
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+//
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  sph_neumann
+//  Compare against values generated by the GNU Scientific Library.
+//  The GSL can be found on the web: http://www.gnu.org/software/gsl/
+#include <limits>
+#include <cmath>
+#if defined(__TEST_DEBUG)
+#  include <iostream>
+#  define VERIFY(A) \
+  if (!(A)) \
+    { \
+      std::cout << "line " << __LINE__ \
+	<< "  max_abs_frac = " << max_abs_frac \
+	<< std::endl; \
+    }
+#else
+#  include <testsuite_hooks.h>
+#endif
+#include "../testcase.h"
+
+
+// Test data for n=0.
+testcase_sph_neumann<double> data001[] = {
+  { -0.056732437092645263, 0, 5.0000000000000000 },
+  { 0.083907152907645249, 0, 10.000000000000000 },
+  { 0.050645860857254747, 0, 15.000000000000000 },
+  { -0.020404103090669597, 0, 20.000000000000000 },
+  { -0.039648112474538942, 0, 25.000000000000000 },
+  { -0.0051417149962528020, 0, 30.000000000000000 },
+  { 0.025819777288328762, 0, 35.000000000000000 },
+  { 0.016673451541306544, 0, 40.000000000000000 },
+  { -0.011673821973727327, 0, 45.000000000000000 },
+  { -0.019299320569842265, 0, 50.000000000000000 },
+  { -0.00040230465930828606, 0, 55.000000000000000 },
+  { 0.015873549673585938, 0, 60.000000000000000 },
+  { 0.0086531361728949541, 0, 65.000000000000000 },
+  { -0.0090474171869471404, 0, 70.000000000000000 },
+  { -0.012290016929663325, 0, 75.000000000000000 },
+  { 0.0013798405479880944, 0, 80.000000000000000 },
+  { 0.011580901686988727, 0, 85.000000000000000 },
+  { 0.0049785957347685574, 0, 90.000000000000000 },
+  { -0.0076860374841559963, 0, 95.000000000000000 },
+  { -0.0086231887228768404, 0, 100.00000000000000 },
+};
+
+// Test function for n=0.
+template<typename Tp>
+  void
+  test001()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data001)
+			   / sizeof(testcase_sph_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_neumann(Tp(data001[i].n), Tp(data001[i].x));
+	const Tp f0 = data001[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000028e-11));
+  }
+
+// Test data for n=1.
+testcase_sph_neumann<double> data002[] = {
+  { 0.18043836751409864, 1, 5.0000000000000000 },
+  { 0.062792826379701502, 1, 10.000000000000000 },
+  { -0.039976131953324147, 1, 15.000000000000000 },
+  { -0.046667467690914864, 1, 20.000000000000000 },
+  { 0.0037081455049293634, 1, 25.000000000000000 },
+  { 0.032762996969886965, 1, 30.000000000000000 },
+  { 0.012971498479556563, 1, 35.000000000000000 },
+  { -0.018210992723451058, 1, 40.000000000000000 },
+  { -0.019168385477952129, 1, 45.000000000000000 },
+  { 0.0048615106626817301, 1, 50.000000000000000 },
+  { 0.018170052158169303, 1, 55.000000000000000 },
+  { 0.0053447361795967109, 1, 60.000000000000000 },
+  { -0.012587316051033977, 1, 65.000000000000000 },
+  { -0.011184829982069090, 1, 70.000000000000000 },
+  { 0.0050065549130635621, 1, 75.000000000000000 },
+  { 0.012440856180892041, 1, 80.000000000000000 },
+  { 0.0022077237839479508, 1, 85.000000000000000 },
+  { -0.0098779785318421041, 1, 90.000000000000000 },
+  { -0.0072731342338976518, 1, 95.000000000000000 },
+  { 0.0049774245238688201, 1, 100.00000000000000 },
+};
+
+// Test function for n=1.
+template<typename Tp>
+  void
+  test002()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data002)
+			   / sizeof(testcase_sph_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_neumann(Tp(data002[i].n), Tp(data002[i].x));
+	const Tp f0 = data002[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for n=2.
+testcase_sph_neumann<double> data003[] = {
+  { 0.16499545760110443, 2, 5.0000000000000000 },
+  { -0.065069304993734783, 2, 10.000000000000000 },
+  { -0.058641087247919575, 2, 15.000000000000000 },
+  { 0.013403982937032370, 2, 20.000000000000000 },
+  { 0.040093089935130458, 2, 25.000000000000000 },
+  { 0.0084180146932414986, 2, 30.000000000000000 },
+  { -0.024707934561509628, 2, 35.000000000000000 },
+  { -0.018039275995565374, 2, 40.000000000000000 },
+  { 0.010395929608530518, 2, 45.000000000000000 },
+  { 0.019591011209603170, 2, 50.000000000000000 },
+  { 0.0013933984133902479, 2, 55.000000000000000 },
+  { -0.015606312864606101, 2, 60.000000000000000 },
+  { -0.0092340892214042153, 2, 65.000000000000000 },
+  { 0.0085680673305727519, 2, 70.000000000000000 },
+  { 0.012490279126185866, 2, 75.000000000000000 },
+  { -0.00091330844120464274, 2, 80.000000000000000 },
+  { -0.011502982024025860, 2, 85.000000000000000 },
+  { -0.0053078616858299611, 2, 90.000000000000000 },
+  { 0.0074563595609802797, 2, 95.000000000000000 },
+  { 0.0087725114585929052, 2, 100.00000000000000 },
+};
+
+// Test function for n=2.
+template<typename Tp>
+  void
+  test003()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data003)
+			   / sizeof(testcase_sph_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_neumann(Tp(data003[i].n), Tp(data003[i].x));
+	const Tp f0 = data003[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000028e-11));
+  }
+
+// Test data for n=5.
+testcase_sph_neumann<double> data004[] = {
+  { -0.32046504674973919, 5, 5.0000000000000000 },
+  { 0.093833541678691818, 5, 10.000000000000000 },
+  { 0.020475698281859061, 5, 15.000000000000000 },
+  { -0.048172347757372780, 5, 20.000000000000000 },
+  { -0.018309489232548347, 5, 25.000000000000000 },
+  { 0.026639390496569996, 5, 30.000000000000000 },
+  { 0.022006038985576210, 5, 35.000000000000000 },
+  { -0.011268975348057965, 5, 40.000000000000000 },
+  { -0.021770388372274858, 5, 45.000000000000000 },
+  { -0.00069711319645853701, 5, 50.000000000000000 },
+  { 0.017439589450220901, 5, 55.000000000000000 },
+  { 0.0088699170919343089, 5, 60.000000000000000 },
+  { -0.010421334444951861, 5, 65.000000000000000 },
+  { -0.012746769858008553, 5, 70.000000000000000 },
+  { 0.0026282888028967737, 5, 75.000000000000000 },
+  { 0.012477658581324189, 5, 80.000000000000000 },
+  { 0.0040771816818182642, 5, 85.000000000000000 },
+  { -0.0089777759570579818, 5, 90.000000000000000 },
+  { -0.0083184557896676149, 5, 95.000000000000000 },
+  { 0.0037206784862748965, 5, 100.00000000000000 },
+};
+
+// Test function for n=5.
+template<typename Tp>
+  void
+  test004()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data004)
+			   / sizeof(testcase_sph_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_neumann(Tp(data004[i].n), Tp(data004[i].x));
+	const Tp f0 = data004[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000028e-11));
+  }
+
+// Test data for n=10.
+testcase_sph_neumann<double> data005[] = {
+  { -26.656114405718711, 10, 5.0000000000000000 },
+  { -0.17245367208805784, 10, 10.000000000000000 },
+  { 0.078461689849642580, 10, 15.000000000000000 },
+  { -0.036843410496289961, 10, 20.000000000000000 },
+  { -0.021158339301097475, 10, 25.000000000000000 },
+  { 0.031219591064754939, 10, 30.000000000000000 },
+  { 0.012840593422414807, 10, 35.000000000000000 },
+  { -0.021803068636888072, 10, 40.000000000000000 },
+  { -0.014071636804469044, 10, 45.000000000000000 },
+  { 0.013524687511158758, 10, 50.000000000000000 },
+  { 0.015684932653180595, 10, 55.000000000000000 },
+  { -0.0056356895567262122, 10, 60.000000000000000 },
+  { -0.015364490270315362, 10, 65.000000000000000 },
+  { -0.0014525575672261295, 10, 70.000000000000000 },
+  { 0.012648951699549433, 10, 75.000000000000000 },
+  { 0.0068571608061120367, 10, 80.000000000000000 },
+  { -0.0080151152941401460, 10, 85.000000000000000 },
+  { -0.0098139742219019149, 10, 90.000000000000000 },
+  { 0.0025002854072314951, 10, 95.000000000000000 },
+  { 0.010025777373636155, 10, 100.00000000000000 },
+};
+
+// Test function for n=10.
+template<typename Tp>
+  void
+  test005()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data005)
+			   / sizeof(testcase_sph_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_neumann(Tp(data005[i].n), Tp(data005[i].x));
+	const Tp f0 = data005[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(5.0000000000000028e-11));
+  }
+
+// Test data for n=20.
+testcase_sph_neumann<double> data006[] = {
+  { -926795140.30575466, 20, 5.0000000000000000 },
+  { -1211.2106053526036, 20, 10.000000000000000 },
+  { -1.5559965765652175, 20, 15.000000000000000 },
+  { -0.093401132250914398, 20, 20.000000000000000 },
+  { 0.044031985675276462, 20, 25.000000000000000 },
+  { -0.036078033606613907, 20, 30.000000000000000 },
+  { 0.029828405631319645, 20, 35.000000000000000 },
+  { -0.0048414810986760759, 20, 40.000000000000000 },
+  { -0.020504694681516944, 20, 45.000000000000000 },
+  { 0.013759531302541216, 20, 50.000000000000000 },
+  { 0.012783038861734196, 20, 55.000000000000000 },
+  { -0.013117009421906418, 20, 60.000000000000000 },
+  { -0.010338106075674407, 20, 65.000000000000000 },
+  { 0.010538610814111244, 20, 70.000000000000000 },
+  { 0.010200029094273744, 20, 75.000000000000000 },
+  { -0.0073123450945617122, 20, 80.000000000000000 },
+  { -0.010581510354950906, 20, 85.000000000000000 },
+  { 0.0036866374015298723, 20, 90.000000000000000 },
+  { 0.010498384318338270, 20, 95.000000000000000 },
+  { 5.6317293788334978e-05, 20, 100.00000000000000 },
+};
+
+// Test function for n=20.
+template<typename Tp>
+  void
+  test006()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data006)
+			   / sizeof(testcase_sph_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_neumann(Tp(data006[i].n), Tp(data006[i].x));
+	const Tp f0 = data006[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(1.0000000000000007e-09));
+  }
+
+// Test data for n=50.
+testcase_sph_neumann<double> data007[] = {
+  { -6.9641091882698388e+42, 50, 5.0000000000000000 },
+  { -4.5282272723512023e+27, 50, 10.000000000000000 },
+  { -9.0004902645887037e+18, 50, 15.000000000000000 },
+  { -9542541667002.5117, 50, 20.000000000000000 },
+  { -363518140.71026671, 50, 25.000000000000000 },
+  { -152551.57233157745, 50, 30.000000000000000 },
+  { -386.26599186208625, 50, 35.000000000000000 },
+  { -4.3290507947291035, 50, 40.000000000000000 },
+  { -0.19968460851503758, 50, 45.000000000000000 },
+  { -0.041900001504607758, 50, 50.000000000000000 },
+  { 0.010696040672421902, 50, 55.000000000000000 },
+  { 0.0078198768555267188, 50, 60.000000000000000 },
+  { -0.010088474938191242, 50, 65.000000000000000 },
+  { 0.0062423671279824801, 50, 70.000000000000000 },
+  { 0.0011284242794941733, 50, 75.000000000000000 },
+  { -0.0093934266037485562, 50, 80.000000000000000 },
+  { 0.013108079602843424, 50, 85.000000000000000 },
+  { -0.0075396607225722626, 50, 90.000000000000000 },
+  { -0.0042605703552836558, 50, 95.000000000000000 },
+  { 0.010747822973682470, 50, 100.00000000000000 },
+};
+
+// Test function for n=50.
+template<typename Tp>
+  void
+  test007()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data007)
+			   / sizeof(testcase_sph_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_neumann(Tp(data007[i].n), Tp(data007[i].x));
+	const Tp f0 = data007[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000014e-11));
+  }
+
+// Test data for n=100.
+testcase_sph_neumann<double> data008[] = {
+  { -1.7997139826259740e+116, 100, 5.0000000000000000 },
+  { -8.5732263093296268e+85, 100, 10.000000000000000 },
+  { -1.9270658593711677e+68, 100, 15.000000000000000 },
+  { -7.2208893582952385e+55, 100, 20.000000000000000 },
+  { -2.0868752613007946e+46, 100, 25.000000000000000 },
+  { -4.2496124023612646e+38, 100, 30.000000000000000 },
+  { -1.7042898348910271e+32, 100, 35.000000000000000 },
+  { -6.3021565260724554e+26, 100, 40.000000000000000 },
+  { -1.3199917400494367e+22, 100, 45.000000000000000 },
+  { -1.1256928913265988e+18, 100, 50.000000000000000 },
+  { -309801083340343.25, 100, 55.000000000000000 },
+  { -232585620046.64737, 100, 60.000000000000000 },
+  { -421135935.93756074, 100, 65.000000000000000 },
+  { -1680637.4531202621, 100, 70.000000000000000 },
+  { -13868.302591128844, 100, 75.000000000000000 },
+  { -227.24385709173322, 100, 80.000000000000000 },
+  { -7.2807038787138731, 100, 85.000000000000000 },
+  { -0.46648154448250878, 100, 90.000000000000000 },
+  { -0.067270772720654556, 100, 95.000000000000000 },
+  { -0.022983850491562267, 100, 100.00000000000000 },
+};
+
+// Test function for n=100.
+template<typename Tp>
+  void
+  test008()
+  {
+    bool test [[gnu::unused]] = true;
+    const Tp eps = std::numeric_limits<Tp>::epsilon();
+    Tp max_abs_diff = -Tp(1);
+    Tp max_abs_frac = -Tp(1);
+    unsigned int num_datum = sizeof(data008)
+			   / sizeof(testcase_sph_neumann<double>);
+    for (unsigned int i = 0; i < num_datum; ++i)
+      {
+	const Tp f = std::sph_neumann(Tp(data008[i].n), Tp(data008[i].x));
+	const Tp f0 = data008[i].f0;
+	const Tp diff = f - f0;
+	if (std::abs(diff) > max_abs_diff)
+	  max_abs_diff = std::abs(diff);
+	if (std::abs(f0) > Tp(10) * eps
+	 && std::abs(f) > Tp(10) * eps)
+	  {
+	    const Tp frac = diff / f0;
+	    if (std::abs(frac) > max_abs_frac)
+	      max_abs_frac = std::abs(frac);
+	  }
+      }
+    VERIFY(max_abs_frac < Tp(2.5000000000000015e-12));
+  }
+
+int
+main()
+{
+  test001<double>();
+  test002<double>();
+  test003<double>();
+  test004<double>();
+  test005<double>();
+  test006<double>();
+  test007<double>();
+  test008<double>();
+  return 0;
+}
Index: testsuite/special_functions/21_sph_neumann/compile.cc
===================================================================
--- testsuite/special_functions/21_sph_neumann/compile.cc	(revision 0)
+++ testsuite/special_functions/21_sph_neumann/compile.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.21 sph_neumann
+
+#include <cmath>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+  unsigned int n = 0;
+
+  std::sph_neumann(n, xf);
+  std::sph_neumannf(n, xf);
+  std::sph_neumann(n, xd);
+  std::sph_neumann(n, xl);
+  std::sph_neumannl(n, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/21_sph_neumann/compile_2.cc
===================================================================
--- testsuite/special_functions/21_sph_neumann/compile_2.cc	(revision 0)
+++ testsuite/special_functions/21_sph_neumann/compile_2.cc	(working copy)
@@ -0,0 +1,41 @@
+// { dg-do compile }
+// { dg-options "-D__STDCPP_WANT_MATH_SPEC_FUNCS__" }
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// 8.1.21 sph_neumann
+
+#include <math.h>
+
+void
+test01()
+{
+  float xf = 0.5F;
+  double xd = 0.5;
+  long double xl = 0.5L;
+  unsigned int n = 0;
+
+  sph_neumann(n, xf);
+  sph_neumannf(n, xf);
+  sph_neumann(n, xd);
+  sph_neumann(n, xl);
+  sph_neumannl(n, xl);
+
+  return;
+}
+
Index: testsuite/special_functions/testcase.h
===================================================================
--- testsuite/special_functions/testcase.h	(revision 0)
+++ testsuite/special_functions/testcase.h	(working copy)
@@ -0,0 +1,256 @@
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+//  testcase.h
+
+//
+//  These are little PODs for special function inputs and
+//  expexted results for the testsuite.
+//
+
+//  Associated Laguerre polynomials.
+template <typename _Tp>
+struct testcase_assoc_laguerre
+{
+  _Tp f0;
+  unsigned int n;
+  unsigned int m;
+  _Tp x;
+  _Tp f;
+};
+
+//  Associated Legendre functions.
+template <typename _Tp>
+struct testcase_assoc_legendre
+{
+  _Tp f0;
+  unsigned int l;
+  unsigned int m;
+  _Tp x;
+  _Tp f;
+};
+
+//  Beta function.
+template <typename _Tp>
+struct testcase_beta
+{
+  _Tp f0;
+  _Tp x;
+  _Tp y;
+  _Tp f;
+};
+
+//  Complete elliptic integrals of the first kind.
+template <typename _Tp>
+struct testcase_comp_ellint_1
+{
+  _Tp f0;
+  _Tp k;
+  _Tp f;
+};
+
+//  Complete elliptic integrals of the second kind.
+template <typename _Tp>
+struct testcase_comp_ellint_2
+{
+  _Tp f0;
+  _Tp k;
+  _Tp f;
+};
+
+//  Complete elliptic integrals of the third kind.
+template <typename _Tp>
+struct testcase_comp_ellint_3
+{
+  _Tp f0;
+  _Tp k;
+  _Tp nu;
+  _Tp f;
+};
+
+//  Confluent hypergeometric functions.
+template <typename _Tp>
+struct testcase_conf_hyperg
+{
+  _Tp f0;
+  _Tp a;
+  _Tp c;
+  _Tp x;
+  _Tp f;
+};
+
+//  Regular modified cylindrical Bessel functions.
+template <typename _Tp>
+struct testcase_cyl_bessel_i
+{
+  _Tp f0;
+  _Tp nu;
+  _Tp x;
+  _Tp f;
+};
+
+//  Cylindrical Bessel functions (of the first kind).
+template <typename _Tp>
+struct testcase_cyl_bessel_j
+{
+  _Tp f0;
+  _Tp nu;
+  _Tp x;
+  _Tp f;
+};
+
+//  Irregular modified cylindrical Bessel functions.
+template <typename _Tp>
+struct testcase_cyl_bessel_k
+{
+  _Tp f0;
+  _Tp nu;
+  _Tp x;
+  _Tp f;
+};
+
+//  Cylindrical Neumann functions.
+template <typename _Tp>
+struct testcase_cyl_neumann
+{
+  _Tp f0;
+  _Tp nu;
+  _Tp x;
+  _Tp f;
+};
+
+//  Elliptic integrals of the first kind.
+template <typename _Tp>
+struct testcase_ellint_1
+{
+  _Tp f0;
+  _Tp k;
+  _Tp phi;
+  _Tp f;
+};
+
+//  Elliptic integrals of the second kind.
+template <typename _Tp>
+struct testcase_ellint_2
+{
+  _Tp f0;
+  _Tp k;
+  _Tp phi;
+  _Tp f;
+};
+
+//  Elliptic integrals of the third kind.
+template <typename _Tp>
+struct testcase_ellint_3
+{
+  _Tp f0;
+  _Tp k;
+  _Tp nu;
+  _Tp phi;
+  _Tp f;
+};
+
+//  Exponential integral.
+template <typename _Tp>
+struct testcase_expint
+{
+  _Tp f0;
+  _Tp x;
+  _Tp f;
+};
+
+//  Hermite polynomials
+template <typename _Tp>
+struct testcase_hermite
+{
+  _Tp f0;
+  unsigned int n;
+  _Tp x;
+  _Tp f;
+};
+
+//  Hypergeometric functions.
+template <typename _Tp>
+struct testcase_hyperg
+{
+  _Tp f0;
+  _Tp a;
+  _Tp b;
+  _Tp c;
+  _Tp x;
+  _Tp f;
+};
+
+//  Laguerre polynomials.
+template <typename _Tp>
+struct testcase_laguerre
+{
+  _Tp f0;
+  unsigned int n;
+  _Tp x;
+  _Tp f;
+};
+
+//  Legendre polynomials.
+template <typename _Tp>
+struct testcase_legendre
+{
+  _Tp f0;
+  unsigned int l;
+  _Tp x;
+  _Tp f;
+};
+
+//  Riemann zeta function.
+template <typename _Tp>
+struct testcase_riemann_zeta
+{
+  _Tp f0;
+  _Tp x;
+  _Tp f;
+};
+
+//  Spherical Bessel functions.
+template <typename _Tp>
+struct testcase_sph_bessel
+{
+  _Tp f0;
+  unsigned int n;
+  _Tp x;
+  _Tp f;
+};
+
+//  Spherical Legendre functions.
+template <typename _Tp>
+struct testcase_sph_legendre
+{
+  _Tp f0;
+  unsigned int l;
+  unsigned int m;
+  _Tp theta;
+  _Tp f;
+};
+
+//  Spherical Neumann functions.
+template <typename _Tp>
+struct testcase_sph_neumann
+{
+  _Tp f0;
+  unsigned int n;
+  _Tp x;
+  _Tp f;
+};
-------------- next part --------------

2015-11-14  Edward Smith-Rowland  <3dw4rd@verizon.net>
	    Jonathan Wakely  <jwakely@redhat.com>
	    Florian Goth <CaptainSifff@gmx.de>
	Implement TR29124 Special Math Functions
	* include/Makefile.am: Add new TR29124 headers.
	* include/Makefile.in: Regenerated.
	* include/bits/specfun.h: New.
	* include/bits/specfun_util.h: New.
	* include/bits/sf_beta.tcc: New.
	* include/bits/sf_bessel.tcc: New.
	* include/bits/sf_chebyshev.tcc: New.
	* include/bits/sf_dawson.tcc: New.
	* include/bits/sf_laguerre.tcc: New.
	* include/bits/sf_ellint.tcc: New.
	* include/bits/sf_expint.tcc: New.
	* include/bits/sf_fresnel.tcc: New.
	* include/bits/sf_gamma.tcc: New.
	* include/bits/sf_gegenbauer.tcc: New.
	* include/bits/sf_hyperg.tcc: New.
	* include/bits/sf_hermite.tcc: New.
	* include/bits/sf_hypint.tcc: New.
	* include/bits/sf_jacobi.tcc: New.
	* include/bits/sf_legendre.tcc: New.
	* include/bits/sf_mod_bessel.tcc: New.
	* include/bits/sf_theta.tcc: New.
	* include/bits/sf_trigint.tcc: New.
	* include/bits/sf_zeta.tcc: New.
	* include/tr1/special_function_util.h: Place functions in std
	if __STDCPP_WANT_MATH_SPEC_FUNCS__ defined as 1.
	* include/tr1/bessel_function.tcc: Ditto.
	* include/tr1/beta_function.tcc: Ditto.
	* include/tr1/cmath: Ditto.
	* include/tr1/ell_integral.tcc: Ditto.
	* include/tr1/exp_integral.tcc: Ditto.
	* include/tr1/gamma.tcc: Ditto.
	* include/tr1/hypergeometric.tcc: Ditto.
	* include/tr1/legendre_function.tcc: Ditto.
	* include/tr1/modified_bessel_func.tcc: Ditto.
	* include/tr1/poly_hermite.tcc: Ditto.
	* include/tr1/poly_laguerre.tcc: Ditto.
	* include/tr1/riemann_zeta.tcc: Ditto.
	* testsuite/libstdc++-dg/conformance.exp: Run tests from
	testsuite/special_function sub-directory.
	* testsuite/special_functions/01_assoc_laguerre/check_nan.cc: New.
	* testsuite/special_functions/01_assoc_laguerre/check_value.cc: New.
	* testsuite/special_functions/01_assoc_laguerre/compile.cc: New.
	* testsuite/special_functions/01_assoc_laguerre/compile_2.cc: New.
	* testsuite/special_functions/02_assoc_legendre/check_nan.cc: New.
	* testsuite/special_functions/02_assoc_legendre/check_value.cc: New.
	* testsuite/special_functions/02_assoc_legendre/compile.cc: New.
	* testsuite/special_functions/02_assoc_legendre/compile_2.cc: New.
	* testsuite/special_functions/03_beta/check_nan.cc: New.
	* testsuite/special_functions/03_beta/check_value.cc: New.
	* testsuite/special_functions/03_beta/compile.cc: New.
	* testsuite/special_functions/03_beta/compile_2.cc: New.
	* testsuite/special_functions/04_comp_ellint_1/check_nan.cc: New.
	* testsuite/special_functions/04_comp_ellint_1/check_value.cc: New.
	* testsuite/special_functions/04_comp_ellint_1/compile.cc: New.
	* testsuite/special_functions/04_comp_ellint_1/compile_2.cc: New.
	* testsuite/special_functions/05_comp_ellint_2/check_nan.cc: New.
	* testsuite/special_functions/05_comp_ellint_2/check_value.cc: New.
	* testsuite/special_functions/05_comp_ellint_2/compile.cc: New.
	* testsuite/special_functions/05_comp_ellint_2/compile_2.cc: New.
	* testsuite/special_functions/06_comp_ellint_3/check_nan.cc: New.
	* testsuite/special_functions/06_comp_ellint_3/check_value.cc: New.
	* testsuite/special_functions/06_comp_ellint_3/compile.cc: New.
	* testsuite/special_functions/06_comp_ellint_3/compile_2.cc: New.
	* testsuite/special_functions/07_cyl_bessel_i/check_nan.cc: New.
	* testsuite/special_functions/07_cyl_bessel_i/check_value.cc: New.
	* testsuite/special_functions/07_cyl_bessel_i/compile.cc: New.
	* testsuite/special_functions/07_cyl_bessel_i/compile_2.cc: New.
	* testsuite/special_functions/07_cyl_bessel_i/pr56216.cc: New.
	* testsuite/special_functions/08_cyl_bessel_j/check_nan.cc: New.
	* testsuite/special_functions/08_cyl_bessel_j/check_value.cc: New.
	* testsuite/special_functions/08_cyl_bessel_j/compile.cc: New.
	* testsuite/special_functions/08_cyl_bessel_j/compile_2.cc: New.
	* testsuite/special_functions/09_cyl_bessel_k/check_nan.cc: New.
	* testsuite/special_functions/09_cyl_bessel_k/check_value.cc: New.
	* testsuite/special_functions/09_cyl_bessel_k/compile.cc: New.
	* testsuite/special_functions/09_cyl_bessel_k/compile_2.cc: New.
	* testsuite/special_functions/10_cyl_neumann/check_nan.cc: New.
	* testsuite/special_functions/10_cyl_neumann/check_value.cc: New.
	* testsuite/special_functions/10_cyl_neumann/compile.cc: New.
	* testsuite/special_functions/10_cyl_neumann/compile_2.cc: New.
	* testsuite/special_functions/11_ellint_1/check_nan.cc: New.
	* testsuite/special_functions/11_ellint_1/check_value.cc: New.
	* testsuite/special_functions/11_ellint_1/compile.cc: New.
	* testsuite/special_functions/11_ellint_1/compile_2.cc: New.
	* testsuite/special_functions/12_ellint_2/check_nan.cc: New.
	* testsuite/special_functions/12_ellint_2/check_value.cc: New.
	* testsuite/special_functions/12_ellint_2/compile.cc: New.
	* testsuite/special_functions/12_ellint_2/compile_2.cc: New.
	* testsuite/special_functions/13_ellint_3/check_nan.cc: New.
	* testsuite/special_functions/13_ellint_3/check_value.cc: New.
	* testsuite/special_functions/13_ellint_3/compile.cc: New.
	* testsuite/special_functions/13_ellint_3/compile_2.cc: New.
	* testsuite/special_functions/14_expint/check_nan.cc: New.
	* testsuite/special_functions/14_expint/check_value_neg.cc: New.
	* testsuite/special_functions/14_expint/check_value_pos.cc: New.
	* testsuite/special_functions/14_expint/compile.cc: New.
	* testsuite/special_functions/14_expint/compile_2.cc: New.
	* testsuite/special_functions/15_hermite/check_nan.cc: New.
	* testsuite/special_functions/15_hermite/compile.cc: New.
	* testsuite/special_functions/15_hermite/compile_2.cc: New.
	* testsuite/special_functions/16_laguerre/check_nan.cc: New.
	* testsuite/special_functions/16_laguerre/check_value.cc: New.
	* testsuite/special_functions/16_laguerre/compile.cc: New.
	* testsuite/special_functions/16_laguerre/compile_2.cc: New.
	* testsuite/special_functions/17_legendre/check_nan.cc: New.
	* testsuite/special_functions/17_legendre/check_value.cc: New.
	* testsuite/special_functions/17_legendre/compile.cc: New.
	* testsuite/special_functions/17_legendre/compile_2.cc: New.
	* testsuite/special_functions/18_riemann_zeta/check_nan.cc: New.
	* testsuite/special_functions/18_riemann_zeta/check_value_neg.cc: New.
	* testsuite/special_functions/18_riemann_zeta/check_value_pos.cc: New.
	* testsuite/special_functions/18_riemann_zeta/compile.cc: New.
	* testsuite/special_functions/18_riemann_zeta/compile_2.cc: New.
	* testsuite/special_functions/19_sph_bessel/check_nan.cc: New.
	* testsuite/special_functions/19_sph_bessel/check_value.cc: New.
	* testsuite/special_functions/19_sph_bessel/compile.cc: New.
	* testsuite/special_functions/19_sph_bessel/compile_2.cc: New.
	* testsuite/special_functions/20_sph_legendre/check_nan.cc: New.
	* testsuite/special_functions/20_sph_legendre/check_value.cc: New.
	* testsuite/special_functions/20_sph_legendre/compile.cc: New.
	* testsuite/special_functions/20_sph_legendre/compile_2.cc: New.
	* testsuite/special_functions/21_sph_neumann/check_nan.cc: New.
	* testsuite/special_functions/21_sph_neumann/check_value.cc: New.
	* testsuite/special_functions/21_sph_neumann/compile.cc: New.
	* testsuite/special_functions/21_sph_neumann/compile_2.cc: New.
	* testsuite/ext/special_functions/airy/airy.cc: New.
	* testsuite/ext/special_functions/conf_hyperg/check_nan.cc: New.
	* testsuite/ext/special_functions/conf_hyperg/check_value.cc: New.
	* testsuite/ext/special_functions/conf_hyperg/compile.cc: New.
	* testsuite/ext/special_functions/conf_hyperg/compile_2.cc: New.
	* testsuite/ext/special_functions/hyperg/check_nan.cc: New.
	* testsuite/ext/special_functions/hyperg/check_value.cc: New.
	* testsuite/ext/special_functions/hyperg/compile.cc: New.
	* testsuite/ext/special_functions/hyperg/compile_2.cc: New.
	* testsuite/special_functions/testcase.h: New.


More information about the Libstdc++ mailing list