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