1#! /usr/bin/env ruby 2 3# This is 'curve1.c' demo done with RubyInline gem (instead of using swig) 4# Contributed by Igor Drozdov <idrozdov@gmail.com> 2012 5# $ ruby curve1_rubyinline.rb 6# 7# Requirements: 8# 9# $ gem install RubyInline 10# 11# To make sure header files and shared librares can be found, 12# export appropriate LD_LIBRARY_PATH and C_INCLUDE_PATH. 13 14require 'rubygems' 15require 'inline' 16 17class Curve 18 inline(:C) do |builder| 19 builder.include("\"lmcurve.h\"") 20 builder.include("\"lmmin.h\"") 21 builder.include("<math.h>") 22 builder.include("<stdio.h>") 23 builder.include("<ruby.h>)") 24 builder.add_link_flags("-llmmin") 25 26 builder.c_raw <<EOC 27double f( double t, const double *p ) 28{ 29 return p[0] + p[1]*(t-p[2])*(t-p[2]); 30} 31EOC 32 33 builder.c <<EOC 34VALUE demo(VALUE t_ary, VALUE y_ary) { 35 /* parameter vector */ 36 int n_par = 3; // number of parameters in model function f 37 double par[3] = { 1, 0, -1 }; // relatively bad starting value 38 39 /* data pairs: slightly distorted standard parabola */ 40 41 int m_dat = 11; // number of data pairs 42 int i; 43 44 /* ruby macros dealing with inputs */ 45 int t_len = RARRAY_LEN(t_ary); 46 int y_len = RARRAY_LEN(y_ary); 47 48 double t[t_len]; 49 double y[t_len]; 50 51 VALUE *t_arr = RARRAY_PTR(t_ary); 52 VALUE *y_arr = RARRAY_PTR(y_ary); 53 54 VALUE result_pars = rb_ary_new(); // ruby array containing fitted params 55 56 /* auxiliary parameters */ 57 lm_status_struct status; 58 lm_control_struct control = lm_control_double; 59 60 for (i = 0; i < t_len; i++) { 61 t[i] = NUM2DBL(t_arr[i]); 62 y[i] = NUM2DBL(y_arr[i]); 63 } 64 65 lmcurve_fit( n_par, par, m_dat, t, y, f, &control, &status ); 66 /* print results */ 67 68 printf( "\\nResults:\\n" ); 69 printf( "status after %d function evaluations:\\n %s\\n", 70 status.nfev, lm_infmsg[status.outcome] ); 71 72 printf("obtained parameters:\\n"); 73 for ( i = 0; i < n_par; ++i) 74 rb_ary_push(result_pars,DBL2NUM(par[i])); 75 printf(" par[%i] = %12g\\n", i, par[i]); 76 printf("obtained norm:\\n %12g\\n", status.fnorm ); 77 78 printf("fitting data as follows:\\n"); 79 for ( i = 0; i < m_dat; ++i) 80 printf( " t[%2d]=%12g y=%12g fit=%12g residue=%12g\\n", 81 i, t[i], y[i], f(t[i],par), y[i] - f(t[i],par) ); 82 83 printf("\\n"); 84 return result_pars; 85} 86EOC 87 88 end 89end 90 91# 92 93t = [ -5.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 ] 94y = [ 25.5, 16.6, 9.9, 4.4, 1.1, 0, 1.1, 4.2, 9.3, 16.4, 25.5 ] 95 96c = Curve.new 97p c.demo(t,y) 98