#ifdef HAVE_GSL_GSL_MULTIMIN_FSDF_H #include "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