1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
#ifdef HAVE_GSL_GSL_MULTIMIN_FSDF_H
#include "rb_gsl.h"
#include "gsl/gsl_multimin_fsdf.h"
static VALUE cfsdf;
#ifndef CHECK_MULTIMIN_FUNCTION_FSDF
#define CHECK_MULTIMIN_FUNCTION_FSDF(x) if(CLASS_OF(x)!=cfsdf)\
rb_raise(rb_eTypeError,\
"wrong argument type %s (GSL::MultiMin::Function_fsdf expected)",\
rb_class2name(CLASS_OF(x)));
#endif
extern VALUE cgsl_multimin_function_fdf;
static const gsl_multimin_fsdfminimizer_type* get_fsdfminimizer_type(VALUE t)
{
char name[64];
switch (TYPE(t)) {
case T_STRING:
strcpy(name, STR2CSTR(t));
if (strcmp(name, "bundle") == 0 || strcmp(name, "bundle_method") == 0)
return gsl_multimin_fsdfminimizer_bundle_method;
else
rb_raise(rb_eTypeError, "%s: unknown minimizer type", name);
break;
default:
rb_raise(rb_eTypeError, "type is given by a String or a Fixnum");
break;
}
}
static VALUE rb_gsl_fsdfminimizer_alloc(VALUE klass, VALUE t, VALUE n)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
const gsl_multimin_fsdfminimizer_type *T;
T = get_fsdfminimizer_type(t);
gmf = gsl_multimin_fsdfminimizer_alloc(T, FIX2INT(n));
return Data_Wrap_Struct(klass, 0, gsl_multimin_fsdfminimizer_free, gmf);
}
static VALUE rb_gsl_fsdfminimizer_set(VALUE obj, VALUE ff, VALUE xx, VALUE ss)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
gsl_multimin_function_fsdf *F = NULL;
gsl_vector *x;
size_t bundle_size;
int status;
CHECK_MULTIMIN_FUNCTION_FSDF(ff);
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
Data_Get_Struct(ff, gsl_multimin_function_fsdf, F);
Data_Get_Vector(xx, x);
bundle_size = (size_t) FIX2INT(ss);
status = gsl_multimin_fsdfminimizer_set(gmf, F, x, bundle_size);
return INT2FIX(status);
}
static VALUE rb_gsl_fsdfminimizer_name(VALUE obj)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
return rb_str_new2(gsl_multimin_fsdfminimizer_name(gmf));
}
static VALUE rb_gsl_fsdfminimizer_iterate(VALUE obj)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
return INT2FIX(gsl_multimin_fsdfminimizer_iterate(gmf));
}
static VALUE rb_gsl_fsdfminimizer_x(VALUE obj)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
gsl_vector *x = NULL;
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
x = gsl_multimin_fsdfminimizer_x(gmf);
return Data_Wrap_Struct(cgsl_vector_view_ro, 0, NULL, x);
}
static VALUE rb_gsl_fsdfminimizer_subgradient(VALUE obj)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
gsl_vector *gradient = NULL;
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
gradient = gsl_multimin_fsdfminimizer_subgradient(gmf);
return Data_Wrap_Struct(cgsl_vector_view_ro, 0, NULL, gradient);
}
static VALUE rb_gsl_fsdfminimizer_minimum(VALUE obj)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
double min;
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
min = gsl_multimin_fsdfminimizer_minimum(gmf);
return rb_float_new(min);
}
static VALUE rb_gsl_fsdfminimizer_f(VALUE obj)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
return rb_float_new(gmf->f);
}
static VALUE rb_gsl_fsdfminimizer_restart(VALUE obj)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
return INT2FIX(gsl_multimin_fsdfminimizer_restart(gmf));
}
static VALUE rb_gsl_fsdfminimizer_test_gradient(VALUE obj, VALUE ea)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
gsl_vector *g = NULL;
Need_Float(ea);
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
g = gsl_multimin_fsdfminimizer_subgradient(gmf);
return INT2FIX(gsl_multimin_test_gradient(g, NUM2DBL(ea)));
}
static VALUE rb_gsl_fsdfminimizer_test_convergence(VALUE obj, VALUE eps)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
return INT2FIX(gsl_multimin_test_convergence(gmf, NUM2DBL(eps)));
}
static VALUE rb_gsl_fsdfminimizer_eps(VALUE obj)
{
gsl_multimin_fsdfminimizer *gmf = NULL;
Data_Get_Struct(obj, gsl_multimin_fsdfminimizer, gmf);
return rb_float_new(gmf->eps);
}
void Init_multimin_fsdf(VALUE module)
{
VALUE cmin;
cmin = rb_define_class_under(module, "FsdfMinimizer", cGSL_Object);
cfsdf = rb_define_class_under(module, "Function_fsdf", cgsl_multimin_function_fdf);
rb_define_singleton_method(cmin, "alloc", rb_gsl_fsdfminimizer_alloc, 2);
rb_define_method(cmin, "set", rb_gsl_fsdfminimizer_set, 3);
rb_define_method(cmin, "name", rb_gsl_fsdfminimizer_name, 0);
rb_define_method(cmin, "iterate", rb_gsl_fsdfminimizer_iterate, 0);
rb_define_method(cmin, "x", rb_gsl_fsdfminimizer_x, 0);
rb_define_method(cmin, "f", rb_gsl_fsdfminimizer_f, 0);
rb_define_method(cmin, "subgradient", rb_gsl_fsdfminimizer_subgradient, 0);
rb_define_method(cmin, "minimum", rb_gsl_fsdfminimizer_minimum, 0);
rb_define_method(cmin, "restart", rb_gsl_fsdfminimizer_restart, 0);
rb_define_method(cmin, "test_gradient", rb_gsl_fsdfminimizer_test_gradient, 1);
rb_define_method(cmin, "test_convergence", rb_gsl_fsdfminimizer_test_convergence, 1);
rb_define_method(cmin, "eps", rb_gsl_fsdfminimizer_eps, 0);
}
#endif
|