Home | History | Annotate | Download | only in inline
      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 (at] 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 
     14 require 'rubygems'
     15 require 'inline'
     16 
     17 class 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
     27 double f( double t, const double *p )
     28 {
     29     return p[0] + p[1]*(t-p[2])*(t-p[2]);
     30 }
     31 EOC
     32 
     33     builder.c <<EOC
     34 VALUE 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 }
     86 EOC
     87 
     88   end
     89 end
     90 
     91 # 
     92 
     93 t = [ -5.0, -4.0, -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 ]
     94 y = [ 25.5, 16.6, 9.9, 4.4, 1.1, 0, 1.1, 4.2, 9.3, 16.4, 25.5 ]
     95 
     96 c = Curve.new
     97 p c.demo(t,y)
     98