### ----------------------------------------------------
### -- Math::Libgsl::Function
### -- Licenses: Artistic-2.0
### -- Authors: Fernando Santagata
### -- File: t/02-function.rakutest
### ----------------------------------------------------
### -- Chunk 3 of 5
  is-approx atanint(1), 0.915965594177219, :rel-tol(10⁻¹⁵), 'atanint(x)';
  lives-ok { ($val, $err) = atanint-e(1) }, 'atanint(x) with error check';
  is-approx $val, 0.915965594177219, :rel-tol(10⁻¹⁵), 'atanint(x) with error check: value';
}, 'exponential integrals';

subtest {
  my ($val, $err);
  is-approx fd-m1(1), 0.731058578630005, :rel-tol(10⁻¹⁵), 'F₋₁(x)';
  lives-ok { ($val, $err) = fd-m1-e(1) }, 'F₋₁(x) with error check';
  is-approx $val, 0.731058578630005, :rel-tol(10⁻¹⁵), 'F₋₁(x) with error check: value';
  is-approx fd0(1), 1.313261687518223, :rel-tol(10⁻¹⁵), 'F₀(x)';
  lives-ok { ($val, $err) = fd0-e(1) }, 'F₀(x) with error check';
  is-approx $val, 1.313261687518223, :rel-tol(10⁻¹⁵), 'F₀(x) with error check: value';
  is-approx fd1(1), 1.806286070444775, :rel-tol(10⁻¹⁵), 'F₁(x)';
  lives-ok { ($val, $err) = fd1-e(1) }, 'F₁(x) with error check';
  is-approx $val, 1.806286070444775, :rel-tol(10⁻¹⁵), 'F₁(x) with error check: value';
  is-approx fd2(1), 2.164165612812701, :rel-tol(10⁻¹⁵), 'F₂(x)';
  lives-ok { ($val, $err) = fd2-e(1) }, 'F₂(x) with error check';
  is-approx $val, 2.164165612812701, :rel-tol(10⁻¹⁵), 'F₂(x) with error check: value';
  is-approx fd-int(3, 1), 2.39822608224894, :rel-tol(10⁻¹⁵), 'Fⱼ(x)';
  lives-ok { ($val, $err) = fd-int-e(3, 1) }, 'Fⱼ(x) with error check';
  is-approx $val, 2.39822608224894, :rel-tol(10⁻¹⁵), 'Fⱼ(x) with error check: value';
  is-approx fd-mhalf(1), 1.027057125474351, :rel-tol(10⁻¹⁵), 'F-1/2(x)';
  lives-ok { ($val, $err) = fd-mhalf-e(1) }, 'F-1/2(x) with error check';
  is-approx $val, 1.027057125474351, :rel-tol(10⁻¹⁵), 'F-1/2(x) with error check: value';
  is-approx fd-half(1), 1.575640776151300, :rel-tol(10⁻¹⁵), 'F1/2(x)';
  lives-ok { ($val, $err) = fd-half-e(1) }, 'F1/2(x) with error check';
  is-approx $val, 1.575640776151300, :rel-tol(10⁻¹⁵), 'F1/2(x) with error check: value';
  is-approx fd-half3(1), 2.002258148778464, :rel-tol(10⁻¹⁵), 'F3/2(x)';
  lives-ok { ($val, $err) = fd-half3-e(1) }, 'F3/2(x) with error check';
  is-approx $val, 2.002258148778464, :rel-tol(10⁻¹⁵), 'F3/2(x) with error check: value';
  is-approx fd-inc0(1, 2), 0.313261687518223, :rel-tol(10⁻¹⁵), 'F₀(x,b)';
  lives-ok { ($val, $err) = fd-inc0-e(1, 2) }, 'F₀(x,b) with error check';
  is-approx $val, 0.313261687518223, :rel-tol(10⁻¹⁵), 'F₀(x,b) with error check: value';
}, 'Fermi-Dirac integrals';

subtest {
  my ($val, $err, $vali, $erri);
  ok gamma(9) == 40320, 'Γ(x)';
  lives-ok { ($val, $err) = gamma-e(9) }, 'Γ(x) with error check';
  ok $val == 40320, 'Γ(x) with error check: value';
  is-approx lngamma(.1), 2.252712651734205, :rel-tol(10⁻¹⁵), 'log(|Γ(x)|)';
  lives-ok { ($val, $err) = lngamma-e(.1) }, 'log(|Γ(x)|) with error check';
  is-approx $val, 2.252712651734205, :rel-tol(10⁻¹⁵), 'log(|Γ(x)|) with error check: value';
  my $sgn;
  lives-ok { ($val, $err, $sgn) = lngamma-sgn-e(-.1) }, 'log(|Γ(x)|) with error check and sign';
  is-approx $val, 2.368961332728788, :rel-tol(10⁻¹⁵), 'log(|Γ(x)|) with error check and sign: value';
  ok $sgn == -1, 'log(|Γ(x)|) with error check: sign';
  is-approx gammastar(9), 1.009298426421819, :rel-tol(10⁻¹⁵), 'Γ*(x)';
  lives-ok { ($val, $err) = gammastar-e(9) }, 'Γ*(x) with error check';
  is-approx $val, 1.009298426421819, :rel-tol(10⁻¹⁵), 'Γ*(x) with error check: value';
  ok gammainv(3) == .5, '1/Γ(x)';
  lives-ok { ($val, $err) = gammainv-e(3) }, '1/Γ(x) with error check';
  ok $val == .5, '1/Γ(x) with error check: value';
  lives-ok { ($val, $err, $vali, $erri) = lngamma-complex-e(5, 2) }, 'log(Γ(z)) with error check';
  is-approx $val, 2.748701756133804, :rel-tol(10⁻¹⁵), 'log(Γ(z)) with error check: re value';
  is-approx $vali, 3.073843410049702, :rel-tol(10⁻¹⁵), 'log(Γ(z)) with error check: im value';
  ok fact(8) == 40320, 'n!';
  dies-ok { fact(300) }, '300! overflows';
  lives-ok { ($val, $err) = fact-e(8) }, 'n! with error check';
  ok $val == 40320, 'n! with error check: value';
  ok doublefact(7) == 105, 'n!!';
  dies-ok { doublefact(300) }, '300!! overflows';
  lives-ok { ($val, $err) = doublefact-e(7) }, 'n!! with error check';
  ok $val == 105, 'n!! with error check: value';
  is-approx lnfact(7), 8.525161361065414, :rel-tol(10⁻¹⁵), 'log(n!)';
  lives-ok { ($val, $err) = lnfact-e(7) }, 'log(n!) with error check';
  is-approx $val, 8.525161361065414, :rel-tol(10⁻¹⁵), 'log(n!) with error check: value';
  is-approx lndoublefact(7), 4.653960350157524, :rel-tol(10⁻¹⁵), 'log(n!!)';
  lives-ok { ($val, $err) = lndoublefact-e(7) }, 'log(n!!) with error check';
  is-approx $val, 4.653960350157524, :rel-tol(10⁻¹⁵), 'log(n!!) with error check: value';
  ok choose(7, 3) == 35, 'n!/(m!(n-m)!)';
  lives-ok { ($val, $err) = choose-e(7, 3) }, 'n!/(m!(n-m)!) with error check';
  ok $val == 35, 'n!/(m!(n-m)!) with error check: value';
  is-approx lnchoose(7, 3), 3.555348061489414, :rel-tol(10⁻¹⁵), 'log(n!)-log(m!)-log((n-m)!)';
  lives-ok { ($val, $err) = lnchoose-e(7, 3) }, 'log(n!)-log(m!)-log((n-m)!) with error check';
  is-approx $val, 3.555348061489414, :rel-tol(10⁻¹⁵), 'log(n!)-log(m!)-log((n-m)!) with error check: value';
  is-approx taylorcoeff(10, 5), 2.691144455467373, :rel-tol(10⁻¹⁵), 'xⁿ/n!';
  dies-ok { taylorcoeff(10, -5) }, 'xⁿ/n! dies when x<0';
  lives-ok { ($val, $err) = taylorcoeff-e(10, 5) }, 'xⁿ/n! with error check';
  is-approx $val, 2.691144455467373, :rel-tol(10⁻¹⁵), 'xⁿ/n! with error check: value';
  ok poch(5, 0) == 1, '(a)ₓ';
  lives-ok { ($val, $err) = poch-e(5, 0) }, '(a)ₓ with error check';
  ok $val == 1, '(a)ₓ with error check: value';
  ok lnpoch(5, 0) == 0, 'log((a)ₓ)';
  lives-ok { ($val, $err) = lnpoch-e(5, 0) }, 'log((a)ₓ) with error check';
  ok $val == 0, 'log((a)ₓ) with error check: value';
  lives-ok { ($val, $err, $sgn) = lnpoch-sgn-e(5, 0)}, 'log((a)ₓ) with error check and sign';
  ok $val == 0, 'log((a)ₓ) with error check and sign: value';
  ok $sgn == 1, 'log((a)ₓ) with error check and sign: sign';
  is-approx pochrel(5, 0), 1.506117668431801, :rel-tol(10⁻¹⁵), '((a)ₓ-1)/x';
  lives-ok { ($val, $err) = pochrel-e(5, 0) }, '((a)ₓ-1)/x with error check';
  is-approx $val, 1.506117668431801, :rel-tol(10⁻¹⁵), '((a)ₓ-1)/x with error check: value';
  is-approx gamma-inc(1, 1), 0.367879441171442, :rel-tol(10⁻¹⁵), 'Γ(a,x)';
  lives-ok { ($val, $err) = gamma-inc-e(1, 1) }, 'Γ(a,x) with error check';
  is-approx $val, 0.367879441171442, :rel-tol(10⁻¹⁵), 'Γ(a,x) with error check: value';
  is-approx gamma-inc-Q(1, 1.01), 0.364218979571523, :rel-tol(10⁻¹⁵), 'Q(a,x)';
  lives-ok { ($val, $err) = gamma-inc-Q-e(1, 1.01) }, 'Q(a,x) with error check';
  is-approx $val, 0.364218979571523, :rel-tol(10⁻¹⁵), 'Q(a,x) with error check: value';
  is-approx gamma-inc-P(100, 99), 0.473304330399461, :rel-tol(10⁻¹⁵), 'P(a,x)';
  lives-ok { ($val, $err) = gamma-inc-P-e(100, 99) }, 'P(a,x) with error check';
  is-approx $val, 0.473304330399461, :rel-tol(10⁻¹⁵), 'P(a,x) with error check: value';
  ok beta(1, 1) == 1, 'B(a,b)';
  lives-ok { ($val, $err) = beta-e(1, 1) }, 'B(a,b) with error check';
  ok $val == 1, 'B(a,b) with error check: value';
  is-approx lnbeta(1, 1.01), -0.009950330853168186, :rel-tol(10⁻¹⁵), 'log(B(a,b))';
  lives-ok { ($val, $err) = lnbeta-e(1, 1.01) }, 'log(B(a,b)) with error check';
  is-approx $val, -0.009950330853168186, :rel-tol(10⁻¹⁵), 'log(B(a,b)) with error check: value';
  ok beta-inc(1, 1, 1) == 1, 'Iₓ(a,b)';
  dies-ok { beta-inc(1, 1, -1) }, 'Iₓ(a,b) dies when x<0';
  dies-ok { beta-inc(1, 1, 2) }, 'Iₓ(a,b) dies when x>1';
  dies-ok { beta-inc(0, 1, 1) }, 'Iₓ(a,b) dies when a=0';
  dies-ok { beta-inc(1, 0, 1) }, 'Iₓ(a,b) dies when b=0';
  lives-ok { ($val, $err) = beta-inc-e(1, 1, 1) }, 'Iₓ(a,b) with error check';
  ok $val == 1, 'Iₓ(a,b) with error check: value';
}, 'gamma e beta functions';

subtest {
  my ($val, $err);
  is-approx gegenpoly1(0, 1), 2, :rel-tol(10⁻¹⁵), 'Cₙ(λ)(x) n=1';
  lives-ok { ($val, $err) = gegenpoly1-e(0, 1) }, 'Cₙ(λ)(x) n=1 with error check';
  is-approx $val, 2, :rel-tol(10⁻¹⁵), 'Cₙ(λ)(x) n=1 with error check: value';
  is-approx gegenpoly2(0, 1), 1, :rel-tol(10⁻¹⁵), 'Cₙ(λ)(x) n=2';
  lives-ok { ($val, $err) = gegenpoly2-e(0, 1) }, 'Cₙ(λ)(x) n=2 with error check';
  is-approx $val, 1, :rel-tol(10⁻¹⁵), 'Cₙ(λ)(x) n=2 with error check: value';
  is-approx gegenpoly3(1, 1), 4, :rel-tol(10⁻¹⁵), 'Cₙ(λ)(x) n=3';
  lives-ok { ($val, $err) = gegenpoly3-e(1, 1) }, 'Cₙ(λ)(x) n=3 with error check';
  is-approx $val, 4, :rel-tol(10⁻¹⁵), 'Cₙ(λ)(x) n=3 with error check: value';
  is-approx gegenpolyn(1, 1, 1), 2, :rel-tol(10⁻¹⁵), 'Cₙ(λ)(x)';
  dies-ok { gegenpolyn(1, -1, 1) }, 'Cₙ(λ)(x) dies when λ < -½';
  lives-ok { ($val, $err) = gegenpolyn-e(1, 1, 1) }, 'Cₙ(λ)(x) with error check';
  is-approx $val, 2, :rel-tol(10⁻¹⁵), 'Cₙ(λ)(x) with error check: value';
  my @res;
  lives-ok { @res = gegenpoly-array(11, 5, 1) }, 'Cₙ(λ)(x) for n=0,1,2…nmax';
  ok @res[1] == 10, 'Cₙ(λ)(x) n=1';
  ok @res[10] == 9.23780e+4, 'Cₙ(λ)(x) n=10';
}, 'Gegenbauer functions';

subtest {
  my ($val, $err);
  ok hermite(0, .75) == 1, 'Hₙ(x)';
  lives-ok { ($val, $err) = hermite-e(0, .75) }, 'Hₙ(x) with error check';
  ok $val == 1, 'Hₙ(x) with error check: value';
  my @out;
  lives-ok { @out = hermite-array(0, .75) }, 'Hₙ(x) array';
  ok @out[0] == 1, 'Hₙ(x) array: results';
  my @a = 1,;
  @a[$_] = @a[$_-1]/2 for 1…10;
  is-approx hermite-series(10, .75, @a), 29.591702461242672, :rel-tol(10⁻¹⁵), 'sum(aₙHₙ(x))';
  lives-ok { ($val, $err) = hermite-series-e(10, .75, @a) }, 'sum(aₙHₙ(x)) with error check';
  is-approx $val, 29.591702461242672, :rel-tol(10⁻¹⁵), 'Hₙ(x) with error check: value';
  ok hermite-prob(0, .75) == 1, 'Heₙ(x)';
  lives-ok { ($val, $err) = hermite-prob-e(0, .75) }, 'Heₙ(x) with error check';
  ok $val == 1, 'Heₙ(x) with error check: value';
  lives-ok { @out = hermite-prob-array(0, .75) }, 'Heₙ(x) array';
  ok @out[0] == 1, 'Heₙ(x) array: results';
  is-approx hermite-prob-series(10, .75, @a), 2.087602422572672, :rel-tol(10⁻¹⁵), 'sum(aₙHeₙ(x))';
  lives-ok { ($val, $err) = hermite-prob-series-e(10, .75, @a) }, 'sum(aₙHeₙ(x)) with error check';
  is-approx $val, 2.087602422572672, :rel-tol(10⁻¹⁵), 'sum(aₙHeₙ(x)) with error check: value';
  ok hermite-der(225, 128, .75) == 0, 'm-derivative of Hₙ(x)';
  lives-ok { ($val, $err) = hermite-der-e(225, 128, .75) }, 'm-derivative of Hₙ(x) with error check';
  ok $val == 0, 'm-derivative of Hₙ(x) with error check: value';
  lives-ok { @out = hermite-array-der(0, 10, .75) }, 'm-derivative of Hₙ(x) array';
  ok @out[0] == 1, 'm-derivative of Hₙ(x) array [0]';
  is-approx @out[10], 38740.4384765625, :rel-tol(10⁻¹⁵), 'm-derivative of Hₙ(x) array [10]';
  lives-ok { @out = hermite-der-array(10, 50, .75) }, 'derivatives of Hₙ(x) array';
  is-approx @out[0], -8.26632218305863100726861832e38, :rel-tol(10⁻¹⁵), 'derivatives of Hₙ(x) array [0]';
  is-approx @out[1], 2.40954750392844799126151557e40, :rel-tol(10⁻¹⁵), 'derivatives of Hₙ(x) array [1]';
  ok hermite-prob-der(225, 128, .75) == 0, 'm-derivative of probabilistic Heₙ(x)';
  lives-ok { ($val, $err) = hermite-prob-der-e(225, 128, .75) }, 'm-derivative of probabilistic Heₙ(x) with error check';
  ok $val == 0, 'm-derivative of probabilistic Heₙ(x) with error check: value';
  lives-ok { @out = hermite-prob-array-der(0, 10, .75) }, 'm-derivative of probabilistic Heₙ(x) array';
  is-approx @out[10], 823.810509681701660156250, :rel-tol(10⁻¹⁵), 'm-derivative of Heₙ(x) array [10]';
  lives-ok { @out = hermite-prob-der-array(10, 50, .75) }, 'derivatives of probabilistic Heₙ(x) array';
  is-approx @out[10], 7.9614368698398116765703194e38, :rel-tol(10⁻¹⁵), 'derivatives of Heₙ(x) array [10]';
  is-approx hermite-func(0, 1.3), 0.322651504564963746879400858624, :rel-tol(10⁻¹⁵), 'ψₙ(x)';
  lives-ok { ($val, $err) = hermite-func-e(0, 1.3) }, 'ψₙ(x) with error check';
  is-approx $val, 0.322651504564963746879400858624, :rel-tol(10⁻¹⁵), 'ψₙ(x) with error check: value';
  lives-ok { @out = hermite-func-array(1, 1.3) }, 'ψₙ(x) array';
  is-approx @out[0], 0.322651504564963746879400858624, :rel-tol(10⁻¹⁵), 'ψₙ(x) array: value';
  is-approx hermite-func-series(10, .75, @a), 0.8171775729199896, :rel-tol(10⁻¹⁵), 'sum(aₙψₙ(x))';
  lives-ok { ($val, $err) = hermite-func-series-e(10, .75, @a) }, 'sum(aₙψₙ(x)) with error check';
  is-approx $val, 0.8171775729199896, :rel-tol(10⁻¹⁵), 'sum(aₙψₙ(x)) with error check: value';
  is-approx hermite-func-der(0, 28, .75), 0.235262808086212406493191404, :rel-tol(10⁻¹⁵), 'm-derivative of ψₙ(x)';
  lives-ok { ($val, $err) = hermite-func-der-e(0, 28,.75) }, 'm-derivative of ψₙ(x) with error check';
  is-approx $val, 0.235262808086212406493191404, :rel-tol(10⁻¹⁵), 'm-derivative of ψₙ(x) with error check: value';
  ok hermite-zero(17, 1) == 0.531633001342654731349086553718, 's-th zero of Hₙ(x)';
  lives-ok { ($val, $err) = hermite-zero-e(17, 1) }, 's-th zero of Hₙ(x) with error check';
  ok $val == 0.531633001342654731349086553718, 's-th zero of Hₙ(x) with error check: value';
  ok hermite-prob-zero(24, 1) == 0.317370096629452319318170455994, 's-th zero of probabilistic Hₙ(x)';
  lives-ok { ($val, $err) = hermite-prob-zero-e(24, 1) }, 's-th zero of probabilistic Hₙ(x) with error check';
  ok $val == 0.317370096629452319318170455994, 's-th zero of probabilistic Hₙ(x) with error check: value';
  ok hermite-func-zero(24, 1) == 0.22441454747251557, 's-th zero of ψₙ(x)';
  lives-ok { ($val, $err) = hermite-func-zero-e(24, 1) }, 's-th zero of ψₙ(x) with error check';
  ok $val == 0.22441454747251557, 's-th zero of ψₙ(x) with error check: value';
}, 'Hermite polynomials and functions';

subtest {
  my ($val, $err, $e10);
  is-approx F01(1, .5), 1.5660829297563505373, :rel-tol(10⁻¹⁵), '₀F₁(c,x)';
  lives-ok { ($val, $err) = F01-e(1, .5) }, '₀F₁(c,x) with error check';
  is-approx $val, 1.5660829297563505373, :rel-tol(10⁻¹⁵), '₀F₁(c,x) with error check: value';
  is-approx F11-int(1, 1, .5), 1.6487212707001281468, :rel-tol(10⁻¹⁵), '₁F₁(m,n,x)';
  lives-ok { ($val, $err) = F11-int-e(1, 1, .5) }, '₁F₁(m,n,x) with error check';
  is-approx $val, 1.6487212707001281468, :rel-tol(10⁻¹⁵), '₁F₁(m,n,x) with error check: value';
  is-approx F11(1, 1.5, 1), 2.0300784692787049755, :rel-tol(10⁻¹⁵), '₁F₁(a,b,x)';
  lives-ok { ($val, $err) = F11-e(1, 1.5, 1) }, '₁F₁(a,b,x) with error check';
  is-approx $val, 2.0300784692787049755, :rel-tol(10⁻¹⁵), '₁F₁(a,b,x) with error check: value';
  is-approx U-int(1, 1, 2), 0.3613286168882225847, :rel-tol(10⁻¹⁵), 'U(m,n,x)';
  lives-ok { ($val, $err) = U-int-e(1, 1, 2) }, 'U(m,n,x) with error check';
  is-approx $val, 0.3613286168882225847, :rel-tol(10⁻¹⁵), 'U(m,n,x) with error check: value';
  lives-ok { ($val, $err, $e10) = U-int-e10(1, 1, 2) }, 'U(m,n,x) with extended range error check';
  is-approx $val, 0.3613286168882225847, :rel-tol(10⁻¹⁵), 'U(m,n,x) with extended range error check: value';
  is-approx U(1, 1.2, 2), 0.3835044780075602550, :rel-tol(10⁻¹⁵), 'U(a,b,x)';
  lives-ok { ($val, $err) = U-e(1, 1.2, 2) }, 'U(a,b,x) with error check';
  is-approx $val, 0.3835044780075602550, :rel-tol(10⁻¹⁵), 'U(a,b,x) with error check: value';
  lives-ok { ($val, $err, $e10) = U-e10(1, 1.2, 2) }, 'U(a,b,x) with extended range error check';
  is-approx $val, 0.3835044780075602550, :rel-tol(10⁻¹⁵), 'U(a,b,x) with extended range error check: value';
  is-approx F21(1, 1, 1, .5), 2, :rel-tol(10⁻¹⁵), '₂F₁(a,b,c,x)';
  lives-ok { ($val, $err) = F21-e(1, 1, 1, .5) }, '₂F₁(a,b,c,x) with error check';
  is-approx $val, 2, :rel-tol(10⁻¹⁵), '₂F₁(a,b,c,x) with error check: value';
  is-approx F21-conj(1, 1, 1, .5), 3.352857095662929028, :rel-tol(10⁻¹⁵), '₂F₁(aᵣ+iaᵢ,aR-iaI,c,x)';
  lives-ok { ($val, $err) = F21-conj-e(1, 1, 1, .5) }, '₂