[multiple changes]

2007-03-16  Benjamin Kosnik  <bkoz@redhat.com>
	
	* testsuite/lib/dg-options.exp (dg-require-c-std): New.
	* testsuite/lib/libstdc++.exp (check_v3_target_c_std): New. Check to
	see if _GLIBCXX_USE_C99_MATH is active. 
	* testsuite/tr1/5_numerical_facilities/special_functions/
	08_cyl_bessel_i/check_nan.cc: Use dg-require-c-std.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	17_hyperg/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	13_ellint_2/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	20_riemann_zeta/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	01_assoc_laguerre/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	02_assoc_legendre/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	22_sph_legendre/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	10_cyl_bessel_k/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	09_cyl_bessel_j/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	21_sph_bessel/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	07_conf_hyperg/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	16_hermite/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	12_ellint_1/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	05_comp_ellint_2/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	18_laguerre/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	14_ellint_3/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	04_comp_ellint_1/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	06_comp_ellint_3/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	19_legendre/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	03_beta/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	11_cyl_neumann/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	15_expint/check_nan.cc: Same.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	23_sph_neumann/check_nan.cc: Same.

	* include/tr1/poly_laguerre.tcc (__poly_laguerre): Don't check if
	unsigned int can be a NaN.

2007-03-16  Edward M. Smith-Rowland  <3dw4rd@verizon.net>

	* docs/html/ext/tr1.html : Marked tr1 math special functions done.
	* docs/html/faq/index.html : Ditto.
	* include/Makefile.in : Added new special function header files.
	* include/Makefile.am : Ditto.	
	* include/tr1/common.h : Added type promotion routines for three
	and four args.

	* include/tr1/special_function_util.h: New.
	* include/tr1/bessel_function.tcc: New.
	* include/tr1/beta_function.tcc: New.
	* include/tr1/ell_integral.tcc: New.
	* include/tr1/exp_integral.tcc: New.
	* include/tr1/gamma.tcc: New.
	* include/tr1/hypergeometric.tcc: New.
	* include/tr1/legendre_function.tcc: New.
	* include/tr1/modified_bessel_func.tcc: New.
	* include/tr1/poly_hermite.tcc: New.
	* include/tr1/poly_laguerre.tcc: New.
	* include/tr1/riemann_zeta.tcc: New.
	* include/tr1/cmath : Included tr1 math special functions.
	* include/tr1/math.h : Ditto.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	testcase.h: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	01_assoc_laguerre/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	01_assoc_laguerre/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	01_assoc_laguerre/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	01_assoc_laguerre/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	02_assoc_legendre/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	02_assoc_legendre/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	02_assoc_legendre/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	02_assoc_legendre/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/03_beta/
	compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/03_beta/
	check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/03_beta/
	check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/03_beta/
	compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	04_comp_ellint_1/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	04_comp_ellint_1/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	04_comp_ellint_1/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	04_comp_ellint_1/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	05_comp_ellint_2/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	05_comp_ellint_2/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	05_comp_ellint_2/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	05_comp_ellint_2/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	06_comp_ellint_3/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	06_comp_ellint_3/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	06_comp_ellint_3/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	06_comp_ellint_3/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	07_conf_hyperg/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	07_conf_hyperg/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	07_conf_hyperg/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	07_conf_hyperg/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	08_cyl_bessel_i/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	08_cyl_bessel_i/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	08_cyl_bessel_i/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	08_cyl_bessel_i/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	09_cyl_bessel_j/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	09_cyl_bessel_j/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	09_cyl_bessel_j/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	09_cyl_bessel_j/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	10_cyl_bessel_k/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	10_cyl_bessel_k/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	10_cyl_bessel_k/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	10_cyl_bessel_k/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	11_cyl_neumann/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	11_cyl_neumann/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	11_cyl_neumann/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	11_cyl_neumann/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/
	compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/
	check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/
	check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/
	compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/
	compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/
	check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/
	check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/
	compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/
	compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/
	check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/
	check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/
	compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/15_expint/
	check_value_neg.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/15_expint/
	compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/15_expint/
	check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/15_expint/
	compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/15_expint/
	check_value_pos.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/
	compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/
	check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/
	compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/
	compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/
	check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/
	check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/
	compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/
	compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/
	check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/
	check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/
	compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/
	compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/
	check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/
	check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/
	compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	20_riemann_zeta/check_value_neg.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	20_riemann_zeta/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	20_riemann_zeta/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	20_riemann_zeta/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	20_riemann_zeta/check_value_pos.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	21_sph_bessel/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	21_sph_bessel/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	21_sph_bessel/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	21_sph_bessel/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	22_sph_legendre/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	22_sph_legendre/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	22_sph_legendre/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	22_sph_legendre/compile_2.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	23_sph_neumann/compile.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	23_sph_neumann/check_nan.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	23_sph_neumann/check_value.cc: New.
	* testsuite/tr1/5_numerical_facilities/special_functions/
	23_sph_neumann/ compile_2.cc: New.

From-SVN: r122986
This commit is contained in:
Benjamin Kosnik 2007-03-16 10:35:16 +00:00
parent 7b1737d07a
commit 7c62b943ba
116 changed files with 60128 additions and 39 deletions

View File

@ -1,3 +1,270 @@
2007-03-16 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/lib/dg-options.exp (dg-require-c-std): New.
* testsuite/lib/libstdc++.exp (check_v3_target_c_std): New. Check to
see if _GLIBCXX_USE_C99_MATH is active.
* testsuite/tr1/5_numerical_facilities/special_functions/
08_cyl_bessel_i/check_nan.cc: Use dg-require-c-std.
* testsuite/tr1/5_numerical_facilities/special_functions/
17_hyperg/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
13_ellint_2/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
20_riemann_zeta/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
01_assoc_laguerre/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
02_assoc_legendre/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
22_sph_legendre/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
10_cyl_bessel_k/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
09_cyl_bessel_j/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
21_sph_bessel/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
07_conf_hyperg/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
16_hermite/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
12_ellint_1/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
05_comp_ellint_2/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
18_laguerre/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
14_ellint_3/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
04_comp_ellint_1/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
06_comp_ellint_3/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
19_legendre/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
03_beta/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
11_cyl_neumann/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
15_expint/check_nan.cc: Same.
* testsuite/tr1/5_numerical_facilities/special_functions/
23_sph_neumann/check_nan.cc: Same.
* include/tr1/poly_laguerre.tcc (__poly_laguerre): Don't check if
unsigned int can be a NaN.
2007-03-16 Edward M. Smith-Rowland <3dw4rd@verizon.net>
* docs/html/ext/tr1.html : Marked tr1 math special functions done.
* docs/html/faq/index.html : Ditto.
* include/Makefile.in : Added new special function header files.
* include/Makefile.am : Ditto.
* include/tr1/common.h : Added type promotion routines for three
and four args.
* include/tr1/special_function_util.h: New.
* include/tr1/bessel_function.tcc: New.
* include/tr1/beta_function.tcc: New.
* include/tr1/ell_integral.tcc: New.
* include/tr1/exp_integral.tcc: New.
* include/tr1/gamma.tcc: New.
* include/tr1/hypergeometric.tcc: New.
* include/tr1/legendre_function.tcc: New.
* include/tr1/modified_bessel_func.tcc: New.
* include/tr1/poly_hermite.tcc: New.
* include/tr1/poly_laguerre.tcc: New.
* include/tr1/riemann_zeta.tcc: New.
* include/tr1/cmath : Included tr1 math special functions.
* include/tr1/math.h : Ditto.
* testsuite/tr1/5_numerical_facilities/special_functions/
testcase.h: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
01_assoc_laguerre/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
01_assoc_laguerre/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
01_assoc_laguerre/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
01_assoc_laguerre/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
02_assoc_legendre/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
02_assoc_legendre/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
02_assoc_legendre/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
02_assoc_legendre/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/03_beta/
compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/03_beta/
check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/03_beta/
check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/03_beta/
compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
04_comp_ellint_1/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
04_comp_ellint_1/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
04_comp_ellint_1/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
04_comp_ellint_1/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
05_comp_ellint_2/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
05_comp_ellint_2/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
05_comp_ellint_2/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
05_comp_ellint_2/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
06_comp_ellint_3/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
06_comp_ellint_3/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
06_comp_ellint_3/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
06_comp_ellint_3/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
07_conf_hyperg/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
07_conf_hyperg/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
07_conf_hyperg/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
07_conf_hyperg/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
08_cyl_bessel_i/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
08_cyl_bessel_i/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
08_cyl_bessel_i/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
08_cyl_bessel_i/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
09_cyl_bessel_j/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
09_cyl_bessel_j/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
09_cyl_bessel_j/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
09_cyl_bessel_j/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
10_cyl_bessel_k/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
10_cyl_bessel_k/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
10_cyl_bessel_k/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
10_cyl_bessel_k/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
11_cyl_neumann/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
11_cyl_neumann/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
11_cyl_neumann/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
11_cyl_neumann/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/
compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/
check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/
check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/12_ellint_1/
compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/
compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/
check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/
check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/13_ellint_2/
compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/
compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/
check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/
check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/14_ellint_3/
compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/15_expint/
check_value_neg.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/15_expint/
compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/15_expint/
check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/15_expint/
compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/15_expint/
check_value_pos.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/
compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/
check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/16_hermite/
compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/
compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/
check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/
check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/17_hyperg/
compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/
compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/
check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/
check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/18_laguerre/
compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/
compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/
check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/
check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/19_legendre/
compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
20_riemann_zeta/check_value_neg.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
20_riemann_zeta/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
20_riemann_zeta/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
20_riemann_zeta/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
20_riemann_zeta/check_value_pos.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
21_sph_bessel/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
21_sph_bessel/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
21_sph_bessel/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
21_sph_bessel/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
22_sph_legendre/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
22_sph_legendre/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
22_sph_legendre/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
22_sph_legendre/compile_2.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
23_sph_neumann/compile.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
23_sph_neumann/check_nan.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
23_sph_neumann/check_value.cc: New.
* testsuite/tr1/5_numerical_facilities/special_functions/
23_sph_neumann/ compile_2.cc: New.
2007-03-15 Hans-Peter Nilsson <hp@axis.com> 2007-03-15 Hans-Peter Nilsson <hp@axis.com>
* testsuite/lib/libstdc++.exp (v3-build_support) <ar>: If it * testsuite/lib/libstdc++.exp (v3-build_support) <ar>: If it
@ -145,9 +412,12 @@
* testsuite/27_io/basic_filebuf/sputn/char/9339.cc: Use it. * testsuite/27_io/basic_filebuf/sputn/char/9339.cc: Use it.
* testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc: Use it. * testsuite/27_io/basic_filebuf/pbackfail/char/9761.cc: Use it.
* testsuite/27_io/basic_filebuf/sync/char/9182-1.cc: Use it. * testsuite/27_io/basic_filebuf/sync/char/9182-1.cc: Use it.
* testsuite/21_strings/basic_string/inserters_extractors/char/10.cc: Use it. * testsuite/21_strings/basic_string/inserters_extractors/
* testsuite/21_strings/basic_string/inserters_extractors/char/11.cc: Use it. char/10.cc: Use it.
* testsuite/21_strings/basic_string/inserters_extractors/char/5.cc: Use it. * testsuite/21_strings/basic_string/inserters_extractors/
char/11.cc: Use it.
* testsuite/21_strings/basic_string/inserters_extractors/
char/5.cc: Use it.
2007-03-13 Paolo Carlini <pcarlini@suse.de> 2007-03-13 Paolo Carlini <pcarlini@suse.de>

View File

@ -807,209 +807,209 @@ release.
<tr> <tr>
<td>5.2</td> <td>5.2</td>
<td>Mathematical special functions</td> <td>Mathematical special functions</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1</td> <td>5.2.1</td>
<td>Additions to header <code>&lt;cmath&gt;</code> synopsis</td> <td>Additions to header <code>&lt;cmath&gt;</code> synopsis</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.1</td> <td>5.2.1.1</td>
<td>associated Laguerre polynomials</td> <td>associated Laguerre polynomials</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.2</td> <td>5.2.1.2</td>
<td>associated Legendre functions</td> <td>associated Legendre functions</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.3</td> <td>5.2.1.3</td>
<td>beta function</td> <td>beta function</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.4</td> <td>5.2.1.4</td>
<td>(complete) elliptic integral of the first kind</td> <td>(complete) elliptic integral of the first kind</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.5</td> <td>5.2.1.5</td>
<td>(complete) elliptic integral of the second kind</td> <td>(complete) elliptic integral of the second kind</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.6</td> <td>5.2.1.6</td>
<td>(complete) elliptic integral of the third kind</td> <td>(complete) elliptic integral of the third kind</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.7</td> <td>5.2.1.7</td>
<td>confluent hypergeometric functions</td> <td>confluent hypergeometric functions</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.8</td> <td>5.2.1.8</td>
<td>regular modified cylindrical Bessel functions</td> <td>regular modified cylindrical Bessel functions</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.9</td> <td>5.2.1.9</td>
<td>cylindrical Bessel functions (of the first kind)</td> <td>cylindrical Bessel functions (of the first kind)</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.10</td> <td>5.2.1.10</td>
<td>irregular modified cylindrical Bessel functions</td> <td>irregular modified cylindrical Bessel functions</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.11</td> <td>5.2.1.11</td>
<td>cylindrical Neumann functions</td> <td>cylindrical Neumann functions</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.12</td> <td>5.2.1.12</td>
<td>(incomplete) elliptic integral of the first kind</td> <td>(incomplete) elliptic integral of the first kind</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.13</td> <td>5.2.1.13</td>
<td>(incomplete) elliptic integral of the second kind</td> <td>(incomplete) elliptic integral of the second kind</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.14</td> <td>5.2.1.14</td>
<td>(incomplete) elliptic integral of the third kind</td> <td>(incomplete) elliptic integral of the third kind</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.15</td> <td>5.2.1.15</td>
<td>exponential integral</td> <td>exponential integral</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.16</td> <td>5.2.1.16</td>
<td>Hermite polynomials</td> <td>Hermite polynomials</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.17</td> <td>5.2.1.17</td>
<td>hypergeometric functions</td> <td>hypergeometric functions</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.18</td> <td>5.2.1.18</td>
<td>Laguerre polynomials</td> <td>Laguerre polynomials</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.19</td> <td>5.2.1.19</td>
<td>Legendre polynomials</td> <td>Legendre polynomials</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.20</td> <td>5.2.1.20</td>
<td>Riemann zeta function</td> <td>Riemann zeta function</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.21</td> <td>5.2.1.21</td>
<td>spherical Bessel functions (of the first kind)</td> <td>spherical Bessel functions (of the first kind)</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.22</td> <td>5.2.1.22</td>
<td>spherical associated Legendre functions</td> <td>spherical associated Legendre functions</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.1.23</td> <td>5.2.1.23</td>
<td>spherical Neumann functions</td> <td>spherical Neumann functions</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>
<td>5.2.2</td> <td>5.2.2</td>
<td>Additions to header <code>&lt;math.h&gt;</code> synopsis</td> <td>Additions to header <code>&lt;math.h&gt;</code> synopsis</td>
<td>done</td>
<td></td> <td></td>
<td></td> <td></td>
<td>missing</td>
<td></td> <td></td>
</tr> </tr>
<tr> <tr>

View File

@ -1047,7 +1047,7 @@ http://clisp.cons.org/~haible/gccinclude-glibc-2.2-compat.diff
and the C++ languages. and the C++ languages.
</p> </p>
<p><strong>Special functions - Under construction - </strong> <p><strong>Special functions - Complete - </strong>
Twenty-three mathematical functions familiar to physicists and Twenty-three mathematical functions familiar to physicists and
engineers are included: cylindrical and spherical Bessel and Neumann engineers are included: cylindrical and spherical Bessel and Neumann
functions, hypergeometric functions, Laguerre polynomials, Legendre functions, hypergeometric functions, Laguerre polynomials, Legendre

View File

@ -533,6 +533,8 @@ tr1_srcdir = ${glibcxx_srcdir}/include/tr1
tr1_builddir = ./tr1 tr1_builddir = ./tr1
tr1_headers = \ tr1_headers = \
${tr1_srcdir}/array \ ${tr1_srcdir}/array \
${tr1_srcdir}/bessel_function.tcc \
${tr1_srcdir}/beta_function.tcc \
${tr1_srcdir}/boost_shared_ptr.h \ ${tr1_srcdir}/boost_shared_ptr.h \
${tr1_srcdir}/ccomplex \ ${tr1_srcdir}/ccomplex \
${tr1_srcdir}/cctype \ ${tr1_srcdir}/cctype \
@ -554,19 +556,29 @@ tr1_headers = \
${tr1_srcdir}/ctype.h \ ${tr1_srcdir}/ctype.h \
${tr1_srcdir}/cwchar \ ${tr1_srcdir}/cwchar \
${tr1_srcdir}/cwctype \ ${tr1_srcdir}/cwctype \
${tr1_srcdir}/ell_integral.tcc \
${tr1_srcdir}/exp_integral.tcc \
${tr1_srcdir}/fenv.h \ ${tr1_srcdir}/fenv.h \
${tr1_srcdir}/float.h \ ${tr1_srcdir}/float.h \
${tr1_srcdir}/functional \ ${tr1_srcdir}/functional \
${tr1_srcdir}/functional_hash.h \ ${tr1_srcdir}/functional_hash.h \
${tr1_srcdir}/gamma.tcc \
${tr1_srcdir}/hashtable \ ${tr1_srcdir}/hashtable \
${tr1_srcdir}/hypergeometric.tcc \
${tr1_srcdir}/hashtable_policy.h \ ${tr1_srcdir}/hashtable_policy.h \
${tr1_srcdir}/inttypes.h \ ${tr1_srcdir}/inttypes.h \
${tr1_srcdir}/limits.h \ ${tr1_srcdir}/limits.h \
${tr1_srcdir}/math.h \ ${tr1_srcdir}/math.h \
${tr1_srcdir}/memory \ ${tr1_srcdir}/memory \
${tr1_srcdir}/modified_bessel_func.tcc \
${tr1_srcdir}/poly_hermite.tcc \
${tr1_srcdir}/poly_laguerre.tcc \
${tr1_srcdir}/legendre_function.tcc \
${tr1_srcdir}/random \ ${tr1_srcdir}/random \
${tr1_srcdir}/random.tcc \ ${tr1_srcdir}/random.tcc \
${tr1_srcdir}/regex \ ${tr1_srcdir}/regex \
${tr1_srcdir}/riemann_zeta.tcc \
${tr1_srcdir}/special_function_util.h \
${tr1_srcdir}/stdarg.h \ ${tr1_srcdir}/stdarg.h \
${tr1_srcdir}/stdbool.h \ ${tr1_srcdir}/stdbool.h \
${tr1_srcdir}/stdint.h \ ${tr1_srcdir}/stdint.h \

View File

@ -763,6 +763,8 @@ tr1_srcdir = ${glibcxx_srcdir}/include/tr1
tr1_builddir = ./tr1 tr1_builddir = ./tr1
tr1_headers = \ tr1_headers = \
${tr1_srcdir}/array \ ${tr1_srcdir}/array \
${tr1_srcdir}/bessel_function.tcc \
${tr1_srcdir}/beta_function.tcc \
${tr1_srcdir}/boost_shared_ptr.h \ ${tr1_srcdir}/boost_shared_ptr.h \
${tr1_srcdir}/ccomplex \ ${tr1_srcdir}/ccomplex \
${tr1_srcdir}/cctype \ ${tr1_srcdir}/cctype \
@ -784,19 +786,29 @@ tr1_headers = \
${tr1_srcdir}/ctype.h \ ${tr1_srcdir}/ctype.h \
${tr1_srcdir}/cwchar \ ${tr1_srcdir}/cwchar \
${tr1_srcdir}/cwctype \ ${tr1_srcdir}/cwctype \
${tr1_srcdir}/ell_integral.tcc \
${tr1_srcdir}/exp_integral.tcc \
${tr1_srcdir}/fenv.h \ ${tr1_srcdir}/fenv.h \
${tr1_srcdir}/float.h \ ${tr1_srcdir}/float.h \
${tr1_srcdir}/functional \ ${tr1_srcdir}/functional \
${tr1_srcdir}/functional_hash.h \ ${tr1_srcdir}/functional_hash.h \
${tr1_srcdir}/gamma.tcc \
${tr1_srcdir}/hashtable \ ${tr1_srcdir}/hashtable \
${tr1_srcdir}/hypergeometric.tcc \
${tr1_srcdir}/hashtable_policy.h \ ${tr1_srcdir}/hashtable_policy.h \
${tr1_srcdir}/inttypes.h \ ${tr1_srcdir}/inttypes.h \
${tr1_srcdir}/limits.h \ ${tr1_srcdir}/limits.h \
${tr1_srcdir}/math.h \ ${tr1_srcdir}/math.h \
${tr1_srcdir}/memory \ ${tr1_srcdir}/memory \
${tr1_srcdir}/modified_bessel_func.tcc \
${tr1_srcdir}/poly_hermite.tcc \
${tr1_srcdir}/poly_laguerre.tcc \
${tr1_srcdir}/legendre_function.tcc \
${tr1_srcdir}/random \ ${tr1_srcdir}/random \
${tr1_srcdir}/random.tcc \ ${tr1_srcdir}/random.tcc \
${tr1_srcdir}/regex \ ${tr1_srcdir}/regex \
${tr1_srcdir}/riemann_zeta.tcc \
${tr1_srcdir}/special_function_util.h \
${tr1_srcdir}/stdarg.h \ ${tr1_srcdir}/stdarg.h \
${tr1_srcdir}/stdbool.h \ ${tr1_srcdir}/stdbool.h \
${tr1_srcdir}/stdint.h \ ${tr1_srcdir}/stdint.h \

View File

@ -0,0 +1,641 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/bessel_function.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland.
//
// References:
// (1) Handbook of Mathematical Functions,
// ed. Milton Abramowitz and Irene A. Stegun,
// Dover Publications,
// Section 9, pp. 355-434, Section 10 pp. 435-478
// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky,
// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
// 2nd ed, pp. 240-245
#ifndef _TR1_BESSEL_FUNCTION_TCC
#define _TR1_BESSEL_FUNCTION_TCC 1
#include "special_function_util.h"
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// [5.2] Special functions
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @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)
{
#if _GLIBCXX_USE_C99_MATH_TR1
__gampl = _Tp(1) / std::_GLIBCXX_TR1::tgamma(_Tp(1) + __mu);
__gammi = _Tp(1) / std::_GLIBCXX_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());
else
__gam1 = (__gammi - __gampl) / (_Tp(2) * __mu);
__gam2 = (__gammi + __gampl) / (_Tp(2));
return;
}
/**
* @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 fuction 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)
{
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;
}
const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
// When the multiplier is N i.e.
// fp_min = N * min()
// Then J_0 and N_0 tank at x = 8 * N (J_0 = 0 and N_0 = nan)!
//const _Tp __fp_min = _Tp(20) * std::numeric_limits<_Tp>::min();
const _Tp __fp_min = std::sqrt(std::numeric_limits<_Tp>::min());
const int __max_iter = 15000;
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))));
const _Tp __mu = __nu - __nl;
const _Tp __mu2 = __mu * __mu;
const _Tp __xi = _Tp(1) / __x;
const _Tp __xi2 = _Tp(2) * __xi;
_Tp __w = __xi2 / __numeric_constants<_Tp>::__pi();
int __isign = 1;
_Tp __h = __nu * __xi;
if (__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;
}
if (__i > __max_iter)
std::__throw_runtime_error(__N("Argument x too large in __bessel_jn; "
"try asymptotic expansion."));
_Tp __Jnul = __isign * __fp_min;
_Tp __Jpnul = __h * __Jnul;
_Tp __Jnul1 = __Jnul;
_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;
}
if (__Jnul == _Tp(0))
__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);
}
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::_GLIBCXX_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;
}
__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;
}
__Nnu = __Nmu;
__Npnu = __nu * __xi * __Nmu - __Nnu1;
return;
}
/**
* @brief This routine computes the asyptotic 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 fuction of the second kind).
*/
template <typename _Tp>
void
__cyl_bessel_jn_asymp(const _Tp __nu, const _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 _Tp __chi = __x - (__nu + _Tp(0.5L))
* __numeric_constants<_Tp>::__pi_2();
const _Tp __c = std::cos(__chi);
const _Tp __s = std::sin(__chi);
__Jnu = __coef * (__c * __P - __s * __Q);
__Nnu = __coef * (__s * __P + __c * __Q);
return;
}
/**
* @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$ respecively.
*
* 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)
{
const _Tp __x2 = __x / _Tp(2);
_Tp __fact = __nu * std::log(__x2);
#if _GLIBCXX_USE_C99_MATH_TR1
__fact -= std::_GLIBCXX_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);
_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;
}
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>
_Tp
__cyl_bessel_j(const _Tp __nu, const _Tp __x)
{
if (__nu < _Tp(0) || __x < _Tp(0))
std::__throw_domain_error(__N("Bad argument "
"in __cyl_bessel_j."));
else if (__isnan(__nu) || __isnan(__x))
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);
else if (__x > _Tp(1000))
{
_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;
}
}
/**
* @brief Return the Neunamm 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)
{
if (__nu < _Tp(0) || __x < _Tp(0))
std::__throw_domain_error(__N("Bad argument "
"in __cyl_neumann_n."));
else if (__isnan(__nu) || __isnan(__x))
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;
}
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;
}
}
/**
* @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)
{
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);
const _Tp __factor = __numeric_constants<_Tp>::__sqrtpio2()
/ 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);
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>
_Tp
__sph_bessel(const unsigned int __n, const _Tp __x)
{
if (__x < _Tp(0))
std::__throw_domain_error(__N("Bad argument "
"in __sph_bessel."));
else if (__isnan(__x))
return std::numeric_limits<_Tp>::quiet_NaN();
else if (__x == _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;
}
}
/**
* @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)
{
if (__x < _Tp(0))
std::__throw_domain_error(__N("Bad argument "
"in __sph_neumann."));
else if (__isnan(__x))
return std::numeric_limits<_Tp>::quiet_NaN();
else if (__x == _Tp(0))
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;
}
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_BESSEL_FUNCTION_TCC

View File

@ -0,0 +1,211 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/beta_function.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland based on:
// (1) Handbook of Mathematical Functions,
// ed. Milton Abramowitz and Irene A. Stegun,
// Dover Publications,
// Section 6, pp. 253-266
// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky,
// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
// 2nd ed, pp. 213-216
// (4) Gamma, Exploring Euler's Constant, Julian Havil,
// Princeton, 2003.
#ifndef _TR1_BETA_FUNCTION_TCC
#define _TR1_BETA_FUNCTION_TCC 1
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// [5.2] Special functions
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @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::_GLIBCXX_TR1::tgamma(__x)
/ std::_GLIBCXX_TR1::tgamma(__x + __y);
__bet *= std::_GLIBCXX_TR1::tgamma(__y);
}
else
{
__bet = std::_GLIBCXX_TR1::tgamma(__y)
/ std::_GLIBCXX_TR1::tgamma(__x + __y);
__bet *= std::_GLIBCXX_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
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>
_Tp
__beta_lgamma(_Tp __x, _Tp __y)
{
#if _GLIBCXX_USE_C99_MATH_TR1
_Tp __bet = std::_GLIBCXX_TR1::lgamma(__x)
+ std::_GLIBCXX_TR1::lgamma(__y)
- std::_GLIBCXX_TR1::lgamma(__x + __y);
#else
_Tp __bet = __log_gamma(__x)
+ __log_gamma(__y)
- __log_gamma(__x + __y);
#endif
__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>
_Tp
__beta_product(_Tp __x, _Tp __y)
{
_Tp __bet = (__x + __y) / (__x * __y);
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;
}
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>
inline _Tp
__beta(_Tp __x, _Tp __y)
{
if (__isnan(__x) || __isnan(__y))
return std::numeric_limits<_Tp>::quiet_NaN();
else
return __beta_lgamma(__x, __y);
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_BETA_FUNCTION_TCC

View File

@ -1,6 +1,6 @@
// TR1 cmath -*- C++ -*- // TR1 cmath -*- C++ -*-
// Copyright (C) 2006 Free Software Foundation, Inc. // Copyright (C) 2006-2007 Free Software Foundation, Inc.
// //
// This file is part of the GNU ISO C++ Library. This library is free // 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 // software; you can redistribute it and/or modify it under the
@ -35,6 +35,7 @@
#define _TR1_CMATH 1 #define _TR1_CMATH 1
#include <bits/c++config.h> #include <bits/c++config.h>
#include <algorithm>
#include <cmath> #include <cmath>
#include <tr1/common.h> #include <tr1/common.h>
@ -937,6 +938,472 @@ _GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
#endif #endif
_GLIBCXX_END_NAMESPACE
}
/**
* @defgroup tr1_math_spec_func Mathematical Special Functions
* A collection of advanced mathematical special functions.
* @{
*/
#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>
// namespace std::tr1
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// 5.2.1.1 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 __promote<_Tp>::__type
assoc_laguerre(unsigned int __n, unsigned int __m, _Tp __x)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__assoc_laguerre<__type>(__n, __m, __x);
}
// 5.2.1.2 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 __promote<_Tp>::__type
assoc_legendre(unsigned int __l, unsigned int __m, _Tp __x)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__assoc_legendre_p<__type>(__l, __m, __x);
}
// 5.2.1.3 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 __promote_2<_Tpx, _Tpy>::__type
beta(_Tpx __x, _Tpy __y)
{
typedef typename __promote_2<_Tpx, _Tpy>::__type __type;
return __detail::__beta<__type>(__x, __y);
}
// 5.2.1.4 Complete elliptic interals 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 __promote<_Tp>::__type
comp_ellint_1(_Tp __k)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__comp_ellint_1<__type>(__k);
}
// 5.2.1.5 Complete elliptic interals 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 __promote<_Tp>::__type
comp_ellint_2(_Tp __k)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__comp_ellint_2<__type>(__k);
}
// 5.2.1.6 Complete elliptic interals 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 __promote_2<_Tp, _Tpn>::__type
comp_ellint_3(_Tp __k, _Tpn __nu)
{
typedef typename __promote_2<_Tp, _Tpn>::__type __type;
return __detail::__comp_ellint_3<__type>(__k, __nu);
}
// 5.2.1.7 Confluent hypergeometric functions.
inline float
conf_hypergf(float __a, float __c, float __x)
{ return __detail::__conf_hyperg<float>(__a, __c, __x); }
inline long double
conf_hypergl(long double __a, long double __c, long double __x)
{ return __detail::__conf_hyperg<long double>(__a, __c, __x); }
template<typename _Tpa, typename _Tpc, typename _Tp>
inline typename __promote_3<_Tpa, _Tpc, _Tp>::__type
conf_hyperg(_Tpa __a, _Tpc __c, _Tp __x)
{
typedef typename __promote_3<_Tpa, _Tpc, _Tp>::__type __type;
return __detail::__conf_hyperg<__type>(__a, __c, __x);
}
// 5.2.1.8 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 __promote_2<_Tpnu, _Tp>::__type
cyl_bessel_i(_Tpnu __nu, _Tp __x)
{
typedef typename __promote_2<_Tpnu, _Tp>::__type __type;
return __detail::__cyl_bessel_i<__type>(__nu, __x);
}
// 5.2.1.9 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 __promote_2<_Tpnu, _Tp>::__type
cyl_bessel_j(_Tpnu __nu, _Tp __x)
{
typedef typename __promote_2<_Tpnu, _Tp>::__type __type;
return __detail::__cyl_bessel_j<__type>(__nu, __x);
}
// 5.2.1.10 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 __promote_2<_Tpnu, _Tp>::__type
cyl_bessel_k(_Tpnu __nu, _Tp __x)
{
typedef typename __promote_2<_Tpnu, _Tp>::__type __type;
return __detail::__cyl_bessel_k<__type>(__nu, __x);
}
// 5.2.1.11 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 __promote_2<_Tpnu, _Tp>::__type
cyl_neumann(_Tpnu __nu, _Tp __x)
{
typedef typename __promote_2<_Tpnu, _Tp>::__type __type;
return __detail::__cyl_neumann_n<__type>(__nu, __x);
}
// 5.2.1.12 Incomplete elliptic interals 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 __promote_2<_Tp, _Tpp>::__type
ellint_1(_Tp __k, _Tpp __phi)
{
typedef typename __promote_2<_Tp, _Tpp>::__type __type;
return __detail::__ellint_1<__type>(__k, __phi);
}
// 5.2.1.13 Incomplete elliptic interals 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 __promote_2<_Tp, _Tpp>::__type
ellint_2(_Tp __k, _Tpp __phi)
{
typedef typename __promote_2<_Tp, _Tpp>::__type __type;
return __detail::__ellint_2<__type>(__k, __phi);
}
// 5.2.1.14 Incomplete elliptic interals 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 __promote_3<_Tp, _Tpn, _Tpp>::__type
ellint_3(_Tp __k, _Tpn __nu, _Tpp __phi)
{
typedef typename __promote_3<_Tp, _Tpn, _Tpp>::__type __type;
return __detail::__ellint_3<__type>(__k, __nu, __phi);
}
// 5.2.1.15 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 __promote<_Tp>::__type
expint(_Tp __x)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__expint<__type>(__x);
}
// 5.2.1.16 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 __promote<_Tp>::__type
hermite(unsigned int __n, _Tp __x)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__poly_hermite<__type>(__n, __x);
}
// 5.2.1.17 Hypergeometric functions.
inline float
hypergf(float __a, float __b, float __c, float __x)
{ return __detail::__hyperg<float>(__a, __b, __c, __x); }
inline long double
hypergl(long double __a, long double __b, long double __c, long double __x)
{ return __detail::__hyperg<long double>(__a, __b, __c, __x); }
template<typename _Tpa, typename _Tpb, typename _Tpc, typename _Tp>
inline typename __promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type
hyperg(_Tpa __a, _Tpb __b, _Tpc __c, _Tp __x)
{
typedef typename __promote_4<_Tpa, _Tpb, _Tpc, _Tp>::__type __type;
return __detail::__hyperg<__type>(__a, __b, __c, __x);
}
// 5.2.1.18 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 __promote<_Tp>::__type
laguerre(unsigned int __n, _Tp __x)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__laguerre<__type>(__n, __x);
}
// 5.2.1.19 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 __promote<_Tp>::__type
legendre(unsigned int __n, _Tp __x)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__poly_legendre_p<__type>(__n, __x);
}
// 5.2.1.20 Riemann zeta function.
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 __promote<_Tp>::__type
riemann_zeta(_Tp __x)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__riemann_zeta<__type>(__x);
}
// 5.2.1.21 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 __promote<_Tp>::__type
sph_bessel(unsigned int __n, _Tp __x)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__sph_bessel<__type>(__n, __x);
}
// 5.2.1.22 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 __promote<_Tp>::__type
sph_legendre(unsigned int __l, unsigned int __m, _Tp __theta)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__sph_legendre<__type>(__l, __m, __theta);
}
// 5.2.1.23 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 __promote<_Tp>::__type
sph_neumann(unsigned int __n, _Tp __x)
{
typedef typename __promote<_Tp>::__type __type;
return __detail::__sph_neumann<__type>(__n, __x);
}
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE _GLIBCXX_END_NAMESPACE
} }

View File

@ -72,6 +72,19 @@ _GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
typedef __typeof__(__type1() + __type2() + __type3()) __type; typedef __typeof__(__type1() + __type2() + __type3()) __type;
}; };
template<typename _Tp, typename _Up, typename _Vp, typename _Wp>
struct __promote_4
{
private:
typedef typename __promote<_Tp>::__type __type1;
typedef typename __promote<_Up>::__type __type2;
typedef typename __promote<_Vp>::__type __type3;
typedef typename __promote<_Wp>::__type __type4;
public:
typedef __typeof__(__type1() + __type2() + __type3() + __type4()) __type;
};
_GLIBCXX_END_NAMESPACE _GLIBCXX_END_NAMESPACE
} // namespace std } // namespace std

View File

@ -0,0 +1,762 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/ell_integral.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland based on:
// (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
// (4) Numerical Recipes in C, 2nd ed, by W. H. Press, S. A. Teukolsky,
// W. T. Vetterling, B. P. Flannery, Cambridge University Press
// (1992), pp. 261-269
#ifndef _TR1_ELL_INTEGRAL_TCC
#define _TR1_ELL_INTEGRAL_TCC 1
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// [5.2] Special functions
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @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)
{
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) || __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);
_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);
}
}
/**
* @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>
_Tp
__comp_ellint_1_series(const _Tp __k)
{
const _Tp __kk = __k * __k;
_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;
}
/**
* @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_1(const _Tp __k)
{
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));
}
/**
* @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_1(const _Tp __k, const _Tp __phi)
{
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();
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);
}
}
/**
* @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>
_Tp
__comp_ellint_2_series(const _Tp __k)
{
const _Tp __kk = __k * __k;
_Tp __term = __kk;
_Tp __sum = __term;
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);
}
/**
* @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)
* - Nunerical 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_rd(const _Tp __x, const _Tp __y, const _Tp __z)
{
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);
}
_Tp __ea = __xndev * __yndev;
_Tp __eb = __zndev * __zndev;
_Tp __ec = __ea - __eb;
_Tp __ed = __ea - _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 - __ea));
return _Tp(3) * __sigma + __power4 * (_Tp(1) + __s1 + __s2)
/ (__mu * std::sqrt(__mu));
}
}
/**
* @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
__comp_ellint_2(const _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."));
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);
}
}
/**
* @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_2(const _Tp __k, const _Tp __phi)
{
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_2."));
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();
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 __E = __s
* __ellint_rf(__cc, _Tp(1) - __kk * __ss, _Tp(1))
- __kk * __sss
* __ellint_rd(__cc, _Tp(1) - __kk * __ss, _Tp(1))
/ _Tp(3);
if (__n == 0)
return __E;
else
return __E + _Tp(2) * __n * __comp_ellint_2(__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)
* - Nunerical 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
__ellint_rc(const _Tp __x, const _Tp __y)
{
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."));
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);
_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);
}
}
/**
* @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)
* - Nunerical 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
__ellint_rj(const _Tp __x, const _Tp __y, const _Tp __z, const _Tp __p)
{
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"));
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);
_Tp __xn = __x;
_Tp __yn = __y;
_Tp __zn = __z;
_Tp __pn = __p;
_Tp __sigma = _Tp(0);
_Tp __power4 = _Tp(1);
const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
const _Tp __errtol = std::pow(__eps / _Tp(8), _Tp(1) / _Tp(6));
_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 __alpha = __pn * (__xnroot + __ynroot + __znroot)
+ __xnroot * __ynroot * __znroot;
const _Tp __alpha2 = __alpha * __alpha;
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);
}
_Tp __ea = __xndev * (__yndev + __zndev) + __yndev * __zndev;
_Tp __eb = __xndev * __yndev * __zndev;
_Tp __ec = __pndev * __pndev;
_Tp __e2 = __ea - _Tp(3) * __ec;
_Tp __e3 = __eb + _Tp(2) * __pndev * (__ea - __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 * __ea * (__c2 - __pndev * __c3)
- __c2 * __pndev * __ec;
return _Tp(3) * __sigma + __power4 * (__s1 + __s2 + __s3)
/ (__mu * std::sqrt(__mu));
}
}
/**
* @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)
{
if (__isnan(__k) || __isnan(__nu))
return std::numeric_limits<_Tp>::quiet_NaN();
else if (__nu == _Tp(1))
return std::numeric_limits<_Tp>::infinity();
else if (std::abs(__k) > _Tp(1))
std::__throw_domain_error(__N("Bad argument in __comp_ellint_3."));
else
{
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);
}
}
/**
* @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)
{
if (__isnan(__k) || __isnan(__nu) || __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_3."));
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();
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);
if (__n == 0)
return __Pi;
else
return __Pi + _Tp(2) * __n * __comp_ellint_3(__k, __nu);
}
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_ELL_INTEGRAL_TCC

View File

@ -0,0 +1,538 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/exp_integral.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland based on:
//
// (1) Handbook of Mathematical Functions,
// Ed. by Milton Abramowitz and Irene A. Stegun,
// Dover Publications, New-York, Section 5, pp. 228-251.
// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky,
// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
// 2nd ed, pp. 222-225.
//
#ifndef _TR1_EXP_INTEGRAL_TCC
#define _TR1_EXP_INTEGRAL_TCC 1
#include "special_function_util.h"
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// [5.2] Special functions
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @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)
{
const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
_Tp __term = _Tp(1);
_Tp __esum = _Tp(0);
_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;
}
return - __esum - __osum
- __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>
_Tp
__expint_E1_asymp(const _Tp __x)
{
_Tp __term = _Tp(1);
_Tp __esum = _Tp(1);
_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;
}
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>
_Tp
__expint_En_series(const unsigned int __n, const _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 __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 = -_TR1_GAMMA_TCC;
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."));
}
/**
* @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)
{
const unsigned int __max_iter = 100;
const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
const _Tp __fp_min = std::numeric_limits<_Tp>::min();
const int __nm1 = __n - 1;
_Tp __b = __x + _Tp(__n);
_Tp __c = _Tp(1) / __fp_min;
_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."));
}
/**
* @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)
{
_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);
}
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;
}
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>
_Tp
__expint_Ei_series(const _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;
}
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>
_Tp
__expint_Ei_asymp(const _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;
}
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>
_Tp
__expint_Ei(const _Tp __x)
{
if (__x < _Tp(0))
return -__expint_E1(-__x);
else if (__x < -std::log(std::numeric_limits<_Tp>::epsilon()))
return __expint_Ei_series(__x);
else
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>
_Tp
__expint_E1(const _Tp __x)
{
if (__x < _Tp(0))
return -__expint_Ei(-__x);
else if (__x < _Tp(1))
return __expint_E1_series(__x);
else if (__x < _Tp(100)) // TODO: Find a good asymptotic switch point.
return __expint_En_cont_frac(1, __x);
else
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>
_Tp
__expint_asymp(const unsigned int __n, const _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;
}
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>
_Tp
__expint_large_n(const unsigned int __n, const _Tp __x)
{
const _Tp __xpn = __x + __n;
const _Tp __xpn2 = __xpn * __xpn;
_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;
}
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>
_Tp
__expint(const unsigned int __n, const _Tp __x)
{
// Return NaN on NaN input.
if (__isnan(__x))
return std::numeric_limits<_Tp>::quiet_NaN();
else if (__n <= 1 && __x == _Tp(0))
return std::numeric_limits<_Tp>::infinity();
else
{
_Tp __E0 = std::exp(__x) / __x;
if (__n == 0)
return __E0;
_Tp __E1 = __expint_E1(__x);
if (__n == 1)
return __E1;
if (__x == _Tp(0))
return _Tp(1) / static_cast<_Tp>(__n - 1);
_Tp __En = __expint_En_recursion(__n, __x);
return __En;
}
}
/**
* 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)
{
if (__isnan(__x))
return std::numeric_limits<_Tp>::quiet_NaN();
else
return __expint_Ei(__x);
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_EXP_INTEGRAL_TCC

View File

@ -0,0 +1,486 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/gamma.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland based on:
// (1) Handbook of Mathematical Functions,
// ed. Milton Abramowitz and Irene A. Stegun,
// Dover Publications,
// Section 6, pp. 253-266
// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky,
// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
// 2nd ed, pp. 213-216
// (4) Gamma, Exploring Euler's Constant, Julian Havil,
// Princeton, 2003.
#ifndef _TR1_GAMMA_TCC
#define _TR1_GAMMA_TCC 1
#include "special_function_util.h"
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @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)
};
if (__n == 0)
return _Tp(1);
if (__n == 1)
return -_Tp(1) / _Tp(2);
// Take care of the rest of the odd ones.
if (__n % 2 == 1)
return _Tp(0);
// Take care of some small evens that are painful for the series.
if (__n < 28)
return __num[__n];
_Tp __fact = _Tp(1);
if ((__n / 2) % 2 == 0)
__fact *= _Tp(-1);
for (unsigned int __k = 1; __k <= __n; ++__k)
__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;
}
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>
inline _Tp
__bernoulli(const 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>
_Tp
__log_gamma_bernoulli(const _Tp __x)
{
_Tp __lg = (__x - _Tp(0.5L)) * std::log(__x) - __x
+ _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;
}
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>
_Tp
__log_gamma_lanczos(const _Tp __x)
{
const _Tp __xm1 = __x - _Tp(1);
static const _Tp __lanczos_cheb_7[9] = {
_Tp( 0.99999999999980993227684700473478L),
_Tp( 676.520368121885098567009190444019L),
_Tp(-1259.13921672240287047156078755283L),
_Tp( 771.3234287776530788486528258894L),
_Tp(-176.61502916214059906584551354L),
_Tp( 12.507343278686904814458936853L),
_Tp(-0.13857109526572011689554707L),
_Tp( 9.984369578019570859563e-6L),
_Tp( 1.50563273514931155834e-7L)
};
static const _Tp __LOGROOT2PI
= _Tp(0.9189385332046727417803297364056176L);
_Tp __sum = __lanczos_cheb_7[0];
for(unsigned int __k = 1; __k < 9; ++__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());
const _Tp __term2 = __LOGROOT2PI + std::log(__sum);
const _Tp __result = __term1 + (__term2 - _Tp(7));
return __result;
}
/**
* @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)
{
if (__x > _Tp(0.5L))
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);
}
}
/**
* @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)
{
if (__x > _Tp(0))
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);
}
}
/**
* @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)
{
// 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::_GLIBCXX_TR1::lgamma(_Tp(1 + __n))
- std::_GLIBCXX_TR1::lgamma(_Tp(1 + __k))
- std::_GLIBCXX_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
}
/**
* @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)
{
// Max e exponent before overflow.
static const _Tp __max_bincoeff
= 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();
else
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>
inline _Tp
__gamma(const _Tp __x)
{
return std::exp(__log_gamma(__x));
}
/**
* @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(const _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;
}
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>
_Tp
__psi_asymp(const _Tp __x)
{
_Tp __sum = std::log(__x) - _Tp(0.5L) / __x;
const _Tp __xx = __x * __x;
_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;
}
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>
_Tp
__psi(const _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();
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);
}
else if (__x > _Tp(100))
return __psi_asymp(__x);
else
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>
_Tp
__psi(const unsigned int __n, const _Tp __x)
{
if (__x <= _Tp(0))
std::__throw_domain_error(__N("Argument out of range "
"in __psi"));
else if (__n == 0)
return __psi(__x);
else
{
const _Tp __hzeta = __hurwitz_zeta(_Tp(__n + 1), __x);
#if _GLIBCXX_USE_C99_MATH_TR1
const _Tp __ln_nfact = std::_GLIBCXX_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;
}
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_GAMMA_TCC

View File

@ -0,0 +1,788 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/hypergeometric.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland based:
// (1) Handbook of Mathematical Functions,
// ed. Milton Abramowitz and Irene A. Stegun,
// Dover Publications,
// Section 6, pp. 555-566
// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
#ifndef _TR1_HYPERGEOMETRIC_TCC
#define _TR1_HYPERGEOMETRIC_TCC 1
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// [5.2] Special functions
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @brief This routine returns the confluent hypereometric 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 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)
{
const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
_Tp __term = _Tp(1);
_Tp __Fac = _Tp(1);
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;
}
if (__i == __max_iter)
std::__throw_runtime_error(__N("Series failed to converge "
"in __conf_hyperg_series."));
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>
_Tp
__conf_hyperg_luke(const _Tp __a, const _Tp __c, const _Tp __xin)
{
const _Tp __big = std::pow(std::numeric_limits<_Tp>::max(), _Tp(0.16L));
const int __nmax = 20000;
const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
const _Tp __x = -__xin;
const _Tp __x3 = __x * __x * __x;
const _Tp __t0 = __a / __c;
const _Tp __t1 = (__a + _Tp(1)) / (_Tp(2) * __c);
const _Tp __t2 = (__a + _Tp(2)) / (_Tp(2) * (__c + _Tp(1)));
_Tp __F = _Tp(1);
_Tp __prec;
_Tp __Bnm3 = _Tp(1);
_Tp __Bnm2 = _Tp(1) + __t1 * __x;
_Tp __Bnm1 = _Tp(1) + __t2 * __x * (_Tp(1) + __t1 / _Tp(3) * __x);
_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;
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);
_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;
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;
}
++__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."));
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 "numerator" parameter.
* @param __c The "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)
{
#if _GLIBCXX_USE_C99_MATH_TR1
const _Tp __c_nint = std::_GLIBCXX_TR1::nearbyint(__c);
#else
const _Tp __c_nint = static_cast<int>(__c + _Tp(0.5L));
#endif
if (__isnan(__a) || __isnan(__c) || __isnan(__x))
return std::numeric_limits<_Tp>::quiet_NaN();
else if (__c_nint == __c && __c_nint <= 0)
return std::numeric_limits<_Tp>::infinity();
else if (__a == _Tp(0))
return _Tp(1);
else if (__c == __a)
return std::exp(__x);
else if (__x < _Tp(0))
return __conf_hyperg_luke(__a, __c, __x);
else
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 "numerator" parameter.
* @param __a The second "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
__hyperg_series(const _Tp __a, const _Tp __b,
const _Tp __c, const _Tp __x)
{
const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
_Tp __term = _Tp(1);
_Tp __Fabc = _Tp(1);
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;
}
if (__i == __max_iter)
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>
_Tp
__hyperg_luke(const _Tp __a, const _Tp __b, const _Tp __c,
const _Tp __xin)
{
const _Tp __big = std::pow(std::numeric_limits<_Tp>::max(), _Tp(0.16L));
const int __nmax = 20000;
const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
const _Tp __x = -__xin;
const _Tp __x3 = __x * __x * __x;
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 __F = _Tp(1);
_Tp __Bnm3 = _Tp(1);
_Tp __Bnm2 = _Tp(1) + __t1 * __x;
_Tp __Bnm1 = _Tp(1) + __t2 * __x * (_Tp(1) + __t1 / _Tp(3) * __x);
_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;
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);
_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;
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;
}
++__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."));
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>
_Tp
__hyperg_reflect(const _Tp __a, const _Tp __b, const _Tp __c,
const _Tp __x)
{
const _Tp __d = __c - __a - __b;
const int __intd = std::floor(__d + _Tp(0.5L));
const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
const _Tp __toler = _Tp(1000) * __eps;
const _Tp __log_max = std::log(std::numeric_limits<_Tp>::max());
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;
_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);
// 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;
}
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;
}
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
// 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);
_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"));
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;
return __F;
}
else
{
// 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;
}
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 __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"));
}
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;
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 "numerator" parameter.
* @param __a The second "numerator" parameter.
* @param __c The "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)
{
#if _GLIBCXX_USE_C99_MATH_TR1
const _Tp __a_nint = std::_GLIBCXX_TR1::nearbyint(__a);
const _Tp __b_nint = std::_GLIBCXX_TR1::nearbyint(__b);
const _Tp __c_nint = std::_GLIBCXX_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 __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."));
else if (__isnan(__a) || __isnan(__b)
|| __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();
else if (std::abs(__c - __b) < __toler || std::abs(__c - __a) < __toler)
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);
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);
}
else
return __hyperg_luke(__a, __b, __c, __x);
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_HYPERGEOMETRIC_TCC

View File

@ -0,0 +1,318 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/legendre_function.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland based on:
// (1) Handbook of Mathematical Functions,
// ed. Milton Abramowitz and Irene A. Stegun,
// Dover Publications,
// Section 8, pp. 331-341
// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky,
// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
// 2nd ed, pp. 252-254
#ifndef _TR1_LEGENDRE_FUNCTION_TCC
#define _TR1_LEGENDRE_FUNCTION_TCC 1
#include "special_function_util.h"
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// [5.2] Special functions
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @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)
{
if ((__x < _Tp(-1)) || (__x > _Tp(+1)))
std::__throw_domain_error(__N("Argument out of range"
" in __poly_legendre_p."));
else if (__isnan(__x))
return std::numeric_limits<_Tp>::quiet_NaN();
else if (__x == +_Tp(1))
return +_Tp(1);
else if (__x == -_Tp(1))
return (__l % 2 == 1 ? -_Tp(1) : +_Tp(1));
else
{
_Tp __p_lm2 = _Tp(1);
if (__l == 0)
return __p_lm2;
_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;
}
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 Rodruigez 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)
{
if (__x < _Tp(-1) || __x > _Tp(+1))
std::__throw_domain_error(__N("Argument out of range"
" in __assoc_legendre_p."));
else if (__m > __l)
std::__throw_domain_error(__N("Degree out of range"
" in __assoc_legendre_p."));
else if (__isnan(__x))
return std::numeric_limits<_Tp>::quiet_NaN();
else if (__m == 0)
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_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;
}
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>
_Tp
__sph_legendre(const unsigned int __l, const unsigned int __m,
const _Tp __theta)
{
if (__isnan(__theta))
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."));
}
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;
}
else if (__x == _Tp(1) || __x == -_Tp(1))
{
// m > 0 here
return _Tp(0);
}
else
{
// 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::_GLIBCXX_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::_GLIBCXX_TR1::lgamma(_Tp(__m + _Tp(0.5L)))
- std::_GLIBCXX_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;
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;
}
return __y_lm;
}
}
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_LEGENDRE_FUNCTION_TCC

View File

@ -96,4 +96,96 @@ using std::_GLIBCXX_TR1::trunc;
#endif #endif
using std::_GLIBCXX_TR1::assoc_laguerref;
using std::_GLIBCXX_TR1::assoc_laguerre;
using std::_GLIBCXX_TR1::assoc_laguerrel;
using std::_GLIBCXX_TR1::assoc_legendref;
using std::_GLIBCXX_TR1::assoc_legendre;
using std::_GLIBCXX_TR1::assoc_legendrel;
using std::_GLIBCXX_TR1::betaf;
using std::_GLIBCXX_TR1::beta;
using std::_GLIBCXX_TR1::betal;
using std::_GLIBCXX_TR1::comp_ellint_1f;
using std::_GLIBCXX_TR1::comp_ellint_1;
using std::_GLIBCXX_TR1::comp_ellint_1l;
using std::_GLIBCXX_TR1::comp_ellint_2f;
using std::_GLIBCXX_TR1::comp_ellint_2;
using std::_GLIBCXX_TR1::comp_ellint_2l;
using std::_GLIBCXX_TR1::comp_ellint_3f;
using std::_GLIBCXX_TR1::comp_ellint_3;
using std::_GLIBCXX_TR1::comp_ellint_3l;
using std::_GLIBCXX_TR1::conf_hypergf;
using std::_GLIBCXX_TR1::conf_hyperg;
using std::_GLIBCXX_TR1::conf_hypergl;
using std::_GLIBCXX_TR1::cyl_bessel_if;
using std::_GLIBCXX_TR1::cyl_bessel_i;
using std::_GLIBCXX_TR1::cyl_bessel_il;
using std::_GLIBCXX_TR1::cyl_bessel_jf;
using std::_GLIBCXX_TR1::cyl_bessel_j;
using std::_GLIBCXX_TR1::cyl_bessel_jl;
using std::_GLIBCXX_TR1::cyl_bessel_kf;
using std::_GLIBCXX_TR1::cyl_bessel_k;
using std::_GLIBCXX_TR1::cyl_bessel_kl;
using std::_GLIBCXX_TR1::cyl_neumannf;
using std::_GLIBCXX_TR1::cyl_neumann;
using std::_GLIBCXX_TR1::cyl_neumannl;
using std::_GLIBCXX_TR1::ellint_1f;
using std::_GLIBCXX_TR1::ellint_1;
using std::_GLIBCXX_TR1::ellint_1l;
using std::_GLIBCXX_TR1::ellint_2f;
using std::_GLIBCXX_TR1::ellint_2;
using std::_GLIBCXX_TR1::ellint_2l;
using std::_GLIBCXX_TR1::ellint_3f;
using std::_GLIBCXX_TR1::ellint_3;
using std::_GLIBCXX_TR1::ellint_3l;
using std::_GLIBCXX_TR1::expintf;
using std::_GLIBCXX_TR1::expint;
using std::_GLIBCXX_TR1::expintl;
using std::_GLIBCXX_TR1::hermitef;
using std::_GLIBCXX_TR1::hermite;
using std::_GLIBCXX_TR1::hermitel;
using std::_GLIBCXX_TR1::hypergf;
using std::_GLIBCXX_TR1::hyperg;
using std::_GLIBCXX_TR1::hypergl;
using std::_GLIBCXX_TR1::laguerref;
using std::_GLIBCXX_TR1::laguerre;
using std::_GLIBCXX_TR1::laguerrel;
using std::_GLIBCXX_TR1::legendref;
using std::_GLIBCXX_TR1::legendre;
using std::_GLIBCXX_TR1::legendrel;
using std::_GLIBCXX_TR1::riemann_zetaf;
using std::_GLIBCXX_TR1::riemann_zeta;
using std::_GLIBCXX_TR1::riemann_zetal;
using std::_GLIBCXX_TR1::sph_besself;
using std::_GLIBCXX_TR1::sph_bessel;
using std::_GLIBCXX_TR1::sph_bessell;
using std::_GLIBCXX_TR1::sph_legendref;
using std::_GLIBCXX_TR1::sph_legendre;
using std::_GLIBCXX_TR1::sph_legendrel;
using std::_GLIBCXX_TR1::sph_neumannf;
using std::_GLIBCXX_TR1::sph_neumann;
using std::_GLIBCXX_TR1::sph_neumannl;
#endif #endif

View File

@ -0,0 +1,450 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/modified_bessel_func.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland.
//
// References:
// (1) Handbook of Mathematical Functions,
// Ed. Milton Abramowitz and Irene A. Stegun,
// Dover Publications,
// Section 9, pp. 355-434, Section 10 pp. 435-478
// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
// (3) Numerical Recipes in C, by W. H. Press, S. A. Teukolsky,
// W. T. Vetterling, B. P. Flannery, Cambridge University Press (1992),
// 2nd ed, pp. 246-249.
#ifndef _TR1_MODIFIED_BESSEL_FUNC_TCC
#define _TR1_MODIFIED_BESSEL_FUNC_TCC 1
#include "special_function_util.h"
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// [5.2] Special functions
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @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)
{
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;
}
const _Tp __eps = std::numeric_limits<_Tp>::epsilon();
const _Tp __fp_min = _Tp(10) * std::numeric_limits<_Tp>::epsilon();
const int __max_iter = 15000;
const _Tp __x_min = _Tp(2);
const int __nl = static_cast<int>(__nu + _Tp(0.5L));
const _Tp __mu = __nu - __nl;
const _Tp __mu2 = __mu * __mu;
const _Tp __xi = _Tp(1) / __x;
const _Tp __xi2 = _Tp(2) * __xi;
_Tp __h = __nu * __xi;
if ( __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;
}
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;
_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;
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;
}
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 __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;
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>
_Tp
__cyl_bessel_i(const _Tp __nu, const _Tp __x)
{
if (__nu < _Tp(0) || __x < _Tp(0))
std::__throw_domain_error(__N("Bad argument "
"in __cyl_bessel_i."));
else if (__isnan(__nu) || __isnan(__x))
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);
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;
}
}
/**
* @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)
{
if (__nu < _Tp(0) || __x < _Tp(0))
std::__throw_domain_error(__N("Bad argument "
"in __cyl_bessel_k."));
else if (__isnan(__nu) || __isnan(__x))
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;
}
}
/**
* @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)
{
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);
const _Tp __factor = __numeric_constants<_Tp>::__sqrtpio2()
/ 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);
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>
void
__airy(const _Tp __x,
_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);
if (__isnan(__x))
return std::numeric_limits<_Tp>::quiet_NaN();
else if (__x > _Tp(0))
{
_Tp __I_nu, __Ip_nu, __K_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(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_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(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);
}
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.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();
}
return;
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_MODIFIED_BESSEL_FUNC_TCC

View File

@ -0,0 +1,138 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/poly_hermite.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland based on:
// (1) Handbook of Mathematical Functions,
// Ed. Milton Abramowitz and Irene A. Stegun,
// Dover Publications, Section 22 pp. 773-802
#ifndef _TR1_POLY_HERMITE_TCC
#define _TR1_POLY_HERMITE_TCC 1
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// [5.2] Special functions
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @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)
{
// Compute H_0.
_Tp __H_0 = 1;
if (__n == 0)
return __H_0;
// Compute H_1.
_Tp __H_1 = 2 * __x;
if (__n == 1)
return __H_1;
// 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;
}
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>
inline _Tp
__poly_hermite(const unsigned int __n, const _Tp __x)
{
if (__isnan(__x))
return std::numeric_limits<_Tp>::quiet_NaN();
else
return __poly_hermite_recursion(__n, __x);
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_POLY_HERMITE_TCC

View File

@ -0,0 +1,342 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/poly_laguerre.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland based on:
// (1) Handbook of Mathematical Functions,
// Ed. Milton Abramowitz and Irene A. Stegun,
// Dover Publications,
// Section 13, pp. 509-510, Section 22 pp. 773-802
// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
#ifndef _TR1_POLY_LAGUERRE_TCC
#define _TR1_POLY_LAGUERRE_TCC 1
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// [5.2] Special functions
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @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 __alpha,
const _Tp __x)
{
const _Tp __a = -_Tp(__n);
const _Tp __b = _Tp(__alpha) + _Tp(1);
const _Tp __eta = _Tp(2) * __b - _Tp(4) * __a;
const _Tp __cos2th = __x / __eta;
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;
#if _GLIBCXX_USE_C99_MATH_TR1
const _Tp __lg_b = std::_GLIBCXX_TR1::lgamma(_Tp(__n) + __b);
const _Tp __lnfact = std::_GLIBCXX_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);
_Tp __pre_term2 = _Tp(0.25L) * std::log(__pre_h);
_Tp __lnpre = __lg_b - __lnfact + _Tp(0.5L) * __x
+ __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 __ser = __ser_term1 + __ser_term2;
return std::exp(__lnpre) * __ser;
}
/**
* @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 __alpha, const _Tp __x)
{
const _Tp __b = _Tp(__alpha) + _Tp(1);
const _Tp __mx = -__x;
const _Tp __tc_sgn = (__x < _Tp(0) ? _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);
_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;
}
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>
_Tp
__poly_laguerre_recursion(const unsigned int __n,
const _Tpa __alpha, const _Tp __x)
{
// Compute l_0.
_Tp __l_0 = _Tp(1);
if (__n == 0)
return __l_0;
// Compute l_1^alpha.
_Tp __l_1 = -__x + _Tp(1) + _Tp(__alpha);
if (__n == 1)
return __l_1;
// Compute l_n^alpha by recursion on n.
_Tp __l_n2 = __l_0;
_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(__alpha) - __x)
* __l_n1 / _Tp(__nn)
- (_Tp(__nn - 1) + _Tp(__alpha)) * __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 __alpha,
const _Tp __x)
{
if (__x < _Tp(0))
std::__throw_domain_error(__N("Negative argument "
"in __poly_laguerre."));
// Return NaN on NaN input.
else if (__isnan(__x))
return std::numeric_limits<_Tp>::quiet_NaN();
else if (__n == 0)
return _Tp(1);
else if (__n == 1)
return _Tp(1) + _Tp(__alpha) - __x;
else if (__x == _Tp(0))
{
_Tp __prod = _Tp(__alpha) + _Tp(1);
for (unsigned int __k = 2; __k <= __n; ++__k)
__prod *= (_Tp(__alpha) + _Tp(__k)) / _Tp(__k);
return __prod;
}
else if (__n > 10000000 && _Tp(__alpha) > -_Tp(1)
&& __x < _Tp(2) * (_Tp(__alpha) + _Tp(1)) + _Tp(4 * __n))
return __poly_laguerre_large_n(__n, __alpha, __x);
else if (_Tp(__alpha) >= _Tp(0)
|| (__x > _Tp(0) && _Tp(__alpha) < -_Tp(__n + 1)))
return __poly_laguerre_recursion(__n, __alpha, __x);
else
return __poly_laguerre_hyperg(__n, __alpha, __x);
}
/**
* @brief This routine returns the associated Laguerre polynomial
* of order n, degree m: @f$ L_n^m @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);
}
/**
* @brief This routine returns the associated 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);
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_POLY_LAGUERRE_TCC

View File

@ -0,0 +1,449 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006-2007
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/riemann_zeta.tcc
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland based on:
// (1) Handbook of Mathematical Functions,
// Ed. by Milton Abramowitz and Irene A. Stegun,
// Dover Publications, New-York, Section 5, pp. 807-808.
// (2) The Gnu Scientific Library, http://www.gnu.org/software/gsl
// (3) Gamma, Exploring Euler's Constant, Julian Havil,
// Princeton, 2003.
#ifndef _TR1_RIEMANN_ZETA_TCC
#define _TR1_RIEMANN_ZETA_TCC 1
#include "special_function_util.h"
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
// [5.2] Special functions
/**
* @ingroup tr1_math_spec_func
* @{
*/
//
// Implementation-space details.
//
namespace __detail
{
/**
* @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)
{
// A user shouldn't get to this.
if (__s < _Tp(1))
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;
}
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>
_Tp
__riemann_zeta_alt(const _Tp __s)
{
_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);
}
__zeta /= _Tp(1) - std::pow(_Tp(2), _Tp(1) - __s);
return __zeta;
}
/**
* @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)
{
_Tp __zeta = _Tp(0);
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);
// This series works until the binomial coefficient blows up
// so use reflection.
if (__s < _Tp(0))
{
#if _GLIBCXX_USE_C99_MATH_TR1
if (std::_GLIBCXX_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::_GLIBCXX_TR1::lgamma(_Tp(1) - __s))
#else
* std::exp(__log_gamma(_Tp(1) - __s))
#endif
/ __numeric_constants<_Tp>::__pi();
return __zeta;
}
}
_Tp __num = _Tp(0.5L);
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::_GLIBCXX_TR1::lgamma(_Tp(1 + __i))
- std::_GLIBCXX_TR1::lgamma(_Tp(1 + __j))
- std::_GLIBCXX_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(1) - std::pow(_Tp(2), _Tp(1) - __s);
return __zeta;
}
/**
* @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)
{
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 const 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;
}
__zeta = _Tp(1) / __zeta;
return __zeta;
}
/**
* @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)
{
if (__isnan(__s))
return std::numeric_limits<_Tp>::quiet_NaN();
else if (__s == _Tp(1))
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::_GLIBCXX_TR1::lgamma(_Tp(1) - __s))
#else
* std::exp(__log_gamma(_Tp(1) - __s))
#endif
/ __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::_GLIBCXX_TR1::tgamma(_Tp(1) - __s)
#else
* std::exp(__log_gamma(_Tp(1) - __s))
#endif
* __riemann_zeta_sum(_Tp(1) - __s);
return __zeta;
}
}
}
else
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>
_Tp
__hurwitz_zeta_glob(const _Tp __a, const _Tp __s)
{
_Tp __zeta = _Tp(0);
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);
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::_GLIBCXX_TR1::lgamma(_Tp(1 + __i))
- std::_GLIBCXX_TR1::lgamma(_Tp(1 + __j))
- std::_GLIBCXX_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 /= __s - _Tp(1);
return __zeta;
}
/**
* @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);
}
} // namespace std::tr1::__detail
/* @} */ // group tr1_math_spec_func
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_RIEMANN_ZETA_TCC

View File

@ -0,0 +1,155 @@
// Special functions -*- C++ -*-
// Copyright (C) 2006
// 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 COPYING. If not, write to the Free
// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.
// As a special exception, you may use this file as part of a free software
// library without restriction. Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License. This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
/** @file tr1/special_function_util.h
* This is an internal header file, included by other library headers.
* You should not attempt to use it directly.
*/
//
// ISO C++ 14882 TR1: 5.2 Special functions
//
// Written by Edward Smith-Rowland based on numerous mathematics books.
#ifndef _TR1_SPECIAL_FUNCTION_UTIL_H
#define _TR1_SPECIAL_FUNCTION_UTIL_H 1
// namespace std::tr1
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
namespace __detail
{
///
/// @brief 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;
};
///
/// @brief A structure for numeric constants.
///
template<typename _Tp>
struct __numeric_constants
{
/// 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); }
};
///
/// @brief 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.
///
#if _GLIBCXX_USE_C99_MATH && !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
template <typename _Tp>
inline bool __isnan(const _Tp __x)
{
return std::isnan(__x);
}
#else
template <typename _Tp>
inline bool __isnan(const _Tp __x)
{
return __builtin_isnan(__x);
}
template <>
inline bool __isnan<float>(const float __x)
{
return __builtin_isnanf(__x);
}
template <>
inline bool __isnan<long double>(const long double __x)
{
return __builtin_isnanl(__x);
}
#endif
} // namespace __detail
_GLIBCXX_END_NAMESPACE
}
#endif // _TR1_SPECIAL_FUNCTION_UTIL_H

View File

@ -1,6 +1,6 @@
# Handlers for additional dg-xxx keywords in tests. # Handlers for additional dg-xxx keywords in tests.
# Copyright (C) 2004, 2005 Free Software Foundation, Inc. # Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@ -14,11 +14,20 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
proc dg-require-c-std { args } {
if { ![ check_v3_target_c_std ] } {
upvar dg-do-what dg-do-what
set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
return
}
return
}
proc dg-require-namedlocale { args } { proc dg-require-debug-mode { args } {
if { ![ check_v3_target_namedlocale ] } { if { ![ check_v3_target_debug_mode ] } {
upvar dg-do-what dg-do-what upvar dg-do-what dg-do-what
set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
return return
@ -35,8 +44,8 @@ proc dg-require-fileio { args } {
return return
} }
proc dg-require-time { args } { proc dg-require-namedlocale { args } {
if { ![ check_v3_target_time ] } { if { ![ check_v3_target_namedlocale ] } {
upvar dg-do-what dg-do-what upvar dg-do-what dg-do-what
set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
return return
@ -53,8 +62,8 @@ proc dg-require-sharedlib { args } {
return return
} }
proc dg-require-debug-mode { args } { proc dg-require-time { args } {
if { ![ check_v3_target_debug_mode ] } { if { ![ check_v3_target_time ] } {
upvar dg-do-what dg-do-what upvar dg-do-what dg-do-what
set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"] set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
return return

View File

@ -579,6 +579,67 @@ proc check_v3_target_fileio { } {
return $et_fileio_saved return $et_fileio_saved
} }
proc check_v3_target_c_std { } {
global et_c_std_saved
global et_c_std_target_name
global tool
if { ![info exists et_c_std_target_name] } {
set et_c_std_target_name ""
}
# If the target has changed since we set the cached value, clear it.
set current_target [current_target_name]
if { $current_target != $et_c_std_target_name } {
verbose "check_v3_target_c_std: `$et_c_std_target_name'" 2
set et_c_std_target_name $current_target
if [info exists et_c_std_saved] {
verbose "check_v3_target_c_std: removing cached result" 2
unset et_c_std_saved
}
}
if [info exists et_c_std_saved] {
verbose "check_v3_target_c_std: using cached result" 2
} else {
set et_c_std_saved 0
# Set up, compile, and execute a C++ test program that tries to use
# C99 functionality.
set src fileio[pid].cc
set exe fileio[pid].x
set f [open $src "w"]
puts $f "#include <tr1/cmath>"
puts $f "int main ()"
puts $f "{"
puts $f " float f = 45.55;"
puts $f " int i = std::tr1::isnan(f);"
puts $f " return 0;"
puts $f "}"
close $f
set lines [v3_target_compile $src $exe executable ""]
file delete $src
if [string match "" $lines] {
# No error message, compilation succeeded.
set result [${tool}_load "./$exe" "" ""]
set status [lindex $result 0]
remote_file build delete $exe
verbose "check_v3_target_c_std: status is <$status>" 2
if { $status == "pass" } {
set et_c_std_saved 1
}
} else {
verbose "check_v3_target_c_std: compilation failed" 2
}
}
return $et_c_std_saved
}
proc check_v3_target_sharedlib { } { proc check_v3_target_sharedlib { } {
global v3-sharedlib global v3-sharedlib
return ${v3-sharedlib} return ${v3-sharedlib}

View File

@ -0,0 +1,57 @@
// { dg-require-c-std "" }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.1 assoc_laguerre
#include <tr1/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, m = 1;
float a = std::tr1::assoc_laguerre(n, m, xf);
float b = std::tr1::assoc_laguerref(n, m, xf);
double c = std::tr1::assoc_laguerre(n, m, xd);
long double d = std::tr1::assoc_laguerre(n, m, xl);
long double e = std::tr1::assoc_laguerrel(n, m, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
return 0;
}

View File

@ -0,0 +1,44 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.1 assoc_laguerre
#include <tr1/cmath>
void
test01()
{
float xf = 0.5F;
double xd = 0.5;
long double xl = 0.5L;
unsigned int n = 2, m = 1;
float a = std::tr1::assoc_laguerre(n, m, xf);
float b = std::tr1::assoc_laguerref(n, m, xf);
double c = std::tr1::assoc_laguerre(n, m, xd);
long double d = std::tr1::assoc_laguerre(n, m, xl);
long double e = std::tr1::assoc_laguerrel(n, m, xl);
return;
}

View File

@ -0,0 +1,44 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.1 assoc_laguerre
#include <tr1/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;
}

View File

@ -0,0 +1,59 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.2 assoc_legendre
#include <tr1/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::tr1::assoc_legendre(l, m, xf);
float b = std::tr1::assoc_legendref(l, m, xf);
double c = std::tr1::assoc_legendre(l, m, xd);
long double d = std::tr1::assoc_legendre(l, m, xl);
long double e = std::tr1::assoc_legendrel(l, m, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
return 0;
}

View File

@ -0,0 +1,44 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.2 assoc_legendre
#include <tr1/cmath>
void
test01()
{
float xf = 0.5F;
double xd = 0.5;
long double xl = 0.5L;
unsigned int l = 2, m = 1;
std::tr1::assoc_legendre(l, m, xf);
std::tr1::assoc_legendref(l, m, xf);
std::tr1::assoc_legendre(l, m, xd);
std::tr1::assoc_legendre(l, m, xl);
std::tr1::assoc_legendrel(l, m, xl);
return;
}

View File

@ -0,0 +1,44 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.2 assoc_legendre
#include <tr1/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;
}

View File

@ -0,0 +1,87 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.3 beta
#include <tr1/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::tr1::beta(xf, yf);
float b = std::tr1::betaf(xf, yf);
double c = std::tr1::beta(xd, yd);
long double d = std::tr1::beta(xl, yl);
long double e = std::tr1::betal(xl, yl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(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::tr1::beta(xf, yf);
float b = std::tr1::betaf(xf, yf);
double c = std::tr1::beta(xd, yd);
long double d = std::tr1::beta(xl, yl);
long double e = std::tr1::betal(xl, yl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,466 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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()
{
const 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::tr1::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()
{
const 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::tr1::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()
{
const 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::tr1::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()
{
const 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::tr1::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()
{
const 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::tr1::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()
{
const 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::tr1::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(1.0000000000000008e-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()
{
const 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::tr1::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(1.0000000000000008e-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()
{
const 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::tr1::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()
{
const 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::tr1::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(1.0000000000000008e-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()
{
const 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::tr1::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.0000000000000029e-12));
}
int main(int, char**)
{
test001<double>();
test002<double>();
test003<double>();
test004<double>();
test005<double>();
test006<double>();
test007<double>();
test008<double>();
test009<double>();
test010<double>();
return 0;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.3 beta
#include <tr1/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::tr1::beta(xf, yf);
std::tr1::betaf(xf, yf);
std::tr1::beta(xd, yd);
std::tr1::beta(xl, yl);
std::tr1::betal(xl, yl);
return;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.3 beta
#include <tr1/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;
}

View File

@ -0,0 +1,57 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.4 comp_ellint_1
#include <tr1/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::tr1::comp_ellint_1(kf);
float b = std::tr1::comp_ellint_1f(kf);
double c = std::tr1::comp_ellint_1(kd);
long double d = std::tr1::comp_ellint_1(kl);
long double e = std::tr1::comp_ellint_1l(kl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
return 0;
}

View File

@ -0,0 +1,97 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.6080486199305126, -0.30000000000000004 },
{ 1.5868678474541664, -0.19999999999999996 },
{ 1.5747455615173562, -0.099999999999999978 },
{ 1.5707963267948966, 0.0000000000000000 },
{ 1.5747455615173562, 0.10000000000000009 },
{ 1.5868678474541664, 0.19999999999999996 },
{ 1.6080486199305126, 0.30000000000000004 },
{ 1.6399998658645112, 0.39999999999999991 },
{ 1.6857503548125963, 0.50000000000000000 },
{ 1.7507538029157526, 0.60000000000000009 },
{ 1.8456939983747236, 0.69999999999999996 },
{ 1.9953027776647296, 0.80000000000000004 },
{ 2.2805491384227699, 0.89999999999999991 },
};
// Test function.
template <typename Tp>
void test001()
{
const 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::tr1::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(int, char**)
{
test001<double>();
return 0;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.4 comp_ellint_1
#include <tr1/cmath>
void
test01()
{
float kf = 0.5F;
double kd = 0.5;
long double kl = 0.5L;
std::tr1::comp_ellint_1(kf);
std::tr1::comp_ellint_1f(kf);
std::tr1::comp_ellint_1(kd);
std::tr1::comp_ellint_1(kl);
std::tr1::comp_ellint_1l(kl);
return;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.4 comp_ellint_1
#include <tr1/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;
}

View File

@ -0,0 +1,57 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.5 comp_ellint_2
#include <tr1/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::tr1::comp_ellint_2(kf);
float b = std::tr1::comp_ellint_2f(kf);
double c = std::tr1::comp_ellint_2(kd);
long double d = std::tr1::comp_ellint_2(kl);
long double e = std::tr1::comp_ellint_2l(kl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
return 0;
}

View File

@ -0,0 +1,97 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.2763499431699066, -0.80000000000000004 },
{ 1.3556611355719557, -0.69999999999999996 },
{ 1.4180833944487243, -0.59999999999999998 },
{ 1.4674622093394274, -0.50000000000000000 },
{ 1.5059416123600402, -0.40000000000000002 },
{ 1.5348334649232489, -0.30000000000000004 },
{ 1.5549685462425296, -0.19999999999999996 },
{ 1.5668619420216685, -0.099999999999999978 },
{ 1.5707963267948966, 0.0000000000000000 },
{ 1.5668619420216685, 0.10000000000000009 },
{ 1.5549685462425296, 0.19999999999999996 },
{ 1.5348334649232489, 0.30000000000000004 },
{ 1.5059416123600404, 0.39999999999999991 },
{ 1.4674622093394274, 0.50000000000000000 },
{ 1.4180833944487241, 0.60000000000000009 },
{ 1.3556611355719557, 0.69999999999999996 },
{ 1.2763499431699066, 0.80000000000000004 },
{ 1.1716970527816142, 0.89999999999999991 },
};
// Test function.
template <typename Tp>
void test001()
{
const 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::tr1::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(5.0000000000000039e-13));
}
int main(int, char**)
{
test001<double>();
return 0;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.5 comp_ellint_2
#include <tr1/cmath>
void
test01()
{
float kf = 0.5F;
double kd = 0.5;
long double kl = 0.5L;
std::tr1::comp_ellint_2(kf);
std::tr1::comp_ellint_2f(kf);
std::tr1::comp_ellint_2(kd);
std::tr1::comp_ellint_2(kl);
std::tr1::comp_ellint_2l(kl);
return;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.4 comp_ellint_2
#include <tr1/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;
}

View File

@ -0,0 +1,87 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.6 comp_ellint_3
#include <tr1/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::tr1::comp_ellint_3(kf, nuf);
float b = std::tr1::comp_ellint_3f(kf, nuf);
double c = std::tr1::comp_ellint_3(kd, nud);
long double d = std::tr1::comp_ellint_3(kl, nul);
long double e = std::tr1::comp_ellint_3l(kl, nul);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(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::tr1::comp_ellint_3(kf, nuf);
float b = std::tr1::comp_ellint_3f(kf, nuf);
double c = std::tr1::comp_ellint_3(kd, nud);
long double d = std::tr1::comp_ellint_3(kl, nul);
long double e = std::tr1::comp_ellint_3l(kl, nul);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,844 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.6600480747670938, -0.90000000000000002, 0.69999999999999996 },
{ 1.6044591960982204, -0.90000000000000002, 0.80000000000000004 },
{ 1.5536420236310946, -0.90000000000000002, 0.90000000000000002 },
};
// Test function for k=-0.90000000000000002.
template <typename Tp>
void test001()
{
const 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::tr1::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.4339837018309474, -0.80000000000000004, 0.80000000000000004 },
{ 1.3911845406776222, -0.80000000000000004, 0.90000000000000002 },
};
// Test function for k=-0.80000000000000004.
template <typename Tp>
void test002()
{
const 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::tr1::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.6721098780092147, -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.3427110650397533, -0.69999999999999996, 0.80000000000000004 },
{ 1.3040500499695911, -0.69999999999999996, 0.90000000000000002 },
};
// Test function for k=-0.69999999999999996.
template <typename Tp>
void test003()
{
const 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::tr1::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.3232737468822811, -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()
{
const 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::tr1::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()
{
const 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::tr1::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()
{
const 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::tr1::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.6080486199305126, -0.30000000000000004, 0.0000000000000000 },
{ 1.5323534693557526, -0.30000000000000004, 0.10000000000000001 },
{ 1.4663658145259875, -0.30000000000000004, 0.20000000000000001 },
{ 1.4081767433479089, -0.30000000000000004, 0.29999999999999999 },
{ 1.3563643538969761, -0.30000000000000004, 0.40000000000000002 },
{ 1.3098448759814960, -0.30000000000000004, 0.50000000000000000 },
{ 1.2677758800420666, -0.30000000000000004, 0.59999999999999998 },
{ 1.2294913236274980, -0.30000000000000004, 0.69999999999999996 },
{ 1.1944567571590046, -0.30000000000000004, 0.80000000000000004 },
{ 1.1622376896064912, -0.30000000000000004, 0.90000000000000002 },
};
// Test function for k=-0.30000000000000004.
template <typename Tp>
void test007()
{
const 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::tr1::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.5868678474541664, -0.19999999999999996, 0.0000000000000000 },
{ 1.5126513474261092, -0.19999999999999996, 0.10000000000000001 },
{ 1.4479323932249568, -0.19999999999999996, 0.20000000000000001 },
{ 1.3908453514752481, -0.19999999999999996, 0.29999999999999999 },
{ 1.3400002519661010, -0.19999999999999996, 0.40000000000000002 },
{ 1.2943374404397376, -0.19999999999999996, 0.50000000000000000 },
{ 1.2530330675914561, -0.19999999999999996, 0.59999999999999998 },
{ 1.2154356555075867, -0.19999999999999996, 0.69999999999999996 },
{ 1.1810223448909913, -0.19999999999999996, 0.80000000000000004 },
{ 1.1493679916141863, -0.19999999999999996, 0.90000000000000002 },
};
// Test function for k=-0.19999999999999996.
template <typename Tp>
void test008()
{
const 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::tr1::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.2073745911083187, -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()
{
const 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::tr1::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.3275651989026322, 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()
{
const 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::tr1::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.2073745911083187, 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()
{
const 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::tr1::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.5868678474541664, 0.19999999999999996, 0.0000000000000000 },
{ 1.5126513474261092, 0.19999999999999996, 0.10000000000000001 },
{ 1.4479323932249568, 0.19999999999999996, 0.20000000000000001 },
{ 1.3908453514752481, 0.19999999999999996, 0.29999999999999999 },
{ 1.3400002519661010, 0.19999999999999996, 0.40000000000000002 },
{ 1.2943374404397376, 0.19999999999999996, 0.50000000000000000 },
{ 1.2530330675914561, 0.19999999999999996, 0.59999999999999998 },
{ 1.2154356555075867, 0.19999999999999996, 0.69999999999999996 },
{ 1.1810223448909913, 0.19999999999999996, 0.80000000000000004 },
{ 1.1493679916141863, 0.19999999999999996, 0.90000000000000002 },
};
// Test function for k=0.19999999999999996.
template <typename Tp>
void test012()
{
const 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::tr1::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.6080486199305126, 0.30000000000000004, 0.0000000000000000 },
{ 1.5323534693557526, 0.30000000000000004, 0.10000000000000001 },
{ 1.4663658145259875, 0.30000000000000004, 0.20000000000000001 },
{ 1.4081767433479089, 0.30000000000000004, 0.29999999999999999 },
{ 1.3563643538969761, 0.30000000000000004, 0.40000000000000002 },
{ 1.3098448759814960, 0.30000000000000004, 0.50000000000000000 },
{ 1.2677758800420666, 0.30000000000000004, 0.59999999999999998 },
{ 1.2294913236274980, 0.30000000000000004, 0.69999999999999996 },
{ 1.1944567571590046, 0.30000000000000004, 0.80000000000000004 },
{ 1.1622376896064912, 0.30000000000000004, 0.90000000000000002 },
};
// Test function for k=0.30000000000000004.
template <typename Tp>
void test013()
{
const 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::tr1::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()
{
const 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::tr1::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()
{
const 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::tr1::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.3232737468822811, 0.60000000000000009, 0.69999999999999996 },
{ 1.2840021261752192, 0.60000000000000009, 0.80000000000000004 },
{ 1.2479362973851875, 0.60000000000000009, 0.90000000000000002 },
};
// Test function for k=0.60000000000000009.
template <typename Tp>
void test016()
{
const 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::tr1::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.6721098780092147, 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.3427110650397533, 0.69999999999999996, 0.80000000000000004 },
{ 1.3040500499695911, 0.69999999999999996, 0.90000000000000002 },
};
// Test function for k=0.69999999999999996.
template <typename Tp>
void test017()
{
const 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::tr1::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.4339837018309474, 0.80000000000000004, 0.80000000000000004 },
{ 1.3911845406776222, 0.80000000000000004, 0.90000000000000002 },
};
// Test function for k=0.80000000000000004.
template <typename Tp>
void test018()
{
const 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::tr1::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.2805491384227699, 0.89999999999999991, 0.0000000000000000 },
{ 2.1537868513875282, 0.89999999999999991, 0.10000000000000001 },
{ 2.0443194576468890, 0.89999999999999991, 0.20000000000000001 },
{ 1.9486280260314424, 0.89999999999999991, 0.29999999999999999 },
{ 1.8641114227238347, 0.89999999999999991, 0.40000000000000002 },
{ 1.7888013241937859, 0.89999999999999991, 0.50000000000000000 },
{ 1.7211781128919521, 0.89999999999999991, 0.59999999999999998 },
{ 1.6600480747670936, 0.89999999999999991, 0.69999999999999996 },
{ 1.6044591960982200, 0.89999999999999991, 0.80000000000000004 },
{ 1.5536420236310944, 0.89999999999999991, 0.90000000000000002 },
};
// Test function for k=0.89999999999999991.
template <typename Tp>
void test019()
{
const 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::tr1::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(int, char**)
{
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;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.6 comp_ellint_3
#include <tr1/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::tr1::comp_ellint_3(kf, nuf);
std::tr1::comp_ellint_3f(kf, nuf);
std::tr1::comp_ellint_3(kd, nud);
std::tr1::comp_ellint_3(kl, nul);
std::tr1::comp_ellint_3l(kl, nul);
return;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.6 comp_ellint_3
#include <tr1/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;
}

View File

@ -0,0 +1,126 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.7 conf_hyperg
#include <tr1/cmath>
#include <testsuite_hooks.h>
void
test01()
{
float af = std::numeric_limits<float>::quiet_NaN();
double ad = std::numeric_limits<double>::quiet_NaN();
long double al = std::numeric_limits<long double>::quiet_NaN();
float cf = 3.0F;
double cd = 3.0;
long double cl = 3.0L;
float xf = 0.5F;
double xd = 0.5;
long double xl = 0.5L;
float a = std::tr1::conf_hyperg(af, cf, xf);
float b = std::tr1::conf_hypergf(af, cf, xf);
double c = std::tr1::conf_hyperg(ad, cd, xd);
long double d = std::tr1::conf_hyperg(al, cl, xl);
long double e = std::tr1::conf_hypergl(al, cl, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
void
test02()
{
float af = 2.0F;
double ad = 2.0;
long double al = 2.0L;
float cf = std::numeric_limits<float>::quiet_NaN();
double cd = std::numeric_limits<double>::quiet_NaN();
long double cl = std::numeric_limits<long double>::quiet_NaN();
float xf = 0.5F;
double xd = 0.5;
long double xl = 0.5L;
float a = std::tr1::conf_hyperg(af, cf, xf);
float b = std::tr1::conf_hypergf(af, cf, xf);
double c = std::tr1::conf_hyperg(ad, cd, xd);
long double d = std::tr1::conf_hyperg(al, cl, xl);
long double e = std::tr1::conf_hypergl(al, cl, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
void
test03()
{
float af = 2.0F;
double ad = 2.0;
long double al = 2.0L;
float cf = 3.0F;
double cd = 3.0;
long double cl = 3.0L;
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::tr1::conf_hyperg(af, cf, xf);
float b = std::tr1::conf_hypergf(af, cf, xf);
double c = std::tr1::conf_hyperg(ad, cd, xd);
long double d = std::tr1::conf_hyperg(al, cl, xl);
long double e = std::tr1::conf_hypergl(al, cl, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
test03();
return 0;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.7 conf_hyperg
#include <tr1/cmath>
void
test01()
{
float af = 2.0F, cf = 3.0F, xf = 0.5F;
double ad = 2.0, cd = 3.0, xd = 0.5;
long double al = 2.0L, cl = 3.0L, xl = 0.5L;
std::tr1::conf_hyperg(af, cf, xf);
std::tr1::conf_hypergf(af, cf, xf);
std::tr1::conf_hyperg(ad, cd, xd);
std::tr1::conf_hyperg(al, cl, xl);
std::tr1::conf_hypergl(al, cl, xl);
return;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.7 conf_hyperg
#include <tr1/math.h>
void
test01()
{
float af = 2.0F, cf = 3.0F, xf = 0.5F;
double ad = 2.0, cd = 3.0, xd = 0.5;
long double al = 2.0L, cl = 3.0L, xl = 0.5L;
conf_hyperg(af, cf, xf);
conf_hypergf(af, cf, xf);
conf_hyperg(ad, cd, xd);
conf_hyperg(al, cl, xl);
conf_hypergl(al, cl, xl);
return;
}

View File

@ -0,0 +1,87 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.8 cyl_bessel_i
#include <tr1/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::tr1::cyl_bessel_i(nuf, xf);
float b = std::tr1::cyl_bessel_if(nuf, xf);
double c = std::tr1::cyl_bessel_i(nud, xd);
long double d = std::tr1::cyl_bessel_i(nul, xl);
long double e = std::tr1::cyl_bessel_il(nul, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(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::tr1::cyl_bessel_i(nuf, xf);
float b = std::tr1::cyl_bessel_if(nuf, xf);
double c = std::tr1::cyl_bessel_i(nud, xd);
long double d = std::tr1::cyl_bessel_i(nul, xl);
long double e = std::tr1::cyl_bessel_il(nul, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,629 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.0834140751773158e+18, 0.0000000000000000, 45.000000000000000 },
{ 2.9325537838493463e+20, 0.0000000000000000, 50.000000000000000 },
{ 4.1487895607332160e+22, 0.0000000000000000, 55.000000000000000 },
{ 5.8940770556098216e+24, 0.0000000000000000, 60.000000000000000 },
{ 8.4030398456255610e+26, 0.0000000000000000, 65.000000000000000 },
{ 1.2015889579125422e+29, 0.0000000000000000, 70.000000000000000 },
{ 1.7226390780357971e+31, 0.0000000000000000, 75.000000000000000 },
{ 2.4751784043341670e+33, 0.0000000000000000, 80.000000000000000 },
{ 3.5634776304081418e+35, 0.0000000000000000, 85.000000000000000 },
{ 5.1392383455086475e+37, 0.0000000000000000, 90.000000000000000 },
{ 7.4233258618752096e+39, 0.0000000000000000, 95.000000000000000 },
{ 1.0737517071310986e+42, 0.0000000000000000, 100.00000000000000 },
};
// Test function for nu=0.0000000000000000.
template <typename Tp>
void test001()
{
const 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::tr1::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.63146593655, 0.33333333333333331, 15.000000000000000 },
{ 43434263.927938439, 0.33333333333333331, 20.000000000000000 },
{ 5761474759.6213636, 0.33333333333333331, 25.000000000000000 },
{ 780201111830.30225, 0.33333333333333331, 30.000000000000000 },
{ 107166066959051.92, 0.33333333333333331, 35.000000000000000 },
{ 14873836574083760., 0.33333333333333331, 40.000000000000000 },
{ 2.0808143020217085e+18, 0.33333333333333331, 45.000000000000000 },
{ 2.9292639365644229e+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.1360491295551829e+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()
{
const 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::tr1::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.9251568529912988e+20, 0.50000000000000000, 50.000000000000000 },
{ 4.1392840094781220e+22, 0.50000000000000000, 55.000000000000000 },
{ 5.8817065760751945e+24, 0.50000000000000000, 60.000000000000000 },
{ 8.3867695787277231e+26, 0.50000000000000000, 65.000000000000000 },
{ 1.1994296461653203e+29, 0.50000000000000000, 70.000000000000000 },
{ 1.7197510246063332e+31, 0.50000000000000000, 75.000000000000000 },
{ 2.4712895036230794e+33, 0.50000000000000000, 80.000000000000000 },
{ 3.5582099086757769e+35, 0.50000000000000000, 85.000000000000000 },
{ 5.1320654031231090e+37, 0.50000000000000000, 90.000000000000000 },
{ 7.4135128383495227e+39, 0.50000000000000000, 95.000000000000000 },
{ 1.0724035825423179e+42, 0.50000000000000000, 100.00000000000000 },
};
// Test function for nu=0.50000000000000000.
template <typename Tp>
void test003()
{
const 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::tr1::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.98138574383, 0.66666666666666663, 15.000000000000000 },
{ 43064361.686912313, 0.66666666666666663, 20.000000000000000 },
{ 5722397441.9603882, 0.66666666666666663, 25.000000000000000 },
{ 775804343498.02661, 0.66666666666666663, 30.000000000000000 },
{ 106649495512800.89, 0.66666666666666663, 35.000000000000000 },
{ 14811199896983756., 0.66666666666666663, 40.000000000000000 },
{ 2.0730345814356961e+18, 0.66666666666666663, 45.000000000000000 },
{ 2.9194166755257467e+20, 0.66666666666666663, 50.000000000000000 },
{ 4.1319059569935366e+22, 0.66666666666666663, 55.000000000000000 },
{ 5.8721031476386222e+24, 0.66666666666666663, 60.000000000000000 },
{ 8.3741368248217830e+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.1264933963228864e+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()
{
const 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::tr1::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.385127775, 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.0601334620815775e+18, 1.0000000000000000, 45.000000000000000 },
{ 2.9030785901035635e+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.7111160152965384e+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.3841518091360157e+39, 1.0000000000000000, 95.000000000000000 },
{ 1.0683693903381569e+42, 1.0000000000000000, 100.00000000000000 },
};
// Test function for nu=1.0000000000000000.
template <typename Tp>
void test005()
{
const 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::tr1::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.38370188634, 2.0000000000000000, 15.000000000000000 },
{ 39312785.221040756, 2.0000000000000000, 20.000000000000000 },
{ 5321931396.0760136, 2.0000000000000000, 25.000000000000000 },
{ 730436828561.38013, 2.0000000000000000, 30.000000000000000 },
{ 101293439862977.19, 2.0000000000000000, 35.000000000000000 },
{ 14159404985256920., 2.0000000000000000, 40.000000000000000 },
{ 1.9918525879736883e+18, 2.0000000000000000, 45.000000000000000 },
{ 2.8164306402451938e+20, 2.0000000000000000, 50.000000000000000 },
{ 3.9993023372677515e+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.2678700343145842e+39, 2.0000000000000000, 95.000000000000000 },
{ 1.0523843193243042e+42, 2.0000000000000000, 100.00000000000000 },
};
// Test function for nu=2.0000000000000000.
template <typename Tp>
void test006()
{
const 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::tr1::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.01120063406, 5.0000000000000000, 15.000000000000000 },
{ 23018392.213413671, 5.0000000000000000, 20.000000000000000 },
{ 3472466208.7419176, 5.0000000000000000, 25.000000000000000 },
{ 512151465476.93494, 5.0000000000000000, 30.000000000000000 },
{ 74756743552251.531, 5.0000000000000000, 35.000000000000000 },
{ 10858318337624276., 5.0000000000000000, 40.000000000000000 },
{ 1.5736087399245906e+18, 5.0000000000000000, 45.000000000000000 },
{ 2.2785483079112829e+20, 5.0000000000000000, 50.000000000000000 },
{ 3.2989391052963687e+22, 5.0000000000000000, 55.000000000000000 },
{ 4.7777652072561742e+24, 5.0000000000000000, 60.000000000000000 },
{ 6.9232165147172671e+26, 5.0000000000000000, 65.000000000000000 },
{ 1.0038643002095153e+29, 5.0000000000000000, 70.000000000000000 },
{ 1.4566328222327068e+31, 5.0000000000000000, 75.000000000000000 },
{ 2.1151488565944838e+33, 5.0000000000000000, 80.000000000000000 },
{ 3.0735883450768236e+35, 5.0000000000000000, 85.000000000000000 },
{ 4.4694790189230327e+37, 5.0000000000000000, 90.000000000000000 },
{ 6.5037505570430971e+39, 5.0000000000000000, 95.000000000000000 },
{ 9.4700938730355882e+41, 5.0000000000000000, 100.00000000000000 },
};
// Test function for nu=5.0000000000000000.
template <typename Tp>
void test007()
{
const 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::tr1::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.96713, 10.000000000000000, 30.000000000000000 },
{ 25449470018534.785, 10.000000000000000, 35.000000000000000 },
{ 4228469210516757.5, 10.000000000000000, 40.000000000000000 },
{ 6.8049404557505152e+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.9732791360862186e+35, 10.000000000000000, 85.000000000000000 },
{ 2.9411893748384672e+37, 10.000000000000000, 90.000000000000000 },
{ 4.3754494922439990e+39, 10.000000000000000, 95.000000000000000 },
{ 6.4989755247201446e+41, 10.000000000000000, 100.00000000000000 },
};
// Test function for nu=10.000000000000000.
template <typename Tp>
void test008()
{
const 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::tr1::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.6470152535015834, 20.000000000000000, 15.000000000000000 },
{ 3188.7503288536154, 20.000000000000000, 20.000000000000000 },
{ 2449840.5422952301, 20.000000000000000, 25.000000000000000 },
{ 1126985104.4483771, 20.000000000000000, 30.000000000000000 },
{ 379617876611.88586, 20.000000000000000, 35.000000000000000 },
{ 104459633129479.89, 20.000000000000000, 40.000000000000000 },
{ 25039579987216504., 20.000000000000000, 45.000000000000000 },
{ 5.4420084027529964e+18, 20.000000000000000, 50.000000000000000 },
{ 1.1007498584335492e+21, 20.000000000000000, 55.000000000000000 },
{ 2.1091734863057236e+23, 20.000000000000000, 60.000000000000000 },
{ 3.8763618091286899e+25, 20.000000000000000, 65.000000000000000 },
{ 6.8946130527930859e+27, 20.000000000000000, 70.000000000000000 },
{ 1.1946319948836447e+30, 20.000000000000000, 75.000000000000000 },
{ 2.0265314377577580e+32, 20.000000000000000, 80.000000000000000 },
{ 3.3784665214179971e+34, 20.000000000000000, 85.000000000000000 },
{ 5.5516089411796670e+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()
{
const 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::tr1::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.5344251866130282e-09, 50.000000000000000, 25.000000000000000 },
{ 0.00014590106916468937, 50.000000000000000, 30.000000000000000 },
{ 1.3965549457254878, 50.000000000000000, 35.000000000000000 },
{ 5726.8656631289878, 50.000000000000000, 40.000000000000000 },
{ 12672593.113027776, 50.000000000000000, 45.000000000000000 },
{ 17650802430.016705, 50.000000000000000, 50.000000000000000 },
{ 17220231607789.926, 50.000000000000000, 55.000000000000000 },
{ 12704607933652172., 50.000000000000000, 60.000000000000000 },
{ 7.4989491942193766e+18, 50.000000000000000, 65.000000000000000 },
{ 3.6944034898904901e+21, 50.000000000000000, 70.000000000000000 },
{ 1.5691634774370194e+24, 50.000000000000000, 75.000000000000000 },
{ 5.8927749458163587e+26, 50.000000000000000, 80.000000000000000 },
{ 1.9958849054749339e+29, 50.000000000000000, 85.000000000000000 },
{ 6.1946050361781518e+31, 50.000000000000000, 90.000000000000000 },
{ 1.7845429728697110e+34, 50.000000000000000, 95.000000000000000 },
{ 4.8219580855940813e+36, 50.000000000000000, 100.00000000000000 },
};
// Test function for nu=50.000000000000000.
template <typename Tp>
void test010()
{
const 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::tr1::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.2836596180818801e-33, 100.00000000000000, 35.000000000000000 },
{ 6.6249380222596129e-27, 100.00000000000000, 40.000000000000000 },
{ 2.3702587262788881e-21, 100.00000000000000, 45.000000000000000 },
{ 2.7278879470966907e-16, 100.00000000000000, 50.000000000000000 },
{ 1.2763258878228088e-11, 100.00000000000000, 55.000000000000000 },
{ 2.8832770906491951e-07, 100.00000000000000, 60.000000000000000 },
{ 0.0035805902717061240, 100.00000000000000, 65.000000000000000 },
{ 27.017219102595398, 100.00000000000000, 70.000000000000000 },
{ 134001.44891209516, 100.00000000000000, 75.000000000000000 },
{ 465194832.85061038, 100.00000000000000, 80.000000000000000 },
{ 1189280653119.4819, 100.00000000000000, 85.000000000000000 },
{ 2334119331258731.0, 100.00000000000000, 90.000000000000000 },
{ 3.6399223078502380e+18, 100.00000000000000, 95.000000000000000 },
{ 4.6415349416161989e+21, 100.00000000000000, 100.00000000000000 },
};
// Test function for nu=100.00000000000000.
template <typename Tp>
void test011()
{
const 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::tr1::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(int, char**)
{
test001<double>();
test002<double>();
test003<double>();
test004<double>();
test005<double>();
test006<double>();
test007<double>();
test008<double>();
test009<double>();
test010<double>();
test011<double>();
return 0;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.8 cyl_bessel_i
#include <tr1/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::tr1::cyl_bessel_i(nuf, xf);
std::tr1::cyl_bessel_if(nuf, xf);
std::tr1::cyl_bessel_i(nud, xd);
std::tr1::cyl_bessel_i(nul, xl);
std::tr1::cyl_bessel_il(nul, xl);
return;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.8 cyl_bessel_i
#include <tr1/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;
}

View File

@ -0,0 +1,87 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.9 cyl_bessel_j
#include <tr1/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::tr1::cyl_bessel_j(nuf, xf);
float b = std::tr1::cyl_bessel_jf(nuf, xf);
double c = std::tr1::cyl_bessel_j(nud, xd);
long double d = std::tr1::cyl_bessel_j(nul, xl);
long double e = std::tr1::cyl_bessel_jl(nul, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(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::tr1::cyl_bessel_j(nuf, xf);
float b = std::tr1::cyl_bessel_jf(nuf, xf);
double c = std::tr1::cyl_bessel_j(nud, xd);
long double d = std::tr1::cyl_bessel_j(nul, xl);
long double e = std::tr1::cyl_bessel_jl(nul, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,629 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.24593576445134832, 0.0000000000000000, 10.000000000000000 },
{ -0.014224472826780788, 0.0000000000000000, 15.000000000000000 },
{ 0.16702466434058319, 0.0000000000000000, 20.000000000000000 },
{ 0.096266783275958140, 0.0000000000000000, 25.000000000000000 },
{ -0.086367983581040184, 0.0000000000000000, 30.000000000000000 },
{ -0.12684568275631256, 0.0000000000000000, 35.000000000000000 },
{ 0.0073668905842372914, 0.0000000000000000, 40.000000000000000 },
{ 0.11581867067325630, 0.0000000000000000, 45.000000000000000 },
{ 0.055812327669251746, 0.0000000000000000, 50.000000000000000 },
{ -0.074548302648236808, 0.0000000000000000, 55.000000000000000 },
{ -0.091471804089061873, 0.0000000000000000, 60.000000000000000 },
{ 0.018687343227677920, 0.0000000000000000, 65.000000000000000 },
{ 0.094908726483013517, 0.0000000000000000, 70.000000000000000 },
{ 0.034643913805097029, 0.0000000000000000, 75.000000000000000 },
{ -0.069742165512210061, 0.0000000000000000, 80.000000000000000 },
{ -0.070940394796273301, 0.0000000000000000, 85.000000000000000 },
{ 0.026630016699969568, 0.0000000000000000, 90.000000000000000 },
{ 0.081811967783384149, 0.0000000000000000, 95.000000000000000 },
{ 0.019985850304223264, 0.0000000000000000, 100.00000000000000 },
};
// Test function for nu=0.0000000000000000.
template <typename Tp>
void test001()
{
const 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::tr1::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.18614516704869569, 0.33333333333333331, 10.000000000000000 },
{ 0.089740004221152581, 0.33333333333333331, 15.000000000000000 },
{ 0.17606058001293898, 0.33333333333333331, 20.000000000000000 },
{ 0.020097162141383202, 0.33333333333333331, 25.000000000000000 },
{ -0.13334053387426156, 0.33333333333333331, 30.000000000000000 },
{ -0.087118009397765442, 0.33333333333333331, 35.000000000000000 },
{ 0.069202942818858165, 0.33333333333333331, 40.000000000000000 },
{ 0.11387616964518317, 0.33333333333333331, 45.000000000000000 },
{ -0.00057226680771807741, 0.33333333333333331, 50.000000000000000 },
{ -0.10331600929280821, 0.33333333333333331, 55.000000000000000 },
{ -0.055618147270528023, 0.33333333333333331, 60.000000000000000 },
{ 0.064711954014113920, 0.33333333333333331, 65.000000000000000 },
{ 0.086879926462481619, 0.33333333333333331, 70.000000000000000 },
{ -0.012614484229891070, 0.33333333333333331, 75.000000000000000 },
{ -0.088199784400034537, 0.33333333333333331, 80.000000000000000 },
{ -0.036703611076564557, 0.33333333333333331, 85.000000000000000 },
{ 0.062916286828779533, 0.33333333333333331, 90.000000000000000 },
{ 0.069465244416806071, 0.33333333333333331, 95.000000000000000 },
{ -0.021271244853702295, 0.33333333333333331, 100.00000000000000 },
};
// Test function for nu=0.33333333333333331.
template <typename Tp>
void test002()
{
const 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::tr1::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.13396768882243942, 0.50000000000000000, 15.000000000000000 },
{ 0.16288076385502981, 0.50000000000000000, 20.000000000000000 },
{ -0.021120283599650416, 0.50000000000000000, 25.000000000000000 },
{ -0.14392965337039987, 0.50000000000000000, 30.000000000000000 },
{ -0.057747757589458860, 0.50000000000000000, 35.000000000000000 },
{ 0.094000962389533579, 0.50000000000000000, 40.000000000000000 },
{ 0.10120783324271412, 0.50000000000000000, 45.000000000000000 },
{ -0.029605831888924662, 0.50000000000000000, 50.000000000000000 },
{ -0.10756039213265806, 0.50000000000000000, 55.000000000000000 },
{ -0.031397461182520445, 0.50000000000000000, 60.000000000000000 },
{ 0.081827430775628568, 0.50000000000000000, 65.000000000000000 },
{ 0.073802429539054637, 0.50000000000000000, 70.000000000000000 },
{ -0.035727009681702594, 0.50000000000000000, 75.000000000000000 },
{ -0.088661035811765446, 0.50000000000000000, 80.000000000000000 },
{ -0.015238065106312407, 0.50000000000000000, 85.000000000000000 },
{ 0.075189068550269425, 0.50000000000000000, 90.000000000000000 },
{ 0.055932643481494140, 0.50000000000000000, 95.000000000000000 },
{ -0.040402132716252113, 0.50000000000000000, 100.00000000000000 },
};
// Test function for nu=0.50000000000000000.
template <typename Tp>
void test003()
{
const 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::tr1::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.35712533549168879, 0.66666666666666663, 5.0000000000000000 },
{ -0.080149603304315822, 0.66666666666666663, 10.000000000000000 },
{ 0.16918875175798076, 0.66666666666666663, 15.000000000000000 },
{ 0.13904826122116526, 0.66666666666666663, 20.000000000000000 },
{ -0.060770629698497579, 0.66666666666666663, 25.000000000000000 },
{ -0.14489851974205059, 0.66666666666666663, 30.000000000000000 },
{ -0.024604880159644467, 0.66666666666666663, 35.000000000000000 },
{ 0.11243936464912015, 0.66666666666666663, 40.000000000000000 },
{ 0.081776275512525379, 0.66666666666666663, 45.000000000000000 },
{ -0.056589908749367770, 0.66666666666666663, 50.000000000000000 },
{ -0.10455814523765933, 0.66666666666666663, 55.000000000000000 },
{ -0.0051030148548608109, 0.66666666666666663, 60.000000000000000 },
{ 0.093398227061639250, 0.66666666666666663, 65.000000000000000 },
{ 0.055763883611864899, 0.66666666666666663, 70.000000000000000 },
{ -0.056395322915757343, 0.66666666666666663, 75.000000000000000 },
{ -0.083131347805783087, 0.66666666666666663, 80.000000000000000 },
{ 0.0072315397874096309, 0.66666666666666663, 85.000000000000000 },
{ 0.082362798520905264, 0.66666666666666663, 90.000000000000000 },
{ 0.038630504403446168, 0.66666666666666663, 95.000000000000000 },
{ -0.056778819380529706, 0.66666666666666663, 100.00000000000000 },
};
// Test function for nu=0.66666666666666663.
template <typename Tp>
void test004()
{
const 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::tr1::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.32757913759146523, 1.0000000000000000, 5.0000000000000000 },
{ 0.043472746168861369, 1.0000000000000000, 10.000000000000000 },
{ 0.20510403861352278, 1.0000000000000000, 15.000000000000000 },
{ 0.066833124175850092, 1.0000000000000000, 20.000000000000000 },
{ -0.12535024958028987, 1.0000000000000000, 25.000000000000000 },
{ -0.11875106261662292, 1.0000000000000000, 30.000000000000000 },
{ 0.043990942179625556, 1.0000000000000000, 35.000000000000000 },
{ 0.12603831803758497, 1.0000000000000000, 40.000000000000000 },
{ 0.028348854376424548, 1.0000000000000000, 45.000000000000000 },
{ -0.097511828125175157, 1.0000000000000000, 50.000000000000000 },
{ -0.078250038308684655, 1.0000000000000000, 55.000000000000000 },
{ 0.046598383758166398, 1.0000000000000000, 60.000000000000000 },
{ 0.097330172226126929, 1.0000000000000000, 65.000000000000000 },
{ 0.0099877887848384625, 1.0000000000000000, 70.000000000000000 },
{ -0.085139995044829109, 1.0000000000000000, 75.000000000000000 },
{ -0.056057296675712610, 1.0000000000000000, 80.000000000000000 },
{ 0.049151460334891116, 1.0000000000000000, 85.000000000000000 },
{ 0.079925646708868064, 1.0000000000000000, 90.000000000000000 },
{ -0.0023925612997268684, 1.0000000000000000, 95.000000000000000 },
{ -0.077145352014112142, 1.0000000000000000, 100.00000000000000 },
};
// Test function for nu=1.0000000000000000.
template <typename Tp>
void test005()
{
const 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::tr1::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.25463031368512062, 2.0000000000000000, 10.000000000000000 },
{ 0.041571677975250479, 2.0000000000000000, 15.000000000000000 },
{ -0.16034135192299817, 2.0000000000000000, 20.000000000000000 },
{ -0.10629480324238134, 2.0000000000000000, 25.000000000000000 },
{ 0.078451246073265340, 2.0000000000000000, 30.000000000000000 },
{ 0.12935945088086262, 2.0000000000000000, 35.000000000000000 },
{ -0.0010649746823580893, 2.0000000000000000, 40.000000000000000 },
{ -0.11455872158985966, 2.0000000000000000, 45.000000000000000 },
{ -0.059712800794258801, 2.0000000000000000, 50.000000000000000 },
{ 0.071702846709739212, 2.0000000000000000, 55.000000000000000 },
{ 0.093025083547667448, 2.0000000000000000, 60.000000000000000 },
{ -0.015692568697643280, 2.0000000000000000, 65.000000000000000 },
{ -0.094623361089160987, 2.0000000000000000, 70.000000000000000 },
{ -0.036914313672959186, 2.0000000000000000, 75.000000000000000 },
{ 0.068340733095317227, 2.0000000000000000, 80.000000000000000 },
{ 0.072096899745329499, 2.0000000000000000, 85.000000000000000 },
{ -0.024853891217550262, 2.0000000000000000, 90.000000000000000 },
{ -0.081862337494957346, 2.0000000000000000, 95.000000000000000 },
{ -0.021528757344505392, 2.0000000000000000, 100.00000000000000 },
};
// Test function for nu=2.0000000000000000.
template <typename Tp>
void test006()
{
const 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::tr1::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(1.0000000000000006e-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.23406152818679365, 5.0000000000000000, 10.000000000000000 },
{ 0.13045613456502966, 5.0000000000000000, 15.000000000000000 },
{ 0.15116976798239504, 5.0000000000000000, 20.000000000000000 },
{ -0.066007995398423044, 5.0000000000000000, 25.000000000000000 },
{ -0.14324029551207709, 5.0000000000000000, 30.000000000000000 },
{ -0.0015053072953907080, 5.0000000000000000, 35.000000000000000 },
{ 0.12257346597711774, 5.0000000000000000, 40.000000000000000 },
{ 0.057984499200954144, 5.0000000000000000, 45.000000000000000 },
{ -0.081400247696569658, 5.0000000000000000, 50.000000000000000 },
{ -0.092569895786432710, 5.0000000000000000, 55.000000000000000 },
{ 0.027454744228344184, 5.0000000000000000, 60.000000000000000 },
{ 0.099110527701539039, 5.0000000000000000, 65.000000000000000 },
{ 0.026058129823895274, 5.0000000000000000, 70.000000000000000 },
{ -0.078523977013751398, 5.0000000000000000, 75.000000000000000 },
{ -0.065862349140031654, 5.0000000000000000, 80.000000000000000 },
{ 0.038669072284680923, 5.0000000000000000, 85.000000000000000 },
{ 0.082759319528415129, 5.0000000000000000, 90.000000000000000 },
{ 0.0079423372702472905, 5.0000000000000000, 95.000000000000000 },
{ -0.074195736964513911, 5.0000000000000000, 100.00000000000000 },
};
// Test function for nu=5.0000000000000000.
template <typename Tp>
void test007()
{
const 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::tr1::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.090071811047659045, 10.000000000000000, 15.000000000000000 },
{ 0.18648255802394512, 10.000000000000000, 20.000000000000000 },
{ -0.075179843948523270, 10.000000000000000, 25.000000000000000 },
{ -0.12987689399858882, 10.000000000000000, 30.000000000000000 },
{ 0.063546391343962852, 10.000000000000000, 35.000000000000000 },
{ 0.11938336278226093, 10.000000000000000, 40.000000000000000 },
{ -0.026971402475010734, 10.000000000000000, 45.000000000000000 },
{ -0.11384784914946940, 10.000000000000000, 50.000000000000000 },
{ -0.015773790303746010, 10.000000000000000, 55.000000000000000 },
{ 0.097177143328071106, 10.000000000000000, 60.000000000000000 },
{ 0.054617389951112157, 10.000000000000000, 65.000000000000000 },
{ -0.065870338561951874, 10.000000000000000, 70.000000000000000 },
{ -0.080417867891894437, 10.000000000000000, 75.000000000000000 },
{ 0.024043850978184754, 10.000000000000000, 80.000000000000000 },
{ 0.086824832700067869, 10.000000000000000, 85.000000000000000 },
{ 0.019554748856312278, 10.000000000000000, 90.000000000000000 },
{ -0.072341598669443757, 10.000000000000000, 95.000000000000000 },
{ -0.054732176935472103, 10.000000000000000, 100.00000000000000 },
};
// Test function for nu=10.000000000000000.
template <typename Tp>
void test008()
{
const 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::tr1::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.0073602340792234882, 20.000000000000000, 15.000000000000000 },
{ 0.16474777377532657, 20.000000000000000, 20.000000000000000 },
{ 0.051994049228303287, 20.000000000000000, 25.000000000000000 },
{ 0.0048310199934041105, 20.000000000000000, 30.000000000000000 },
{ -0.10927417397178038, 20.000000000000000, 35.000000000000000 },
{ 0.12779393355084886, 20.000000000000000, 40.000000000000000 },
{ 0.0047633437900312841, 20.000000000000000, 45.000000000000000 },
{ -0.11670435275957974, 20.000000000000000, 50.000000000000000 },
{ 0.025389204574566695, 20.000000000000000, 55.000000000000000 },
{ 0.10266020557876331, 20.000000000000000, 60.000000000000000 },
{ -0.023138582263434168, 20.000000000000000, 65.000000000000000 },
{ -0.096058573489952323, 20.000000000000000, 70.000000000000000 },
{ 0.0068961047221522270, 20.000000000000000, 75.000000000000000 },
{ 0.090565405489918357, 20.000000000000000, 80.000000000000000 },
{ 0.015985497599497155, 20.000000000000000, 85.000000000000000 },
{ -0.080345344044422506, 20.000000000000000, 90.000000000000000 },
{ -0.040253075701614051, 20.000000000000000, 95.000000000000000 },
{ 0.062217458498338679, 20.000000000000000, 100.00000000000000 },
};
// Test function for nu=20.000000000000000.
template <typename Tp>
void test009()
{
const 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::tr1::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.7561594280229727e-12, 50.000000000000000, 25.000000000000000 },
{ 2.0581656631564181e-08, 50.000000000000000, 30.000000000000000 },
{ 7.6069951699272926e-06, 50.000000000000000, 35.000000000000000 },
{ 0.00068185243531768255, 50.000000000000000, 40.000000000000000 },
{ 0.017284343240791228, 50.000000000000000, 45.000000000000000 },
{ 0.12140902189761522, 50.000000000000000, 50.000000000000000 },
{ 0.13594720957176004, 50.000000000000000, 55.000000000000000 },
{ -0.13798273148535209, 50.000000000000000, 60.000000000000000 },
{ 0.12116217746619408, 50.000000000000000, 65.000000000000000 },
{ -0.11394866738787141, 50.000000000000000, 70.000000000000000 },
{ 0.094076799581573417, 50.000000000000000, 75.000000000000000 },
{ -0.039457764590251236, 50.000000000000000, 80.000000000000000 },
{ -0.040412060734136369, 50.000000000000000, 85.000000000000000 },
{ 0.090802099838032252, 50.000000000000000, 90.000000000000000 },
{ -0.055979156267280269, 50.000000000000000, 95.000000000000000 },
{ -0.038698339728525460, 50.000000000000000, 100.00000000000000 },
};
// Test function for nu=50.000000000000000.
template <typename Tp>
void test010()
{
const 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::tr1::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.00015043869999501605, 100.00000000000000, 85.000000000000000 },
{ 0.0026021305819963472, 100.00000000000000, 90.000000000000000 },
{ 0.023150768009428162, 100.00000000000000, 95.000000000000000 },
{ 0.096366673295861571, 100.00000000000000, 100.00000000000000 },
};
// Test function for nu=100.00000000000000.
template <typename Tp>
void test011()
{
const 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::tr1::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(int, char**)
{
test001<double>();
test002<double>();
test003<double>();
test004<double>();
test005<double>();
test006<double>();
test007<double>();
test008<double>();
test009<double>();
test010<double>();
test011<double>();
return 0;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.9 cyl_bessel_j
#include <tr1/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::tr1::cyl_bessel_j(nuf, xf);
std::tr1::cyl_bessel_jf(nuf, xf);
std::tr1::cyl_bessel_j(nud, xd);
std::tr1::cyl_bessel_j(nul, xl);
std::tr1::cyl_bessel_jl(nul, xl);
return;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.9 cyl_bessel_j
#include <tr1/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;
}

View File

@ -0,0 +1,87 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.10 cyl_bessel_k
#include <tr1/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::tr1::cyl_bessel_k(nuf, xf);
float b = std::tr1::cyl_bessel_kf(nuf, xf);
double c = std::tr1::cyl_bessel_k(nud, xd);
long double d = std::tr1::cyl_bessel_k(nul, xl);
long double e = std::tr1::cyl_bessel_kl(nul, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(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::tr1::cyl_bessel_k(nuf, xf);
float b = std::tr1::cyl_bessel_kf(nuf, xf);
double c = std::tr1::cyl_bessel_k(nud, xd);
long double d = std::tr1::cyl_bessel_k(nul, xl);
long double e = std::tr1::cyl_bessel_kl(nul, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,618 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.3334561226187255e-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()
{
const 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::tr1::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.0816880942511496e-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()
{
const 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::tr1::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()
{
const 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::tr1::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.0836820479428609e-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()
{
const 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::tr1::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.3923945937225050e-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()
{
const 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::tr1::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.5731181045619477e-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.6898316402103145e-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()
{
const 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::tr1::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.7541849985312275e-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.0181216822204116e-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()
{
const 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::tr1::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.2605303776606440e-06, 10.000000000000000, 15.000000000000000 },
{ 6.3162145283215787e-09, 10.000000000000000, 20.000000000000000 },
{ 2.4076769602801230e-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.5939871900169603e-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.9606323347034084e-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()
{
const 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::tr1::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.74427820770549, 20.000000000000000, 10.000000000000000 },
{ 0.012141257729731146, 20.000000000000000, 15.000000000000000 },
{ 5.5431116361258155e-06, 20.000000000000000, 20.000000000000000 },
{ 6.3744029330352105e-09, 20.000000000000000, 25.000000000000000 },
{ 1.2304516475442478e-11, 20.000000000000000, 30.000000000000000 },
{ 3.2673136479809012e-14, 20.000000000000000, 35.000000000000000 },
{ 1.0703023799997383e-16, 20.000000000000000, 40.000000000000000 },
{ 4.0549953175660486e-19, 20.000000000000000, 45.000000000000000 },
{ 1.7061483797220352e-21, 20.000000000000000, 50.000000000000000 },
{ 7.7617008115659413e-24, 20.000000000000000, 55.000000000000000 },
{ 3.7482954006874725e-26, 20.000000000000000, 60.000000000000000 },
{ 1.8966880763956578e-28, 20.000000000000000, 65.000000000000000 },
{ 9.9615763479998882e-31, 20.000000000000000, 70.000000000000000 },
{ 5.3921623063091066e-33, 20.000000000000000, 75.000000000000000 },
{ 2.9920407657642272e-35, 20.000000000000000, 80.000000000000000 },
{ 1.6948662723618263e-37, 20.000000000000000, 85.000000000000000 },
{ 9.7689149642963025e-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()
{
const 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::tr1::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.0613737753892579e+27, 50.000000000000000, 10.000000000000000 },
{ 1.7267736974519191e+18, 50.000000000000000, 15.000000000000000 },
{ 411711209122.01794, 50.000000000000000, 20.000000000000000 },
{ 1972478.7419813862, 50.000000000000000, 25.000000000000000 },
{ 58.770686258007267, 50.000000000000000, 30.000000000000000 },
{ 0.0058659391182535195, 50.000000000000000, 35.000000000000000 },
{ 1.3634854128794103e-06, 50.000000000000000, 40.000000000000000 },
{ 5.8652396362160840e-10, 50.000000000000000, 45.000000000000000 },
{ 4.0060134766400903e-13, 50.000000000000000, 50.000000000000000 },
{ 3.9062324485711016e-16, 50.000000000000000, 55.000000000000000 },
{ 5.0389298085176520e-19, 50.000000000000000, 60.000000000000000 },
{ 8.1305344250110396e-22, 50.000000000000000, 65.000000000000000 },
{ 1.5732816234949002e-24, 50.000000000000000, 70.000000000000000 },
{ 3.5349854993874397e-27, 50.000000000000000, 75.000000000000000 },
{ 8.9940101003189485e-30, 50.000000000000000, 80.000000000000000 },
{ 2.5403205503080723e-32, 50.000000000000000, 85.000000000000000 },
{ 7.8397596486715711e-35, 50.000000000000000, 90.000000000000000 },
{ 2.6098900651329550e-37, 50.000000000000000, 95.000000000000000 },
{ 9.2745226536133274e-40, 50.000000000000000, 100.00000000000000 },
};
// Test function for nu=50.000000000000000.
template <typename Tp>
void test010()
{
const 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::tr1::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.0398601930616797e+115, 100.00000000000000, 5.0000000000000000 },
{ 4.5966740842695286e+85, 100.00000000000000, 10.000000000000000 },
{ 8.2565552242653898e+67, 100.00000000000000, 15.000000000000000 },
{ 1.7081356456876038e+55, 100.00000000000000, 20.000000000000000 },
{ 1.9858028128780595e+45, 100.00000000000000, 25.000000000000000 },
{ 1.2131584253026677e+37, 100.00000000000000, 30.000000000000000 },
{ 1.1016916354696684e+30, 100.00000000000000, 35.000000000000000 },
{ 7.0074023297775712e+23, 100.00000000000000, 40.000000000000000 },
{ 1.9236643958470909e+18, 100.00000000000000, 45.000000000000000 },
{ 16394035276269.254, 100.00000000000000, 50.000000000000000 },
{ 343254952.89495456, 100.00000000000000, 55.000000000000000 },
{ 14870.012754946305, 100.00000000000000, 60.000000000000000 },
{ 1.1708099078572209, 100.00000000000000, 65.000000000000000 },
{ 0.00015161193930722305, 100.00000000000000, 70.000000000000000 },
{ 2.9850234381623436e-08, 100.00000000000000, 75.000000000000000 },
{ 8.3928710724649065e-12, 100.00000000000000, 80.000000000000000 },
{ 3.2033435630927728e-15, 100.00000000000000, 85.000000000000000 },
{ 1.5922281431788077e-18, 100.00000000000000, 90.000000000000000 },
{ 9.9589454577674300e-22, 100.00000000000000, 95.000000000000000 },
{ 7.6171296304940858e-25, 100.00000000000000, 100.00000000000000 },
};
// Test function for nu=100.00000000000000.
template <typename Tp>
void test011()
{
const 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::tr1::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(5.0000000000000039e-13));
}
int main(int, char**)
{
test001<double>();
test002<double>();
test003<double>();
test004<double>();
test005<double>();
test006<double>();
test007<double>();
test008<double>();
test009<double>();
test010<double>();
test011<double>();
return 0;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.10 cyl_bessel_k
#include <tr1/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::tr1::cyl_bessel_k(nuf, xf);
std::tr1::cyl_bessel_kf(nuf, xf);
std::tr1::cyl_bessel_k(nud, xd);
std::tr1::cyl_bessel_k(nul, xl);
std::tr1::cyl_bessel_kl(nul, xl);
return;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.10 cyl_bessel_k
#include <tr1/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;
}

View File

@ -0,0 +1,87 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.11 cyl_neumann
#include <tr1/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::tr1::cyl_neumann(nuf, xf);
float b = std::tr1::cyl_neumannf(nuf, xf);
double c = std::tr1::cyl_neumann(nud, xd);
long double d = std::tr1::cyl_neumann(nul, xl);
long double e = std::tr1::cyl_neumannl(nul, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(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::tr1::cyl_neumann(nuf, xf);
float b = std::tr1::cyl_neumannf(nuf, xf);
double c = std::tr1::cyl_neumann(nud, xd);
long double d = std::tr1::cyl_neumann(nul, xl);
long double e = std::tr1::cyl_neumannl(nul, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,618 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.30851762524903376, 0.0000000000000000, 5.0000000000000000 },
{ 0.055671167283599395, 0.0000000000000000, 10.000000000000000 },
{ 0.20546429603891825, 0.0000000000000000, 15.000000000000000 },
{ 0.062640596809383955, 0.0000000000000000, 20.000000000000000 },
{ -0.12724943226800620, 0.0000000000000000, 25.000000000000000 },
{ -0.11729573168666411, 0.0000000000000000, 30.000000000000000 },
{ 0.045797987195155640, 0.0000000000000000, 35.000000000000000 },
{ 0.12593641705826095, 0.0000000000000000, 40.000000000000000 },
{ 0.027060469763313322, 0.0000000000000000, 45.000000000000000 },
{ -0.098064995470077104, 0.0000000000000000, 50.000000000000000 },
{ -0.077569178730412622, 0.0000000000000000, 55.000000000000000 },
{ 0.047358952209449412, 0.0000000000000000, 60.000000000000000 },
{ 0.097183557740181933, 0.0000000000000000, 65.000000000000000 },
{ 0.0093096664589410131, 0.0000000000000000, 70.000000000000000 },
{ -0.085369047647775642, 0.0000000000000000, 75.000000000000000 },
{ -0.055620339089769981, 0.0000000000000000, 80.000000000000000 },
{ 0.049567884951494258, 0.0000000000000000, 85.000000000000000 },
{ 0.079776475854877765, 0.0000000000000000, 90.000000000000000 },
{ -0.0028230995861232323, 0.0000000000000000, 95.000000000000000 },
{ -0.077244313365083112, 0.0000000000000000, 100.00000000000000 },
};
// Test function for nu=0.0000000000000000.
template <typename Tp>
void test001()
{
const 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::tr1::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.18192321129343830, 0.33333333333333331, 5.0000000000000000 },
{ 0.17020111788268769, 0.33333333333333331, 10.000000000000000 },
{ 0.18540507541540799, 0.33333333333333331, 15.000000000000000 },
{ -0.028777707635715091, 0.33333333333333331, 20.000000000000000 },
{ -0.15829741864944166, 0.33333333333333331, 25.000000000000000 },
{ -0.058645772316705216, 0.33333333333333331, 30.000000000000000 },
{ 0.10294930308870620, 0.33333333333333331, 35.000000000000000 },
{ 0.10547870367098920, 0.33333333333333331, 40.000000000000000 },
{ -0.034334228816010864, 0.33333333333333331, 45.000000000000000 },
{ -0.11283489933031278, 0.33333333333333331, 50.000000000000000 },
{ -0.030007358986895123, 0.33333333333333331, 55.000000000000000 },
{ 0.086699173295718093, 0.33333333333333331, 60.000000000000000 },
{ 0.074875579668878672, 0.33333333333333331, 65.000000000000000 },
{ -0.039323246374552645, 0.33333333333333331, 70.000000000000000 },
{ -0.091263539574475222, 0.33333333333333331, 75.000000000000000 },
{ -0.013358849535984282, 0.33333333333333331, 80.000000000000000 },
{ 0.078373575537830184, 0.33333333333333331, 85.000000000000000 },
{ 0.055812482883955974, 0.33333333333333331, 90.000000000000000 },
{ -0.043310380106990579, 0.33333333333333331, 95.000000000000000 },
{ -0.076900504962136587, 0.33333333333333331, 100.00000000000000 },
};
// Test function for nu=0.33333333333333331.
template <typename Tp>
void test002()
{
const 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::tr1::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.10121770918510843, 0.50000000000000000, 5.0000000000000000 },
{ 0.21170886633139813, 0.50000000000000000, 10.000000000000000 },
{ 0.15650551590730860, 0.50000000000000000, 15.000000000000000 },
{ -0.072806904785061841, 0.50000000000000000, 20.000000000000000 },
{ -0.15817308404205055, 0.50000000000000000, 25.000000000000000 },
{ -0.022470290598831121, 0.50000000000000000, 30.000000000000000 },
{ 0.12187835265849536, 0.50000000000000000, 35.000000000000000 },
{ 0.084138655676395432, 0.50000000000000000, 40.000000000000000 },
{ -0.062482641933003132, 0.50000000000000000, 45.000000000000000 },
{ -0.10888475635053953, 0.50000000000000000, 50.000000000000000 },
{ -0.0023805454010948804, 0.50000000000000000, 55.000000000000000 },
{ 0.098104683735037904, 0.50000000000000000, 60.000000000000000 },
{ 0.055663470218594434, 0.50000000000000000, 65.000000000000000 },
{ -0.060396767883824809, 0.50000000000000000, 70.000000000000000 },
{ -0.084922578922046868, 0.50000000000000000, 75.000000000000000 },
{ 0.0098472271924441215, 0.50000000000000000, 80.000000000000000 },
{ 0.085190643574343639, 0.50000000000000000, 85.000000000000000 },
{ 0.037684970437156261, 0.50000000000000000, 90.000000000000000 },
{ -0.059772904856097479, 0.50000000000000000, 95.000000000000000 },
{ -0.068803091468728053, 0.50000000000000000, 100.00000000000000 },
};
// Test function for nu=0.50000000000000000.
template <typename Tp>
void test003()
{
const 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::tr1::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.016050662643389616, 0.66666666666666663, 5.0000000000000000 },
{ 0.23937232657540730, 0.66666666666666663, 10.000000000000000 },
{ 0.11762106604241242, 0.66666666666666663, 15.000000000000000 },
{ -0.11182254014899563, 0.66666666666666663, 20.000000000000000 },
{ -0.14756582982938804, 0.66666666666666663, 25.000000000000000 },
{ 0.015078692908077665, 0.66666666666666663, 30.000000000000000 },
{ 0.13260911815705798, 0.66666666666666663, 35.000000000000000 },
{ 0.057217565989652795, 0.66666666666666663, 40.000000000000000 },
{ -0.086373755152382048, 0.66666666666666663, 45.000000000000000 },
{ -0.097624139208051630, 0.66666666666666663, 50.000000000000000 },
{ 0.025354902147023434, 0.66666666666666663, 55.000000000000000 },
{ 0.10288136476351209, 0.66666666666666663, 60.000000000000000 },
{ 0.032728379560128203, 0.66666666666666663, 65.000000000000000 },
{ -0.077363672735747777, 0.66666666666666663, 70.000000000000000 },
{ -0.072855870458293975, 0.66666666666666663, 75.000000000000000 },
{ 0.032358106046953494, 0.66666666666666663, 80.000000000000000 },
{ 0.086240651537394228, 0.66666666666666663, 85.000000000000000 },
{ 0.017029601697285159, 0.66666666666666663, 90.000000000000000 },
{ -0.072173520560584709, 0.66666666666666663, 95.000000000000000 },
{ -0.056057339204073985, 0.66666666666666663, 100.00000000000000 },
};
// Test function for nu=0.66666666666666663.
template <typename Tp>
void test004()
{
const 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::tr1::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.14786314339122689, 1.0000000000000000, 5.0000000000000000 },
{ 0.24901542420695388, 1.0000000000000000, 10.000000000000000 },
{ 0.021073628036873546, 1.0000000000000000, 15.000000000000000 },
{ -0.16551161436252118, 1.0000000000000000, 20.000000000000000 },
{ -0.098829964783237384, 1.0000000000000000, 25.000000000000000 },
{ 0.084425570661747149, 1.0000000000000000, 30.000000000000000 },
{ 0.12751273354559012, 1.0000000000000000, 35.000000000000000 },
{ -0.0057935058215496330, 1.0000000000000000, 40.000000000000000 },
{ -0.11552517964639945, 1.0000000000000000, 45.000000000000000 },
{ -0.056795668562014713, 1.0000000000000000, 50.000000000000000 },
{ 0.073846265432577940, 1.0000000000000000, 55.000000000000000 },
{ 0.091869609369866906, 1.0000000000000000, 60.000000000000000 },
{ -0.017940374275377303, 1.0000000000000000, 65.000000000000000 },
{ -0.094844652625716244, 1.0000000000000000, 70.000000000000000 },
{ -0.035213785160580456, 1.0000000000000000, 75.000000000000000 },
{ 0.069395913784588051, 1.0000000000000000, 80.000000000000000 },
{ 0.071233187582749782, 1.0000000000000000, 85.000000000000000 },
{ -0.026187238607768282, 1.0000000000000000, 90.000000000000000 },
{ -0.081827958724501229, 1.0000000000000000, 95.000000000000000 },
{ -0.020372312002759942, 1.0000000000000000, 100.00000000000000 },
};
// Test function for nu=1.0000000000000000.
template <typename Tp>
void test005()
{
const 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::tr1::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.36766288260552449, 2.0000000000000000, 5.0000000000000000 },
{ -0.0058680824422086154, 2.0000000000000000, 10.000000000000000 },
{ -0.20265447896733510, 2.0000000000000000, 15.000000000000000 },
{ -0.079191758245636068, 2.0000000000000000, 20.000000000000000 },
{ 0.11934303508534720, 2.0000000000000000, 25.000000000000000 },
{ 0.12292410306411393, 2.0000000000000000, 30.000000000000000 },
{ -0.038511545278264774, 2.0000000000000000, 35.000000000000000 },
{ -0.12622609234933843, 2.0000000000000000, 40.000000000000000 },
{ -0.032194922192042189, 2.0000000000000000, 45.000000000000000 },
{ 0.095793168727596509, 2.0000000000000000, 50.000000000000000 },
{ 0.080254497473415454, 2.0000000000000000, 55.000000000000000 },
{ -0.044296631897120513, 2.0000000000000000, 60.000000000000000 },
{ -0.097735569256347382, 2.0000000000000000, 65.000000000000000 },
{ -0.012019513676818619, 2.0000000000000000, 70.000000000000000 },
{ 0.084430013376826832, 2.0000000000000000, 75.000000000000000 },
{ 0.057355236934384685, 2.0000000000000000, 80.000000000000000 },
{ -0.047891809949547205, 2.0000000000000000, 85.000000000000000 },
{ -0.080358414490605948, 2.0000000000000000, 90.000000000000000 },
{ 0.0011004057182389959, 2.0000000000000000, 95.000000000000000 },
{ 0.076836867125027908, 2.0000000000000000, 100.00000000000000 },
};
// Test function for nu=2.0000000000000000.
template <typename Tp>
void test006()
{
const 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::tr1::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.45369482249110188, 5.0000000000000000, 5.0000000000000000 },
{ 0.13540304768936232, 5.0000000000000000, 10.000000000000000 },
{ 0.16717271575940021, 5.0000000000000000, 15.000000000000000 },
{ -0.10003576788953225, 5.0000000000000000, 20.000000000000000 },
{ -0.14705799311372267, 5.0000000000000000, 25.000000000000000 },
{ 0.031627359289264322, 5.0000000000000000, 30.000000000000000 },
{ 0.13554781474770031, 5.0000000000000000, 35.000000000000000 },
{ 0.031869448780850372, 5.0000000000000000, 40.000000000000000 },
{ -0.10426932700176872, 5.0000000000000000, 45.000000000000000 },
{ -0.078548413913081608, 5.0000000000000000, 50.000000000000000 },
{ 0.055257033062858382, 5.0000000000000000, 55.000000000000000 },
{ 0.099464632840450901, 5.0000000000000000, 60.000000000000000 },
{ 0.00023860469499600970, 5.0000000000000000, 65.000000000000000 },
{ -0.091861802216406066, 5.0000000000000000, 70.000000000000000 },
{ -0.048383671296970077, 5.0000000000000000, 75.000000000000000 },
{ 0.060293667104896330, 5.0000000000000000, 80.000000000000000 },
{ 0.077506166682734010, 5.0000000000000000, 85.000000000000000 },
{ -0.015338764062239803, 5.0000000000000000, 90.000000000000000 },
{ -0.081531504045514375, 5.0000000000000000, 95.000000000000000 },
{ -0.029480196281662041, 5.0000000000000000, 100.00000000000000 },
};
// Test function for nu=5.0000000000000000.
template <typename Tp>
void test007()
{
const 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::tr1::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.129110095610098, 10.000000000000000, 5.0000000000000000 },
{ -0.35981415218340279, 10.000000000000000, 10.000000000000000 },
{ 0.21997141360195582, 10.000000000000000, 15.000000000000000 },
{ -0.043894653515658202, 10.000000000000000, 20.000000000000000 },
{ -0.14871839049980651, 10.000000000000000, 25.000000000000000 },
{ 0.075056702122397012, 10.000000000000000, 30.000000000000000 },
{ 0.12222473135000553, 10.000000000000000, 35.000000000000000 },
{ -0.046723877232677867, 10.000000000000000, 40.000000000000000 },
{ -0.11739339009322178, 10.000000000000000, 45.000000000000000 },
{ 0.0057238971820535740, 10.000000000000000, 50.000000000000000 },
{ 0.10733910125831635, 10.000000000000000, 55.000000000000000 },
{ 0.036290350559545506, 10.000000000000000, 60.000000000000000 },
{ -0.083239127691715639, 10.000000000000000, 65.000000000000000 },
{ -0.069639384138314872, 10.000000000000000, 70.000000000000000 },
{ 0.045798335061325038, 10.000000000000000, 75.000000000000000 },
{ 0.086269195064844428, 10.000000000000000, 80.000000000000000 },
{ -0.0018234674126248629, 10.000000000000000, 85.000000000000000 },
{ -0.082067762371231298, 10.000000000000000, 90.000000000000000 },
{ -0.038798074754578075, 10.000000000000000, 95.000000000000000 },
{ 0.058331574236414815, 10.000000000000000, 100.00000000000000 },
};
// Test function for nu=10.000000000000000.
template <typename Tp>
void test008()
{
const 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::tr1::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.69143212, 20.000000000000000, 5.0000000000000000 },
{ -1597.4838482696264, 20.000000000000000, 10.000000000000000 },
{ -3.3087330924737630, 20.000000000000000, 15.000000000000000 },
{ -0.28548945860020319, 20.000000000000000, 20.000000000000000 },
{ 0.19804074776289243, 20.000000000000000, 25.000000000000000 },
{ -0.16848153948742675, 20.000000000000000, 30.000000000000000 },
{ 0.10102784152594022, 20.000000000000000, 35.000000000000000 },
{ 0.045161820565805928, 20.000000000000000, 40.000000000000000 },
{ -0.12556489308015448, 20.000000000000000, 45.000000000000000 },
{ 0.016442633948115841, 20.000000000000000, 50.000000000000000 },
{ 0.10853448778255187, 20.000000000000000, 55.000000000000000 },
{ -0.026721408520664677, 20.000000000000000, 60.000000000000000 },
{ -0.098780425256324203, 20.000000000000000, 65.000000000000000 },
{ 0.016201957786018205, 20.000000000000000, 70.000000000000000 },
{ 0.093591198265063735, 20.000000000000000, 75.000000000000000 },
{ 0.0040484400737295740, 20.000000000000000, 80.000000000000000 },
{ -0.086314929459920503, 20.000000000000000, 85.000000000000000 },
{ -0.028274110097231495, 20.000000000000000, 90.000000000000000 },
{ 0.072349520791638755, 20.000000000000000, 95.000000000000000 },
{ 0.051247973076188565, 20.000000000000000, 100.00000000000000 },
};
// Test function for nu=20.000000000000000.
template <typename Tp>
void test009()
{
const 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::tr1::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.7888370175838943e+42, 50.000000000000000, 5.0000000000000000 },
{ -3.6410665018007421e+27, 50.000000000000000, 10.000000000000000 },
{ -1.0929732912175405e+19, 50.000000000000000, 15.000000000000000 },
{ -15606426801663.732, 50.000000000000000, 20.000000000000000 },
{ -753573251.44662631, 50.000000000000000, 25.000000000000000 },
{ -386759.32602734747, 50.000000000000000, 30.000000000000000 },
{ -1172.8690492895341, 50.000000000000000, 35.000000000000000 },
{ -15.615608873419953, 50.000000000000000, 40.000000000000000 },
{ -0.87058346204176951, 50.000000000000000, 45.000000000000000 },
{ -0.21031655464397736, 50.000000000000000, 50.000000000000000 },
{ 0.093048240412999375, 50.000000000000000, 55.000000000000000 },
{ 0.0086417699626745066, 50.000000000000000, 60.000000000000000 },
{ -0.025019788459221974, 50.000000000000000, 65.000000000000000 },
{ -0.0014815155191908913, 50.000000000000000, 70.000000000000000 },
{ 0.050335774732164155, 50.000000000000000, 75.000000000000000 },
{ -0.092924250967987204, 50.000000000000000, 80.000000000000000 },
{ 0.087332463030205670, 50.000000000000000, 85.000000000000000 },
{ -0.016164237701651891, 50.000000000000000, 90.000000000000000 },
{ -0.068897613820457920, 50.000000000000000, 95.000000000000000 },
{ 0.076505263944802962, 50.000000000000000, 100.00000000000000 },
};
// Test function for nu=50.000000000000000.
template <typename Tp>
void test010()
{
const 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::tr1::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.8491482711800245e+85, 100.00000000000000, 10.000000000000000 },
{ -1.6375955323195320e+68, 100.00000000000000, 15.000000000000000 },
{ -8.2002648144679137e+55, 100.00000000000000, 20.000000000000000 },
{ -2.9712216432562373e+46, 100.00000000000000, 25.000000000000000 },
{ -7.2875284708240766e+38, 100.00000000000000, 30.000000000000000 },
{ -3.4251079902108953e+32, 100.00000000000000, 35.000000000000000 },
{ -1.4552439438101799e+27, 100.00000000000000, 40.000000000000000 },
{ -3.4506612476220073e+22, 100.00000000000000, 45.000000000000000 },
{ -3.2938001882025948e+18, 100.00000000000000, 50.000000000000000 },
{ -1005686182055527.4, 100.00000000000000, 55.000000000000000 },
{ -831892881402.11377, 100.00000000000000, 60.000000000000000 },
{ -1650863778.0598330, 100.00000000000000, 65.000000000000000 },
{ -7192614.1976097804, 100.00000000000000, 70.000000000000000 },
{ -64639.072261231602, 100.00000000000000, 75.000000000000000 },
{ -1152.5905185698464, 100.00000000000000, 80.000000000000000 },
{ -40.250761402102000, 100.00000000000000, 85.000000000000000 },
{ -2.8307771387185459, 100.00000000000000, 90.000000000000000 },
{ -0.45762200495904559, 100.00000000000000, 95.000000000000000 },
{ -0.16692141141757649, 100.00000000000000, 100.00000000000000 },
};
// Test function for nu=100.00000000000000.
template <typename Tp>
void test011()
{
const 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::tr1::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(int, char**)
{
test001<double>();
test002<double>();
test003<double>();
test004<double>();
test005<double>();
test006<double>();
test007<double>();
test008<double>();
test009<double>();
test010<double>();
test011<double>();
return 0;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.11 cyl_neumann
#include <tr1/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::tr1::cyl_neumann(nuf, xf);
std::tr1::cyl_neumannf(nuf, xf);
std::tr1::cyl_neumann(nud, xd);
std::tr1::cyl_neumann(nul, xl);
std::tr1::cyl_neumannl(nul, xl);
return;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.11 cyl_neumann
#include <tr1/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;
}

View File

@ -0,0 +1,87 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.12 ellint_1
#include <tr1/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::tr1::ellint_1(kf, phif);
float b = std::tr1::ellint_1f(kf, phif);
double c = std::tr1::ellint_1(kd, phid);
long double d = std::tr1::ellint_1(kl, phil);
long double e = std::tr1::ellint_1l(kl, phil);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(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::tr1::ellint_1(kf, phif);
float b = std::tr1::ellint_1f(kf, phif);
double c = std::tr1::ellint_1(kd, phid);
long double d = std::tr1::ellint_1(kl, phil);
long double e = std::tr1::ellint_1l(kl, phil);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,844 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.17525427376115027, -0.90000000000000002, 0.17453292519943295 },
{ 0.35492464591297446, -0.90000000000000002, 0.34906585039886590 },
{ 0.54388221416157134, -0.90000000000000002, 0.52359877559829882 },
{ 0.74797400423532523, -0.90000000000000002, 0.69813170079773179 },
{ 0.97463898451966458, -0.90000000000000002, 0.87266462599716477 },
{ 1.2334463254523440, -0.90000000000000002, 1.0471975511965976 },
{ 1.5355247765594910, -0.90000000000000002, 1.2217304763960306 },
{ 1.8882928567775124, -0.90000000000000002, 1.3962634015954636 },
{ 2.2805491384227703, -0.90000000000000002, 1.5707963267948966 },
};
// Test function for k=-0.90000000000000002.
template <typename Tp>
void test001()
{
const 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::tr1::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.17510154241338902, -0.80000000000000004, 0.17453292519943295 },
{ 0.35365068839779390, -0.80000000000000004, 0.34906585039886590 },
{ 0.53926804409084561, -0.80000000000000004, 0.52359877559829882 },
{ 0.73587926028070383, -0.80000000000000004, 0.69813170079773179 },
{ 0.94770942970071170, -0.80000000000000004, 0.87266462599716477 },
{ 1.1789022995388239, -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()
{
const 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::tr1::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.17496737466916720, -0.69999999999999996, 0.17453292519943295 },
{ 0.35254687535677925, -0.69999999999999996, 0.34906585039886590 },
{ 0.53536740275997130, -0.69999999999999996, 0.52359877559829882 },
{ 0.72603797651684465, -0.69999999999999996, 0.69813170079773179 },
{ 0.92698296348313458, -0.69999999999999996, 0.87266462599716477 },
{ 1.1400447527693316, -0.69999999999999996, 1.0471975511965976 },
{ 1.3657668117194071, -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()
{
const 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::tr1::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.17485154362988362, -0.59999999999999998, 0.17453292519943295 },
{ 0.35160509865544326, -0.59999999999999998, 0.34906585039886590 },
{ 0.53210652578446160, -0.59999999999999998, 0.52359877559829882 },
{ 0.71805304664485670, -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()
{
const 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::tr1::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.52942862705190585, -0.50000000000000000, 0.52359877559829882 },
{ 0.71164727562630326, -0.50000000000000000, 0.69813170079773179 },
{ 0.89824523594227768, -0.50000000000000000, 0.87266462599716477 },
{ 1.0895506700518851, -0.50000000000000000, 1.0471975511965976 },
{ 1.2853005857432933, -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()
{
const 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::tr1::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.17467414669441531, -0.40000000000000002, 0.17453292519943295 },
{ 0.35018222772483443, -0.40000000000000002, 0.34906585039886590 },
{ 0.52729015917508748, -0.40000000000000002, 0.52359877559829882 },
{ 0.70662374407341255, -0.40000000000000002, 0.69813170079773179 },
{ 0.88859210497602170, -0.40000000000000002, 0.87266462599716477 },
{ 1.0733136290471379, -0.40000000000000002, 1.0471975511965976 },
{ 1.2605612170157061, -0.40000000000000002, 1.2217304763960306 },
{ 1.4497513956433437, -0.40000000000000002, 1.3962634015954636 },
{ 1.6399998658645112, -0.40000000000000002, 1.5707963267948966 },
};
// Test function for k=-0.40000000000000002.
template <typename Tp>
void test006()
{
const 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::tr1::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.17461228653000102, -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.0614897067260523, -0.30000000000000004, 1.0471975511965976 },
{ 1.2428416824174218, -0.30000000000000004, 1.2217304763960306 },
{ 1.4251795877015925, -0.30000000000000004, 1.3962634015954636 },
{ 1.6080486199305126, -0.30000000000000004, 1.5707963267948966 },
};
// Test function for k=-0.30000000000000004.
template <typename Tp>
void test007()
{
const 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::tr1::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.17456817290292811, -0.19999999999999996, 0.17453292519943295 },
{ 0.34934315932086801, -0.19999999999999996, 0.34906585039886590 },
{ 0.52450880529443988, -0.19999999999999996, 0.52359877559829882 },
{ 0.70020491009844910, -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.5868678474541664, -0.19999999999999996, 1.5707963267948966 },
};
// Test function for k=-0.19999999999999996.
template <typename Tp>
void test008()
{
const 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::tr1::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.17454173353063665, -0.099999999999999978, 0.17453292519943295 },
{ 0.34913506721468085, -0.099999999999999978, 0.34906585039886590 },
{ 0.52382550016538953, -0.099999999999999978, 0.52359877559829882 },
{ 0.69864700854177031, -0.099999999999999978, 0.69813170079773179 },
{ 0.87361792586964870, -0.099999999999999978, 0.87266462599716477 },
{ 1.0487386319621685, -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()
{
const 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::tr1::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.17453292519943295, 0.0000000000000000, 0.17453292519943295 },
{ 0.34906585039886584, 0.0000000000000000, 0.34906585039886590 },
{ 0.52359877559829882, 0.0000000000000000, 0.52359877559829882 },
{ 0.69813170079773179, 0.0000000000000000, 0.69813170079773179 },
{ 0.87266462599716477, 0.0000000000000000, 0.87266462599716477 },
{ 1.0471975511965976, 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()
{
const 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::tr1::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.17454173353063665, 0.10000000000000009, 0.17453292519943295 },
{ 0.34913506721468085, 0.10000000000000009, 0.34906585039886590 },
{ 0.52382550016538953, 0.10000000000000009, 0.52359877559829882 },
{ 0.69864700854177031, 0.10000000000000009, 0.69813170079773179 },
{ 0.87361792586964870, 0.10000000000000009, 0.87266462599716477 },
{ 1.0487386319621685, 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()
{
const 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::tr1::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.17456817290292811, 0.19999999999999996, 0.17453292519943295 },
{ 0.34934315932086801, 0.19999999999999996, 0.34906585039886590 },
{ 0.52450880529443988, 0.19999999999999996, 0.52359877559829882 },
{ 0.70020491009844910, 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.5868678474541664, 0.19999999999999996, 1.5707963267948966 },
};
// Test function for k=0.19999999999999996.
template <typename Tp>
void test012()
{
const 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::tr1::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.17461228653000102, 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.0614897067260523, 0.30000000000000004, 1.0471975511965976 },
{ 1.2428416824174218, 0.30000000000000004, 1.2217304763960306 },
{ 1.4251795877015925, 0.30000000000000004, 1.3962634015954636 },
{ 1.6080486199305126, 0.30000000000000004, 1.5707963267948966 },
};
// Test function for k=0.30000000000000004.
template <typename Tp>
void test013()
{
const 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::tr1::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.17467414669441531, 0.39999999999999991, 0.17453292519943295 },
{ 0.35018222772483443, 0.39999999999999991, 0.34906585039886590 },
{ 0.52729015917508748, 0.39999999999999991, 0.52359877559829882 },
{ 0.70662374407341255, 0.39999999999999991, 0.69813170079773179 },
{ 0.88859210497602170, 0.39999999999999991, 0.87266462599716477 },
{ 1.0733136290471379, 0.39999999999999991, 1.0471975511965976 },
{ 1.2605612170157061, 0.39999999999999991, 1.2217304763960306 },
{ 1.4497513956433437, 0.39999999999999991, 1.3962634015954636 },
{ 1.6399998658645112, 0.39999999999999991, 1.5707963267948966 },
};
// Test function for k=0.39999999999999991.
template <typename Tp>
void test014()
{
const 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::tr1::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.52942862705190585, 0.50000000000000000, 0.52359877559829882 },
{ 0.71164727562630326, 0.50000000000000000, 0.69813170079773179 },
{ 0.89824523594227768, 0.50000000000000000, 0.87266462599716477 },
{ 1.0895506700518851, 0.50000000000000000, 1.0471975511965976 },
{ 1.2853005857432933, 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()
{
const 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::tr1::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.17485154362988362, 0.60000000000000009, 0.17453292519943295 },
{ 0.35160509865544326, 0.60000000000000009, 0.34906585039886590 },
{ 0.53210652578446160, 0.60000000000000009, 0.52359877559829882 },
{ 0.71805304664485670, 0.60000000000000009, 0.69813170079773179 },
{ 0.91082759030195970, 0.60000000000000009, 0.87266462599716477 },
{ 1.1112333229323366, 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()
{
const 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::tr1::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.17496737466916720, 0.69999999999999996, 0.17453292519943295 },
{ 0.35254687535677925, 0.69999999999999996, 0.34906585039886590 },
{ 0.53536740275997130, 0.69999999999999996, 0.52359877559829882 },
{ 0.72603797651684465, 0.69999999999999996, 0.69813170079773179 },
{ 0.92698296348313458, 0.69999999999999996, 0.87266462599716477 },
{ 1.1400447527693316, 0.69999999999999996, 1.0471975511965976 },
{ 1.3657668117194071, 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()
{
const 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::tr1::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.17510154241338902, 0.80000000000000004, 0.17453292519943295 },
{ 0.35365068839779390, 0.80000000000000004, 0.34906585039886590 },
{ 0.53926804409084561, 0.80000000000000004, 0.52359877559829882 },
{ 0.73587926028070383, 0.80000000000000004, 0.69813170079773179 },
{ 0.94770942970071170, 0.80000000000000004, 0.87266462599716477 },
{ 1.1789022995388239, 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()
{
const 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::tr1::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.17525427376115027, 0.89999999999999991, 0.17453292519943295 },
{ 0.35492464591297446, 0.89999999999999991, 0.34906585039886590 },
{ 0.54388221416157123, 0.89999999999999991, 0.52359877559829882 },
{ 0.74797400423532501, 0.89999999999999991, 0.69813170079773179 },
{ 0.97463898451966458, 0.89999999999999991, 0.87266462599716477 },
{ 1.2334463254523438, 0.89999999999999991, 1.0471975511965976 },
{ 1.5355247765594910, 0.89999999999999991, 1.2217304763960306 },
{ 1.8882928567775117, 0.89999999999999991, 1.3962634015954636 },
{ 2.2805491384227699, 0.89999999999999991, 1.5707963267948966 },
};
// Test function for k=0.89999999999999991.
template <typename Tp>
void test019()
{
const 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::tr1::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(int, char**)
{
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;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.12 ellint_1
#include <tr1/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::tr1::ellint_1(kf, phif);
std::tr1::ellint_1f(kf, phif);
std::tr1::ellint_1(kd, phid);
std::tr1::ellint_1(kl, phil);
std::tr1::ellint_1l(kl, phil);
return;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.12 ellint_1
#include <tr1/math.h>
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);
ellint_1(kf, phif);
ellint_1f(kf, phif);
ellint_1(kd, phid);
ellint_1(kl, phil);
ellint_1l(kl, phil);
return;
}

View File

@ -0,0 +1,87 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.13 ellint_2
#include <tr1/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::tr1::ellint_2(kf, phif);
float b = std::tr1::ellint_2f(kf, phif);
double c = std::tr1::ellint_2(kd, phid);
long double d = std::tr1::ellint_2(kl, phil);
long double e = std::tr1::ellint_2l(kl, phil);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(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::tr1::ellint_2(kf, phif);
float b = std::tr1::ellint_2f(kf, phif);
double c = std::tr1::ellint_2(kd, phid);
long double d = std::tr1::ellint_2(kl, phil);
long double e = std::tr1::ellint_2l(kl, phil);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
return 0;
}

View File

@ -0,0 +1,844 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.17381690606167963, -0.90000000000000002, 0.17453292519943295 },
{ 0.34337919186972055, -0.90000000000000002, 0.34906585039886590 },
{ 0.50464268659856337, -0.90000000000000002, 0.52359877559829882 },
{ 0.65400003842368593, -0.90000000000000002, 0.69813170079773179 },
{ 0.78854928419904657, -0.90000000000000002, 0.87266462599716477 },
{ 0.90645698626315407, -0.90000000000000002, 1.0471975511965976 },
{ 1.0075154899135925, -0.90000000000000002, 1.2217304763960306 },
{ 1.0940135583194071, -0.90000000000000002, 1.3962634015954636 },
{ 1.1716970527816140, -0.90000000000000002, 1.5707963267948966 },
};
// Test function for k=-0.90000000000000002.
template <typename Tp>
void test001()
{
const 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::tr1::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(5.0000000000000029e-12));
}
// Test data for k=-0.80000000000000004.
testcase_ellint_2<double> data002[] = {
{ -0.0000000000000000, -0.80000000000000004, 0.0000000000000000 },
{ 0.17396762274534808, -0.80000000000000004, 0.17453292519943295 },
{ 0.34458685226969316, -0.80000000000000004, 0.34906585039886590 },
{ 0.50872923654502444, -0.80000000000000004, 0.52359877559829882 },
{ 0.66372016539176237, -0.80000000000000004, 0.69813170079773179 },
{ 0.80760344410167406, -0.80000000000000004, 0.87266462599716477 },
{ 0.93945480372495072, -0.80000000000000004, 1.0471975511965976 },
{ 1.0597473310395036, -0.80000000000000004, 1.2217304763960306 },
{ 1.1706981862452361, -0.80000000000000004, 1.3962634015954636 },
{ 1.2763499431699066, -0.80000000000000004, 1.5707963267948966 },
};
// Test function for k=-0.80000000000000004.
template <typename Tp>
void test002()
{
const 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::tr1::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(1.0000000000000008e-12));
}
// Test data for k=-0.69999999999999996.
testcase_ellint_2<double> data003[] = {
{ -0.0000000000000000, -0.69999999999999996, 0.0000000000000000 },
{ 0.17410041242702540, -0.69999999999999996, 0.17453292519943295 },
{ 0.34564605085764760, -0.69999999999999996, 0.34906585039886590 },
{ 0.51228495693314657, -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.2304180097292916, -0.69999999999999996, 1.3962634015954636 },
{ 1.3556611355719557, -0.69999999999999996, 1.5707963267948966 },
};
// Test function for k=-0.69999999999999996.
template <typename Tp>
void test003()
{
const 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::tr1::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(5.0000000000000039e-13));
}
// Test data for k=-0.59999999999999998.
testcase_ellint_2<double> data004[] = {
{ -0.0000000000000000, -0.59999999999999998, 0.0000000000000000 },
{ 0.17421534919599130, -0.59999999999999998, 0.17453292519943295 },
{ 0.34655927787174101, -0.59999999999999998, 0.34906585039886590 },
{ 0.51533034538432165, -0.59999999999999998, 0.52359877559829882 },
{ 0.67916550597453029, -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.4180833944487243, -0.59999999999999998, 1.5707963267948966 },
};
// Test function for k=-0.59999999999999998.
template <typename Tp>
void test004()
{
const 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::tr1::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(5.0000000000000039e-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.51788193485993805, -0.50000000000000000, 0.52359877559829882 },
{ 0.68506022954164536, -0.50000000000000000, 0.69813170079773179 },
{ 0.84831662803347196, -0.50000000000000000, 0.87266462599716477 },
{ 1.0075555551444717, -0.50000000000000000, 1.0471975511965976 },
{ 1.1631768599287302, -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()
{
const 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::tr1::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.17439190872481269, -0.40000000000000002, 0.17453292519943295 },
{ 0.34795581767099210, -0.40000000000000002, 0.34906585039886590 },
{ 0.51995290683804474, -0.40000000000000002, 0.52359877559829882 },
{ 0.68981638464431549, -0.40000000000000002, 0.69813170079773179 },
{ 0.85722088859936041, -0.40000000000000002, 0.87266462599716477 },
{ 1.0221301327876993, -0.40000000000000002, 1.0471975511965976 },
{ 1.1848138019818371, -0.40000000000000002, 1.2217304763960306 },
{ 1.3458259266501531, -0.40000000000000002, 1.3962634015954636 },
{ 1.5059416123600402, -0.40000000000000002, 1.5707963267948966 },
};
// Test function for k=-0.40000000000000002.
template <typename Tp>
void test006()
{
const 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::tr1::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.17445362864048916, -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.0332234514065410, -0.30000000000000004, 1.0471975511965976 },
{ 1.2011943182068923, -0.30000000000000004, 1.2217304763960306 },
{ 1.3682566113689620, -0.30000000000000004, 1.3962634015954636 },
{ 1.5348334649232489, -0.30000000000000004, 1.5707963267948966 },
};
// Test function for k=-0.30000000000000004.
template <typename Tp>
void test007()
{
const 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::tr1::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.17449769027652814, -0.19999999999999996, 0.17453292519943295 },
{ 0.34878893400762095, -0.19999999999999996, 0.34906585039886590 },
{ 0.52269152856057410, -0.19999999999999996, 0.52359877559829882 },
{ 0.69606913360157596, -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.5549685462425296, -0.19999999999999996, 1.5707963267948966 },
};
// Test function for k=-0.19999999999999996.
template <typename Tp>
void test008()
{
const 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::tr1::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.17452411766649945, -0.099999999999999978, 0.17453292519943295 },
{ 0.34899665805442398, -0.099999999999999978, 0.34906585039886590 },
{ 0.52337222400508787, -0.099999999999999978, 0.52359877559829882 },
{ 0.69761705217284875, -0.099999999999999978, 0.69813170079773179 },
{ 0.87171309273007491, -0.099999999999999978, 0.87266462599716477 },
{ 1.0456602197056328, -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()
{
const 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::tr1::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.17453292519943295, 0.0000000000000000, 0.17453292519943295 },
{ 0.34906585039886584, 0.0000000000000000, 0.34906585039886590 },
{ 0.52359877559829882, 0.0000000000000000, 0.52359877559829882 },
{ 0.69813170079773179, 0.0000000000000000, 0.69813170079773179 },
{ 0.87266462599716477, 0.0000000000000000, 0.87266462599716477 },
{ 1.0471975511965976, 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()
{
const 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::tr1::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.17452411766649945, 0.10000000000000009, 0.17453292519943295 },
{ 0.34899665805442398, 0.10000000000000009, 0.34906585039886590 },
{ 0.52337222400508787, 0.10000000000000009, 0.52359877559829882 },
{ 0.69761705217284875, 0.10000000000000009, 0.69813170079773179 },
{ 0.87171309273007491, 0.10000000000000009, 0.87266462599716477 },
{ 1.0456602197056328, 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()
{
const 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::tr1::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.17449769027652814, 0.19999999999999996, 0.17453292519943295 },
{ 0.34878893400762095, 0.19999999999999996, 0.34906585039886590 },
{ 0.52269152856057410, 0.19999999999999996, 0.52359877559829882 },
{ 0.69606913360157596, 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.5549685462425296, 0.19999999999999996, 1.5707963267948966 },
};
// Test function for k=0.19999999999999996.
template <typename Tp>
void test012()
{
const 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::tr1::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.17445362864048916, 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.0332234514065410, 0.30000000000000004, 1.0471975511965976 },
{ 1.2011943182068923, 0.30000000000000004, 1.2217304763960306 },
{ 1.3682566113689620, 0.30000000000000004, 1.3962634015954636 },
{ 1.5348334649232489, 0.30000000000000004, 1.5707963267948966 },
};
// Test function for k=0.30000000000000004.
template <typename Tp>
void test013()
{
const 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::tr1::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.17439190872481269, 0.39999999999999991, 0.17453292519943295 },
{ 0.34795581767099210, 0.39999999999999991, 0.34906585039886590 },
{ 0.51995290683804474, 0.39999999999999991, 0.52359877559829882 },
{ 0.68981638464431549, 0.39999999999999991, 0.69813170079773179 },
{ 0.85722088859936041, 0.39999999999999991, 0.87266462599716477 },
{ 1.0221301327876993, 0.39999999999999991, 1.0471975511965976 },
{ 1.1848138019818373, 0.39999999999999991, 1.2217304763960306 },
{ 1.3458259266501531, 0.39999999999999991, 1.3962634015954636 },
{ 1.5059416123600404, 0.39999999999999991, 1.5707963267948966 },
};
// Test function for k=0.39999999999999991.
template <typename Tp>
void test014()
{
const 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::tr1::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.51788193485993805, 0.50000000000000000, 0.52359877559829882 },
{ 0.68506022954164536, 0.50000000000000000, 0.69813170079773179 },
{ 0.84831662803347196, 0.50000000000000000, 0.87266462599716477 },
{ 1.0075555551444717, 0.50000000000000000, 1.0471975511965976 },
{ 1.1631768599287302, 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()
{
const 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::tr1::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.17421534919599130, 0.60000000000000009, 0.17453292519943295 },
{ 0.34655927787174101, 0.60000000000000009, 0.34906585039886590 },
{ 0.51533034538432165, 0.60000000000000009, 0.52359877559829882 },
{ 0.67916550597453029, 0.60000000000000009, 0.69813170079773179 },
{ 0.83720218180349870, 0.60000000000000009, 0.87266462599716477 },
{ 0.98922159354937789, 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()
{
const 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::tr1::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(5.0000000000000039e-13));
}
// Test data for k=0.69999999999999996.
testcase_ellint_2<double> data017[] = {
{ -0.0000000000000000, 0.69999999999999996, 0.0000000000000000 },
{ 0.17410041242702540, 0.69999999999999996, 0.17453292519943295 },
{ 0.34564605085764760, 0.69999999999999996, 0.34906585039886590 },
{ 0.51228495693314657, 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.2304180097292916, 0.69999999999999996, 1.3962634015954636 },
{ 1.3556611355719557, 0.69999999999999996, 1.5707963267948966 },
};
// Test function for k=0.69999999999999996.
template <typename Tp>
void test017()
{
const 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::tr1::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(5.0000000000000039e-13));
}
// Test data for k=0.80000000000000004.
testcase_ellint_2<double> data018[] = {
{ -0.0000000000000000, 0.80000000000000004, 0.0000000000000000 },
{ 0.17396762274534808, 0.80000000000000004, 0.17453292519943295 },
{ 0.34458685226969316, 0.80000000000000004, 0.34906585039886590 },
{ 0.50872923654502444, 0.80000000000000004, 0.52359877559829882 },
{ 0.66372016539176237, 0.80000000000000004, 0.69813170079773179 },
{ 0.80760344410167406, 0.80000000000000004, 0.87266462599716477 },
{ 0.93945480372495072, 0.80000000000000004, 1.0471975511965976 },
{ 1.0597473310395036, 0.80000000000000004, 1.2217304763960306 },
{ 1.1706981862452361, 0.80000000000000004, 1.3962634015954636 },
{ 1.2763499431699066, 0.80000000000000004, 1.5707963267948966 },
};
// Test function for k=0.80000000000000004.
template <typename Tp>
void test018()
{
const 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::tr1::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(1.0000000000000008e-12));
}
// Test data for k=0.89999999999999991.
testcase_ellint_2<double> data019[] = {
{ -0.0000000000000000, 0.89999999999999991, 0.0000000000000000 },
{ 0.17381690606167963, 0.89999999999999991, 0.17453292519943295 },
{ 0.34337919186972055, 0.89999999999999991, 0.34906585039886590 },
{ 0.50464268659856337, 0.89999999999999991, 0.52359877559829882 },
{ 0.65400003842368581, 0.89999999999999991, 0.69813170079773179 },
{ 0.78854928419904657, 0.89999999999999991, 0.87266462599716477 },
{ 0.90645698626315385, 0.89999999999999991, 1.0471975511965976 },
{ 1.0075154899135930, 0.89999999999999991, 1.2217304763960306 },
{ 1.0940135583194071, 0.89999999999999991, 1.3962634015954636 },
{ 1.1716970527816142, 0.89999999999999991, 1.5707963267948966 },
};
// Test function for k=0.89999999999999991.
template <typename Tp>
void test019()
{
const 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::tr1::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(5.0000000000000029e-12));
}
int main(int, char**)
{
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;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.13 ellint_2
#include <tr1/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::tr1::ellint_2(kf, phif);
std::tr1::ellint_2f(kf, phif);
std::tr1::ellint_2(kd, phid);
std::tr1::ellint_2(kl, phil);
std::tr1::ellint_2l(kl, phil);
return;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.13 ellint_2
#include <tr1/math.h>
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);
ellint_2(kf, phif);
ellint_2f(kf, phif);
ellint_2(kd, phid);
ellint_2(kl, phil);
ellint_2l(kl, phil);
return;
}

View File

@ -0,0 +1,126 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.13 ellint_3
#include <tr1/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::tr1::ellint_3(kf, nuf, phif);
float b = std::tr1::ellint_3f(kf, nuf, phif);
double c = std::tr1::ellint_3(kd, nud, phid);
long double d = std::tr1::ellint_3(kl, nul, phil);
long double e = std::tr1::ellint_3l(kl, nul, phil);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(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::tr1::ellint_3(kf, nuf, phif);
float b = std::tr1::ellint_3f(kf, nuf, phif);
double c = std::tr1::ellint_3(kd, nud, phid);
long double d = std::tr1::ellint_3(kl, nul, phil);
long double e = std::tr1::ellint_3l(kl, nul, phil);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(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::tr1::ellint_3(kf, nuf, phif);
float b = std::tr1::ellint_3f(kf, nuf, phif);
double c = std::tr1::ellint_3(kd, nud, phid);
long double d = std::tr1::ellint_3(kl, nul, phil);
long double e = std::tr1::ellint_3l(kl, nul, phil);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
test03();
return 0;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.14 ellint_3
#include <tr1/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::tr1::ellint_3(kf, nuf, phif);
std::tr1::ellint_3f(kf, nuf, phif);
std::tr1::ellint_3(kd, nud, phid);
std::tr1::ellint_3(kl, nul, phil);
std::tr1::ellint_3l(kl, nul, phil);
return;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.14 ellint_3
#include <tr1/math.h>
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);
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;
}

View File

@ -0,0 +1,57 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.15 expint
#include <tr1/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::tr1::expint(xf);
float b = std::tr1::expintf(xf);
double c = std::tr1::expint(xd);
long double d = std::tr1::expint(xl);
long double e = std::tr1::expintl(xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
return 0;
}

View File

@ -0,0 +1,128 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.2256908094623838e-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.8409618012250666e-16, -32.000000000000000 },
{ -1.0767670386162383e-15, -31.000000000000000 },
{ -3.0215520106888128e-15, -30.000000000000000 },
{ -8.4877597783535618e-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.00036008245216265867, -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()
{
const 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::tr1::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(int, char**)
{
test001<double>();
return 0;
}

View File

@ -0,0 +1,128 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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.50474333550139, 7.0000000000000000 },
{ 440.37989953483827, 8.0000000000000000 },
{ 1037.8782907170896, 9.0000000000000000 },
{ 2492.2289762418782, 10.000000000000000 },
{ 6071.4063740986112, 11.000000000000000 },
{ 14959.532666397527, 12.000000000000000 },
{ 37197.688490689041, 13.000000000000000 },
{ 93192.513633965369, 14.000000000000000 },
{ 234955.85249076830, 15.000000000000000 },
{ 595560.99867083703, 16.000000000000000 },
{ 1516637.8940425171, 17.000000000000000 },
{ 3877904.3305974435, 18.000000000000000 },
{ 9950907.2510468438, 19.000000000000000 },
{ 25615652.664056588, 20.000000000000000 },
{ 66127186.355484918, 21.000000000000000 },
{ 171144671.30036369, 22.000000000000000 },
{ 443966369.83027118, 23.000000000000000 },
{ 1154115391.8491828, 24.000000000000000 },
{ 3005950906.5255489, 25.000000000000000 },
{ 7842940991.8981876, 26.000000000000000 },
{ 20496497119.880810, 27.000000000000000 },
{ 53645118592.314682, 28.000000000000000 },
{ 140599195758.40689, 29.000000000000000 },
{ 368973209407.27423, 30.000000000000000 },
{ 969455575968.39392, 31.000000000000000 },
{ 2550043566357.7866, 32.000000000000000 },
{ 6714640184076.4980, 33.000000000000000 },
{ 17698037244116.266, 34.000000000000000 },
{ 46690550144661.594, 35.000000000000000 },
{ 123285207991209.75, 36.000000000000000 },
{ 325798899867226.44, 37.000000000000000 },
{ 861638819996578.62, 38.000000000000000 },
{ 2280446200301902.5, 39.000000000000000 },
{ 6039718263611242.0, 40.000000000000000 },
{ 16006649143245042., 41.000000000000000 },
{ 42447960921368504., 42.000000000000000 },
{ 1.1263482901669667e+17, 43.000000000000000 },
{ 2.9904447186323366e+17, 44.000000000000000 },
{ 7.9439160357044531e+17, 45.000000000000000 },
{ 2.1113423886478239e+18, 46.000000000000000 },
{ 5.6143296808103434e+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()
{
const 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::tr1::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(int, char**)
{
test001<double>();
return 0;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.15 expint
#include <tr1/cmath>
void
test01()
{
float xf = 0.5F;
double xd = 0.5;
long double xl = 0.5L;
std::tr1::expint(xf);
std::tr1::expintf(xf);
std::tr1::expint(xd);
std::tr1::expint(xl);
std::tr1::expintl(xl);
return;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.15 expint
#include <tr1/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;
}

View File

@ -0,0 +1,59 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.4 hermite
#include <tr1/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::tr1::hermite(n, xf);
float b = std::tr1::hermitef(n, xf);
double c = std::tr1::hermite(n, xd);
long double d = std::tr1::hermite(n, xl);
long double e = std::tr1::hermitel(n, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
return 0;
}

View File

@ -0,0 +1,44 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.16 hermite
#include <tr1/cmath>
void
test01()
{
float xf = 2.5F;
double xd = 2.5;
long double xl = 2.5L;
unsigned int n = 5;
std::tr1::hermite(n, xf);
std::tr1::hermitef(n, xf);
std::tr1::hermite(n, xd);
std::tr1::hermite(n, xl);
std::tr1::hermitel(n, xl);
return;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.16 hermite
#include <tr1/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;
}

View File

@ -0,0 +1,173 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.17 hyperg
#include <tr1/cmath>
#include <testsuite_hooks.h>
void
test01()
{
float af = std::numeric_limits<float>::quiet_NaN();
double ad = std::numeric_limits<double>::quiet_NaN();
long double al = std::numeric_limits<long double>::quiet_NaN();
float bf = 10.0F;
double bd = 10.0;
long double bl = 10.0L;
float cf = 3.0F;
double cd = 3.0;
long double cl = 3.0L;
float xf = 0.5F;
double xd = 0.5;
long double xl = 0.5L;
float a = std::tr1::hyperg(af, bf, cf, xf);
float b = std::tr1::hypergf(af, bf, cf, xf);
double c = std::tr1::hyperg(ad, bd, cd, xd);
long double d = std::tr1::hyperg(al, bl, cl, xl);
long double e = std::tr1::hypergl(al, bl, cl, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
void
test02()
{
float af = 2.0F;
double ad = 2.0;
long double al = 2.0L;
float bf = std::numeric_limits<float>::quiet_NaN();
double bd = std::numeric_limits<double>::quiet_NaN();
long double bl = std::numeric_limits<long double>::quiet_NaN();
float cf = 3.0F;
double cd = 3.0;
long double cl = 3.0L;
float xf = 0.5F;
double xd = 0.5;
long double xl = 0.5L;
float a = std::tr1::hyperg(af, bf, cf, xf);
float b = std::tr1::hypergf(af, bf, cf, xf);
double c = std::tr1::hyperg(ad, bd, cd, xd);
long double d = std::tr1::hyperg(al, bl, cl, xl);
long double e = std::tr1::hypergl(al, bl, cl, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
void
test03()
{
float af = 2.0F;
double ad = 2.0;
long double al = 2.0L;
float bf = 10.0F;
double bd = 10.0;
long double bl = 10.0L;
float cf = std::numeric_limits<float>::quiet_NaN();
double cd = std::numeric_limits<double>::quiet_NaN();
long double cl = std::numeric_limits<long double>::quiet_NaN();
float xf = 0.5F;
double xd = 0.5;
long double xl = 0.5L;
float a = std::tr1::hyperg(af, bf, cf, xf);
float b = std::tr1::hypergf(af, bf, cf, xf);
double c = std::tr1::hyperg(ad, bd, cd, xd);
long double d = std::tr1::hyperg(al, bl, cl, xl);
long double e = std::tr1::hypergl(al, bl, cl, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
void
test04()
{
float af = 2.0F;
double ad = 2.0;
long double al = 2.0L;
float bf = 10.0F;
double bd = 10.0;
long double bl = 10.0L;
float cf = 3.0F;
double cd = 3.0;
long double cl = 3.0L;
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::tr1::hyperg(af, bf, cf, xf);
float b = std::tr1::hypergf(af, bf, cf, xf);
double c = std::tr1::hyperg(ad, bd, cd, xd);
long double d = std::tr1::hyperg(al, bl, cl, xl);
long double e = std::tr1::hypergl(al, bl, cl, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
test02();
test03();
test04();
return 0;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.17 hyperg
#include <tr1/cmath>
void
test01()
{
float af = 2.0F, bf = 10.0F, cf = 3.0F, xf = 0.5F;
double ad = 2.0, bd = 10.0, cd = 3.0, xd = 0.5;
long double al = 2.0L, bl = 10.0L, cl = 3.0L, xl = 0.5L;
std::tr1::hyperg(af, bf, cf, xf);
std::tr1::hypergf(af, bf, cf, xf);
std::tr1::hyperg(ad, bd, cd, xd);
std::tr1::hyperg(al, bl, cl, xl);
std::tr1::hypergl(al, bl, cl, xl);
return;
}

View File

@ -0,0 +1,42 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.17 hyperg
#include <tr1/math.h>
void
test01()
{
float af = 2.0F, bf = 10.0F, cf = 3.0F, xf = 0.5F;
double ad = 2.0, bd = 10.0, cd = 3.0, xd = 0.5;
long double al = 2.0L, bl = 10.0L, cl = 3.0L, xl = 0.5L;
hyperg(af, bf, cf, xf);
hypergf(af, bf, cf, xf);
hyperg(ad, bd, cd, xd);
hyperg(al, bl, cl, xl);
hypergl(al, bl, cl, xl);
return;
}

View File

@ -0,0 +1,59 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.18 laguerre
#include <tr1/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::tr1::laguerre(n, xf);
float b = std::tr1::laguerref(n, xf);
double c = std::tr1::laguerre(n, xd);
long double d = std::tr1::laguerre(n, xl);
long double e = std::tr1::laguerrel(n, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
return 0;
}

View File

@ -0,0 +1,470 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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()
{
const 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::tr1::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()
{
const 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::tr1::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()
{
const 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::tr1::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()
{
const 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::tr1::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.7562761794532620, 10, 5.0000000000000000 },
{ 27.984126984126981, 10, 10.000000000000000 },
{ -237.51841517857147, 10, 15.000000000000000 },
{ 3227.8077601410932, 10, 20.000000000000000 },
{ -45786.199797453693, 10, 25.000000000000000 },
{ 15129.571428571489, 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()
{
const 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::tr1::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.0202257444769129, 20, 5.0000000000000000 },
{ -11.961333867812119, 20, 10.000000000000000 },
{ -50.151037960139455, 20, 15.000000000000000 },
{ 2829.4728613531738, 20, 20.000000000000000 },
{ -11583.947899113535, 20, 25.000000000000000 },
{ -18439.424502520938, 20, 30.000000000000000 },
{ -38838.223606979467, 20, 35.000000000000000 },
{ 24799805.877530701, 20, 40.000000000000000 },
{ -673953823.59913290, 20, 45.000000000000000 },
{ 7551960453.7672529, 20, 50.000000000000000 },
{ 31286508510.614754, 20, 55.000000000000000 },
{ -1379223608444.9155, 20, 60.000000000000000 },
{ -6692517968212.9727, 20, 65.000000000000000 },
{ 165423821874449.94, 20, 70.000000000000000 },
{ 3082390018008546.5, 20, 75.000000000000000 },
{ 29500368536981676., 20, 80.000000000000000 },
{ 2.0353526354974186e+17, 20, 85.000000000000000 },
{ 1.1292309514432899e+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()
{
const 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::tr1::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(1.0000000000000008e-12));
}
// Test data for n=50.
testcase_laguerre<double> data007[] = {
{ 1.0000000000000000, 50, 0.0000000000000000 },
{ 1.4735258819430563, 50, 5.0000000000000000 },
{ 17.534183446338233, 50, 10.000000000000000 },
{ -195.62436619077388, 50, 15.000000000000000 },
{ 980.26961889790766, 50, 20.000000000000000 },
{ 24812.277673870871, 50, 25.000000000000000 },
{ 293000.50735962350, 50, 30.000000000000000 },
{ 2316195.5013375296, 50, 35.000000000000000 },
{ -14896937.968694847, 50, 40.000000000000000 },
{ -502066598.00813466, 50, 45.000000000000000 },
{ 2513677852.6916885, 50, 50.000000000000000 },
{ 45129675503.538948, 50, 55.000000000000000 },
{ -883876565337.99207, 50, 60.000000000000000 },
{ 9361319947203.8379, 50, 65.000000000000000 },
{ -80967880733583.219, 50, 70.000000000000000 },
{ 717391079438942.88, 50, 75.000000000000000 },
{ -8217471769564850.0, 50, 80.000000000000000 },
{ 1.2595276229009984e+17, 50, 85.000000000000000 },
{ -2.1140031308048906e+18, 50, 90.000000000000000 },
{ 3.2438187475835138e+19, 50, 95.000000000000000 },
{ -3.9710103487094673e+20, 50, 100.00000000000000 },
};
// Test function for n=50.
template <typename Tp>
void test007()
{
const 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::tr1::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.4555271625328832, 100, 5.0000000000000000 },
{ 13.277662844303402, 100, 10.000000000000000 },
{ 91.737038454342013, 100, 15.000000000000000 },
{ 1854.0367283243393, 100, 20.000000000000000 },
{ -11281.698886837237, 100, 25.000000000000000 },
{ 170141.86987046539, 100, 30.000000000000000 },
{ -2950092.7025822792, 100, 35.000000000000000 },
{ -7272442.3156007063, 100, 40.000000000000000 },
{ 295697471.90876174, 100, 45.000000000000000 },
{ 4847420871.2690468, 100, 50.000000000000000 },
{ 59406998102.392273, 100, 55.000000000000000 },
{ 693492765740.29736, 100, 60.000000000000000 },
{ 6606192010150.3096, 100, 65.000000000000000 },
{ 17125518672239.707, 100, 70.000000000000000 },
{ -870493767065151.38, 100, 75.000000000000000 },
{ -13763178176383754., 100, 80.000000000000000 },
{ 30667078414479724., 100, 85.000000000000000 },
{ 2.1307220490380198e+18, 100, 90.000000000000000 },
{ -7.2706523009007862e+18, 100, 95.000000000000000 },
{ -2.6292260693068920e+20, 100, 100.00000000000000 },
};
// Test function for n=100.
template <typename Tp>
void test008()
{
const 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::tr1::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(int, char**)
{
test001<double>();
test002<double>();
test003<double>();
test004<double>();
test005<double>();
test006<double>();
test007<double>();
test008<double>();
return 0;
}

View File

@ -0,0 +1,44 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.18 laguerre
#include <tr1/cmath>
void
test01()
{
float xf = 0.5F;
double xd = 0.5;
long double xl = 0.5L;
unsigned int n = 2;
std::tr1::laguerre(n, xf);
std::tr1::laguerref(n, xf);
std::tr1::laguerre(n, xd);
std::tr1::laguerre(n, xl);
std::tr1::laguerrel(n, xl);
return;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.18 laguerre
#include <tr1/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;
}

View File

@ -0,0 +1,59 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.19 legendre
#include <tr1/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::tr1::legendre(l, xf);
float b = std::tr1::legendref(l, xf);
double c = std::tr1::legendre(l, xd);
long double d = std::tr1::legendre(l, xl);
long double e = std::tr1::legendrel(l, xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
return 0;
}

View File

@ -0,0 +1,470 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 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 <tr1/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()
{
const 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::tr1::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()
{
const 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::tr1::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()
{
const 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::tr1::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.041141249999999997, 5, -0.90000000000000002 },
{ 0.39951999999999993, 5, -0.80000000000000004 },
{ 0.36519874999999991, 5, -0.69999999999999996 },
{ 0.15263999999999994, 5, -0.59999999999999998 },
{ -0.089843750000000000, 5, -0.50000000000000000 },
{ -0.27063999999999988, 5, -0.40000000000000002 },
{ -0.34538624999999995, 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.34538624999999995, 5, 0.30000000000000004 },
{ 0.27064000000000010, 5, 0.39999999999999991 },
{ 0.089843750000000000, 5, 0.50000000000000000 },
{ -0.15264000000000022, 5, 0.60000000000000009 },
{ -0.36519874999999991, 5, 0.69999999999999996 },
{ -0.39951999999999993, 5, 0.80000000000000004 },
{ -0.041141250000000407, 5, 0.89999999999999991 },
{ 1.0000000000000000, 5, 1.0000000000000000 },
};
// Test function for l=5.
template <typename Tp>
void test004()
{
const 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::tr1::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.26314561785585977, 10, -0.90000000000000002 },
{ 0.30052979559999998, 10, -0.80000000000000004 },
{ 0.085805795531640333, 10, -0.69999999999999996 },
{ -0.24366274560000006, 10, -0.59999999999999998 },
{ -0.18822860717773438, 10, -0.50000000000000000 },
{ 0.096839064399999869, 10, -0.40000000000000002 },
{ 0.25147634951601561, 10, -0.30000000000000004 },
{ 0.12907202559999989, 10, -0.19999999999999996 },
{ -0.12212499738710947, 10, -0.099999999999999978 },
{ -0.24609375000000000, 10, 0.0000000000000000 },
{ -0.12212499738710922, 10, 0.10000000000000009 },
{ 0.12907202559999989, 10, 0.19999999999999996 },
{ 0.25147634951601561, 10, 0.30000000000000004 },
{ 0.096839064400000258, 10, 0.39999999999999991 },
{ -0.18822860717773438, 10, 0.50000000000000000 },
{ -0.24366274559999987, 10, 0.60000000000000009 },
{ 0.085805795531640333, 10, 0.69999999999999996 },
{ 0.30052979559999998, 10, 0.80000000000000004 },
{ -0.26314561785585888, 10, 0.89999999999999991 },
{ 1.0000000000000000, 10, 1.0000000000000000 },
};
// Test function for l=10.
template <typename Tp>
void test005()
{
const 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::tr1::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.14930823530984821, 20, -0.90000000000000002 },
{ 0.22420460541741344, 20, -0.80000000000000004 },
{ -0.20457394463834172, 20, -0.69999999999999996 },
{ 0.15916752910098114, 20, -0.59999999999999998 },
{ -0.048358381067373557, 20, -0.50000000000000000 },
{ -0.10159261558628156, 20, -0.40000000000000002 },
{ 0.18028715947998047, 20, -0.30000000000000004 },
{ -0.098042194344594741, 20, -0.19999999999999996 },
{ -0.082077130944527649, 20, -0.099999999999999978 },
{ 0.17619705200195312, 20, 0.0000000000000000 },
{ -0.082077130944528037, 20, 0.10000000000000009 },
{ -0.098042194344594741, 20, 0.19999999999999996 },
{ 0.18028715947998047, 20, 0.30000000000000004 },
{ -0.10159261558628112, 20, 0.39999999999999991 },
{ -0.048358381067373557, 20, 0.50000000000000000 },
{ 0.15916752910098084, 20, 0.60000000000000009 },
{ -0.20457394463834172, 20, 0.69999999999999996 },
{ 0.22420460541741344, 20, 0.80000000000000004 },
{ -0.14930823530984949, 20, 0.89999999999999991 },
{ 1.0000000000000000, 20, 1.0000000000000000 },
};
// Test function for l=20.
template <typename Tp>
void test006()
{
const 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::tr1::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.17003765994383685, 50, -0.90000000000000002 },
{ 0.13879737345093118, 50, -0.80000000000000004 },
{ -0.014572731645892805, 50, -0.69999999999999996 },
{ -0.058860798844002173, 50, -0.59999999999999998 },
{ -0.031059099239609828, 50, -0.50000000000000000 },
{ 0.041569033381825368, 50, -0.40000000000000002 },
{ 0.10911051574714808, 50, -0.30000000000000004 },
{ 0.083432272204197466, 50, -0.19999999999999996 },
{ -0.038205812661313579, 50, -0.099999999999999978 },
{ -0.11227517265921705, 50, 0.0000000000000000 },
{ -0.038205812661314169, 50, 0.10000000000000009 },
{ 0.083432272204197466, 50, 0.19999999999999996 },
{ 0.10911051574714808, 50, 0.30000000000000004 },
{ 0.041569033381824647, 50, 0.39999999999999991 },
{ -0.031059099239609828, 50, 0.50000000000000000 },
{ -0.058860798844001430, 50, 0.60000000000000009 },
{ -0.014572731645892805, 50, 0.69999999999999996 },
{ 0.13879737345093118, 50, 0.80000000000000004 },
{ -0.17003765994383663, 50, 0.89999999999999991 },
{ 1.0000000000000000, 50, 1.0000000000000000 },
};
// Test function for l=50.
template <typename Tp>
void test007()
{
const 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::tr1::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.10226582055871908, 100, -0.90000000000000002 },
{ 0.050861167913584124, 100, -0.80000000000000004 },
{ -0.077132507199778780, 100, -0.69999999999999996 },
{ -0.023747023905133110, 100, -0.59999999999999998 },
{ -0.060518025961861198, 100, -0.50000000000000000 },
{ -0.072258202125684429, 100, -0.40000000000000002 },
{ 0.057127392202801719, 100, -0.30000000000000004 },
{ 0.014681835355659636, 100, -0.19999999999999996 },
{ -0.063895098434750303, 100, -0.099999999999999978 },
{ 0.079589237387178727, 100, 0.0000000000000000 },
{ -0.063895098434749775, 100, 0.10000000000000009 },
{ 0.014681835355659636, 100, 0.19999999999999996 },
{ 0.057127392202801719, 100, 0.30000000000000004 },
{ -0.072258202125685012, 100, 0.39999999999999991 },
{ -0.060518025961861198, 100, 0.50000000000000000 },
{ -0.023747023905134217, 100, 0.60000000000000009 },
{ -0.077132507199778780, 100, 0.69999999999999996 },
{ 0.050861167913584124, 100, 0.80000000000000004 },
{ 0.10226582055871723, 100, 0.89999999999999991 },
{ 1.0000000000000000, 100, 1.0000000000000000 },
};
// Test function for l=100.
template <typename Tp>
void test008()
{
const 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::tr1::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(2.5000000000000020e-13));
}
int main(int, char**)
{
test001<double>();
test002<double>();
test003<double>();
test004<double>();
test005<double>();
test006<double>();
test007<double>();
test008<double>();
return 0;
}

View File

@ -0,0 +1,44 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.19 legendre
#include <tr1/cmath>
void
test01()
{
float xf = 0.5F;
double xd = 0.5;
long double xl = 0.5L;
unsigned int l = 2;
std::tr1::legendre(l, xf);
std::tr1::legendref(l, xf);
std::tr1::legendre(l, xd);
std::tr1::legendre(l, xl);
std::tr1::legendrel(l, xl);
return;
}

View File

@ -0,0 +1,43 @@
// { dg-do compile }
// 2006-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.19 legendre
#include <tr1/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;
}

View File

@ -0,0 +1,57 @@
// { dg-require-c-std "" }
// 2007-01-10 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2006-2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// 5.2.1.20 riemann_zeta
#include <tr1/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::tr1::riemann_zeta(xf);
float b = std::tr1::riemann_zetaf(xf);
double c = std::tr1::riemann_zeta(xd);
long double d = std::tr1::riemann_zeta(xl);
long double e = std::tr1::riemann_zetal(xl);
VERIFY(std::tr1::isnan<float>(a));
VERIFY(std::tr1::isnan<float>(b));
VERIFY(std::tr1::isnan<double>(c));
VERIFY(std::tr1::isnan<long double>(d));
VERIFY(std::tr1::isnan<long double>(e));
return;
}
int
main()
{
test01();
return 0;
}

View File

@ -0,0 +1,133 @@
// 2007-02-04 Edward Smith-Rowland <3dw4rd@verizon.net>
//
// Copyright (C) 2007 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 COPYING. If not, write to the Free
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
// riemann_zeta
// Compare against values generated by the GNU Scientific Library.
// The GSL can be found on the web: http://www.gnu.org/software/gsl/
#include <tr1/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.0015440036789213965, -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.0016960463875825209, -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()
{
const 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_riemann_zeta<double>);
for (unsigned int i = 0; i < num_datum; ++i)
{
const Tp f = std::tr1::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(5.0000000000000039e-13));
}
int main(int, char**)
{
test001<double>();
return 0;
}

Some files were not shown because too many files have changed in this diff Show More