xref: /aosp_15_r20/external/lmfit/ruby/inline/curve1_rubyinline.rb (revision 5ddc57e5d924f146ab5fd87df586563e2270da38)
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