/*
math.c
Ruby/GSL: Ruby extension library for GSL (GNU Scientific Library)
(C) Copyright 2001-2006 by Yoshiki Tsunesada
Ruby/GSL is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#include "rb_gsl_config.h"
#include "rb_gsl_math.h"
#include "rb_gsl_complex.h"
#ifdef HAVE_NARRAY_H
#include "narray.h"
#endif
static void rb_gsl_define_const(VALUE module);
static void rb_gsl_define_const(VALUE module)
{
rb_define_const(module, "M_E", rb_float_new(M_E));
rb_define_const(module, "M_LOG2E", rb_float_new(M_LOG2E));
rb_define_const(module, "M_LOG10E", rb_float_new(M_LOG10E));
rb_define_const(module, "M_SQRT2", rb_float_new(M_SQRT2));
rb_define_const(module, "M_SQRT1_2", rb_float_new(M_SQRT1_2));
rb_define_const(module, "M_SQRT3", rb_float_new(M_SQRT3));
rb_define_const(module, "M_PI", rb_float_new(M_PI));
rb_define_const(module, "M_PI_2", rb_float_new(M_PI_2));
rb_define_const(module, "M_PI_4", rb_float_new(M_PI_4));
rb_define_const(module, "M_SQRTPI", rb_float_new(M_SQRTPI));
rb_define_const(module, "M_2_SQRTPI", rb_float_new(M_2_SQRTPI));
rb_define_const(module, "M_1_PI", rb_float_new(M_1_PI));
rb_define_const(module, "M_2_PI", rb_float_new(M_2_PI));
rb_define_const(module, "M_LN10", rb_float_new(M_LN10));
rb_define_const(module, "M_LN2", rb_float_new(M_LN2));
rb_define_const(module, "M_LNPI", rb_float_new(M_LNPI));
rb_define_const(module, "M_EULER", rb_float_new(M_EULER));
rb_define_const(module, "POSINF", rb_float_new(GSL_POSINF));
rb_define_const(module, "NEGINF", rb_float_new(GSL_NEGINF));
rb_define_const(module, "NAN", rb_float_new(GSL_NAN));
}
static VALUE rb_GSL_POSINF(VALUE obj)
{
return rb_float_new(GSL_POSINF);
}
static VALUE rb_GSL_NEGINF(VALUE obj)
{
return rb_float_new(GSL_NEGINF);
}
static VALUE rb_GSL_NAN(VALUE obj)
{
return rb_float_new(GSL_NAN);
}
static VALUE rb_gsl_isnan(VALUE obj, VALUE x)
{
Need_Float(x);
return INT2FIX(gsl_isnan(NUM2DBL(x)));
}
static VALUE rb_gsl_isnan2(VALUE obj, VALUE x)
{
Need_Float(x);
if (gsl_isnan(NUM2DBL(x))) return Qtrue;
else return Qfalse;
}
static VALUE rb_gsl_isinf(VALUE obj, VALUE x)
{
Need_Float(x);
return INT2FIX(gsl_isinf(NUM2DBL(x)));
}
static VALUE rb_gsl_isinf2(VALUE obj, VALUE x)
{
Need_Float(x);
if (gsl_isinf(NUM2DBL(x))) return Qtrue;
else return Qfalse;
}
static VALUE rb_gsl_finite(VALUE obj, VALUE x)
{
Need_Float(x);
return INT2FIX(gsl_finite(NUM2DBL(x)));
}
static VALUE rb_gsl_finite2(VALUE obj, VALUE x)
{
Need_Float(x);
if (gsl_finite(NUM2DBL(x))) return Qtrue;
else return Qfalse;
}
/*****/
static VALUE rb_gsl_math_eval(double (*func)(const double), VALUE xx);
VALUE rb_gsl_math_complex_eval(gsl_complex (*func)(gsl_complex), VALUE obj)
{
gsl_complex *z, *znew;
gsl_vector_complex *v, *vnew;
gsl_matrix_complex *m, *mnew;
size_t i, j;
if (COMPLEX_P(obj)) {
Data_Get_Struct(obj, gsl_complex, z);
znew = xmalloc(sizeof(gsl_complex));
*znew = (*func)(*z);
return Data_Wrap_Struct(cgsl_complex, 0, free, znew);
} else if (VECTOR_COMPLEX_P(obj)) {
Data_Get_Struct(obj, gsl_vector_complex, v);
vnew = gsl_vector_complex_alloc(v->size);
for (i = 0; i < v->size; i++) {
z = GSL_COMPLEX_AT(v, i);
gsl_vector_complex_set(vnew, i, (*func)(*z));
}
return Data_Wrap_Struct(cgsl_vector_complex, 0, gsl_vector_complex_free, vnew);
} else if (MATRIX_COMPLEX_P(obj)) {
Data_Get_Struct(obj, gsl_matrix_complex, m);
mnew = gsl_matrix_complex_alloc(m->size1, m->size2);
for (i = 0; i < m->size1; i++) {
for (j = 0; j < m->size2; j++) {
gsl_matrix_complex_set(mnew, i, j, (*func)(gsl_matrix_complex_get(m, i, j)));
}
}
return Data_Wrap_Struct(cgsl_matrix_complex, 0, gsl_matrix_complex_free, mnew);
} else {
rb_raise(rb_eTypeError,
"wrong argument type %s "
" (GSL::Complex or GSL::Vector::Complex expected)",
rb_class2name(CLASS_OF(obj)));
}
}
static VALUE rb_gsl_math_eval(double (*func)(const double), VALUE xx)
{
VALUE x, ary;
size_t i, size;
#ifdef HAVE_NARRAY_H
struct NARRAY *na;
double *ptr1, *ptr2;
#endif
if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
switch (TYPE(xx)) {
case T_FIXNUM:
case T_BIGNUM:
case T_FLOAT:
return rb_float_new((*func)(NUM2DBL(xx)));
break;
case T_ARRAY:
size = RARRAY(xx)->len;
ary = rb_ary_new2(size);
for (i = 0; i < size; i++) {
x = rb_ary_entry(xx, i);
Need_Float(x);
rb_ary_store(ary, i, rb_float_new((*func)(RFLOAT(x)->value)));
}
return ary;
break;
default:
#ifdef HAVE_NARRAY_H
if (NA_IsNArray(xx)) {
GetNArray(xx, na);
ptr1 = (double*) na->ptr;
size = na->total;
ary = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(xx));
ptr2 = NA_PTR_TYPE(ary, double*);
for (i = 0; i < size; i++) ptr2[i] = (*func)(ptr1[i]);
return ary;
}
#endif
if (VECTOR_P(xx)) {
return vector_eval_create(xx, func);
} else if (MATRIX_P(xx)) {
return matrix_eval_create(xx, func);
} else {
rb_raise(rb_eTypeError, "wrong argument type %s (Array or Vector or Matrix expected)", rb_class2name(CLASS_OF(xx)));
}
break;
}
/* never reach here */
return Qnil;
}
static VALUE rb_gsl_math_eval2(double (*func)(const double, const double), VALUE xx,
VALUE yy);
static VALUE rb_gsl_math_eval2(double (*func)(const double, const double), VALUE xx,
VALUE yy)
{
VALUE x, y, ary;
size_t i, j, size;
gsl_vector *v = NULL, *v2 = NULL, *vnew = NULL;
gsl_matrix *m = NULL, *m2 = NULL, *mnew = NULL;
#ifdef HAVE_NARRAY_H
struct NARRAY *nax, *nay;
double *ptr1, *ptr2, *ptr3;
#endif
if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
switch (TYPE(xx)) {
case T_FIXNUM:
case T_BIGNUM:
case T_FLOAT:
Need_Float(yy);
return rb_float_new((*func)(NUM2DBL(xx), NUM2DBL(yy)));
break;
case T_ARRAY:
Check_Type(yy, T_ARRAY);
size = RARRAY(xx)->len;
if (size != RARRAY(yy)->len) rb_raise(rb_eRuntimeError, "array sizes are different.");
ary = rb_ary_new2(size);
for (i = 0; i < size; i++) {
x = rb_ary_entry(xx, i);
y = rb_ary_entry(yy, i);
Need_Float(x); Need_Float(y);
rb_ary_store(ary, i, rb_float_new((*func)(RFLOAT(x)->value, RFLOAT(y)->value)));
}
return ary;
break;
default:
#ifdef HAVE_NARRAY_H
if (NA_IsNArray(xx)) {
GetNArray(xx, nax);
GetNArray(yy, nay);
ptr1 = (double*) nax->ptr;
ptr2 = (double*) nay->ptr;
size = nax->total;
ary = na_make_object(NA_DFLOAT, nax->rank, nax->shape, CLASS_OF(xx));
ptr3 = NA_PTR_TYPE(ary, double*);
for (i = 0; i < size; i++) ptr3[i] = (*func)(ptr1[i], ptr2[i]);
return ary;
}
#endif
if (VECTOR_P(xx)) {
CHECK_VECTOR(yy);
Data_Get_Struct(xx, gsl_vector, v);
Data_Get_Struct(yy, gsl_vector, v2);
vnew = gsl_vector_alloc(v->size);
for (i = 0; i < v->size; i++) {
gsl_vector_set(vnew, i, (*func)(gsl_vector_get(v, i), gsl_vector_get(v2, i)));
}
return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew);
} else if (MATRIX_P(xx)) {
CHECK_MATRIX(yy);
Data_Get_Struct(xx, gsl_matrix, m);
Data_Get_Struct(yy, gsl_matrix, m2);
mnew = gsl_matrix_alloc(m->size1, m->size2);
for (i = 0; i < m->size1; i++) {
for (j = 0; j < m->size2; j++) {
gsl_matrix_set(mnew, i, j, (*func)(gsl_matrix_get(m, i, j), gsl_matrix_get(m2, i, j)));
}
}
return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew);
} else {
rb_raise(rb_eTypeError,
"wrong argument type %s "
"(Array or Vector or Matrix expected)", rb_class2name(CLASS_OF(xx)));
}
break;
}
/* never reach here */
return Qnil;
}
static VALUE rb_gsl_sqrt(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(sqrt, x);
}
static VALUE rb_gsl_log1p(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(gsl_log1p, x);
}
static VALUE rb_gsl_expm1(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(gsl_expm1, x);
}
static VALUE rb_gsl_hypot(VALUE obj, VALUE x, VALUE y)
{
return rb_gsl_math_eval2(gsl_hypot, x, y);
}
static VALUE rb_gsl_acosh(VALUE obj, VALUE x)
{
if (COMPLEX_P(x) || VECTOR_COMPLEX_P(x) || MATRIX_COMPLEX_P(x))
return rb_gsl_math_complex_eval(gsl_complex_arccosh, x);
return rb_gsl_math_eval(gsl_acosh, x);
}
static VALUE rb_gsl_asinh(VALUE obj, VALUE x)
{
if (COMPLEX_P(x) || VECTOR_COMPLEX_P(x) || MATRIX_COMPLEX_P(x))
return rb_gsl_math_complex_eval(gsl_complex_arcsinh, x);
return rb_gsl_math_eval(gsl_asinh, x);
}
static VALUE rb_gsl_atanh(VALUE obj, VALUE x)
{
if (COMPLEX_P(x) || VECTOR_COMPLEX_P(x) || MATRIX_COMPLEX_P(x))
return rb_gsl_math_complex_eval(gsl_complex_arctanh, x);
return rb_gsl_math_eval(gsl_atanh, x);
}
#include <math.h>
/* xx: Numeric, Complex, Vector, Matrix
nn: Numeric, Complex
*/
static VALUE rb_gsl_pow(VALUE obj, VALUE xx, VALUE nn)
{
VALUE x, ary, argv[2];
size_t i, j, size;
double n;
gsl_vector *v = NULL, *vnew = NULL;
gsl_matrix *m = NULL, *mnew = NULL;
#ifdef HAVE_NARRAY_H
struct NARRAY *na;
double *ptr1, *ptr2;
#endif
if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
switch (TYPE(xx)) {
case T_FIXNUM:
case T_BIGNUM:
case T_FLOAT:
return rb_float_new(pow(NUM2DBL(xx), NUM2DBL(nn)));
break;
case T_ARRAY:
n = NUM2DBL(nn);
size = RARRAY(xx)->len;
ary = rb_ary_new2(size);
for (i = 0; i < size; i++) {
x = rb_ary_entry(xx, i);
Need_Float(x);
rb_ary_store(ary, i, rb_float_new(pow(NUM2DBL(x), n)));
}
return ary;
break;
default:
#ifdef HAVE_NARRAY_H
if (NA_IsNArray(xx)) {
n = NUM2DBL(nn);
GetNArray(xx, na);
ptr1 = (double*) na->ptr;
size = na->total;
ary = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(xx));
ptr2 = NA_PTR_TYPE(ary, double*);
for (i = 0; i < size; i++) ptr2[i] = pow(ptr1[i], n);
return ary;
}
#endif
if (VECTOR_P(xx)) {
n = NUM2DBL(nn);
Data_Get_Struct(xx, gsl_vector, v);
vnew = gsl_vector_alloc(v->size);
for (i = 0; i < v->size; i++) {
gsl_vector_set(vnew, i, pow(gsl_vector_get(v, i), n));
}
return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew);
}
if (MATRIX_P(xx)) {
n = NUM2DBL(nn);
Data_Get_Struct(xx, gsl_matrix, m);
mnew = gsl_matrix_alloc(m->size1, m->size2);
for (i = 0; i < m->size1; i++) {
for (j = 0; j < m->size2; j++) {
gsl_matrix_set(mnew, i, j, pow(gsl_matrix_get(m, i, j), n));
}
}
return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew);
}
if (COMPLEX_P(xx) || VECTOR_COMPLEX_P(xx) || MATRIX_COMPLEX_P(xx)) {
argv[0] = xx;
argv[1] = nn;
return rb_gsl_complex_pow(2, argv, obj);
}
rb_raise(rb_eTypeError, "wrong argument type %s (Array or Vector or Matrix expected)", rb_class2name(CLASS_OF(xx)));
break;
}
/* never reach here */
return Qnil;
}
static VALUE rb_gsl_pow_int(VALUE obj, VALUE xx, VALUE nn)
{
VALUE x, ary, argv[2];
size_t i, j, size;
int n;
gsl_vector *v = NULL, *vnew = NULL;
gsl_matrix *m = NULL, *mnew = NULL;
#ifdef HAVE_NARRAY_H
struct NARRAY *na;
double *ptr1, *ptr2;
#endif
if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
switch (TYPE(xx)) {
case T_FIXNUM:
case T_BIGNUM:
case T_FLOAT:
return rb_float_new(gsl_pow_int(NUM2DBL(xx), FIX2INT(nn)));
break;
case T_ARRAY:
CHECK_FIXNUM(nn);
n = FIX2INT(nn);
size = RARRAY(xx)->len;
ary = rb_ary_new2(size);
for (i = 0; i < size; i++) {
x = rb_ary_entry(xx, i);
Need_Float(x);
rb_ary_store(ary, i, rb_float_new(gsl_pow_int(RFLOAT(x)->value, n)));
}
return ary;
break;
default:
#ifdef HAVE_NARRAY_H
if (NA_IsNArray(xx)) {
CHECK_FIXNUM(nn);
n = FIX2INT(nn);
GetNArray(xx, na);
ptr1 = (double*) na->ptr;
size = na->total;
ary = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(xx));
ptr2 = NA_PTR_TYPE(ary, double*);
for (i = 0; i < size; i++) ptr2[i] = gsl_pow_int(ptr1[i], n);
return ary;
}
#endif
if (VECTOR_P(xx)) {
CHECK_FIXNUM(nn);
n = FIX2INT(nn);
Data_Get_Struct(xx, gsl_vector, v);
vnew = gsl_vector_alloc(v->size);
for (i = 0; i < v->size; i++) {
gsl_vector_set(vnew, i, gsl_pow_int(gsl_vector_get(v, i), n));
}
return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew);
} else if (MATRIX_P(xx)) {
CHECK_FIXNUM(nn);
n = FIX2INT(nn);
Data_Get_Struct(xx, gsl_matrix, m);
mnew = gsl_matrix_alloc(m->size1, m->size2);
for (i = 0; i < m->size1; i++) {
for (j = 0; j < m->size2; j++) {
gsl_matrix_set(mnew, i, j, gsl_pow_int(gsl_matrix_get(m, i, j), n));
}
}
return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew);
} else if (COMPLEX_P(xx) || VECTOR_COMPLEX_P(xx) || MATRIX_COMPLEX_P(xx)) {
argv[0] = xx;
argv[1] = nn;
return rb_gsl_complex_pow_real(2, argv, obj);
} else {
rb_raise(rb_eTypeError, "wrong argument type %s (Array or Vector or Matrix expected)", rb_class2name(CLASS_OF(xx)));
}
break;
}
/* never reach here */
return Qnil;
}
static VALUE rb_gsl_pow_2(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(gsl_pow_2, x);
}
static VALUE rb_gsl_pow_3(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(gsl_pow_3, x);
}
static VALUE rb_gsl_pow_4(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(gsl_pow_4, x);
}
static VALUE rb_gsl_pow_5(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(gsl_pow_5, x);
}
static VALUE rb_gsl_pow_6(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(gsl_pow_6, x);
}
static VALUE rb_gsl_pow_7(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(gsl_pow_7, x);
}
static VALUE rb_gsl_pow_8(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(gsl_pow_8, x);
}
static VALUE rb_gsl_pow_9(VALUE obj, VALUE x)
{
return rb_gsl_math_eval(gsl_pow_9, x);
}
/*****/
static VALUE rb_GSL_SIGN(VALUE obj, VALUE x)
{
return INT2FIX(GSL_SIGN(NUM2DBL(x)));
}
static VALUE rb_GSL_IS_ODD(VALUE obj, VALUE n)
{
CHECK_FIXNUM(n);
return INT2FIX(GSL_IS_ODD(FIX2INT(n)));
}
static VALUE rb_GSL_IS_ODD2(VALUE obj, VALUE n)
{
CHECK_FIXNUM(n);
if (GSL_IS_ODD(FIX2INT(n))) return Qtrue;
else return Qfalse;
}
static VALUE rb_GSL_IS_EVEN(VALUE obj, VALUE n)
{
CHECK_FIXNUM(n);
return INT2FIX(GSL_IS_EVEN(FIX2INT(n)));
}
static VALUE rb_GSL_IS_EVEN2(VALUE obj, VALUE n)
{
CHECK_FIXNUM(n);
if (GSL_IS_EVEN(FIX2INT(n))) return Qtrue;
else return Qfalse;
}
static VALUE rb_GSL_MAX(VALUE obj, VALUE aa, VALUE bb)
{
double a, b;
double max;
/* Need_Float(aa); Need_Float(bb);*/
a = NUM2DBL(aa);
b = NUM2DBL(bb);
max = GSL_MAX_DBL(a, b);
if (gsl_fcmp(max, a, 1.0e-10) == 0) return aa;
else return bb;
}
static VALUE rb_GSL_MIN(VALUE obj, VALUE aa, VALUE bb)
{
double a, b;
double min;
/* Need_Float(aa); Need_Float(bb);*/
a = NUM2DBL(aa);
b = NUM2DBL(bb);
min = GSL_MIN_DBL(a, b);
if (gsl_fcmp(min, a, 1.0e-10) == 0) return aa;
else return bb;
}
static VALUE rb_GSL_MAX_DBL(VALUE obj, VALUE aa, VALUE bb)
{
Need_Float(aa); Need_Float(bb);
return rb_float_new(GSL_MAX_DBL(NUM2DBL(aa), NUM2DBL(bb)));
}
static VALUE rb_GSL_MIN_DBL(VALUE obj, VALUE aa, VALUE bb)
{
Need_Float(aa); Need_Float(bb);
return rb_float_new(GSL_MAX_DBL(NUM2DBL(aa), NUM2DBL(bb)));
}
static VALUE rb_GSL_MAX_INT(VALUE obj, VALUE aa, VALUE bb)
{
if (TYPE(aa) != T_FIXNUM || TYPE(bb) != T_FIXNUM)
return rb_GSL_MAX(obj, aa, bb);
else
return INT2FIX(GSL_MAX_INT(FIX2INT(aa), FIX2INT(bb)));
}
static VALUE rb_GSL_MIN_INT(VALUE obj, VALUE aa, VALUE bb)
{
if (TYPE(aa) != T_FIXNUM || TYPE(bb) != T_FIXNUM)
return rb_GSL_MIN(obj, aa, bb);
return
INT2FIX(GSL_MIN_INT(FIX2INT(aa), FIX2INT(bb)));
}
#ifdef GSL_1_3_LATER
static VALUE rb_gsl_ldexp(VALUE obj, VALUE x, VALUE e)
{
return rb_float_new(gsl_ldexp(NUM2DBL(x), FIX2INT(e)));
}
static VALUE rb_gsl_frexp(VALUE obj, VALUE x)
{
int e;
double val;
Need_Float(x);
val = gsl_frexp(NUM2DBL(x), &e);
return rb_ary_new3(2, rb_float_new(val), INT2FIX(e));
}
#endif
static VALUE rb_gsl_fcmp(int argc, VALUE *argv, VALUE obj)
{
double a, b, epsilon = 1e-10;
switch (argc) {
case 3:
epsilon = NUM2DBL(argv[2]);
/* no break, do next */
case 2:
a = NUM2DBL(argv[0]);
b = NUM2DBL(argv[1]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments");
break;
}
return INT2FIX(gsl_fcmp(a, b, epsilon));
}
static VALUE rb_gsl_equal(int argc, VALUE *argv, VALUE obj)
{
double a, b, epsilon = 1e-10;
int retval;
switch (argc) {
case 3:
epsilon = NUM2DBL(argv[2]);
/* no break, do next */
case 2:
a = NUM2DBL(argv[0]);
b = NUM2DBL(argv[1]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments");
break;
}
retval = gsl_fcmp(a, b, epsilon);
if (retval == 0) return Qtrue;
else return Qfalse;
}
void Init_gsl_math(VALUE module)
{
rb_gsl_define_const(module);
rb_define_module_function(module, "posinf", rb_GSL_POSINF, 0);
rb_define_module_function(module, "neginf", rb_GSL_NEGINF, 0);
rb_define_module_function(module, "nan", rb_GSL_NAN, 0);
rb_define_module_function(module, "isnan", rb_gsl_isnan, 1);
rb_define_module_function(module, "isnan?", rb_gsl_isnan2, 1);
rb_define_module_function(module, "isinf", rb_gsl_isinf, 1);
rb_define_module_function(module, "isinf?", rb_gsl_isinf2, 1);
rb_define_module_function(module, "finite", rb_gsl_finite, 1);
rb_define_module_function(module, "finite?", rb_gsl_finite2, 1);
rb_define_module_function(module, "sqrt", rb_gsl_sqrt, 1);
rb_define_module_function(module, "log1p", rb_gsl_log1p, 1);
rb_define_module_function(module, "expm1", rb_gsl_expm1, 1);
rb_define_module_function(module, "hypot", rb_gsl_hypot, 2);
rb_define_module_function(module, "acosh", rb_gsl_acosh, 1);
rb_define_module_function(module, "asinh", rb_gsl_asinh, 1);
rb_define_module_function(module, "atanh", rb_gsl_atanh, 1);
rb_define_module_function(module, "pow", rb_gsl_pow, 2);
rb_define_module_function(module, "pow_int", rb_gsl_pow_int, 2);
rb_define_module_function(module, "pow_2", rb_gsl_pow_2, 1);
rb_define_module_function(module, "pow_3", rb_gsl_pow_3, 1);
rb_define_module_function(module, "pow_4", rb_gsl_pow_4, 1);
rb_define_module_function(module, "pow_5", rb_gsl_pow_5, 1);
rb_define_module_function(module, "pow_6", rb_gsl_pow_6, 1);
rb_define_module_function(module, "pow_7", rb_gsl_pow_7, 1);
rb_define_module_function(module, "pow_8", rb_gsl_pow_8, 1);
rb_define_module_function(module, "pow_9", rb_gsl_pow_9, 1);
rb_define_module_function(module, "sign", rb_GSL_SIGN, 1);
rb_define_module_function(module, "SIGN", rb_GSL_SIGN, 1);
rb_define_module_function(module, "is_odd", rb_GSL_IS_ODD, 1);
rb_define_module_function(module, "IS_ODD", rb_GSL_IS_ODD, 1);
rb_define_module_function(module, "is_odd?", rb_GSL_IS_ODD2, 1);
rb_define_module_function(module, "IS_ODD?", rb_GSL_IS_ODD2, 1);
rb_define_module_function(module, "is_even", rb_GSL_IS_EVEN, 1);
rb_define_module_function(module, "IS_EVEN", rb_GSL_IS_EVEN, 1);
rb_define_module_function(module, "is_even?", rb_GSL_IS_EVEN2, 1);
rb_define_module_function(module, "IS_EVEN?", rb_GSL_IS_EVEN2, 1);
rb_define_module_function(module, "max", rb_GSL_MAX, 2);
rb_define_module_function(module, "MAX", rb_GSL_MAX, 2);
rb_define_module_function(module, "min", rb_GSL_MIN, 2);
rb_define_module_function(module, "MIN", rb_GSL_MIN, 2);
rb_define_module_function(module, "max_dbl", rb_GSL_MAX_DBL, 2);
rb_define_module_function(module, "MAX_DBL", rb_GSL_MAX_DBL, 2);
rb_define_module_function(module, "min_dbl", rb_GSL_MIN_DBL, 2);
rb_define_module_function(module, "MIN_DBL", rb_GSL_MIN_DBL, 2);
rb_define_module_function(module, "max_int", rb_GSL_MAX_INT, 2);
rb_define_module_function(module, "MAX_INT", rb_GSL_MAX_INT, 2);
rb_define_module_function(module, "min_int", rb_GSL_MIN_INT, 2);
rb_define_module_function(module, "MIN_INT", rb_GSL_MIN_INT, 2);
rb_define_module_function(module, "fcmp", rb_gsl_fcmp, -1);
rb_define_singleton_method(module, "equal?", rb_gsl_equal, -1);
#ifdef GSL_1_3_LATER
rb_define_module_function(module, "ldexp", rb_gsl_ldexp, 2);
rb_define_module_function(module, "frexp", rb_gsl_frexp, 1);
#endif
}
syntax highlighted by Code2HTML, v. 0.9.1