
#line 1 "../gen/tmpl/lib.c"
/*
  gsl_sys.c
  Ruby/Numo::GSL - GSL wrapper for Ruby/Numo::NArray

  created on: 2017-03-11
  Copyright (C) 2017 Masahiro Tanaka
*/

#include <ruby.h>
#include <assert.h>
#include "numo/narray.h"
#include "numo/template.h"
#include "../numo_gsl.h"
#line 15 "../gen/tmpl/lib.c"
#include <gsl/gsl_sys.h>
#include <gsl/gsl_pow_int.h>
#include <gsl/gsl_math.h>
#include <gsl/gsl_mode.h>

#line 18 "../gen/tmpl/lib.c"
static VALUE mGSL;



#line 1 "../gen/tmpl/module.c"
/*
  module definition: Numo::GSL
*/



#line 1 "../gen/tmpl/m_Int_f_DFloat.c"
static void
iter_sys_s_isnan(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x;
    int      y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_isnan(x);
        SET_DATA_STRIDE(p2,s2,int,y);
    }
}

/*
  @overload isnan(x)
  @param  [DFloat]   x
  @return [Int]      result

  This function returns 1 if x is not-a-number.
*/
static VALUE
sys_s_isnan(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cI,0}};
    ndfunc_t ndf = {iter_sys_s_isnan, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_Int_f_DFloat.c"
static void
iter_sys_s_isinf(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x;
    int      y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_isinf(x);
        SET_DATA_STRIDE(p2,s2,int,y);
    }
}

/*
  @overload isinf(x)
  @param  [DFloat]   x
  @return [Int]      result

  This function returns +1 if x is positive infinity,
-1 if x is negative infinity and 0
otherwise.Note that the C99 standard only requires the
system isinf function to return a non-zero value, without the
sign of the infinity.  The implementation in some earlier versions of
GSL used the system isinf function and may have this behavior
on some platforms.  Therefore, it is advisable to test the sign of
x separately, if needed, rather than relying the sign of the
return value from gsl_isinf().
*/
static VALUE
sys_s_isinf(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cI,0}};
    ndfunc_t ndf = {iter_sys_s_isinf, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_Int_f_DFloat.c"
static void
iter_sys_s_finite(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x;
    int      y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_finite(x);
        SET_DATA_STRIDE(p2,s2,int,y);
    }
}

/*
  @overload finite(x)
  @param  [DFloat]   x
  @return [Int]      result

  This function returns 1 if x is a real number, and 0 if it is
infinite or not-a-number.
*/
static VALUE
sys_s_finite(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cI,0}};
    ndfunc_t ndf = {iter_sys_s_finite, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_log1p(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_log1p(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload log1p(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  This function computes the value of \log(1+x) in a way that is
accurate for small x. It provides an alternative to the BSD math
function log1p(x).
*/
static VALUE
sys_s_log1p(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_log1p, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_expm1(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_expm1(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload expm1(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  This function computes the value of \exp(x)-1 in a way that is
accurate for small x. It provides an alternative to the BSD math
function expm1(x).
*/
static VALUE
sys_s_expm1(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_expm1, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat_x2.c"
static void
iter_sys_s_hypot(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2, *p3;
    ssize_t  s1, s2, s3;
    double   x, y, z;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);
    INIT_PTR(lp, 2, p3, s3);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        GET_DATA_STRIDE(p2,s2,double,y);
        z = gsl_hypot(x,y);
        SET_DATA_STRIDE(p3,s3,double,z);
    }
}

/*
  @overload hypot(x, y)
  @param  [DFloat]   x
  @param  [DFloat]   y
  @return [DFloat]   result

  This function computes the value of
$\sqrt{x^2 + y^2}$
\sqrt[x^2 + y^2] in a way that avoids overflow. It provides an
alternative to the BSD math function hypot(x,y).
*/
static VALUE
sys_s_hypot(VALUE mod, VALUE v0, VALUE v1)
{
    ndfunc_arg_in_t ain[2] = {{cDF,0},{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_hypot, STRIDE_LOOP|NDF_EXTRACT, 2,1, ain,aout};

    return na_ndloop(&ndf, 2, v0, v1);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat_x3.c"
static void
iter_sys_s_hypot3(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2, *p3, *p4;
    ssize_t  s1, s2, s3, s4;
    double   x1, x2, x3, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);
    INIT_PTR(lp, 2, p3, s3);
    INIT_PTR(lp, 3, p4, s4);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x1);
        GET_DATA_STRIDE(p2,s2,double,x2);
        GET_DATA_STRIDE(p3,s3,double,x3);
        y = gsl_hypot3(x1,x2,x3);
        SET_DATA_STRIDE(p4,s4,double,y);
    }
}

/*
  @overload hypot3(x, y, z)
  @param  [DFloat]   x
  @param  [DFloat]   y
  @param  [DFloat]   z
  @return [DFloat]   result

  This function computes the value of
$\sqrt{x^2 + y^2 + z^2}$
\sqrt[x^2 + y^2 + z^2] in a way that avoids overflow.
*/
static VALUE
sys_s_hypot3(VALUE mod, VALUE v0, VALUE v1, VALUE v2)
{
    ndfunc_arg_in_t ain[3] = {{cDF,0},{cDF,0},{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_hypot3, STRIDE_LOOP|NDF_EXTRACT, 3,1, ain,aout};

    return na_ndloop(&ndf, 3, v0, v1, v2);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_acosh(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_acosh(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload acosh(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  This function computes the value of \arccosh(x). It provides an
alternative to the standard math function acosh(x).
*/
static VALUE
sys_s_acosh(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_acosh, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_asinh(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_asinh(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload asinh(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  This function computes the value of \arcsinh(x). It provides an
alternative to the standard math function asinh(x).
*/
static VALUE
sys_s_asinh(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_asinh, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_atanh(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_atanh(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload atanh(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  This function computes the value of \arctanh(x). It provides an
alternative to the standard math function atanh(x).
*/
static VALUE
sys_s_atanh(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_atanh, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat_Int.c"
static void
iter_sys_s_ldexp(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2, *p3;
    ssize_t  s1, s2, s3;
    double   x, z;
    int      y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);
    INIT_PTR(lp, 2, p3, s3);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        GET_DATA_STRIDE(p2,s2,int,y);
        z = gsl_ldexp(x,y);
        SET_DATA_STRIDE(p3,s3,double,z);
    }
}

/*
  @overload ldexp(x, e)
  @param  [DFloat]   x
  @param  [DFloat]   e
  @return [DFloat]   result

  This function computes the value of x * 2^e. It provides an
alternative to the standard math function ldexp(x,e).
*/
static VALUE
sys_s_ldexp(VALUE mod, VALUE v0, VALUE v1)
{
    ndfunc_arg_in_t ain[2] = {{cDF,0},{cInt,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_ldexp, STRIDE_LOOP|NDF_EXTRACT, 2,1, ain,aout};

    return na_ndloop(&ndf, 2, v0, v1);
}


#line 1 "../gen/tmpl/m_DFloat_Int_f_DFloat.c"
static void
iter_sys_s_frexp(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2, *p3;
    ssize_t  s1, s2, s3;
    double   x, z;
    int      y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);
    INIT_PTR(lp, 2, p3, s3);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        z = gsl_frexp(x,&y);
        SET_DATA_STRIDE(p2,s2,double,z);
        SET_DATA_STRIDE(p3,s3,int,y);
    }
}

/*
  @overload frexp(x)
  @param  [DFloat]   x
  @return [DFloat]   array of [result, e]

  This function splits the number x into its normalized fraction
f and exponent e, such that x = f * 2^e and
$0.5 \le f < 1$
0.5 <= f < 1. The function returns f and stores the
exponent in e. If x is zero, both f and e
are set to zero. This function provides an alternative to the standard
math function frexp(x, e).
*/
static VALUE
sys_s_frexp(VALUE mod, VALUE v0, VALUE v1)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[2] = {{cDF,0},{cInt,0}};
    ndfunc_t ndf = {iter_sys_s_frexp, STRIDE_LOOP|NDF_EXTRACT, 1,2, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat_Int.c"
static void
iter_sys_s_pow_int(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2, *p3;
    ssize_t  s1, s2, s3;
    double   x, z;
    int      y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);
    INIT_PTR(lp, 2, p3, s3);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        GET_DATA_STRIDE(p2,s2,int,y);
        z = gsl_pow_int(x,y);
        SET_DATA_STRIDE(p3,s3,double,z);
    }
}

/*
  @overload pow_int(x, n)
  @param  [DFloat]   x
  @param  [DFloat]   n
  @return [DFloat]   result

  These routines computes the power x^n for integer n.  The
power is computed efficiently---for example, x^8 is computed as
((x^2)^2)^2, requiring only 3 multiplications.  A version of this
function which also computes the numerical error in the result is
available as gsl_sf_pow_int_e.
*/
static VALUE
sys_s_pow_int(VALUE mod, VALUE v0, VALUE v1)
{
    ndfunc_arg_in_t ain[2] = {{cDF,0},{cInt,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_pow_int, STRIDE_LOOP|NDF_EXTRACT, 2,1, ain,aout};

    return na_ndloop(&ndf, 2, v0, v1);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat_UInt.c"
static void
iter_sys_s_pow_uint(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2, *p3;
    ssize_t  s1, s2, s3;
    double   x, z;
    unsigned int y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);
    INIT_PTR(lp, 2, p3, s3);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        GET_DATA_STRIDE(p2,s2,unsigned int,y);
        z = gsl_pow_uint(x,y);
        SET_DATA_STRIDE(p3,s3,double,z);
    }
}

/*
  @overload pow_uint(x, n)
  @param  [DFloat]   x
  @param  [DFloat]   n
  @return [DFloat]   result

  These routines computes the power x^n for integer n.  The
power is computed efficiently---for example, x^8 is computed as
((x^2)^2)^2, requiring only 3 multiplications.  A version of this
function which also computes the numerical error in the result is
available as gsl_sf_pow_int_e.
*/
static VALUE
sys_s_pow_uint(VALUE mod, VALUE v0, VALUE v1)
{
    ndfunc_arg_in_t ain[2] = {{cDF,0},{cUInt,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_pow_uint, STRIDE_LOOP|NDF_EXTRACT, 2,1, ain,aout};

    return na_ndloop(&ndf, 2, v0, v1);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_pow_2(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_pow_2(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload pow_2(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  These functions can be used to compute small integer powers x^2,
x^3, etc. efficiently. The functions will be inlined when 
HAVE_INLINE is defined, so that use of these functions 
should be as efficient as explicitly writing the corresponding 
product expression.
*/
static VALUE
sys_s_pow_2(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_pow_2, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_pow_3(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_pow_3(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload pow_3(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  These functions can be used to compute small integer powers x^2,
x^3, etc. efficiently. The functions will be inlined when 
HAVE_INLINE is defined, so that use of these functions 
should be as efficient as explicitly writing the corresponding 
product expression.
*/
static VALUE
sys_s_pow_3(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_pow_3, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_pow_4(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_pow_4(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload pow_4(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  These functions can be used to compute small integer powers x^2,
x^3, etc. efficiently. The functions will be inlined when 
HAVE_INLINE is defined, so that use of these functions 
should be as efficient as explicitly writing the corresponding 
product expression.
*/
static VALUE
sys_s_pow_4(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_pow_4, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_pow_5(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_pow_5(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload pow_5(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  These functions can be used to compute small integer powers x^2,
x^3, etc. efficiently. The functions will be inlined when 
HAVE_INLINE is defined, so that use of these functions 
should be as efficient as explicitly writing the corresponding 
product expression.
*/
static VALUE
sys_s_pow_5(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_pow_5, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_pow_6(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_pow_6(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload pow_6(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  These functions can be used to compute small integer powers x^2,
x^3, etc. efficiently. The functions will be inlined when 
HAVE_INLINE is defined, so that use of these functions 
should be as efficient as explicitly writing the corresponding 
product expression.
*/
static VALUE
sys_s_pow_6(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_pow_6, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_pow_7(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_pow_7(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload pow_7(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  These functions can be used to compute small integer powers x^2,
x^3, etc. efficiently. The functions will be inlined when 
HAVE_INLINE is defined, so that use of these functions 
should be as efficient as explicitly writing the corresponding 
product expression.
*/
static VALUE
sys_s_pow_7(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_pow_7, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_pow_8(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_pow_8(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload pow_8(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  These functions can be used to compute small integer powers x^2,
x^3, etc. efficiently. The functions will be inlined when 
HAVE_INLINE is defined, so that use of these functions 
should be as efficient as explicitly writing the corresponding 
product expression.
*/
static VALUE
sys_s_pow_8(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_pow_8, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_DFloat_f_DFloat.c"
static void
iter_sys_s_pow_9(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2;
    ssize_t  s1, s2;
    double   x, y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x);
        y = gsl_pow_9(x);
        SET_DATA_STRIDE(p2,s2,double,y);
    }
}

/*
  @overload pow_9(x)
  @param  [DFloat]   x
  @return [DFloat]   result

  These functions can be used to compute small integer powers x^2,
x^3, etc. efficiently. The functions will be inlined when 
HAVE_INLINE is defined, so that use of these functions 
should be as efficient as explicitly writing the corresponding 
product expression.
*/
static VALUE
sys_s_pow_9(VALUE mod, VALUE v0)
{
    ndfunc_arg_in_t ain[1] = {{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cDF,0}};
    ndfunc_t ndf = {iter_sys_s_pow_9, STRIDE_LOOP|NDF_EXTRACT, 1,1, ain,aout};

    return na_ndloop(&ndf, 1, v0);
}


#line 1 "../gen/tmpl/m_Int_f_DFloat_x3.c"
static void
iter_sys_s_fcmp(na_loop_t *const lp)
{
    size_t   i;
    char    *p1, *p2, *p3, *p4;
    ssize_t  s1, s2, s3, s4;
    double   x1, x2, x3;
    int      y;

    INIT_COUNTER(lp, i);
    INIT_PTR(lp, 0, p1, s1);
    INIT_PTR(lp, 1, p2, s2);
    INIT_PTR(lp, 2, p3, s3);
    INIT_PTR(lp, 3, p4, s4);

    for (; i--; ) {
        GET_DATA_STRIDE(p1,s1,double,x1);
        GET_DATA_STRIDE(p2,s2,double,x2);
        GET_DATA_STRIDE(p3,s3,double,x3);
        y = gsl_fcmp(x1,x2,x3);
        SET_DATA_STRIDE(p4,s4,int,y);
    }
}

/*
  @overload fcmp(x, y, epsilon)
  @param  [DFloat]   x
  @param  [DFloat]   y
  @param  [DFloat]   epsilon
  @return [Int]      result

  This function determines whether x and y are approximately
equal to a relative accuracy epsilon.

The relative accuracy is measured using an interval of size 2
\delta, where \delta = 2^k \epsilon and k is the
maximum base-2 exponent of x and y as computed by the
function frexp.  

If x and y lie within this interval, they are considered
approximately equal and the function returns 0. Otherwise if x <
y, the function returns -1, or if x > y, the function returns
+1.

Note that x and y are compared to relative accuracy, so
this function is not suitable for testing whether a value is
approximately zero. 

The implementation is based on the package fcmp by T.C. Belding.
*/
static VALUE
sys_s_fcmp(VALUE mod, VALUE v0, VALUE v1, VALUE v2)
{
    ndfunc_arg_in_t ain[3] = {{cDF,0},{cDF,0},{cDF,0}};
    ndfunc_arg_out_t aout[1] = {{cI,0}};
    ndfunc_t ndf = {iter_sys_s_fcmp, STRIDE_LOOP|NDF_EXTRACT, 3,1, ain,aout};

    return na_ndloop(&ndf, 3, v0, v1, v2);
}


































































































#line 28 "../gen/tmpl/lib.c"
void
Init_sys(void)
{
    VALUE mN;
    mN = rb_define_module("Numo");
    mGSL = rb_define_module_under(mN, "GSL");

    


#line 1 "../gen/tmpl/init_module.c"

    /*
      Document-module: Numo::GSL
      
    */
    {
    
    
    rb_define_module_function(mGSL, "isnan", sys_s_isnan, 1);
    rb_define_module_function(mGSL, "isinf", sys_s_isinf, 1);
    rb_define_module_function(mGSL, "finite", sys_s_finite, 1);
    rb_define_module_function(mGSL, "log1p", sys_s_log1p, 1);
    rb_define_module_function(mGSL, "expm1", sys_s_expm1, 1);
    rb_define_module_function(mGSL, "hypot", sys_s_hypot, 2);
    rb_define_module_function(mGSL, "hypot3", sys_s_hypot3, 3);
    rb_define_module_function(mGSL, "acosh", sys_s_acosh, 1);
    rb_define_module_function(mGSL, "asinh", sys_s_asinh, 1);
    rb_define_module_function(mGSL, "atanh", sys_s_atanh, 1);
    rb_define_module_function(mGSL, "ldexp", sys_s_ldexp, 2);
    rb_define_module_function(mGSL, "frexp", sys_s_frexp, 2);
    rb_define_module_function(mGSL, "pow_int", sys_s_pow_int, 2);
    rb_define_module_function(mGSL, "pow_uint", sys_s_pow_uint, 2);
    rb_define_module_function(mGSL, "pow_2", sys_s_pow_2, 1);
    rb_define_module_function(mGSL, "pow_3", sys_s_pow_3, 1);
    rb_define_module_function(mGSL, "pow_4", sys_s_pow_4, 1);
    rb_define_module_function(mGSL, "pow_5", sys_s_pow_5, 1);
    rb_define_module_function(mGSL, "pow_6", sys_s_pow_6, 1);
    rb_define_module_function(mGSL, "pow_7", sys_s_pow_7, 1);
    rb_define_module_function(mGSL, "pow_8", sys_s_pow_8, 1);
    rb_define_module_function(mGSL, "pow_9", sys_s_pow_9, 1);
    rb_define_module_function(mGSL, "fcmp", sys_s_fcmp, 3);
    /**/
    rb_define_const(mGSL,"MODE_DEFAULT",DBL2NUM(GSL_MODE_DEFAULT));
    /**/
    rb_define_const(mGSL,"PREC_APPROX",DBL2NUM(GSL_PREC_APPROX));
    /**/
    rb_define_const(mGSL,"PREC_DOUBLE",DBL2NUM(GSL_PREC_DOUBLE));
    /**/
    rb_define_const(mGSL,"PREC_SINGLE",DBL2NUM(GSL_PREC_SINGLE));
    /*The reciprocal of pi, 1/\pi */
    rb_define_const(mGSL,"M_1_PI",DBL2NUM(M_1_PI));
    /*Twice the reciprocal of pi, 2/\pi */
    rb_define_const(mGSL,"M_2_PI",DBL2NUM(M_2_PI));
    /*Two divided by the square root of pi, 2/\sqrt\pi */
    rb_define_const(mGSL,"M_2_SQRTPI",DBL2NUM(M_2_SQRTPI));
    /*The base of exponentials, e */
    rb_define_const(mGSL,"M_E",DBL2NUM(M_E));
    /*Euler's constant, \gamma */
    rb_define_const(mGSL,"M_EULER",DBL2NUM(M_EULER));
    /*The natural logarithm of ten, \ln(10) */
    rb_define_const(mGSL,"M_LN10",DBL2NUM(M_LN10));
    /*The natural logarithm of two, \ln(2) */
    rb_define_const(mGSL,"M_LN2",DBL2NUM(M_LN2));
    /*The natural logarithm of pi, \ln(\pi) */
    rb_define_const(mGSL,"M_LNPI",DBL2NUM(M_LNPI));
    /*The base-10 logarithm of e, $\log_{10}(e)$ \log_10 (e) */
    rb_define_const(mGSL,"M_LOG10E",DBL2NUM(M_LOG10E));
    /*The base-2 logarithm of e, \log_2 (e) */
    rb_define_const(mGSL,"M_LOG2E",DBL2NUM(M_LOG2E));
    /*The constant pi, \pi */
    rb_define_const(mGSL,"M_PI",DBL2NUM(M_PI));
    /*Pi divided by two, \pi/2 */
    rb_define_const(mGSL,"M_PI_2",DBL2NUM(M_PI_2));
    /*Pi divided by four, \pi/4 */
    rb_define_const(mGSL,"M_PI_4",DBL2NUM(M_PI_4));
    /*The square root of one-half, $\sqrt{1/2}$ \sqrt[1/2] */
    rb_define_const(mGSL,"M_SQRT1_2",DBL2NUM(M_SQRT1_2));
    /*The square root of two, \sqrt 2 */
    rb_define_const(mGSL,"M_SQRT2",DBL2NUM(M_SQRT2));
    /*The square root of three, \sqrt 3 */
    rb_define_const(mGSL,"M_SQRT3",DBL2NUM(M_SQRT3));
    /*The square root of pi, \sqrt\pi */
    rb_define_const(mGSL,"M_SQRTPI",DBL2NUM(M_SQRTPI));
    /**/
    rb_define_const(mGSL,"EIGEN_SORT_VAL_ASC",INT2FIX(0));
    /**/
    rb_define_const(mGSL,"EIGEN_SORT_VAL_DESC",INT2FIX(1));
    /**/
    rb_define_const(mGSL,"EIGEN_SORT_ABS_ASC",INT2FIX(2));
    /**/
    rb_define_const(mGSL,"EIGEN_SORT_ABS_DESC",INT2FIX(3));
    /**/
    rb_define_const(mGSL,"SUCCESS",INT2FIX(0));
    /**/
    rb_define_const(mGSL,"FAILURE",INT2FIX(-1));
    /*iteration has not converged*/
    rb_define_const(mGSL,"CONTINUE",INT2FIX(-2));
    /*input domain error, e.g sqrt(-1)*/
    rb_define_const(mGSL,"EDOM",INT2FIX(1));
    /*output range error, e.g. exp(1e100)*/
    rb_define_const(mGSL,"ERANGE",INT2FIX(2));
    /*invalid pointer*/
    rb_define_const(mGSL,"EFAULT",INT2FIX(3));
    /*invalid argument supplied by user*/
    rb_define_const(mGSL,"EINVAL",INT2FIX(4));
    /*generic failure*/
    rb_define_const(mGSL,"EFAILED",INT2FIX(5));
    /*factorization failed*/
    rb_define_const(mGSL,"EFACTOR",INT2FIX(6));
    /*sanity check failed - shouldn't happen*/
    rb_define_const(mGSL,"ESANITY",INT2FIX(7));
    /*malloc failed*/
    rb_define_const(mGSL,"ENOMEM",INT2FIX(8));
    /*problem with user-supplied function*/
    rb_define_const(mGSL,"EBADFUNC",INT2FIX(9));
    /*iterative process is out of control*/
    rb_define_const(mGSL,"ERUNAWAY",INT2FIX(10));
    /*exceeded max number of iterations*/
    rb_define_const(mGSL,"EMAXITER",INT2FIX(11));
    /*tried to divide by zero*/
    rb_define_const(mGSL,"EZERODIV",INT2FIX(12));
    /*user specified an invalid tolerance*/
    rb_define_const(mGSL,"EBADTOL",INT2FIX(13));
    /*failed to reach the specified tolerance*/
    rb_define_const(mGSL,"ETOL",INT2FIX(14));
    /*underflow*/
    rb_define_const(mGSL,"EUNDRFLW",INT2FIX(15));
    /*overflow*/
    rb_define_const(mGSL,"EOVRFLW",INT2FIX(16));
    /*loss of accuracy*/
    rb_define_const(mGSL,"ELOSS",INT2FIX(17));
    /*failed because of roundoff error*/
    rb_define_const(mGSL,"EROUND",INT2FIX(18));
    /*matrix, vector lengths are not conformant*/
    rb_define_const(mGSL,"EBADLEN",INT2FIX(19));
    /*matrix not square*/
    rb_define_const(mGSL,"ENOTSQR",INT2FIX(20));
    /*apparent singularity detected*/
    rb_define_const(mGSL,"ESING",INT2FIX(21));
    /*integral or series is divergent*/
    rb_define_const(mGSL,"EDIVERGE",INT2FIX(22));
    /*requested feature is not supported by the hardware*/
    rb_define_const(mGSL,"EUNSUP",INT2FIX(23));
    /*requested feature not (yet) implemented*/
    rb_define_const(mGSL,"EUNIMPL",INT2FIX(24));
    /*cache limit exceeded*/
    rb_define_const(mGSL,"ECACHE",INT2FIX(25));
    /*table limit exceeded*/
    rb_define_const(mGSL,"ETABLE",INT2FIX(26));
    /*iteration is not making progress towards solution*/
    rb_define_const(mGSL,"ENOPROG",INT2FIX(27));
    /*jacobian evaluations are not improving the solution*/
    rb_define_const(mGSL,"ENOPROGJ",INT2FIX(28));
    /*cannot reach the specified tolerance in F*/
    rb_define_const(mGSL,"ETOLF",INT2FIX(29));
    /*cannot reach the specified tolerance in X*/
    rb_define_const(mGSL,"ETOLX",INT2FIX(30));
    /*cannot reach the specified tolerance in gradient*/
    rb_define_const(mGSL,"ETOLG",INT2FIX(31));
    /*end of file*/
    rb_define_const(mGSL,"EOF",INT2FIX(32));
    /**/
    rb_define_const(mGSL,"MESSAGE_MASK_A",INT2FIX(1));
    /**/
    rb_define_const(mGSL,"MESSAGE_MASK_B",INT2FIX(2));
    /**/
    rb_define_const(mGSL,"MESSAGE_MASK_C",INT2FIX(4));
    /**/
    rb_define_const(mGSL,"MESSAGE_MASK_D",INT2FIX(8));
    /**/
    rb_define_const(mGSL,"MESSAGE_MASK_E",INT2FIX(16));
    /**/
    rb_define_const(mGSL,"MESSAGE_MASK_F",INT2FIX(32));
    /**/
    rb_define_const(mGSL,"MESSAGE_MASK_G",INT2FIX(64));
    /**/
    rb_define_const(mGSL,"MESSAGE_MASK_H",INT2FIX(128));
    /**/
    rb_define_const(mGSL,"IEEE_TYPE_NAN",INT2FIX(1));
    /**/
    rb_define_const(mGSL,"IEEE_TYPE_INF",INT2FIX(2));
    /**/
    rb_define_const(mGSL,"IEEE_TYPE_NORMAL",INT2FIX(3));
    /**/
    rb_define_const(mGSL,"IEEE_TYPE_DENORMAL",INT2FIX(4));
    /**/
    rb_define_const(mGSL,"IEEE_TYPE_ZERO",INT2FIX(5));
    /**/
    rb_define_const(mGSL,"IEEE_SINGLE_PRECISION",INT2FIX(1));
    /**/
    rb_define_const(mGSL,"IEEE_DOUBLE_PRECISION",INT2FIX(2));
    /**/
    rb_define_const(mGSL,"IEEE_EXTENDED_PRECISION",INT2FIX(3));
    /**/
    rb_define_const(mGSL,"IEEE_ROUND_TO_NEAREST",INT2FIX(1));
    /**/
    rb_define_const(mGSL,"IEEE_ROUND_DOWN",INT2FIX(2));
    /**/
    rb_define_const(mGSL,"IEEE_ROUND_UP",INT2FIX(3));
    /**/
    rb_define_const(mGSL,"IEEE_ROUND_TO_ZERO",INT2FIX(4));
    /**/
    rb_define_const(mGSL,"IEEE_MASK_INVALID",INT2FIX(1));
    /**/
    rb_define_const(mGSL,"IEEE_MASK_DENORMALIZED",INT2FIX(2));
    /**/
    rb_define_const(mGSL,"IEEE_MASK_DIVISION_BY_ZERO",INT2FIX(4));
    /**/
    rb_define_const(mGSL,"IEEE_MASK_OVERFLOW",INT2FIX(8));
    /**/
    rb_define_const(mGSL,"IEEE_MASK_UNDERFLOW",INT2FIX(16));
    /**/
    rb_define_const(mGSL,"IEEE_MASK_ALL",INT2FIX(31));
    /**/
    rb_define_const(mGSL,"IEEE_TRAP_INEXACT",INT2FIX(32));
    /*15 point Gauss-Kronrod rule*/
    rb_define_const(mGSL,"INTEG_GAUSS15",INT2FIX(1));
    /*21 point Gauss-Kronrod rule*/
    rb_define_const(mGSL,"INTEG_GAUSS21",INT2FIX(2));
    /*31 point Gauss-Kronrod rule*/
    rb_define_const(mGSL,"INTEG_GAUSS31",INT2FIX(3));
    /*41 point Gauss-Kronrod rule*/
    rb_define_const(mGSL,"INTEG_GAUSS41",INT2FIX(4));
    /*51 point Gauss-Kronrod rule*/
    rb_define_const(mGSL,"INTEG_GAUSS51",INT2FIX(5));
    /*61 point Gauss-Kronrod rule*/
    rb_define_const(mGSL,"INTEG_GAUSS61",INT2FIX(6));
    /**/
    rb_define_const(mGSL,"VEGAS_MODE_IMPORTANCE",INT2FIX(1));
    /**/
    rb_define_const(mGSL,"VEGAS_MODE_IMPORTANCE_ONLY",INT2FIX(0));
    /**/
    rb_define_const(mGSL,"VEGAS_MODE_STRATIFIED",INT2FIX(-1));
#line 12 "../gen/tmpl/init_module.c"
    }
#line 41 "../gen/tmpl/lib.c"
}
