### ----------------------------------------------------
### -- Math::Libgsl::Function
### -- Licenses: Artistic-2.0
### -- Authors: Fernando Santagata
### -- File: t/01-raw-function.rakutest
### ----------------------------------------------------
### -- Chunk 2 of 5
4825557695775, :rel-tol(10⁻¹⁵), 'zero of Jnu';
  ok gsl_sf_bessel_zero_Jnu_e(0e0, 1, $res) == 0, 'zero of Jnu with error check';
  is-approx $res.val, 2.404825557695775, :rel-tol(10⁻¹⁵), 'zero of Jnu with error check: value';
}, 'raw - Bessel functions';

subtest {
  my gsl_sf_result $res .= new;
  is-approx gsl_sf_clausen(π/20), 0.447888244813355, :rel-tol(10⁻¹⁵), 'Clausen';
  ok gsl_sf_clausen_e(π/20, $res) == 0, 'Clausen with error check';
  is-approx $res.val, 0.447888244813355, :rel-tol(10⁻¹⁵), 'Clausen with error check: value';
}, 'raw - Clausen functions';

subtest {
  my gsl_sf_result $res .= new;
  is-approx gsl_sf_hydrogenicR_1(3e0, 2e0), 0.025759948256148472, :rel-tol(10⁻¹⁵), 'hydrogenic R 1';
  ok gsl_sf_hydrogenicR_1_e(3e0, 2e0, $res) == 0, 'hydrogenic R 1 with error check';
  is-approx $res.val, 0.025759948256148472, :rel-tol(10⁻¹⁵), 'hydrogenic R 1 with error check: value';
  is-approx gsl_sf_hydrogenicR(4, 1, 3e0, 0e0), 0e0, :rel-tol(10⁻¹⁵), 'hydrogenic R';
  ok gsl_sf_hydrogenicR_e(4, 1, 3e0, 0e0, $res) == 0, 'hydrogenic R with error check';
  is-approx $res.val, 0e0, :rel-tol(10⁻¹⁵), 'hydrogenic R with error check: value';

  my num64 ($exp_F, $exp_G);
  my num64 $eta   = 1e0;
  my num64 $x     = 5e0;
  my num64 $L_F   = 0e0;
  my int32 $k     = 0;
  my gsl_sf_result $F  .= new;
  my gsl_sf_result $Fp .= new;
  my gsl_sf_result $G  .= new;
  my gsl_sf_result $Gp .= new;
  ok gsl_sf_coulomb_wave_FG_e($eta, $x, $L_F, $k, $F, $Fp, $G, $Gp, $exp_F, $exp_G) == 0, 'F and G + derivatives';
  is-approx $F.val, 0.684937412005944, :rel-tol(10⁻¹⁵), 'F: value';
  is-approx $Fp.val, -0.723642386255606, :rel-tol(10⁻¹⁵), 'F derivative: value';
  is-approx $G.val, -0.8984143590920198, :rel-tol(10⁻¹⁵), 'G: value';
  is-approx $Gp.val, -0.510804758519035, :rel-tol(10⁻¹⁵), 'G derivative: value';

  my num64 $L_min = 1e0;
  my int32 $kmax  = 3;
  my CArray[num64] $fc_array .= new: 0e0, 0e0, 0e0, 0e0;
  my num64 $F_exponent = 0e0;
  ok gsl_sf_coulomb_wave_F_array($L_min, $kmax, $eta, $x, $fc_array, $F_exponent) == 0, 'F array';
  is-deeply $fc_array.list».round(10⁻¹⁵), (1.092881104936675, 1.186370500609351, 0.904222651420796, 0.526623050054267), 'F array results';
  ok $F_exponent == 0, 'F array overflow exponent';

  $F_exponent = 0e0;
  my num64 $G_exponent = 0e0;
  $fc_array[^4] = 0e0, 0e0, 0e0, 0e0;
  my CArray[num64] $gc_array .= new: 0e0, 0e0, 0e0, 0e0;
  ok gsl_sf_coulomb_wave_FG_array($L_min, $kmax, $eta, $x, $fc_array, $gc_array, $F_exponent, $G_exponent) == 0, 'FG array';
  is-deeply $fc_array.list».round(10⁻¹⁵), (1.092881104936676, 1.186370500609353, 0.904222651420797, 0.526623050054267), 'FG array results: F';
  is-deeply $gc_array.list».round(10⁻¹⁵), (-0.401136354144034, 0.382961011797984, 1.091535333071877, 1.708616969572756), 'FG array results: G';
  ok $F_exponent == 0, 'F array overflow exponent';
  ok $G_exponent == 0, 'G array overflow exponent';

  $fc_array[^4] = 0e0, 0e0, 0e0, 0e0;
  $gc_array[^4] = 0e0, 0e0, 0e0, 0e0;
  $F_exponent = 0e0;
  $G_exponent = 0e0;
  my CArray[num64] $fcp_array .= new: 0e0, 0e0, 0e0, 0e0;
  my CArray[num64] $gcp_array .= new: 0e0, 0e0, 0e0, 0e0;
  ok gsl_sf_coulomb_wave_FGp_array($L_min, $kmax, $eta, $x, $fc_array, $fcp_array, $gc_array, $gcp_array, $F_exponent, $G_exponent) == 0, 'FG array + derivatives';
  is-deeply $fc_array.list».round(10⁻¹⁵), (1.092881104936676, 1.186370500609353, 0.904222651420797, 0.526623050054267), 'FG array results: F';
  is-deeply $gc_array.list».round(10⁻¹⁵), (-0.401136354144034, 0.382961011797984, 1.091535333071877, 1.708616969572756), 'FG array results: G';
  is-deeply $fcp_array.list».round(10⁻¹⁵), (-0.342809548488476, 0.154144770433327, 0.406603168927167, 0.37909717266402), 'FG array results: F derivative';
  is-deeply $gcp_array.list».round(10⁻¹⁵), (-0.789186146285826, -0.79314898867443, -0.615089960092336, -0.668918949964118), 'FG array results: G derivative';
  ok $F_exponent == 0, 'F array overflow exponent';
  ok $G_exponent == 0, 'G array overflow exponent';

  $fc_array[^4] = 0e0, 0e0, 0e0, 0e0;
  $F_exponent = 0e0;
  ok gsl_sf_coulomb_wave_sphF_array($L_min, $kmax, $eta, $x, $fc_array, $F_exponent) == 0, 'F/x array';
  is-deeply $fc_array.list».round(10⁻¹⁵), (0.218576220987335, 0.23727410012187, 0.180844530284159, 0.105324610010853), 'F/x array results';
  ok $F_exponent == 0, 'F/x array overflow exponent';

  my num64 $L = 2e0;
  my gsl_sf_result $result .= new;
  ok gsl_sf_coulomb_CL_e($L, $eta, $result) == 0, 'Normalization Constant';
  is-approx $result.val, 0.011428736368066569, :rel-tol(10⁻¹⁵), 'Normalization Constant: value';

  my CArray[num64] $cl .= new: 0e0, 0e0, 0e0, 0e0;
  ok gsl_sf_coulomb_CL_array($L_min, $kmax, $eta, $cl) == 0, 'Normalization Constant array';
  is-deeply $cl.list».round(10⁻¹⁵), (0.051110862831842, 0.011428736368067, 0.001720992271461, 0.000197106469892), 'Normalization Constant array: values';
}, 'raw - Coulomb functions';

subtest {
  my gsl_sf_result $res .= new;
  ok gsl_sf_coupling_3j(0, 1, 1, 0,  1, -1) == sqrt(½), '3-j';
  ok gsl_sf_coupling_3j_e(0, 1, 1, 0,  1, -1, $res) == 0, '3-j with error check';
  ok $res.val == sqrt(½), '3-j with error check: value';
  ok gsl_sf_coupling_6j(2, 2, 4, 2,  2, 2) == 1e0/6e0, '6-j';
  ok gsl_sf_coupling_6j_e(2, 2, 4, 2,  2, 2, $res) == 0, '6-j with error check';
  ok $res.val == 1e0/6e0, '6-j with error check: value';
  is-approx gsl_sf_coupling_9j(4, 2,  4, 3, 3, 2, 1, 1, 2), (-sqrt(⅙)/10e0), :rel-tol(10⁻¹⁵), '9-j';
  ok gsl_sf_coupling_9j_e(4, 2,  4, 3, 3, 2, 1, 1, 2, $res) == 0, '9-j with error check';
  is-approx $res.val, (-sqrt(⅙)/10e0), :rel-tol(10⁻¹⁵), '9-j with error check: value';
}, 'raw - Coupling coefficients';

subtest {
  my gsl_sf_result $res .= new;
  is-approx gsl_sf_dawson(0.5e0), 0.424436383502022, :rel-tol(10⁻¹⁵), 'Dawson';
  ok gsl_sf_dawson_e(0.5e0, $res) == 0, 'Dawson with error check';
  is-approx $res.val, 0.424436383502022, :rel-tol(10⁻¹⁵), 'Dawson with error check: value';
}, 'raw - Dawson function';

subtest {
  my gsl_sf_result $res .= new;
  is-approx gsl_sf_debye_1(0.1e0), 0.975277750004723, :rel-tol(10⁻¹⁵), 'Debye 1';
  ok gsl_sf_debye_1_e(0.1e0, $res) == 0, 'Debye 1 with error check';
  is-approx $res.val, 0.975277750004723, :rel-tol(10⁻¹⁵), 'Debye 1 with error check: value';
  is-approx gsl_sf_debye_2(0.1e0), 0.967083287045303, :rel-tol(10⁻¹⁵), 'Debye 2';
  ok gsl_sf_debye_2_e(0.1e0, $res) == 0, 'Debye 2 with error check';
  is-approx $res.val, 0.967083287045303, :rel-tol(10⁻¹⁵), 'Debye 2 with error check: value';
  is-approx gsl_sf_debye_3(0.1e0), 0.962999940487211, :rel-tol(10⁻¹⁵), 'Debye 3';
  ok gsl_sf_debye_3_e(0.1e0, $res) == 0, 'Debye 3 with error check';
  is-approx $res.val, 0.962999940487211, :rel-tol(10⁻¹⁵), 'Debye 3 with error check: value';
  is-approx gsl_sf_debye_4(0.1e0), 0.960555486124336, :rel-tol(10⁻¹⁵), 'Debye 4';
  ok gsl_sf_debye_4_e(0.1e0, $res) == 0, 'Debye 4 with error check';
  is-approx $res.val, 0.960555486124336, :rel-tol(10⁻¹⁵), 'Debye 4 with error check: value';
  is-approx gsl_sf_debye_5(0.1e0), 0.958928494283106, :rel-tol(10⁻¹⁵), 'Debye 5';
  ok gsl_sf_debye_5_e(0.1e0, $res) == 0, 'Debye 5 with error check';
  is-approx $res.val, 0.958928494283106, :rel-tol(10⁻¹⁵), 'Debye 5 with error check: value';
  is-approx gsl_sf_debye_6(0.1e0), 0.957767773826055, :rel-tol(10⁻¹⁵), 'Debye 6';
  ok gsl_sf_debye_6_e(0.1e0, $res) == 0, 'Debye 6 with error check';
  is-approx $res.val, 0.957767773826055, :rel-tol(10⁻¹⁵), 'Debye 6 with error check: value';
}, 'raw - Debye functions';

subtest {
  my gsl_sf_result $res .= new;
  is-approx gsl_sf_dilog(0.1e0), 0.10261779109939113, :rel-tol(10⁻¹⁵), 'real dilogarithm';
  ok gsl_sf_dilog_e(0.1e0, $res) == 0, 'real dilogarithm with error check';
  is-approx $res.val, 0.10261779109939113, :rel-tol(10⁻¹⁵), 'real dilogarithm with error check: value';
  my gsl_sf_result $res_re .= new;
  my gsl_sf_result $res_im .= new;
  ok gsl_sf_complex_dilog_xy_e(0e0, -.5e0, $res_re, $res_im) == 0, 'complex dilogarithm';
  is-approx $res_re.val, -0.058975074421566, :rel-tol(10⁻¹⁵), 'complex dilogarithm: re';
  is-approx $res_im.val, -0.487222358294522, :rel-tol(10⁻¹⁵), 'complex dilogarithm: img';
  ok gsl_sf_complex_dilog_e(0.98e0, π/2, $res_re, $res_im) == 0, 'complex dilogarithm polar coord';
  is-approx $res_re.val, -0.198716383777859, :rel-tol(10⁻¹⁵), 'complex dilogarithm polar coord: re';
  is-approx $res_im.val, 0.900200458829818, :rel-tol(10⁻¹⁵), 'complex dilogarithm polar coord: img';
  ok gsl_sf_complex_spence_xy_e(-0.5e0, 0e0, $res_re, $res_im) == 0, 'Spence dilogarithm';
  is-approx $res_re.val, 2.374395270272480, :rel-tol(10⁻¹⁵), 'Spence dilogarithm: re';
  is-approx $res_im.val, -1.273806204919600, :rel-tol(10⁻¹⁵), 'Spence dilogarithm: img';
}, 'raw - Dilogarithms';

subtest {
  my gsl_sf_result $res .= new;
  ok gsl_sf_multiply(-3e0, 2e0) == -6e0, 'multiplication';
  ok gsl_sf_multiply_e(-3e0, 2e0, $res) == 0, 'multiplication with error check';
  ok $res.val == -6e0, 'multiplication with error check: value';
  ok gsl_sf_multiply_err_e(-3e0, .001e0, 2e0, .001e0, $res) == 0, 'multiplication with abs errors';
  ok $res.val == -6, 'multiplication with abs errors: value';
  is-approx $res.err, 0.005000000000002665, :rel-tol(10⁻¹⁵), 'multiplication with abs errors: error';
}, 'raw - multiplication with error propagation';

subtest {
  my gsl_sf_result $res .= new;
  is-approx gsl_sf_ellint_Kcomp(.99e0, GSL_MODE_DEFAULT), 3.356600523361192, :rel-tol(10⁻¹⁵), 'Legendre K';
  ok gsl_sf_ellint_Kcomp_e(.99e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre K with error check';
  is-approx $res.val, 3.356600523361192, :rel-tol(10⁻¹⁵), 'Legendre K with error check: value';
  is-approx gsl_sf_ellint_Ecomp(.99e0, GSL_MODE_DEFAULT), 1.028475809028804, :rel-tol(10⁻¹⁵), 'Legendre E';
  ok gsl_sf_ellint_Ecomp_e(.99e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre E with error check';
  is-approx $res.val, 1.028475809028804, :rel-tol(10⁻¹⁵), 'Legendre E with error check: value';
  is-approx gsl_sf_ellint_Pcomp(.99e0, .1e0, GSL_MODE_DEFAULT), 3.137926123518364, :rel-tol(10⁻¹⁵), 'Legendre P';
  ok gsl_sf_ellint_Pcomp_e(.99e0, .1e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre P with error check';
  is-approx $res.val, 3.137926123518364, :rel-tol(10⁻¹⁵), 'Legendre P with error check: value';
  is-approx gsl_sf_ellint_Dcomp(.99e0, GSL_MODE_DEFAULT), 2.375395076351788, :rel-tol(10⁻¹⁵), 'Legendre D';
  ok gsl_sf_ellint_Dcomp_e(.99e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre D with error check';
  is-approx $res.val, 2.375395076351788, :rel-tol(10⁻¹⁵), 'Legendre D with error check: value';
  is-approx gsl_sf_ellint_F(π/3, .99e0, GSL_MODE_DEFAULT), 1.306533339273877, :rel-tol(10⁻¹⁵), 'Legendre incomplete F';
  ok gsl_sf_ellint_F_e(π/3, .99e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre incomplete F with error check';
  is-approx $res.val, 1.306533339273877, :rel-tol(10⁻¹⁵), 'Legendre incomplete F with error check: value';
  is-approx gsl_sf_ellint_E(π/3, .99e0, GSL_MODE_DEFAULT), 0.870481922037794, :rel-tol(10⁻¹⁵), 'Legendre incomplete E';
  ok gsl_sf_ellint_E_e(π/3, .99e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre incomplete E with error check';
  is-approx $res.val, 0.870481922037794, :rel-tol(10⁻¹⁵), 'Legendre incomplete E with error check: value';
  is-approx gsl_sf_ellint_P(π/3, .99e0, .5e0, GSL_MODE_DEFAULT), 1.12887265987641, :rel-tol(10⁻¹⁵), 'Legendre incomplete P';
  ok gsl_sf_ellint_P_e(π/3, .99e0, .5e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre incomplete P with error check';
  is-approx $res.val, 1.12887265987641, :rel-tol(10⁻¹⁵), 'Legendre incomplete P with error check: value';
  is-approx gsl_sf_ellint_D(π/2, .99e0, GSL_MODE_DEFAULT), 2.375395076351788, :rel-tol(10⁻¹⁵), 'Legendre incomplete D';
  ok gsl_sf_ellint_D_e(π/2, .99e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre incomplete D with error check';
  is-approx $res.val, 2.375395076351788, :rel-tol(10⁻¹⁵), 'Legendre incomplete D with error check: value';
  is-approx gsl_sf_ellint_RC(1e0, 2e0, GSL_MODE_DEFAULT), 0.785398163397448, :rel-tol(10⁻¹⁵), 'Legendre incomplete RC';
  ok gsl_sf_ellint_RC_e(1e0, 2e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre incomplete RC with error check';
  is-approx $res.val, 0.785398163397448, :rel-tol(10⁻¹⁵), 'Legendre incomplete RC with error check: value';
  is-approx gsl_sf_ellint_RD(1e0, 2e0, 3e0, GSL_MODE_DEFAULT), 0.29046028102899063, :rel-tol(10⁻¹⁵), 'Legendre incomplete RD';
  ok gsl_sf_ellint_RD_e(1e0, 2e0, 3e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre incomplete RD with error check';
  is-approx $res.val, 0.29046028102899063, :rel-tol(10⁻¹⁵), 'Legendre incomplete RD with error check: value';
  is-approx gsl_sf_ellint_RF(1e0, 2e0, 3e0, GSL_MODE_DEFAULT), 0.726945935468908, :rel-tol(10⁻¹⁵), 'Legendre incomplete RF';
  ok gsl_sf_ellint_RF_e(1e0, 2e0, 3e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre incomplete RF with error check';
  is-approx $res.val, 0.726945935468908, :rel-tol(10⁻¹⁵), 'Legendre incomplete RF with error check: value';
  is-approx gsl_sf_ellint_RJ(2e0, 3e0, 4e0, 5e0, GSL_MODE_DEFAULT), 0.1429757966715675, :rel-tol(10⁻¹⁵), 'Legendre incomplete RJ';
  ok gsl_sf_ellint_RJ_e(2e0, 3e0, 4e0, 5e0, GSL_MODE_DEFAULT, $res) == 0, 'Legendre incomplete RJ with error check';
  is-approx $res.val, 0.1429757966715675, :rel-tol(10⁻¹⁵), 'Legendre incomplete RJ with error check: value';
}, 'raw - elliptic integrals';

subtest {
  my num64 $sn;
  my num64 $cn;
  my num64 $dn;
  ok gsl_sf_elljac_e(.5e0, .5e0, $sn, $cn, $dn) == 0, 'Jacobi';
  is-approx $sn, 0.4707504736556575, :rel-tol(10⁻¹⁵), 'Jacobi sn: value';
  is-approx $cn, 0.882266394890440, :rel-tol(10⁻¹⁵), 'Jacobi cn: value';
  is-approx $dn, 0.942972425777386, :rel-tol(10⁻¹⁵), 'Jacobi dn: value';
}, 'raw - elliptic functions';

subtest {
  my gsl_sf_result $res .= new;
  ok gsl_sf_erf(-10e0) == -1, 'erf';
  ok gsl_sf_erf_e(-10e0, $res) == 0, 'erf with error check';
  ok $res.val == -1, 'erf with error check: value';
  ok gsl_sf_erfc(-10e0) == 2, 'erfc';
  ok gsl_sf_erfc_e(-10e0, $res) == 0, 'erfc with error check';
  ok $res.val == 2, 'erfc with error check: value';
  is-approx gsl_sf_log_erfc(-.1e0), 0.1065764005865225, :rel-tol(10⁻¹⁵), 'log erfc';
  ok gsl_sf_log_erfc_e(-.1e0, $res) == 0, 'log erfc with error check';
  is-approx $res.val, 0.1065764005865225, :rel-tol(10⁻¹⁵), 'log erfc with error check: value';
  is-approx gsl_sf_erf_Z(1e0), 0.24197072451914334, :rel-tol(10⁻¹⁵), 'erf Z';
  ok gsl_sf_erf_Z_e(1e0, $res) == 0, 'erf Z with error check';
  is-approx $res.val, 0.24197072451914334, :rel-tol(10⁻¹⁵), 'erf Z with error check: value';
  is-approx gsl_sf_erf_Q(1e0), 0.158655253931457, :rel-tol(10⁻¹⁵), 'erf Q';
  ok gsl_sf_erf_Q_e(1e0, $res) == 0, 'erf Q with error check';
  is-approx $res.val, 0.158655253931457, :rel-tol(10⁻¹⁵), 'erf Q with error check: value';
  is-approx gsl_sf_hazard(-1e0), 0.2875999709391784, :rel-tol(10⁻¹⁵), 'hazard';
  ok gsl_sf_hazard_e(-1e0, $res) == 0, 'erf Q with error check';
  is-approx $res.val, 0.2875999709391784, :rel-tol(10⁻¹⁵), 'hazard with error check: value';
}, 'raw - error functions';

subtest {
  my gsl_sf_result $res .= new;
  my gsl_sf_result_e10 $rese10 .= new;
  ok gsl_sf_exp(10e0) == exp(10e0), 'exp';
  ok gsl_sf_exp_e(10e0, $res) == 0, 'exp with error check';
  ok $res.val == exp(10e0), 'exp with error check: value';
  ok gsl_sf_exp_e10_e(10e0, $rese10) == 0, 'exp with extended range error check';
  ok $rese10.val == exp(10e0), 'exp with extended range error check: value';
  ok gsl_sf_exp_mult(10e0, -2e0) == -2 * exp(10e0), 'exp mult';
  ok gsl_sf_exp_mult_e(10e0, -2e0, $res) == 0, 'exp mult with error check';
  ok $res.val == -2 * exp(10e0), 'exp mult with error check: value';
  ok gsl_sf_exp_mult_e10_e(10e0, -2e0, $rese10) == 0, 'exp mult with extended range error check';
  ok $rese10.val == -2 * exp(10e0), 'exp mult with extended range error check: value';
  ok gsl_sf_expm1(-10e0) == exp(-10e0) - 1, 'exp(x) - 1';
  ok gsl_sf_expm1_e(-10e0, $res) == 0, 'exp(x) - 1 with error check';
  ok $res.val == exp(-10e0) - 1, 'exp(x) - 1 with error check: value';
  is-approx gsl_sf_exprel(-10e0), 0.09999546000702375, :rel-tol(10⁻¹⁵), '(exp(x) - 1) / x';
  ok gsl_sf_exprel_e(-10e0, $res) == 0, '(exp(x) - 1) / x with error check';
  is-approx $res.val, 0.09999546000702375, :rel-tol(10⁻¹⁵), '(exp(x) - 1) / x with error check: value';
  is-approx gsl_sf_ex