### ----------------------------------------------------
### -- Math::Libgsl::Function
### -- Licenses: Artistic-2.0
### -- Authors: Fernando Santagata
### -- File: t/02-function.rakutest
### ----------------------------------------------------
### -- Chunk 2 of 5
3, 1, 5) }, 'coulomb-wave-F-array';
  is-deeply %res<outF>».round(10⁻¹⁵), (1.092881104936675, 1.186370500609351, 0.904222651420796, 0.526623050054267)».round(10⁻¹⁵), 'F array results';
  ok %res<overflow> == False, 'no overflow';
  ok %res<expF> == 0, 'overflow exponent';

  lives-ok { %res = coulomb-wave-FG-array(1, 3, 1, 5) }, 'coulomb-wave-FG-array';
  is-deeply %res<outF>».round(10⁻¹⁵), (1.092881104936676, 1.186370500609353, 0.904222651420797, 0.526623050054267)».round(10⁻¹⁵), 'F array results';
  is-deeply %res<outG>».round(10⁻¹⁵), (-0.401136354144034, 0.382961011797984, 1.091535333071877, 1.708616969572756)».round(10⁻¹⁵), 'G array results';
  ok %res<overflow> == False, 'no overflow';
  ok %res<expF> == 0, 'F overflow exponent';
  ok %res<expG> == 0, 'G overflow exponent';

  lives-ok { %res = coulomb-wave-FGp-array(1, 3, 1, 5) }, 'coulomb-wave-FGp-array';
  is-deeply %res<outF>».round(10⁻¹⁵), (1.092881104936676, 1.186370500609353, 0.904222651420797, 0.526623050054267)».round(10⁻¹⁵), 'F array results';
  is-deeply %res<outG>».round(10⁻¹⁵), (-0.401136354144034, 0.382961011797984, 1.091535333071877, 1.708616969572756)».round(10⁻¹⁵), 'G array results';
  is-deeply %res<outFp>».round(10⁻¹⁵), (-0.342809548488476, 0.154144770433327, 0.406603168927167, 0.37909717266402)».round(10⁻¹⁵), "F' array results";
  is-deeply %res<outGp>».round(10⁻¹⁵), (-0.789186146285826, -0.79314898867443, -0.615089960092336, -0.668918949964118)».round(10⁻¹⁵), "G' array results";
  ok %res<overflow> == False, 'no overflow';
  ok %res<expF> == 0, 'F overflow exponent';
  ok %res<expG> == 0, 'G overflow exponent';

  lives-ok { %res = coulomb-wave-sphF-array(1, 3, 1, 5) }, 'coulomb-wave-sphF-array';
  is-deeply %res<outF>».round(10⁻¹⁵), (0.218576220987335, 0.23727410012187, 0.180844530284159, 0.105324610010853)».round(10⁻¹⁵), 'F array results';
  ok %res<overflow> == False, 'no overflow';
  ok %res<expF> == 0, 'F overflow exponent';

  lives-ok { ($val, $err) = coulomb-CL-e(2, 1) }, 'Normalization Constant';
  is-approx $val, 0.011428736368066569, :rel-tol(10⁻¹⁵), 'Normalization Constant: value';
  my @out;
  lives-ok { @out = coulomb-CL-array(1, 3, 1) }, 'Normalization Constant';
  is-deeply @out».round(10⁻¹⁵), [ 0.051110862831842, 0.011428736368067, 0.001720992271461, 0.000197106469892 ], 'Normalization Constant array: values';
}, 'Coulomb functions';

subtest {
  my ($val, $err);
  ok coupling3j(0, 1, 1, 0,  1, -1) == sqrt(½), '3-j';
  lives-ok { ($val, $err) = coupling3j-e(0, 1, 1, 0,  1, -1) }, '3-j with error check';
  ok $val == sqrt(½), '3-j with error check: value';
  ok coupling6j(2, 2, 4, 2,  2, 2) == ⅙, '6-j';
  lives-ok { ($val, $err) = coupling6j-e(2, 2, 4, 2,  2, 2) }, '6-j with error check';
  ok $val == ⅙, '6-j with error check: value';
  is-approx coupling9j(4, 2, 4, 3, 3, 2, 1, 1, 2), -sqrt(⅙) / 10, :rel-tol(10⁻¹⁵), '9-j';
  lives-ok { ($val, $err) = coupling9j-e(4, 2, 4, 3, 3, 2, 1, 1, 2) }, '9-j with error check';
  is-approx $val, -sqrt(⅙) / 10, :rel-tol(10⁻¹⁵), '9-j with error check: value';
}, 'Coupling coefficients';

subtest {
  my ($val, $err);
  is-approx dawson(.5), 0.424436383502022, :rel-tol(10⁻¹⁵), 'Dawson';
  lives-ok { ($val, $err) = dawson-e(.5) }, 'Dawson with error check';
  is-approx $val, 0.424436383502022, :rel-tol(10⁻¹⁵), 'Dawson with error check: value';
}, 'Dawson function';

subtest {
  my ($val, $err);
  is-approx debye1(.1), 0.975277750004723, :rel-tol(10⁻¹⁵), 'Debye 1';
  lives-ok { ($val, $err) = debye1-e(.1) }, 'Debye 1 with error check';
  is-approx $val, 0.975277750004723, :rel-tol(10⁻¹⁵), 'Debye 1 with error check: value';
  is-approx debye2(0.1e0), 0.967083287045303, :rel-tol(10⁻¹⁵), 'Debye 2';
  lives-ok { ($val, $err) = debye2-e(.1) }, 'Debye 2 with error check';
  is-approx $val, 0.967083287045303, :rel-tol(10⁻¹⁵), 'Debye 2 with error check: value';
  is-approx debye3(.1), 0.962999940487211, :rel-tol(10⁻¹⁵), 'Debye 3';
  lives-ok { ($val, $err) = debye3-e(.1) }, 'Debye 3 with error check';
  is-approx $val, 0.962999940487211, :rel-tol(10⁻¹⁵), 'Debye 3 with error check: value';
  is-approx debye4(.1), 0.960555486124336, :rel-tol(10⁻¹⁵), 'Debye 4';
  lives-ok { ($val, $err) = debye4-e(.1) }, 'Debye 4 with error check';
  is-approx $val, 0.960555486124336, :rel-tol(10⁻¹⁵), 'Debye 4 with error check: value';
  is-approx debye5(0.1e0), 0.958928494283106, :rel-tol(10⁻¹⁵), 'Debye 5';
  lives-ok { ($val, $err) = debye5-e(.1) }, 'Debye 5 with error check';
  is-approx $val, 0.958928494283106, :rel-tol(10⁻¹⁵), 'Debye 5 with error check: value';
  is-approx debye6(0.1e0), 0.957767773826055, :rel-tol(10⁻¹⁵), 'Debye 6';
  lives-ok { ($val, $err) = debye6-e(.1) }, 'Debye 6 with error check';
  is-approx $val, 0.957767773826055, :rel-tol(10⁻¹⁵), 'Debye 6 with error check: value';
}, 'Debye functions';

subtest {
  my ($val, $err, $errre, $errim);
  is-approx dilog(.1), 0.10261779109939113, :rel-tol(10⁻¹⁵), 'real dilogarithm';
  lives-ok { ($val, $err) = dilog-e(.1) }, 'real dilogarithm with error check';
  is-approx $val, 0.10261779109939113, :rel-tol(10⁻¹⁵), 'real dilogarithm with error check: value';
  lives-ok { ($val, $errre, $errim) = complex-dilog-xy-e(0, -.5) }, 'complex dilogarithm';
  is-approx $val, -0.058975074421566 -i * 0.487222358294522, :rel-tol(10⁻¹⁵), 'complex dilogarithm: value';
  lives-ok { ($val, $errre, $errim) = complex-dilog-e(.98, π/2) }, 'complex dilogarithm, polar coord';
  is-approx $val, -0.198716383777859 + i * 0.900200458829818, :rel-tol(10⁻¹⁵), 'complex dilogarithm, polar coord: value';
  lives-ok { ($val, $errre, $errim) = complex-spence-xy-e(-.5, 0) }, 'Spence dilogarithm';
  is-approx $val, 2.374395270272480 - i * 1.273806204919600, :rel-tol(10⁻¹⁵), 'Spence dilogarithm: value';
}, 'Dilogarithms';

subtest {
  my ($val, $err);
  ok multiply(-3, 2) == -6, 'multiplication';
  lives-ok { ($val, $err) = multiply-e(-3, 2) }, 'multiplication with error check';
  ok $val == -6, 'multiplication with error check: value';
  lives-ok { ($val, $err) = multiply-err-e(-3, .001, 2, .001) }, 'multiplication with abs errors';
  ok $val == -6, 'multiplication with abs errors: value';
  is-approx $err, 0.005000000000002665, :rel-tol(10⁻¹⁵), 'multiplication with abs errors: error';
}, 'multiplication with error propagation';

subtest {
  my ($val, $err);
  is-approx Kcomp(.99, GSL_MODE_DEFAULT), 3.356600523361192, :rel-tol(10⁻¹⁵), 'Legendre K';
  lives-ok { ($val, $err) = Kcomp-e(.99, GSL_MODE_DEFAULT) }, 'Legendre K with error check';
  is-approx $val, 3.356600523361192, :rel-tol(10⁻¹⁵), 'Legendre K with error check: value';
  is-approx Ecomp(.99, GSL_MODE_DEFAULT), 1.028475809028804, :rel-tol(10⁻¹⁵), 'Legendre E';
  lives-ok { ($val, $err) = Ecomp-e(.99, GSL_MODE_DEFAULT) }, 'Legendre E with error check';
  is-approx $val, 1.028475809028804, :rel-tol(10⁻¹⁵), 'Legendre E with error check: value';
  is-approx Pcomp(.99, .1, GSL_MODE_DEFAULT), 3.137926123518364, :rel-tol(10⁻¹⁵), 'Legendre P';
  lives-ok { ($val, $err) = Pcomp-e(.99, .1, GSL_MODE_DEFAULT) }, 'Legendre P with error check';
  is-approx $val, 3.137926123518364, :rel-tol(10⁻¹⁵), 'Legendre P with error check: value';
  is-approx Dcomp(.99, GSL_MODE_DEFAULT), 2.375395076351788, :rel-tol(10⁻¹⁵), 'Legendre D';
  lives-ok { ($val, $err) = Dcomp-e(.99, GSL_MODE_DEFAULT) }, 'Legendre D with error check';
  is-approx $val, 2.375395076351788, :rel-tol(10⁻¹⁵), 'Legendre D with error check: value';
  is-approx F(π/3, .99, GSL_MODE_DEFAULT), 1.306533339273877, :rel-tol(10⁻¹⁵), 'Legendre incomplete F';
  lives-ok { ($val, $err) = F-e(π/3, .99, GSL_MODE_DEFAULT) }, 'Legendre incomplete F with error check';
  is-approx $val, 1.306533339273877, :rel-tol(10⁻¹⁵), 'Legendre incomplete F with error check: value';
  is-approx E(π/3, .99, GSL_MODE_DEFAULT), 0.870481922037794, :rel-tol(10⁻¹⁵), 'Legendre incomplete E';
  lives-ok { ($val, $err) = E-e(π/3, .99, GSL_MODE_DEFAULT) }, 'Legendre incomplete E with error check';
  is-approx $val, 0.870481922037794, :rel-tol(10⁻¹⁵), 'Legendre incomplete E with error check: value';
  is-approx P(π/3, .99, .5, GSL_MODE_DEFAULT), 1.12887265987641, :rel-tol(10⁻¹⁵), 'Legendre incomplete P';
  lives-ok { ($val, $err) = P-e(π/3, .99, .5, GSL_MODE_DEFAULT) }, 'Legendre incomplete P with error check';
  is-approx $val, 1.12887265987641, :rel-tol(10⁻¹⁵), 'Legendre incomplete P with error check: value';
  is-approx D(π/2, .99, GSL_MODE_DEFAULT), 2.375395076351788, :rel-tol(10⁻¹⁵), 'Legendre incomplete D';
  lives-ok { ($val, $err) = D-e(π/2, .99e0, GSL_MODE_DEFAULT) }, 'Legendre incomplete D with error check';
  is-approx $val, 2.375395076351788, :rel-tol(10⁻¹⁵), 'Legendre incomplete D with error check: value';
  is-approx RC(1, 2, GSL_MODE_DEFAULT), 0.785398163397448, :rel-tol(10⁻¹⁵), 'Legendre incomplete RC';
  lives-ok { ($val, $err) = RC-e(1e0, 2e0, GSL_MODE_DEFAULT) }, 'Legendre incomplete RC with error check';
  is-approx $val, 0.785398163397448, :rel-tol(10⁻¹⁵), 'Legendre incomplete RC with error check: value';
  is-approx RD(1, 2, 3, GSL_MODE_DEFAULT), 0.29046028102899063, :rel-tol(10⁻¹⁵), 'Legendre incomplete RD';
  lives-ok { ($val, $err) = RD-e(1e0, 2e0, 3e0, GSL_MODE_DEFAULT) }, 'Legendre incomplete RD with error check';
  is-approx $val, 0.29046028102899063, :rel-tol(10⁻¹⁵), 'Legendre incomplete RD with error check: value';
  is-approx RF(1, 2, 3, GSL_MODE_DEFAULT), 0.726945935468908, :rel-tol(10⁻¹⁵), 'Legendre incomplete RF';
  lives-ok { ($val, $err) = RF-e(1, 2, 3, GSL_MODE_DEFAULT) }, 'Legendre incomplete RF with error check';
  is-approx $val, 0.726945935468908, :rel-tol(10⁻¹⁵), 'Legendre incomplete RF with error check: value';
  is-approx RJ(2, 3, 4, 5, GSL_MODE_DEFAULT), 0.1429757966715675, :rel-tol(10⁻¹⁵), 'Legendre incomplete RJ';
  lives-ok { ($val, $err) = RJ-e(2, 3, 4, 5, GSL_MODE_DEFAULT) }, 'Legendre incomplete RJ with error check';
  is-approx $val, 0.1429757966715675, :rel-tol(10⁻¹⁵), 'Legendre incomplete RJ with error check: value';
}, 'elliptic integrals';

subtest {
  my ($sn, $cn, $dn);
  lives-ok { ($sn, $cn, $dn) = elljac-e(.5, .5) }, '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';
}, 'elliptic functions';

subtest {
  my ($val, $err);
  ok erf(-10e0) == -1, 'erf';
  lives-ok { ($val, $err) = erf-e(-10) }, 'erf with error check';
  ok $val == -1, 'erf with error check: value';
  ok erfc(-10e0) == 2, 'erfc';
  lives-ok { ($val, $err) = erfc-e(-10) }, 'erfc with error check';
  ok $val == 2, 'erfc with error check: value';
  is-approx log-erfc(-.1), 0.1065764005865225, :rel-tol(10⁻¹⁵), 'log erfc';
  lives-ok { ($val, $err) = log-erfc-e(-.1) }, 'log erfc with error check';
  is-approx $val, 0.1065764005865225, :rel-tol(10⁻¹⁵), 'log erfc with error check: value';
  is-approx erf-Z(1), 0.24197072451914334, :rel-tol(10⁻¹⁵), 'erf Z';
  lives-ok { ($val, $err) = erf-Z-e(1) }, 'erf Z with error check';
  is-approx $val, 0.24197072451914334, :rel-tol(10⁻¹⁵), 'erf Z with error check: value';
  is-approx erf-Q(1), 0.158655253931457, :rel-tol(10⁻¹⁵), 'erf Q';
  lives-ok { ($val, $err) = erf-Q-e(1) }, 'erf Q with error check';
  is-approx $val, 0.158655253931457, :rel-tol(10⁻¹⁵), 'erf Q with error check: value';
  is-approx hazard(-1), 0.2875999709391784, :rel-tol(10⁻¹⁵), 'hazard';
  lives-ok { ($val, $err) = hazard-e(-1) }, 'erf Q with error check';
  is-approx $val, 0.2875999709391784, :rel-tol(10⁻¹⁵), 'hazard with error check: value';
}, 'error functions';

subtest {
  my ($val, $err, $e10);
  ok gexp(10) == exp(10), 'exp';
  lives-ok { ($val, $err) = gexp-e(10) }, 'exp with error check';
  ok $val == exp(10), 'exp with error check: value';
  lives-ok { ($val, $err, $e10) = gexp-e10(10) }, 'exp with extended range error check';
  ok $val == exp(10), 'exp with extended range error check: value';
  ok gexp-mult(10, -2) == -2 * exp(10), 'exp mult';
  lives-ok { ($val, $err) = gexp-mult-e(10, -2) }, 'exp mult with error check';
  ok $val == -2 * exp(10), 'exp mult with error check: value';
  lives-ok { ($val, $err, $e10) = gexp-mult-e10(10, -2) }, 'exp mult with extended range error check';
  ok $val == -2 * exp(10), 'exp mult with extended range error check: value';
  ok gexpm1(-10) == exp(-10) - 1, 'exp(x) - 1';
  lives-ok { ($val, $err) = gexpm1-e(-10) }, 'exp(x) - 1 with error check';
  ok $val == exp(-10) - 1, 'exp(x) - 1 with error check: value';
  is-approx gexprel(-10), 0.09999546000702375, :rel-tol(10⁻¹⁵), '(exp(x) - 1) / x';
  lives-ok { ($val, $err) = gexprel-e(-10) }, '(exp(x) - 1) / x with error check';
  is-approx $val, 0.09999546000702375, :rel-tol(10⁻¹⁵), '(exp(x) - 1) / x with error check: value';
  is-approx gexprel2(-10), 0.18000090799859525, :rel-tol(10⁻¹⁵), '2 * (exp(x) - 1 - x) / x²';
  lives-ok { ($val, $err) = gexprel2-e(-10) }, '2 * (exp(x) - 1 - x) / x² with error check';
  is-approx $val, 0.18000090799859525, :rel-tol(10⁻¹⁵), '2 * (exp(x) - 1 - x) / x² with error check: value';
  is-approx gexprel-n(3, -10), 0.24599972760042138, :rel-tol(10⁻¹⁵), 'N relative exponential';
  lives-ok { ($val, $err) = gexprel-n-e(3, -10) }, 'N relative exponential with error check';
  is-approx $val, 0.24599972760042138, :rel-tol(10⁻¹⁵), 'N relative exponential with error check: value';
  lives-ok { ($val, $err) = gexp-err-e(-10, 16 * 2.2204460492503131e-16) }, 'exp with absolute error';
  ok $val == exp(-10), 'exp with absolute error: value';
  lives-ok { ($val, $err, $e10) = gexp-err-e10(1, 16 * 2.2204460492503131e-16) }, 'exp with extended range error check';
  ok $val == 𝑒, 'exp with extended range error check: value';
  lives-ok { ($val, $err) = gexp-mult-err-e(-10, 2 * 2.2204460492503131e-16, 2, 2 * 2.2204460492503131e-16) }, 'y * exp(x) with absolute error';
  ok $val == 2 * exp(-10), 'y * exp(x) with absolute error: value';
  lives-ok { ($val, $err, $e10) = gexp-mult-err-e10(-10, 2 * 2.2204460492503131e-16, 2, 2 * 2.2204460492503131e-16) }, 'y * exp(x) with extended range error check';
  ok $val == 2 * exp(-10), 'y * exp(x) with extended range error check: value';
}, 'exponential functions';

subtest {
  my ($val, $err);
  is-approx E1(1), 0.21938393439552029, :rel-tol(10⁻¹⁵), 'E₁(x)';
  lives-ok { ($val, $err) = E1-e(1) }, 'E₁(x) with error check';
  is-approx $val, 0.21938393439552029, :rel-tol(10⁻¹⁵), 'E₁(x) with error check: value';
  is-approx E2(1), 0.148495506775922, :rel-tol(10⁻¹⁵), 'E₂(x)';
  lives-ok { ($val, $err) = E2-e(1) }, 'E₂(x) with error check';
  is-approx $val, 0.148495506775922, :rel-tol(10⁻¹⁵), 'E₂(x) with error check: value';
  is-approx En(1, 1), 0.21938393439552029, :rel-tol(10⁻¹⁵), 'Eₙ(x)';
  lives-ok { ($val, $err) = En-e(1, 1) }, 'Eₙ(x) with error check';
  is-approx $val, 0.21938393439552029, :rel-tol(10⁻¹⁵), 'Eₙ(x) with error check: value';
  is-approx Ei(1), 1.895117816355937, :rel-tol(10⁻¹⁵), 'Eᵢ(x)';
  lives-ok { ($val, $err) = Ei-e(1) }, 'Eᵢ(x) with error check';
  is-approx $val, 1.895117816355937, :rel-tol(10⁻¹⁵), 'Eᵢ(x) with error check: value';
  is-approx Shi(.1), 0.100055572225057, :rel-tol(10⁻¹⁵), 'Shi(x)';
  lives-ok { ($val, $err) = Shi-e(.1) }, 'Shi(x) with error check';
  is-approx $val, 0.100055572225057, :rel-tol(10⁻¹⁵), 'Shi(x) with error check: value';
  is-approx Chi(1), 0.837866940980208, :rel-tol(10⁻¹⁵), 'Chi(x)';
  lives-ok { ($val, $err) = Chi-e(1) }, 'Chi(x) with error check';
  is-approx $val, 0.837866940980208, :rel-tol(10⁻¹⁵), 'Chi(x) with error check: value';
  is-approx expint3(1), 0.807511182139672, :rel-tol(10⁻¹⁵), 'Ei₃(x)';
  lives-ok { ($val, $err) = expint3-e(1) }, 'Ei₃(x) with error check';
  is-approx $val, 0.807511182139672, :rel-tol(10⁻¹⁵), 'Ei₃(x) with error check: value';
  is-approx Si(1), 0.946083070367183, :rel-tol(10⁻¹⁵), 'Si(x)';
  lives-ok { ($val, $err) = Si-e(1) }, 'Si(x) with error check';
  is-approx $val, 0.946083070367183, :rel-tol(10⁻¹⁵), 'Si(x) with error check: value';
  is-approx Ci(1), 0.337403922900968, :rel-tol(10⁻¹⁵), 'Ci(x)';
  lives-ok { ($val, $err) = Ci-e(1) }, 'Ci(x) with error check';
  is-approx $val, 0.337403922900968, :rel-tol(10⁻¹⁵), 'Ci(x) with error check: value';
