### ----------------------------------------------------
### -- Math::Libgsl::Function
### -- Licenses: Artistic-2.0
### -- Authors: Fernando Santagata
### -- File: t/01-raw-function.rakutest
### ----------------------------------------------------
### -- Chunk 1 of 5
#!/usr/bin/env raku

use Test;
use lib 'lib';
use Math::Libgsl::Raw::Function :ALL;
use Math::Libgsl::Constants;
use NativeCall;

subtest {
  is-approx gsl_sf_airy_Ai(0e0, GSL_PREC_DOUBLE), 0.355028053887817, :rel-tol(10⁻¹⁵), 'Ai';
  my gsl_sf_result $res .= new;
  ok gsl_sf_airy_Ai_e(0e0, GSL_PREC_DOUBLE, $res) == 0, 'Ai with error check';
  is-approx $res.val, 0.355028053887817, :rel-tol(10⁻¹⁵), 'Ai: value';
  ok $res.err < 10⁻¹⁶, 'Ai: error';
  is-approx gsl_sf_airy_Bi(0e0, GSL_PREC_DOUBLE), 0.614926627446001, :rel-tol(10⁻¹⁵), 'Bi';
  ok gsl_sf_airy_Bi_e(0e0, GSL_PREC_DOUBLE, $res) == 0, 'Bi with error check';
  is-approx $res.val, 0.614926627446001, :rel-tol(10⁻¹⁵), 'Bi: value';
  ok $res.err < 10⁻¹⁵, 'Bi: error';
  is-approx gsl_sf_airy_Ai_scaled(10e0, GSL_PREC_DOUBLE), 0.158123666854346, :rel-tol(10⁻¹⁵), 'Ai scaled';
  ok gsl_sf_airy_Ai_scaled_e(10e0, GSL_PREC_DOUBLE, $res) == 0, 'Ai scaled with error check';
  is-approx $res.val, 0.158123666854346, :rel-tol(10⁻¹⁵), 'Ai scaled: value';
  is-approx gsl_sf_airy_Bi_scaled(10e0, GSL_PREC_DOUBLE), 0.318340105336734, :rel-tol(10⁻¹⁴), 'Bi scaled';
  ok gsl_sf_airy_Bi_scaled_e(10e0, GSL_PREC_DOUBLE, $res) == 0, 'Bi scaled with error check';
  is-approx $res.val, 0.318340105336734, :rel-tol(10⁻¹⁴), 'Bi scaled: value';
  is-approx gsl_sf_airy_Ai_deriv(0e0, GSL_PREC_DOUBLE), -0.258819403792807, :rel-tol(10⁻¹⁵), 'Ai deriv';
  ok gsl_sf_airy_Ai_deriv_e(0e0, GSL_PREC_DOUBLE, $res) == 0, 'Ai deriv with error check';
  is-approx $res.val, -0.258819403792807, :rel-tol(10⁻¹⁵), 'Ai deriv: value';
  is-approx gsl_sf_airy_Bi_deriv(0e0, GSL_PREC_DOUBLE), 0.448288357353826, :rel-tol(10⁻¹⁵), 'Bi deriv';
  ok gsl_sf_airy_Bi_deriv_e(0e0, GSL_PREC_DOUBLE, $res) == 0, 'Bi deriv with error check';
  is-approx $res.val, 0.448288357353826, :rel-tol(10⁻¹⁵), 'Bi deriv: value';
  is-approx gsl_sf_airy_Ai_deriv_scaled(10e0, GSL_PREC_DOUBLE), -0.503909360711311, :rel-tol(10⁻¹⁵), 'Ai deriv scaled';
  ok gsl_sf_airy_Ai_deriv_scaled_e(10e0, GSL_PREC_DOUBLE, $res) == 0, 'Ai deriv scaled with error check';
  is-approx $res.val, -0.503909360711311, :rel-tol(10⁻¹⁵), 'Ai deriv scaled: value';
  is-approx gsl_sf_airy_Bi_deriv_scaled(10e0, GSL_PREC_DOUBLE), 0.998555942673837, :rel-tol(10⁻¹⁵), 'Bi deriv scaled';
  ok gsl_sf_airy_Bi_deriv_scaled_e(10e0, GSL_PREC_DOUBLE, $res) == 0, 'Bi deriv scaled with error check';
  is-approx $res.val, 0.998555942673837, :rel-tol(10⁻¹⁵), 'Bi deriv scaled: value';
  is-approx gsl_sf_airy_zero_Ai(1), -2.338107410459767, :rel-tol(10⁻¹⁵), 'zero of Ai';
  ok gsl_sf_airy_zero_Ai_e(1, $res) == 0, 'zero of Ai with error check';
  is-approx $res.val, -2.338107410459767, :rel-tol(10⁻¹⁵), 'zero of Ai: value';
  ok gsl_sf_airy_zero_Bi(1).round(10⁻¹⁴) == -1.17371322270913, 'zero of Bi';
  ok gsl_sf_airy_zero_Bi_e(1, $res) == 0, 'zero of Bi with error check';
  ok $res.val.round(10⁻¹⁴) == -1.17371322270913, 'zero of Bi: value';
  ok gsl_sf_airy_zero_Ai_deriv(1).round(10⁻¹⁴) == -1.01879297164747, 'zero of Ai deriv';
  ok gsl_sf_airy_zero_Ai_deriv_e(1, $res) == 0, 'zero of Ai deriv with error check';
  ok $res.val.round(10⁻¹⁴) == -1.01879297164747, 'zero of Ai deriv: value';
  ok gsl_sf_airy_zero_Bi_deriv(1).round(10⁻¹⁴) == -2.29443968261412, 'zero of Bi deriv';
  ok gsl_sf_airy_zero_Bi_deriv_e(1, $res) == 0, 'zero of Bi deriv with error check';
  ok $res.val.round(10⁻¹⁴) == -2.29443968261412, 'zero of Bi deriv: value';
}, 'raw - Airy functions';

subtest {
  ok gsl_sf_bessel_J0(0e0) == 1, 'J0';
  my gsl_sf_result $res .= new;
  ok gsl_sf_bessel_J0_e(2.0e0, $res) == 0, 'J0 with error check';
  is-approx $res.val, 0.223890779141236, :rel-tol(10⁻¹⁴), 'J0 with error check: value';
  ok gsl_sf_bessel_J1(0e0) == 0, 'J1';
  ok gsl_sf_bessel_J1_e(2.0e0, $res) == 0, 'J1 with error check';
  is-approx $res.val, 0.576724807756873, :rel-tol(10⁻¹⁵), 'J1 with error check: value';
  ok gsl_sf_bessel_Jn(2, 0e0) == 0, 'Jn';
  ok gsl_sf_bessel_Jn_e(4, 0.1e0, $res) == 0, 'Jn with error check';
  is-approx $res.val, 2.602864854568404e-07, :rel-tol(10⁻¹⁵), 'Jn with error check: value';
  my $result = CArray[num64].allocate: 3;
  ok gsl_sf_bessel_Jn_array(0, 2, 0e0, $result) == 0, 'Jn array returns ok';
  is-deeply $result.list, (1e0, 0e0, 0e0), 'Jn array results';
  is-approx gsl_sf_bessel_Y0(0.1e0), -1.534238651350367, :rel-tol(10⁻¹⁵), 'Y0';
  ok gsl_sf_bessel_Y0_e(0.1e0, $res) == 0, 'Y0 with error check';
  is-approx $res.val, -1.534238651350367, :rel-tol(10⁻¹⁵), 'Y0 with error check: value';
  is-approx gsl_sf_bessel_Y1(0.1e0), -6.458951094702026, :rel-tol(10⁻¹⁵), 'Y1';
  ok gsl_sf_bessel_Y1_e(0.1e0, $res) == 0, 'Y1 with error check';
  is-approx $res.val, -6.458951094702026, :rel-tol(10⁻¹⁵), 'Y1 with error check: value';
  ok gsl_sf_bessel_Yn(4, 0.1e0) == -305832.2979335312, 'Yn';
  ok gsl_sf_bessel_Yn_e(4, 0.1e0, $res) == 0, 'Yn with error check';
  ok $res.val == -305832.2979335312, 'Yn with error check: value';
  ok gsl_sf_bessel_Yn_array(0, 2, 0.1e0, $result) == 0, 'Yn array returns ok';
  is-deeply $result.list».round(10⁻¹⁵), (-1.534238651350367, -6.458951094702026, -127.644783242690176), 'Yn array results';
  is-approx gsl_sf_bessel_I0(.1e0), 1.002501562934096, :rel-tol(10⁻¹⁵), 'I0';
  ok gsl_sf_bessel_I0_e(.1e0, $res) == 0, 'I0 with error check';
  is-approx $res.val, 1.002501562934096, :rel-tol(10⁻¹⁵), 'I0 with error check: value';
  is-approx gsl_sf_bessel_I1(0.1e0), 0.050062526047092694, :rel-tol(10⁻¹⁵), 'I1';
  ok gsl_sf_bessel_I1_e(0.1e0, $res) == 0, 'I1 with error check';
  is-approx $res.val, 0.050062526047092694, :rel-tol(10⁻¹⁵), 'I1 with error check: value';
  is-approx gsl_sf_bessel_In(-4, 0.1e0), 2.6054690212996574e-07, :rel-tol(10⁻¹⁵), 'In';
  ok gsl_sf_bessel_In_e(-4, 0.1e0, $res) == 0, 'In with error check';
  is-approx $res.val, 2.6054690212996574e-07, :rel-tol(10⁻¹⁵), 'In with error check: value';
  ok gsl_sf_bessel_In_array(0, 2, 0.1e0, $result) == 0, 'In array returns ok';
  is-deeply $result.list».round(10⁻¹⁵), (1.002501562934096, 0.050062526047093, 0.001251041992242), 'In array results';
  ok gsl_sf_bessel_I0_scaled(.1e0) == 0.9071009257823011, 'I0 scaled';
  ok gsl_sf_bessel_I0_scaled_e(.1e0, $res) == 0, 'I0 scaled with error check';
  ok $res.val == 0.9071009257823011, 'I0 scaled with error check: value';
  ok gsl_sf_bessel_I1_scaled(0.1e0) == 0.045298446808809324, 'I1 scaled';
  ok gsl_sf_bessel_I1_scaled_e(0.1e0, $res) == 0, 'I1 scaled with error check';
  ok $res.val == 0.045298446808809324, 'I1 scaled with error check: value';
  ok gsl_sf_bessel_In_scaled(-4, 0.1e0) == 2.3575258620054605e-07, 'In scaled';
  ok gsl_sf_bessel_In_scaled_e(-4, 0.1e0, $res) == 0, 'In scaled with error check';
  ok $res.val == 2.3575258620054605e-07, 'In scaled with error check: value';
  ok gsl_sf_bessel_In_scaled_array(0, 2, 0.1e0, $result) == 0, 'In scaled array returns ok';
  is-deeply $result.list».round(10⁻¹⁵), (0.907100925782301, 0.045298446808809, 0.001131989606115), 'In scaled array results';
  is-approx gsl_sf_bessel_K0(.1e0), 2.427069024702017, :rel-tol(10⁻¹⁵), 'K0';
  ok gsl_sf_bessel_K0_e(.1e0, $res) == 0, 'K0 with error check';
  ok $res.val == 2.427069024702017, 'K0 with error check: value';
  is-approx gsl_sf_bessel_K1(.1e0), 9.853844780870606, :rel-tol(10⁻¹⁵), 'K1';
  ok gsl_sf_bessel_K1_e(.1e0, $res) == 0, 'K1 with error check';
  ok $res.val == 9.853844780870606, 'K1 with error check: value';
  is-approx gsl_sf_bessel_Kn(0, .1e0), 2.427069024702017, :rel-tol(10⁻¹⁵), 'Kn';
  ok gsl_sf_bessel_Kn_e(0, .1e0, $res) == 0, 'Kn with error check';
  ok $res.val == 2.427069024702017, 'Kn with error check: value';
  ok gsl_sf_bessel_Kn_array(0, 2, .1e0, $result) == 0, 'Kn array returns ok';
  is-deeply $result.list».round(10⁻¹⁵), (2.427069024702017, 9.853844780870606, 199.503964642114144), 'Kn array results';
  is-approx gsl_sf_bessel_K0_scaled(.1e0), 2.682326102262895, :rel-tol(10⁻¹⁵), 'K0 scaled';
  ok gsl_sf_bessel_K0_scaled_e(.1e0, $res) == 0, 'K0 scaled with error check';
  ok $res.val == 2.682326102262895, 'K0 scaled with error check: value';
  is-approx gsl_sf_bessel_K1_scaled(.1e0), 10.890182683049698, :rel-tol(10⁻¹⁵), 'K1 scaled';
  ok gsl_sf_bessel_K1_scaled_e(.1e0, $res) == 0, 'K1 scaled with error check';
  ok $res.val == 10.890182683049698, 'K1 scaled with error check: value';
  is-approx gsl_sf_bessel_Kn_scaled(5, 2e0), 69.68655087607676, :rel-tol(10⁻¹⁵), 'Kn scaled';
  ok gsl_sf_bessel_Kn_scaled_e(5, 2e0, $res) == 0, 'Kn scaled with error check';
  is-approx $res.val, 69.68655087607676, :rel-tol(10⁻¹⁵), 'Kn scaled with error check: value';
  is-approx gsl_sf_bessel_Kn_scaled_array(5, 8, 2e0, $result), 0, :rel-tol(10⁻¹⁵), 'Kn scaled array';
  is-deeply $result.list».round(10⁻¹⁵), (69.68655087607676, 364.658500356566016, 2257.63755301547264), 'Kn scaled array results';
  is-approx gsl_sf_bessel_j0(1e0), 0.841470984807897, :rel-tol(10⁻¹⁵), 'j0';
  ok gsl_sf_bessel_j0_e(1e0, $res) == 0, 'j0 with error check';
  is-approx $res.val, 0.841470984807897, :rel-tol(10⁻¹⁵), 'j0 with error check: value';
  is-approx gsl_sf_bessel_j1(1e0), 0.301168678939757, :rel-tol(10⁻¹⁵), 'j1';
  ok gsl_sf_bessel_j1_e(1e0, $res) == 0, 'j1 with error check';
  is-approx $res.val, 0.301168678939757, :rel-tol(10⁻¹⁵), 'j1 with error check: value';
  is-approx gsl_sf_bessel_j2(1e0), 0.06203505201137386, :rel-tol(10⁻¹⁵), 'j2';
  ok gsl_sf_bessel_j2_e(1e0, $res) == 0, 'j2 with error check';
  is-approx $res.val, 0.06203505201137386, :rel-tol(10⁻¹⁵), 'j2 with error check: value';
  is-approx gsl_sf_bessel_jl(0, 0e0), 1, :rel-tol(10⁻¹⁵), 'jl';
  ok gsl_sf_bessel_jl_e(0, 0e0, $res) == 0, 'jl with error check';
  is-approx $res.val, 1, :rel-tol(10⁻¹⁵), 'jl with error check: value';
  ok gsl_sf_bessel_jl_array(2, 0e0, $result) == 0, 'jl array returns ok';
  is-deeply $result.list».round(10⁻¹⁵), (1.0, 0.0, 0.0), 'jl array scaled results';
  ok gsl_sf_bessel_jl_array(2, 0e0, $result) == 0, 'jl array steed returns ok';
  is-deeply $result.list».round(10⁻¹⁵), (1.0, 0.0, 0.0), 'jl array steed scaled results';
  is-approx gsl_sf_bessel_y0(1e0), -0.54030230586814, :rel-tol(10⁻¹⁵), 'y0';
  ok gsl_sf_bessel_y0_e(1e0, $res) == 0, 'y0 with error check';
  is-approx $res.val, -0.54030230586814, :rel-tol(10⁻¹⁵), 'y0 with error check: value';
  is-approx gsl_sf_bessel_y1(1e0), -1.381773290676036, :rel-tol(10⁻¹⁵), 'y1';
  ok gsl_sf_bessel_y1_e(1e0, $res) == 0, 'y1 with error check';
  is-approx $res.val, -1.381773290676036, :rel-tol(10⁻¹⁵), 'y1 with error check: value';
  is-approx gsl_sf_bessel_y2(1e0), -3.605017566159968, :rel-tol(10⁻¹⁵), 'y2';
  ok gsl_sf_bessel_y2_e(1e0, $res) == 0, 'y2 with error check';
  is-approx $res.val, -3.605017566159968, :rel-tol(10⁻¹⁵), 'y2 with error check: value';
  is-approx gsl_sf_bessel_yl(0, 1e0), -0.54030230586814, :rel-tol(10⁻¹⁵), 'yl';
  ok gsl_sf_bessel_yl_e(0, 1e0, $res) == 0, 'yl with error check';
  is-approx $res.val, -0.54030230586814, :rel-tol(10⁻¹⁵), 'yl with error check: value';
  ok gsl_sf_bessel_yl_array(0, 1e0, $result) == 0, 'yl array';
  is-deeply $result.list».round(10⁻¹⁵), (-0.54030230586814, .0, .0), 'yl array results';
  ok gsl_sf_bessel_i0_scaled(0e0) == 1, 'i0 scaled';
  ok gsl_sf_bessel_i0_scaled_e(0e0, $res) == 0, 'i0 scaled with error check';
  ok $res.val == 1, 'i0 scaled with error check: value';
  ok gsl_sf_bessel_i1_scaled(0e0) == .0, 'i1 scaled';
  ok gsl_sf_bessel_i1_scaled_e(0e0, $res) == 0, 'i1 scaled with error check';
  ok $res.val == .0, 'i1 scaled with error check: value';
  ok gsl_sf_bessel_i2_scaled(0e0) == .0, 'i2 scaled';
  ok gsl_sf_bessel_i2_scaled_e(0e0, $res) == 0, 'i2 scaled with error check';
  ok $res.val == .0, 'i2 scaled with error check: value';
  ok gsl_sf_bessel_il_scaled(0, 0e0) == 1e0, 'il scaled';
  ok gsl_sf_bessel_il_scaled_e(0, 0e0, $res) == 0, 'il scaled with error check';
  ok $res.val == 1e0, 'il scaled with error check: value';
  ok gsl_sf_bessel_il_scaled_array(3, 0e0, $result) == 0, 'il scaled array';
  is-deeply $result.list, (1e0, 0e0, 0e0), 'il scaled array results';
  is-approx gsl_sf_bessel_k0_scaled(2e0), 0.785398163397448, :rel-tol(10⁻¹⁵), 'k0 scaled';
  ok gsl_sf_bessel_k0_scaled_e(2e0, $res) == 0, 'k0 scaled with error check';
  is-approx $res.val, 0.785398163397448, :rel-tol(10⁻¹⁵), 'k0 scaled with error check: value';
  is-approx gsl_sf_bessel_k1_scaled(2e0), 1.178097245096172, :rel-tol(10⁻¹⁵), 'k1 scaled';
  ok gsl_sf_bessel_k1_scaled_e(2e0, $res) == 0, 'k1 scaled with error check';
  is-approx $res.val, 1.178097245096172, :rel-tol(10⁻¹⁵), 'k1 scaled with error check: value';
  is-approx gsl_sf_bessel_k2_scaled(2e0), 2.552544031041707, :rel-tol(10⁻¹⁵), 'k2 scaled';
  ok gsl_sf_bessel_k2_scaled_e(2e0, $res) == 0, 'k2 scaled with error check';
  is-approx $res.val, 2.552544031041707, :rel-tol(10⁻¹⁵), 'k2 scaled with error check: value';
  is-approx gsl_sf_bessel_kl_scaled(5, 2e0), 138.107358294920048, :rel-tol(10⁻¹⁵), 'kl scaled';
  ok gsl_sf_bessel_kl_scaled_e(5, 2e0, $res) == 0, 'kl scaled with error check';
  is-approx $res.val, 138.107358294920048, :rel-tol(10⁻¹⁵), 'kl scaled with error check: value';
  is-approx gsl_sf_bessel_kl_scaled_array(2, 2e0, $result), 0, :rel-tol(10⁻¹⁵), 'kl scaled array';
  is-deeply $result.list».round(10⁻¹⁵), (0.785398163397448, 1.178097245096172, 2.552544031041707), 'kl scaled array results';
  is-approx gsl_sf_bessel_Jnu(.75e0, 1e0), 0.558652493204891, :rel-tol(10⁻¹⁵), 'Jnu';
  ok gsl_sf_bessel_Jnu_e(.75e0, 1e0, $res) == 0, 'Jnu with error check';
  is-approx $res.val, 0.558652493204891, :rel-tol(10⁻¹⁵), 'Jnu with error check: value';
  my CArray[num64] $v .= new: .1e0, .2e0 … 10e0;
  ok gsl_sf_bessel_sequence_Jnu_e(2e0, GSL_MODE_DEFAULT, 100, $v) == 0, 'Jnu sequence with error check';
  is-approx $v[0], 0.0012489586587999192, :rel-tol(10⁻¹⁵), 'Jnu sequence with error check: value [0]';
  is-approx $v[20], 0.37462362515054953, :rel-tol(10⁻¹⁵), 'Jnu sequence with error check: value [20]';
  is-approx gsl_sf_bessel_Ynu(.0001e0, 1e0), 0.08813676933044477, :rel-tol(10⁻¹⁵), 'Ynu';
  ok gsl_sf_bessel_Ynu_e(.0001e0, 1e0, $res) == 0, 'Ynu with error check';
  is-approx $res.val, 0.08813676933044477, :rel-tol(10⁻¹⁵), 'Ynu with error check: value';
  is-approx gsl_sf_bessel_Inu(1e0, 1e0), 0.565159103992485, :rel-tol(10⁻¹⁵), 'Inu';
  ok gsl_sf_bessel_Inu_e(1e0, 1e0, $res) == 0, 'Inu with error check';
  is-approx $res.val, 0.565159103992485, :rel-tol(10⁻¹⁵), 'Inu with error check: value';
  is-approx gsl_sf_bessel_Inu_scaled(1e0, 1e0), 0.20791041534970847, :rel-tol(10⁻¹⁵), 'Inu scaled';
  ok gsl_sf_bessel_Inu_scaled_e(1e0, 1e0, $res) == 0, 'Inu scaled with error check';
  is-approx $res.val, 0.20791041534970847, :rel-tol(10⁻¹⁵), 'Inu scaled with error check: value';
  is-approx gsl_sf_bessel_Knu(1e0, 1e0), 0.601907230197235, :rel-tol(10⁻¹⁵), 'Knu';
  ok gsl_sf_bessel_Knu_e(1e0, 1e0, $res) == 0, 'Knu with error check';
  is-approx $res.val, 0.601907230197235, :rel-tol(10⁻¹⁵), 'Knu with error check: value';
  is-approx gsl_sf_bessel_lnKnu(1e0, 1e0), -0.507651948210752, :rel-tol(10⁻¹⁵), 'lnKnu';
  ok gsl_sf_bessel_lnKnu_e(1e0, 1e0, $res) == 0, 'lnKnu with error check';
  is-approx $res.val, -0.507651948210752, :rel-tol(10⁻¹⁵), 'lnKnu with error check: value';
  is-approx gsl_sf_bessel_Knu_scaled(1e0, 1e0), 1.636153486263258, :rel-tol(10⁻¹⁵), 'Knu scaled';
  ok gsl_sf_bessel_Knu_scaled_e(1e0, 1e0, $res) == 0, 'Knu scaled with error check';
  is-approx $res.val, 1.636153486263258, :rel-tol(10⁻¹⁵), 'Knu scaled with error check: value';
  is-approx gsl_sf_bessel_zero_J0(1), 2.404825557695771, :rel-tol(10⁻¹⁵), 'zero of J0';
  ok gsl_sf_bessel_zero_J0_e(1, $res) == 0, 'zero of J0 with error check';
  is-approx $res.val, 2.404825557695771, :rel-tol(10⁻¹⁵), 'zero of J0 with error check: value';
  is-approx gsl_sf_bessel_zero_J1(1), 3.831705970207503, :rel-tol(10⁻¹⁵), 'zero of J1';
  ok gsl_sf_bessel_zero_J1_e(1, $res) == 0, 'zero of J1 with error check';
  is-approx $res.val, 3.831705970207503, :rel-tol(10⁻¹⁵), 'zero of J1 with error check: value';
  is-approx gsl_sf_bessel_zero_Jnu(0e0, 1), 2.40