/*
fit.c
Ruby/GSL: Ruby extension library for GSL (GNU Scientific Library)
(C) Copyright 2004 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.
*/
#include "rb_gsl_config.h"
#include "rb_gsl_fit.h"
/* linear fit without weights: y = c0 + c1 x */
/* This returns 7 elements array */
static VALUE rb_gsl_fit_linear(int argc, VALUE *argv, VALUE obj)
{
double *ptrx, *ptry;
double c0, c1, cov00, cov01, cov11, sumsq;
int status;
size_t n, stridex, stridey;
switch (argc) {
case 2:
ptrx = get_vector_ptr(argv[0], &stridex, &n);
ptry = get_vector_ptr(argv[1], &stridey, &n);
break;
case 3:
CHECK_FIXNUM(argv[2]);
ptrx = get_vector_ptr(argv[0], &stridex, &n);
ptry = get_vector_ptr(argv[1], &stridey, &n);
n = FIX2INT(argv[2]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
break;
}
status = gsl_fit_linear(ptrx, stridex, ptry, stridey, n, &c0, &c1, &cov00,
&cov01, &cov11, &sumsq);
return rb_ary_new3(7, rb_float_new(c0), rb_float_new(c1), rb_float_new(cov00),
rb_float_new(cov01), rb_float_new(cov11), rb_float_new(sumsq),
INT2FIX(status));
}
/* linear fit with weights: y = c0 + c1 x */
static VALUE rb_gsl_fit_wlinear(int argc, VALUE *argv, VALUE obj)
{
double *ptrx, *ptry, *ptrw;
double c0, c1, cov00, cov01, cov11, sumsq;
int status;
size_t n, stridex, stridey, stridew;
switch (argc) {
case 3:
ptrx = get_vector_ptr(argv[0], &stridex, &n);
ptrw = get_vector_ptr(argv[1], &stridew, &n);
ptry = get_vector_ptr(argv[2], &stridey, &n);
break;
case 4:
CHECK_FIXNUM(argv[3]);
ptrx = get_vector_ptr(argv[0], &stridex, &n);
ptrw = get_vector_ptr(argv[1], &stridew, &n);
ptry = get_vector_ptr(argv[2], &stridey, &n);
n = FIX2INT(argv[3]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
break;
}
status = gsl_fit_wlinear(ptrx, stridex, ptrw, stridew, ptry, stridey,
n,
&c0, &c1, &cov00, &cov01, &cov11, &sumsq);
return rb_ary_new3(7, rb_float_new(c0), rb_float_new(c1), rb_float_new(cov00),
rb_float_new(cov01), rb_float_new(cov11), rb_float_new(sumsq),
INT2FIX(status));
}
static VALUE rb_gsl_fit_linear_est(int argc, VALUE *argv, VALUE obj)
{
double y, yerr, x, c0, c1, c00, c01, c11;
int status;
size_t i;
switch (argc) {
case 2:
x = NUM2DBL(argv[0]);
if (TYPE(argv[1]) == T_ARRAY) {
c0 = NUM2DBL(rb_ary_entry(argv[1], 0));
c1 = NUM2DBL(rb_ary_entry(argv[1], 1));
c00 = NUM2DBL(rb_ary_entry(argv[1], 2));
c01 = NUM2DBL(rb_ary_entry(argv[1], 3));
c11 = NUM2DBL(rb_ary_entry(argv[1], 4));
} else {
rb_raise(rb_eTypeError, "argv[1] Array expected");
}
break;
case 6:
for (i = 0; i < 6; i++) Need_Float(argv[i]);
x = NUM2DBL(argv[0]);
c0 = NUM2DBL(argv[1]);
c1 = NUM2DBL(argv[2]);
c00 = NUM2DBL(argv[3]);
c01 = NUM2DBL(argv[4]);
c11 = NUM2DBL(argv[5]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 6)", argc);
}
status = gsl_fit_linear_est(x, c0, c1, c00, c01, c11, &y, &yerr);
return rb_ary_new3(3, rb_float_new(y), rb_float_new(yerr), INT2FIX(status));
}
static VALUE rb_gsl_fit_mul(int argc, VALUE *argv, VALUE obj)
{
double *ptrx, *ptry;
double c1, cov11, sumsq;
int status;
size_t n, stridex, stridey;
switch (argc) {
case 2:
ptrx = get_vector_ptr(argv[0], &stridex, &n);
ptry = get_vector_ptr(argv[1], &stridey, &n);
break;
case 3:
CHECK_FIXNUM(argv[2]);
ptrx = get_vector_ptr(argv[0], &stridex, &n);
ptry = get_vector_ptr(argv[1], &stridey, &n);
n = FIX2INT(argv[2]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
break;
}
status = gsl_fit_mul(ptrx, stridex, ptry, stridey, n, &c1, &cov11, &sumsq);
return rb_ary_new3(4, rb_float_new(c1),
rb_float_new(cov11), rb_float_new(sumsq), INT2FIX(status));
}
static VALUE rb_gsl_fit_wmul(int argc, VALUE *argv, VALUE obj)
{
double *ptrx, *ptry, *ptrw;
double c1, cov11, sumsq;
int status;
size_t n, stridex, stridey, stridew;
switch (argc) {
case 3:
ptrx = get_vector_ptr(argv[0], &stridex, &n);
ptrw = get_vector_ptr(argv[1], &stridew, &n);
ptry = get_vector_ptr(argv[2], &stridey, &n);
break;
case 4:
CHECK_FIXNUM(argv[3]);
ptrx = get_vector_ptr(argv[0], &stridex, &n);
ptrw = get_vector_ptr(argv[1], &stridew, &n);
ptry = get_vector_ptr(argv[2], &stridey, &n);
n = FIX2INT(argv[3]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
break;
}
status = gsl_fit_wmul(ptrx, stridex, ptrw, stridew, ptry, stridey,
n, &c1, &cov11, &sumsq);
return rb_ary_new3(4, rb_float_new(c1),
rb_float_new(cov11), rb_float_new(sumsq), INT2FIX(status));
}
static VALUE rb_gsl_fit_mul_est(int argc, VALUE *argv, VALUE obj)
{
double y, yerr, x, c1, c11;
int status;
switch (argc) {
case 2:
Need_Float(argv[0]);
if (TYPE(argv[1]) == T_ARRAY) {
c1 = NUM2DBL(rb_ary_entry(argv[1], 0));
c11 = NUM2DBL(rb_ary_entry(argv[1], 1));
} else {
rb_raise(rb_eTypeError, "argv[1]: Array expected");
}
x = NUM2DBL(argv[0]);
break;
case 3:
Need_Float(argv[0]); Need_Float(argv[1]); Need_Float(argv[2]);
x = NUM2DBL(argv[0]);
c1 = NUM2DBL(argv[1]);
c11 = NUM2DBL(argv[2]);
break;
default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
break;
}
status = gsl_fit_mul_est(x, c1, c11, &y, &yerr);
return rb_ary_new3(3, rb_float_new(y), rb_float_new(yerr), INT2FIX(status));
}
void Init_gsl_fit(VALUE module)
{
VALUE mgsl_fit;
mgsl_fit = rb_define_module_under(module, "Fit");
rb_define_module_function(mgsl_fit, "linear", rb_gsl_fit_linear, -1);
rb_define_module_function(mgsl_fit, "wlinear", rb_gsl_fit_wlinear, -1);
rb_define_module_function(mgsl_fit, "linear_est", rb_gsl_fit_linear_est, -1);
rb_define_module_function(mgsl_fit, "mul", rb_gsl_fit_mul, -1);
rb_define_module_function(mgsl_fit, "wmul", rb_gsl_fit_wmul, -1);
rb_define_module_function(mgsl_fit, "mul_est", rb_gsl_fit_mul_est, -1);
}
syntax highlighted by Code2HTML, v. 0.9.1