gsl 1.12.108

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/README.rdoc +29 -0
  2. data/Rakefile +54 -0
  3. data/VERSION +2 -0
  4. data/ext/MANIFEST +119 -0
  5. data/ext/alf.c +206 -0
  6. data/ext/array.c +666 -0
  7. data/ext/array_complex.c +247 -0
  8. data/ext/blas.c +29 -0
  9. data/ext/blas1.c +731 -0
  10. data/ext/blas2.c +1093 -0
  11. data/ext/blas3.c +881 -0
  12. data/ext/block.c +44 -0
  13. data/ext/block_source.c +886 -0
  14. data/ext/bspline.c +130 -0
  15. data/ext/bundle.c +3 -0
  16. data/ext/cdf.c +754 -0
  17. data/ext/cheb.c +542 -0
  18. data/ext/combination.c +283 -0
  19. data/ext/common.c +325 -0
  20. data/ext/complex.c +1004 -0
  21. data/ext/const.c +673 -0
  22. data/ext/const_additional.c +120 -0
  23. data/ext/cqp.c +283 -0
  24. data/ext/deriv.c +195 -0
  25. data/ext/dht.c +361 -0
  26. data/ext/diff.c +166 -0
  27. data/ext/dirac.c +395 -0
  28. data/ext/eigen.c +2373 -0
  29. data/ext/error.c +194 -0
  30. data/ext/extconf.rb +281 -0
  31. data/ext/fcmp.c +66 -0
  32. data/ext/fft.c +1092 -0
  33. data/ext/fit.c +205 -0
  34. data/ext/fresnel.c +312 -0
  35. data/ext/function.c +524 -0
  36. data/ext/geometry.c +139 -0
  37. data/ext/graph.c +1638 -0
  38. data/ext/gsl.c +271 -0
  39. data/ext/gsl_narray.c +653 -0
  40. data/ext/histogram.c +1995 -0
  41. data/ext/histogram2d.c +1068 -0
  42. data/ext/histogram3d.c +884 -0
  43. data/ext/histogram3d_source.c +750 -0
  44. data/ext/histogram_find.c +101 -0
  45. data/ext/histogram_oper.c +159 -0
  46. data/ext/ieee.c +98 -0
  47. data/ext/integration.c +1138 -0
  48. data/ext/interp.c +512 -0
  49. data/ext/jacobi.c +739 -0
  50. data/ext/linalg.c +4047 -0
  51. data/ext/linalg_complex.c +741 -0
  52. data/ext/math.c +725 -0
  53. data/ext/matrix.c +39 -0
  54. data/ext/matrix_complex.c +1732 -0
  55. data/ext/matrix_double.c +560 -0
  56. data/ext/matrix_int.c +256 -0
  57. data/ext/matrix_source.c +2733 -0
  58. data/ext/min.c +250 -0
  59. data/ext/monte.c +992 -0
  60. data/ext/multifit.c +1879 -0
  61. data/ext/multimin.c +808 -0
  62. data/ext/multimin_fsdf.c +156 -0
  63. data/ext/multiroots.c +955 -0
  64. data/ext/ndlinear.c +321 -0
  65. data/ext/nmf.c +167 -0
  66. data/ext/nmf_wrap.c +72 -0
  67. data/ext/ntuple.c +469 -0
  68. data/ext/odeiv.c +959 -0
  69. data/ext/ool.c +879 -0
  70. data/ext/oper_complex_source.c +253 -0
  71. data/ext/permutation.c +596 -0
  72. data/ext/poly.c +42 -0
  73. data/ext/poly2.c +265 -0
  74. data/ext/poly_source.c +1885 -0
  75. data/ext/qrng.c +171 -0
  76. data/ext/randist.c +1873 -0
  77. data/ext/rational.c +480 -0
  78. data/ext/rng.c +612 -0
  79. data/ext/root.c +408 -0
  80. data/ext/sf.c +1494 -0
  81. data/ext/sf_airy.c +200 -0
  82. data/ext/sf_bessel.c +867 -0
  83. data/ext/sf_clausen.c +28 -0
  84. data/ext/sf_coulomb.c +206 -0
  85. data/ext/sf_coupling.c +118 -0
  86. data/ext/sf_dawson.c +29 -0
  87. data/ext/sf_debye.c +157 -0
  88. data/ext/sf_dilog.c +42 -0
  89. data/ext/sf_elementary.c +44 -0
  90. data/ext/sf_ellint.c +206 -0
  91. data/ext/sf_elljac.c +29 -0
  92. data/ext/sf_erfc.c +93 -0
  93. data/ext/sf_exp.c +164 -0
  94. data/ext/sf_expint.c +211 -0
  95. data/ext/sf_fermi_dirac.c +148 -0
  96. data/ext/sf_gamma.c +344 -0
  97. data/ext/sf_gegenbauer.c +96 -0
  98. data/ext/sf_hyperg.c +197 -0
  99. data/ext/sf_laguerre.c +112 -0
  100. data/ext/sf_lambert.c +47 -0
  101. data/ext/sf_legendre.c +367 -0
  102. data/ext/sf_log.c +104 -0
  103. data/ext/sf_mathieu.c +238 -0
  104. data/ext/sf_power.c +46 -0
  105. data/ext/sf_psi.c +98 -0
  106. data/ext/sf_synchrotron.c +48 -0
  107. data/ext/sf_transport.c +76 -0
  108. data/ext/sf_trigonometric.c +207 -0
  109. data/ext/sf_zeta.c +119 -0
  110. data/ext/signal.c +310 -0
  111. data/ext/siman.c +718 -0
  112. data/ext/sort.c +208 -0
  113. data/ext/spline.c +395 -0
  114. data/ext/stats.c +799 -0
  115. data/ext/sum.c +168 -0
  116. data/ext/tamu_anova.c +56 -0
  117. data/ext/tensor.c +38 -0
  118. data/ext/tensor_source.c +1123 -0
  119. data/ext/vector.c +38 -0
  120. data/ext/vector_complex.c +2236 -0
  121. data/ext/vector_double.c +1433 -0
  122. data/ext/vector_int.c +204 -0
  123. data/ext/vector_source.c +3329 -0
  124. data/ext/wavelet.c +937 -0
  125. data/include/rb_gsl.h +151 -0
  126. data/include/rb_gsl_array.h +238 -0
  127. data/include/rb_gsl_cheb.h +21 -0
  128. data/include/rb_gsl_common.h +343 -0
  129. data/include/rb_gsl_complex.h +25 -0
  130. data/include/rb_gsl_const.h +29 -0
  131. data/include/rb_gsl_dirac.h +13 -0
  132. data/include/rb_gsl_eigen.h +17 -0
  133. data/include/rb_gsl_fft.h +62 -0
  134. data/include/rb_gsl_fit.h +25 -0
  135. data/include/rb_gsl_function.h +27 -0
  136. data/include/rb_gsl_graph.h +70 -0
  137. data/include/rb_gsl_histogram.h +63 -0
  138. data/include/rb_gsl_histogram3d.h +97 -0
  139. data/include/rb_gsl_integration.h +17 -0
  140. data/include/rb_gsl_interp.h +46 -0
  141. data/include/rb_gsl_linalg.h +25 -0
  142. data/include/rb_gsl_math.h +26 -0
  143. data/include/rb_gsl_odeiv.h +21 -0
  144. data/include/rb_gsl_poly.h +71 -0
  145. data/include/rb_gsl_rational.h +37 -0
  146. data/include/rb_gsl_rng.h +21 -0
  147. data/include/rb_gsl_root.h +22 -0
  148. data/include/rb_gsl_sf.h +119 -0
  149. data/include/rb_gsl_statistics.h +17 -0
  150. data/include/rb_gsl_tensor.h +45 -0
  151. data/include/rb_gsl_with_narray.h +22 -0
  152. data/include/templates_off.h +87 -0
  153. data/include/templates_on.h +241 -0
  154. data/lib/gsl/gnuplot.rb +41 -0
  155. data/lib/gsl/oper.rb +68 -0
  156. data/lib/ool.rb +22 -0
  157. data/lib/ool/conmin.rb +30 -0
  158. metadata +224 -0
@@ -0,0 +1,1879 @@
1
+ /*
2
+ multifit.c
3
+ Ruby/GSL: Ruby extension library for GSL (GNU Scientific Library)
4
+ (C) Copyright 2004 by Yoshiki Tsunesada
5
+
6
+ Ruby/GSL is free software: you can redistribute it and/or modify it
7
+ under the terms of the GNU General Public License.
8
+ This library is distributed in the hope that it will be useful, but
9
+ WITHOUT ANY WARRANTY.
10
+ */
11
+ #include "rb_gsl_config.h"
12
+ #include "rb_gsl_fit.h"
13
+ #include "rb_gsl_function.h"
14
+ #include "rb_gsl_common.h"
15
+
16
+ #ifdef HAVE_NDLINEAR_GSL_MULTIFIT_NDLINEAR_H
17
+ #include <ndlinear/gsl_multifit_ndlinear.h>
18
+ void Init_ndlinear(VALUE module);
19
+ #endif
20
+
21
+ #ifndef CHECK_WORKSPACE
22
+ #define CHECK_WORKSPACE(x) if(CLASS_OF(x)!=cgsl_multifit_workspace)\
23
+ rb_raise(rb_eTypeError,\
24
+ "wrong argument type %s (GSL::MultiFit::Workspace expected)",\
25
+ rb_class2name(CLASS_OF(x)));
26
+ #endif
27
+
28
+ #ifndef CHECK_MULTIFIT_FUNCTION_FDF
29
+ #define CHECK_MULTIFIT_FUNCTION_FDF(x) if(CLASS_OF(x)!=cgsl_multifit_function_fdf)\
30
+ rb_raise(rb_eTypeError,\
31
+ "wrong argument type %s (GSL::MultiFit::Workspace expected)",\
32
+ rb_class2name(CLASS_OF(x)));
33
+ #endif
34
+
35
+ static VALUE cgsl_multifit_workspace;
36
+ static VALUE cgsl_multifit_function_fdf;
37
+
38
+ enum MultiFit_Solver_Type{
39
+ GSL_MULTIFIT_FDFSOLVER_LMSDER,
40
+ GSL_MULTIFIT_FDFSOLVER_LMDER,
41
+ };
42
+
43
+ static VALUE rb_gsl_multifit_workspace_new(VALUE klass, VALUE n, VALUE p)
44
+ {
45
+ gsl_multifit_linear_workspace *w = NULL;
46
+ CHECK_FIXNUM(n); CHECK_FIXNUM(p);
47
+ w = gsl_multifit_linear_alloc(FIX2INT(n), FIX2INT(p));
48
+ return Data_Wrap_Struct(cgsl_multifit_workspace, 0, gsl_multifit_linear_free, w);
49
+ }
50
+
51
+ static VALUE rb_gsl_multifit_linear(int argc, VALUE *argv, VALUE obj)
52
+ {
53
+ gsl_multifit_linear_workspace *space = NULL;
54
+ gsl_matrix *x = NULL, *cov = NULL;
55
+ gsl_vector *y = NULL, *c = NULL;
56
+ double chisq;
57
+ int status, flag = 0;
58
+ VALUE vc, vcov;
59
+ if (argc != 2 && argc != 3)
60
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
61
+ Data_Get_Matrix(argv[0], x);
62
+ Data_Get_Vector(argv[1], y);
63
+ if (argc == 3) {
64
+ CHECK_WORKSPACE(argv[2]);
65
+ Data_Get_Struct(argv[2], gsl_multifit_linear_workspace, space);
66
+ } else {
67
+ space = gsl_multifit_linear_alloc(x->size1, x->size2);
68
+ flag = 1;
69
+ }
70
+ cov = gsl_matrix_alloc(x->size2, x->size2);
71
+ c = gsl_vector_alloc(x->size2);
72
+ status = gsl_multifit_linear(x, y, c, cov, &chisq, space);
73
+ if (flag == 1) gsl_multifit_linear_free(space);
74
+ vc = Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, c);
75
+ vcov = Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, cov);
76
+ return rb_ary_new3(4, vc, vcov, rb_float_new(chisq), INT2FIX(status));
77
+ }
78
+
79
+ static VALUE rb_gsl_multifit_wlinear(int argc, VALUE *argv, VALUE obj)
80
+ {
81
+ gsl_multifit_linear_workspace *space = NULL;
82
+ gsl_matrix *x = NULL, *cov = NULL;
83
+ gsl_vector *w = NULL, *y = NULL, *c = NULL;
84
+ double chisq;
85
+ int status, flag = 0;
86
+ VALUE vc, vcov;
87
+ if (argc != 3 && argc != 4)
88
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 3 or 4)", argc);
89
+ Data_Get_Matrix(argv[0], x);
90
+ Data_Get_Vector(argv[1], w);
91
+ Data_Get_Vector(argv[2], y);
92
+ if (argc == 4) {
93
+ CHECK_WORKSPACE(argv[3]);
94
+ Data_Get_Struct(argv[3], gsl_multifit_linear_workspace, space);
95
+ } else {
96
+ space = gsl_multifit_linear_alloc(x->size1, x->size2);
97
+ flag = 1;
98
+ }
99
+ cov = gsl_matrix_alloc(x->size2, x->size2);
100
+ c = gsl_vector_alloc(x->size2);
101
+ status = gsl_multifit_wlinear(x, w, y, c, cov, &chisq, space);
102
+ if (flag == 1) gsl_multifit_linear_free(space);
103
+ vc = Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, c);
104
+ vcov = Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, cov);
105
+ return rb_ary_new3(4, vc, vcov, rb_float_new(chisq), INT2FIX(status));
106
+ }
107
+
108
+ static void calc_X_power(gsl_matrix *X, gsl_vector *x, size_t order)
109
+ {
110
+ size_t i, j;
111
+ double val;
112
+ for (i = 0; i < x->size; i++) {
113
+ val = 1.0;
114
+ gsl_matrix_set(X, i, 0, val);
115
+ for (j = 1; j <= order; j++) {
116
+ val *= gsl_vector_get(x, i);
117
+ gsl_matrix_set(X, i, j, val);
118
+ }
119
+ }
120
+ }
121
+
122
+ static void calc_X_legendre(gsl_matrix *X, gsl_vector *v, size_t order)
123
+ {
124
+ size_t i, n;
125
+ double a, b, c, x;
126
+ for (i = 0; i < v->size; i++) {
127
+ a = 1.0;
128
+ b = gsl_vector_get(v, i);
129
+ gsl_matrix_set(X, i, 0, a);
130
+ gsl_matrix_set(X, i, 1, b);
131
+ for (n = 2; n <= order; n++) {
132
+ x = gsl_vector_get(v, i);
133
+ c = ((2*n-1)*x*b - (n-1)*a)/n;
134
+ gsl_matrix_set(X, i, n, c);
135
+ a = b;
136
+ b = c;
137
+ }
138
+ }
139
+ }
140
+
141
+ static VALUE rb_gsl_multifit_XXXfit(int argc, VALUE *argv, VALUE obj,
142
+ void (*fn)(gsl_matrix*, gsl_vector*,size_t))
143
+ {
144
+ gsl_multifit_linear_workspace *space = NULL;
145
+ gsl_matrix *X = NULL, *cov = NULL;
146
+ gsl_vector *x, *y = NULL, *w, *c = NULL, *err;
147
+ gsl_vector_view xx, yy, ww;
148
+ size_t order, i;
149
+ double chisq;
150
+ int status, flag = 0, flagw = 0;
151
+ VALUE vc, verr;
152
+ if (argc != 3 && argc != 4 && argc != 5)
153
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 3 or 4)", argc);
154
+ x = &xx.vector;
155
+ w = &ww.vector;
156
+ y = &yy.vector;
157
+ Data_Get_Vector(argv[0], x);
158
+ if (argc >= 3 && VECTOR_P(argv[2])) {
159
+ Data_Get_Vector(argv[1], w);
160
+ Data_Get_Vector(argv[2], y);
161
+ order = NUM2INT(argv[3]);
162
+ flagw = 1;
163
+ } else {
164
+ Data_Get_Vector(argv[1], y);
165
+ order = NUM2INT(argv[2]);
166
+ flagw = 0;
167
+ }
168
+ if (rb_obj_is_kind_of(argv[argc-1], cgsl_multifit_workspace)) {
169
+ Data_Get_Struct(argv[argc-1], gsl_multifit_linear_workspace, space);
170
+ } else {
171
+ space = gsl_multifit_linear_alloc(x->size, order + 1);
172
+ flag = 1;
173
+ }
174
+ cov = gsl_matrix_alloc(order + 1, order + 1);
175
+ c = gsl_vector_alloc(order + 1);
176
+ X = gsl_matrix_alloc(x->size, order + 1);
177
+ (*fn)(X, x, order);
178
+ if (flagw == 0) status = gsl_multifit_linear(X, y, c, cov, &chisq, space);
179
+ else status = gsl_multifit_wlinear(X, w, y, c, cov, &chisq, space);
180
+ if (flag == 1) gsl_multifit_linear_free(space);
181
+ err = gsl_vector_alloc(order + 1);
182
+ vc = Data_Wrap_Struct(cgsl_poly, 0, gsl_vector_free, c);
183
+ verr = Data_Wrap_Struct(cgsl_poly, 0, gsl_vector_free, err);
184
+ for (i = 0; i < err->size; i++)
185
+ gsl_vector_set(err, i, sqrt(chisq/((double)x->size-err->size)*gsl_matrix_get(cov, i, i)));
186
+
187
+ gsl_matrix_free(X);
188
+ gsl_matrix_free(cov);
189
+ return rb_ary_new3(4, vc, verr, rb_float_new(chisq), INT2FIX(status));
190
+ }
191
+
192
+ static VALUE rb_gsl_multifit_polyfit(int argc, VALUE *argv, VALUE obj)
193
+ {
194
+ return rb_gsl_multifit_XXXfit(argc, argv, obj, calc_X_power);
195
+ }
196
+
197
+ static VALUE rb_gsl_multifit_legfit(int argc, VALUE *argv, VALUE obj)
198
+ {
199
+ return rb_gsl_multifit_XXXfit(argc, argv, obj, calc_X_legendre);
200
+ }
201
+
202
+ /**********/
203
+
204
+ static VALUE rb_gsl_multifit_fdfsolver_new(int argc, VALUE *argv, VALUE klass)
205
+ {
206
+ const gsl_multifit_fdfsolver_type *T;
207
+ gsl_multifit_fdfsolver *solver = NULL;
208
+ size_t n, p;
209
+ char name[64];
210
+ switch (argc) {
211
+ case 3:
212
+ switch (TYPE(argv[0])) {
213
+ case T_STRING:
214
+ strcpy(name, STR2CSTR(argv[0]));
215
+ if (str_tail_grep(name, "lmsder") == 0) {
216
+ T = gsl_multifit_fdfsolver_lmsder;
217
+ } else if (str_tail_grep(name, "lmder") == 0) {
218
+ T = gsl_multifit_fdfsolver_lmder;
219
+ } else {
220
+ rb_raise(rb_eTypeError, "unknown solver type %s (lmsder of lmder)",
221
+ name);
222
+ }
223
+ break;
224
+ case T_FIXNUM:
225
+ switch (FIX2INT(argv[0])) {
226
+ case GSL_MULTIFIT_FDFSOLVER_LMSDER:
227
+ T = gsl_multifit_fdfsolver_lmsder;
228
+ break;
229
+ case GSL_MULTIFIT_FDFSOLVER_LMDER:
230
+ T = gsl_multifit_fdfsolver_lmder;
231
+ break;
232
+ default:
233
+ rb_raise(rb_eTypeError,
234
+ "unknown solver type (GSL::MultiFit::FdfSolver::LMSDER or LMDER expected)");
235
+ break;
236
+ }
237
+ break;
238
+ default:
239
+ rb_raise(rb_eTypeError, "wrong argument type %s (Fixnum or String)",
240
+ rb_class2name(CLASS_OF(argv[0])));
241
+ break;
242
+ }
243
+ CHECK_FIXNUM(argv[1]); CHECK_FIXNUM(argv[2]);
244
+ n = FIX2INT(argv[1]);
245
+ p = FIX2INT(argv[2]);
246
+ break;
247
+ case 2:
248
+ CHECK_FIXNUM(argv[0]); CHECK_FIXNUM(argv[1]);
249
+ T = gsl_multifit_fdfsolver_lmsder;
250
+ n = FIX2INT(argv[0]);
251
+ p = FIX2INT(argv[1]);
252
+ break;
253
+ default:
254
+ rb_raise(rb_eArgError, "wrong number of arguments");
255
+ break;
256
+ }
257
+ solver = gsl_multifit_fdfsolver_alloc(T, n, p);
258
+ return Data_Wrap_Struct(klass, 0, gsl_multifit_fdfsolver_free, solver);
259
+ }
260
+
261
+ static VALUE rb_gsl_multifit_fdfsolver_set(VALUE obj, VALUE ff, VALUE xx)
262
+ {
263
+ gsl_multifit_fdfsolver *solver = NULL;
264
+ gsl_multifit_function_fdf *f = NULL;
265
+ gsl_vector *x = NULL;
266
+ int status;
267
+ CHECK_MULTIFIT_FUNCTION_FDF(ff);
268
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
269
+ Data_Get_Struct(ff, gsl_multifit_function_fdf, f);
270
+ Data_Get_Vector(xx, x);
271
+ status = gsl_multifit_fdfsolver_set(solver, f, x);
272
+ return INT2FIX(status);
273
+ }
274
+
275
+ static VALUE rb_gsl_multifit_fdfsolver_name(VALUE obj)
276
+ {
277
+ gsl_multifit_fdfsolver *solver = NULL;
278
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
279
+ return rb_str_new2(gsl_multifit_fdfsolver_name(solver));
280
+ }
281
+
282
+ static VALUE rb_gsl_multifit_fdfsolver_iterate(VALUE obj)
283
+ {
284
+ gsl_multifit_fdfsolver *solver = NULL;
285
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
286
+ return INT2FIX(gsl_multifit_fdfsolver_iterate(solver));
287
+ }
288
+
289
+ static VALUE rb_gsl_multifit_fdfsolver_position(VALUE obj)
290
+ {
291
+ gsl_multifit_fdfsolver *solver = NULL;
292
+ gsl_vector *x = NULL;
293
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
294
+ x = gsl_multifit_fdfsolver_position(solver);
295
+ return Data_Wrap_Struct(cgsl_vector_view_ro, 0, NULL, x);
296
+ }
297
+
298
+ static VALUE rb_gsl_multifit_fdfsolver_print_state(VALUE obj, VALUE i)
299
+ {
300
+ gsl_multifit_fdfsolver *solver = NULL;
301
+ CHECK_FIXNUM(i);
302
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
303
+ printf("iter: %d x = %15.8f %15.8f %15.8f |f(x)| = %g\n",
304
+ (int) FIX2INT(i), gsl_vector_get(solver->x, 0), gsl_vector_get(solver->x, 1),
305
+ gsl_vector_get(solver->x, 2), gsl_blas_dnrm2(solver->f));
306
+ return Qtrue;
307
+ }
308
+
309
+ static VALUE rb_gsl_multifit_fdfsolver_fdf(VALUE obj)
310
+ {
311
+ gsl_multifit_fdfsolver *solver = NULL;
312
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
313
+ return Data_Wrap_Struct(cgsl_multifit_function_fdf, 0, NULL, solver->fdf);
314
+ }
315
+
316
+ static VALUE rb_gsl_multifit_fdfsolver_test_delta(VALUE obj, VALUE r, VALUE a)
317
+ {
318
+ gsl_multifit_fdfsolver *solver = NULL;
319
+ Need_Float(r); Need_Float(a);
320
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
321
+ return INT2FIX(gsl_multifit_test_delta(solver->dx, solver->x, NUM2DBL(r), NUM2DBL(a)));
322
+ }
323
+
324
+ static VALUE rb_gsl_multifit_fdfsolver_test_gradient(int argc, VALUE *argv, VALUE obj)
325
+ {
326
+ gsl_multifit_fdfsolver *solver = NULL;
327
+ gsl_vector *g = NULL;
328
+ int status;
329
+ double epsabs;
330
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
331
+ switch (argc) {
332
+ case 1:
333
+ Need_Float(argv[0]);
334
+ g = gsl_vector_alloc(solver->x->size);
335
+ gsl_multifit_gradient(solver->J, solver->f, g);
336
+ epsabs = NUM2DBL(argv[0]);
337
+ status = gsl_multifit_test_gradient(g, epsabs);
338
+ gsl_vector_free(g);
339
+ break;
340
+ case 2:
341
+ Need_Float(argv[1]);
342
+ Data_Get_Vector(argv[0], g);
343
+ epsabs = NUM2DBL(argv[1]);
344
+ status = gsl_multifit_test_gradient(g, epsabs);
345
+ break;
346
+ default:
347
+ rb_raise(rb_eArgError, "wrong number of arguments");
348
+ break;
349
+ }
350
+ return INT2FIX(status);
351
+ }
352
+
353
+ static VALUE rb_gsl_multifit_fdfsolver_gradient(int argc, VALUE *argv, VALUE obj)
354
+ {
355
+ gsl_multifit_fdfsolver *solver = NULL;
356
+ gsl_vector *g = NULL;
357
+ int status;
358
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
359
+ if (argc == 1) {
360
+ Data_Get_Vector(argv[0], g);
361
+ return INT2FIX(gsl_multifit_gradient(solver->J, solver->f, g));
362
+ } else {
363
+ g = gsl_vector_alloc(solver->x->size);
364
+ status = gsl_multifit_gradient(solver->J, solver->f, g);
365
+ return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, g);
366
+ }
367
+ }
368
+
369
+ static VALUE rb_gsl_multifit_fdfsolver_covar(int argc, VALUE *argv, VALUE obj)
370
+ {
371
+ gsl_multifit_fdfsolver *solver = NULL;
372
+ gsl_matrix *covar = NULL;
373
+ double epsrel;
374
+ int status;
375
+ if (argc < 1) rb_raise(rb_eArgError, "too few arguments");
376
+ Need_Float(argv[0]);
377
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
378
+ epsrel = NUM2DBL(argv[0]);
379
+ switch (argc) {
380
+ case 1:
381
+ covar = gsl_matrix_alloc(solver->x->size, solver->x->size);
382
+ status = gsl_multifit_covar(solver->J, epsrel, covar);
383
+ return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, covar);
384
+ break;
385
+ case 2:
386
+ Data_Get_Matrix(argv[1], covar);
387
+ return INT2FIX(gsl_multifit_covar(solver->J, epsrel, covar));
388
+ break;
389
+ default:
390
+ rb_raise(rb_eArgError, "wrong number of arguments");
391
+ break;
392
+ }
393
+ }
394
+
395
+ static VALUE rb_gsl_multifit_fdfsolver_x(VALUE obj)
396
+ {
397
+ gsl_multifit_fdfsolver *solver = NULL;
398
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
399
+ return Data_Wrap_Struct(cgsl_vector_view_ro, 0, NULL, solver->x);
400
+ }
401
+
402
+ static VALUE rb_gsl_multifit_fdfsolver_dx(VALUE obj)
403
+ {
404
+ gsl_multifit_fdfsolver *solver = NULL;
405
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
406
+ return Data_Wrap_Struct(cgsl_vector_view_ro, 0, NULL, solver->dx);
407
+ }
408
+
409
+ static VALUE rb_gsl_multifit_fdfsolver_f(VALUE obj)
410
+ {
411
+ gsl_multifit_fdfsolver *solver = NULL;
412
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
413
+ return Data_Wrap_Struct(cgsl_vector_view_ro, 0, NULL, solver->f);
414
+ }
415
+
416
+ static VALUE rb_gsl_multifit_fdfsolver_J(VALUE obj)
417
+ {
418
+ gsl_multifit_fdfsolver *solver = NULL;
419
+ Data_Get_Struct(obj, gsl_multifit_fdfsolver, solver);
420
+ return Data_Wrap_Struct(cgsl_matrix_view_ro, 0, NULL, solver->J);
421
+ }
422
+
423
+ /* singleton */
424
+ static VALUE rb_gsl_multifit_test_delta(VALUE obj, VALUE ddx, VALUE xx, VALUE a, VALUE r)
425
+ {
426
+ gsl_vector *dx = NULL, *x = NULL;
427
+ Need_Float(a); Need_Float(r);
428
+ Data_Get_Vector(ddx, dx);
429
+ Data_Get_Vector(xx, x);
430
+ return INT2FIX(gsl_multifit_test_delta(dx, x, NUM2DBL(a), NUM2DBL(r)));
431
+ }
432
+
433
+ static VALUE rb_gsl_multifit_test_gradient(VALUE obj, VALUE gg, VALUE a)
434
+ {
435
+ gsl_vector *g = NULL;
436
+ Need_Float(a);
437
+ Data_Get_Vector(gg, g);
438
+ return INT2FIX(gsl_multifit_test_gradient(g, NUM2DBL(a)));
439
+ }
440
+
441
+ static VALUE rb_gsl_multifit_gradient(int argc, VALUE *argv, VALUE obj)
442
+ {
443
+ gsl_vector *g = NULL, *f = NULL;
444
+ gsl_matrix *J = NULL;
445
+ int status;
446
+ switch (argc) {
447
+ case 2:
448
+ Data_Get_Matrix(argv[0], J);
449
+ Data_Get_Vector(argv[1], f);
450
+ g = gsl_vector_alloc(f->size);
451
+ status = gsl_multifit_gradient(J, f, g);
452
+ return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, g);
453
+ break;
454
+ case 3:
455
+ Data_Get_Matrix(argv[0], J);
456
+ Data_Get_Vector(argv[1], f);
457
+ Data_Get_Vector(argv[2], g);
458
+ return INT2FIX(gsl_multifit_gradient(J, f, g));
459
+ break;
460
+ default:
461
+ rb_raise(rb_eArgError, "wrong number of arguments");
462
+ break;
463
+ }
464
+ }
465
+
466
+ static VALUE rb_gsl_multifit_covar(int argc, VALUE *argv, VALUE obj)
467
+ {
468
+ gsl_matrix *J = NULL, *covar = NULL;
469
+ double epsrel;
470
+ int status;
471
+ switch (argc) {
472
+ case 2:
473
+ Need_Float(argv[1]);
474
+ Data_Get_Matrix(argv[0], J);
475
+ epsrel = NUM2DBL(argv[1]);
476
+ covar = gsl_matrix_alloc(J->size2, J->size2);
477
+ status = gsl_multifit_covar(J, epsrel, covar);
478
+ return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, covar);
479
+ break;
480
+ case 3:
481
+ Need_Float(argv[1]);
482
+ Data_Get_Matrix(argv[0], J);
483
+ epsrel = NUM2DBL(argv[1]);
484
+ Data_Get_Matrix(argv[2], covar);
485
+ status = gsl_multifit_covar(J, epsrel, covar);
486
+ return INT2FIX(status);
487
+ break;
488
+ default:
489
+ rb_raise(rb_eArgError, "wrong number of arguments");
490
+ break;
491
+ }
492
+ }
493
+
494
+ static void rb_gsl_multifit_define_const(VALUE klass)
495
+ {
496
+ rb_define_const(klass, "LMSDER",
497
+ INT2FIX(GSL_MULTIFIT_FDFSOLVER_LMSDER));
498
+ rb_define_const(klass, "LMDER",
499
+ INT2FIX(GSL_MULTIFIT_FDFSOLVER_LMDER));
500
+
501
+ rb_define_const(klass, "Lmsder",
502
+ INT2FIX(GSL_MULTIFIT_FDFSOLVER_LMSDER));
503
+ rb_define_const(klass, "Lmder",
504
+ INT2FIX(GSL_MULTIFIT_FDFSOLVER_LMDER));
505
+ }
506
+
507
+ static void gsl_multifit_function_fdf_free(gsl_multifit_function_fdf *f);
508
+ static void gsl_multifit_function_fdf_free(gsl_multifit_function_fdf *f)
509
+ {
510
+ free((gsl_multifit_function_fdf *) f);
511
+ }
512
+
513
+ static void gsl_multifit_function_fdf_mark(gsl_multifit_function_fdf *F);
514
+ static void gsl_multifit_function_fdf_mark(gsl_multifit_function_fdf *F)
515
+ {
516
+ rb_gc_mark((VALUE) F->params);
517
+ }
518
+
519
+ static int gsl_multifit_function_fdf_f(const gsl_vector *x, void *params,
520
+ gsl_vector *f);
521
+ static int gsl_multifit_function_fdf_df(const gsl_vector *x, void *params,
522
+ gsl_matrix *J);
523
+ static int gsl_multifit_function_fdf_fdf(const gsl_vector *x, void *params,
524
+ gsl_vector *f, gsl_matrix *J);
525
+
526
+ static VALUE rb_gsl_multifit_function_fdf_set_procs(int argc, VALUE *argv, VALUE obj);
527
+
528
+ static VALUE rb_gsl_multifit_function_fdf_new(int argc, VALUE *argv, VALUE klass)
529
+ {
530
+ gsl_multifit_function_fdf *func = NULL;
531
+ VALUE obj;
532
+ func = ALLOC(gsl_multifit_function_fdf);
533
+ func->f = &gsl_multifit_function_fdf_f;
534
+ func->df = &gsl_multifit_function_fdf_df;
535
+ func->fdf = &gsl_multifit_function_fdf_fdf;
536
+ func->params = NULL;
537
+ obj = Data_Wrap_Struct(klass, gsl_multifit_function_fdf_mark, gsl_multifit_function_fdf_free, func);
538
+ switch (argc) {
539
+ case 0:
540
+ case 1:
541
+ break;
542
+ case 2:
543
+ case 3:
544
+ rb_gsl_multifit_function_fdf_set_procs(argc, argv, obj);
545
+ break;
546
+ default:
547
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0-3)", argc);
548
+ break;
549
+ }
550
+ return obj;
551
+ }
552
+
553
+ static VALUE rb_gsl_multifit_function_fdf_set_procs(int argc, VALUE *argv, VALUE obj)
554
+ {
555
+ gsl_multifit_function_fdf *func = NULL;
556
+ VALUE ary;
557
+ Data_Get_Struct(obj, gsl_multifit_function_fdf, func);
558
+ if (func->params == NULL) {
559
+ ary = rb_ary_new2(4);
560
+ /* (VALUE) func->params = ary;*/
561
+ func->params = (void *) ary;
562
+ } else {
563
+ ary = (VALUE) func->params;
564
+ }
565
+ rb_ary_store(ary, 0, argv[0]);
566
+ rb_ary_store(ary, 1, argv[1]);
567
+ switch (argc) {
568
+ case 2:
569
+ break;
570
+ case 3:
571
+ if (TYPE(argv[2]) == T_FIXNUM) {
572
+ func->p = FIX2INT(argv[2]);
573
+ rb_ary_store(ary, 2, Qnil);
574
+ } else rb_ary_store(ary, 2, argv[2]);
575
+ break;
576
+ case 4:
577
+ if (TYPE(argv[2]) == T_FIXNUM) {
578
+ func->p = FIX2INT(argv[2]);
579
+ rb_ary_store(ary, 2, argv[3]);
580
+ } else {
581
+ func->p = FIX2INT(argv[3]);
582
+ rb_ary_store(ary, 2, argv[2]);
583
+ }
584
+ break;
585
+ default:
586
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 3 or 4)", argc);
587
+ break;
588
+ }
589
+ return obj;
590
+ }
591
+
592
+ static VALUE rb_gsl_multifit_function_fdf_set_data(int argc, VALUE *argv, VALUE obj)
593
+ {
594
+ VALUE ary, ary2;
595
+ gsl_multifit_function_fdf *func = NULL;
596
+ Data_Get_Struct(obj, gsl_multifit_function_fdf, func);
597
+ if (func->params == NULL) {
598
+ ary = rb_ary_new2(4);
599
+ /* (VALUE) func->params = ary;*/
600
+ func->params = (void *) ary;
601
+ } else {
602
+ ary = (VALUE) func->params;
603
+ }
604
+ switch (argc) {
605
+ case 2:
606
+ ary2 = rb_ary_new3(2, argv[0], argv[1]); /* t, y */
607
+ break;
608
+ case 3:
609
+ ary2 = rb_ary_new3(3, argv[0], argv[1], argv[2]); /* t, y, sigma */
610
+ break;
611
+ default:
612
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 or 3)", argc);
613
+ break;
614
+ }
615
+ func->n = NUM2INT(rb_funcall(argv[0], rb_intern("size"), 0));
616
+ rb_ary_store(ary, 3, ary2);
617
+ return obj;
618
+ }
619
+
620
+ static int gsl_multifit_function_fdf_f(const gsl_vector *x, void *params,
621
+ gsl_vector *f)
622
+ {
623
+ VALUE vt_y_sigma, vt, vy, vsigma, vf, vx, proc, ary;
624
+ ary = (VALUE) params;
625
+ vt_y_sigma = rb_ary_entry(ary, 3);
626
+ proc = rb_ary_entry(ary, 0);
627
+ vx = Data_Wrap_Struct(cgsl_vector, 0, NULL, (gsl_vector *) x);
628
+ vf = Data_Wrap_Struct(cgsl_vector, 0, NULL, f);
629
+ switch (RARRAY_LEN(vt_y_sigma)) {
630
+ case 2:
631
+ vt = rb_ary_entry(vt_y_sigma, 0);
632
+ vy = rb_ary_entry(vt_y_sigma, 1);
633
+ rb_funcall(proc, RBGSL_ID_call, 4, vx, vt, vy, vf);
634
+ break;
635
+ case 3:
636
+ vt = rb_ary_entry(vt_y_sigma, 0);
637
+ vy = rb_ary_entry(vt_y_sigma, 1);
638
+ vsigma = rb_ary_entry(vt_y_sigma,2);
639
+ rb_funcall(proc, RBGSL_ID_call, 5, vx, vt, vy, vsigma, vf);
640
+ break;
641
+ default:
642
+ rb_raise(rb_eArgError, "bad argument");
643
+ break;
644
+ }
645
+ return GSL_SUCCESS;
646
+ }
647
+
648
+ static int gsl_multifit_function_fdf_df(const gsl_vector *x, void *params,
649
+ gsl_matrix *J)
650
+ {
651
+ VALUE vt_y_sigma, vt, vy, vsigma, vJ, vx, proc, ary;
652
+ ary = (VALUE) params;
653
+ vt_y_sigma = rb_ary_entry(ary, 3);
654
+ proc = rb_ary_entry(ary, 1);
655
+ vx = Data_Wrap_Struct(cgsl_vector, 0, NULL, (gsl_vector *) x);
656
+ vJ = Data_Wrap_Struct(cgsl_matrix, 0, NULL, J);
657
+ switch (RARRAY_LEN(vt_y_sigma)) {
658
+ case 2:
659
+ vt = rb_ary_entry(vt_y_sigma, 0);
660
+ vy = rb_ary_entry(vt_y_sigma, 1);
661
+ rb_funcall(proc, RBGSL_ID_call, 4, vx, vt, vy, vJ);
662
+ break;
663
+ case 3:
664
+ vt = rb_ary_entry(vt_y_sigma, 0);
665
+ vy = rb_ary_entry(vt_y_sigma, 1);
666
+ vsigma = rb_ary_entry(vt_y_sigma,2);
667
+ rb_funcall(proc, RBGSL_ID_call, 5, vx, vt, vy, vsigma, vJ);
668
+ break;
669
+ default:
670
+ rb_raise(rb_eArgError, "bad argument");
671
+ break;
672
+ }
673
+ return GSL_SUCCESS;
674
+ }
675
+
676
+ static int gsl_multifit_function_fdf_fdf(const gsl_vector *x, void *params,
677
+ gsl_vector *f, gsl_matrix *J)
678
+ {
679
+ VALUE vt_y_sigma, vt, vy, vsigma, vf, vJ, vx, proc_f, proc_df, proc_fdf;
680
+ VALUE ary;
681
+ ary = (VALUE) params;
682
+ vt_y_sigma = rb_ary_entry(ary, 3);
683
+ proc_f = rb_ary_entry(ary, 0);
684
+ proc_df = rb_ary_entry(ary, 1);
685
+ proc_fdf = rb_ary_entry(ary, 2);
686
+ vx = Data_Wrap_Struct(cgsl_vector, 0, NULL, (gsl_vector *) x);
687
+ vf = Data_Wrap_Struct(cgsl_vector, 0, NULL, f);
688
+ vJ = Data_Wrap_Struct(cgsl_matrix, 0, NULL, J);
689
+ switch (RARRAY_LEN(vt_y_sigma)) {
690
+ case 2:
691
+ vt = rb_ary_entry(vt_y_sigma, 0);
692
+ vy = rb_ary_entry(vt_y_sigma, 1);
693
+ if (NIL_P(proc_fdf)) {
694
+ rb_funcall(proc_f, RBGSL_ID_call, 4, vx, vt, vy, vf);
695
+ rb_funcall(proc_df, RBGSL_ID_call, 4, vx, vt, vy, vJ);
696
+ } else
697
+ rb_funcall(proc_fdf, RBGSL_ID_call, 5, vx, vt, vy, vf, vJ);
698
+ break;
699
+ case 3:
700
+ vt = rb_ary_entry(vt_y_sigma, 0);
701
+ vy = rb_ary_entry(vt_y_sigma, 1);
702
+ vsigma = rb_ary_entry(vt_y_sigma,2);
703
+ if (NIL_P(proc_fdf)) {
704
+ rb_funcall(proc_f, RBGSL_ID_call, 5, vx, vt, vy, vsigma, vf);
705
+ rb_funcall(proc_df, RBGSL_ID_call, 5, vx, vt, vy, vsigma, vJ);
706
+ } else
707
+ rb_funcall(proc_fdf, RBGSL_ID_call, 6, vx, vt, vy, vsigma, vf, vJ);
708
+ break;
709
+ default:
710
+ rb_raise(rb_eArgError, "bad argument");
711
+ break;
712
+ }
713
+ return GSL_SUCCESS;
714
+ }
715
+
716
+ static VALUE rb_gsl_multifit_function_fdf_params(VALUE obj)
717
+ {
718
+ gsl_multifit_function_fdf *f = NULL;
719
+ Data_Get_Struct(obj, gsl_multifit_function_fdf, f);
720
+ return (VALUE) f->params;
721
+ }
722
+
723
+ static VALUE rb_gsl_multifit_function_fdf_n(VALUE obj)
724
+ {
725
+ gsl_multifit_function_fdf *f = NULL;
726
+ Data_Get_Struct(obj, gsl_multifit_function_fdf, f);
727
+ return INT2FIX(f->n);
728
+ }
729
+
730
+ static VALUE rb_gsl_multifit_function_fdf_set_n(VALUE obj, VALUE n)
731
+ {
732
+ gsl_multifit_function_fdf *f = NULL;
733
+ Data_Get_Struct(obj, gsl_multifit_function_fdf, f);
734
+ f->n = FIX2INT(n);
735
+ return obj;
736
+ }
737
+
738
+ static VALUE rb_gsl_multifit_function_fdf_p(VALUE obj)
739
+ {
740
+ gsl_multifit_function_fdf *f = NULL;
741
+ Data_Get_Struct(obj, gsl_multifit_function_fdf, f);
742
+ return INT2FIX(f->p);
743
+ }
744
+
745
+ /*****/
746
+ struct fitting_xydata {
747
+ gsl_vector *x, *y, *w;
748
+ };
749
+
750
+ /* Gaussian fit
751
+ y = y0 + A exp(-(x-x0/sigma)^2)
752
+ v[0] = y0
753
+ v[1] = A
754
+ v[2] = x0
755
+ v[3] = var = sigma^2
756
+ */
757
+ static int Gaussian_f(const gsl_vector *v, void *data, gsl_vector *f)
758
+ {
759
+ gsl_vector *x, *y, *w;
760
+ double y0, A, x0, var, xi, yi, wi;
761
+ size_t i;
762
+ struct fitting_xydata *xydata;
763
+ xydata = (struct fitting_xydata*) data;
764
+ x = xydata->x;
765
+ y = xydata->y;
766
+ w = xydata->w;
767
+ var = gsl_vector_get(v, 3);
768
+ x0 = gsl_vector_get(v, 2);
769
+ A = gsl_vector_get(v, 1);
770
+ y0 = gsl_vector_get(v, 0);
771
+ for (i = 0; i < x->size; i++) {
772
+ xi = gsl_vector_get(x, i);
773
+ yi = gsl_vector_get(y, i);
774
+ if (w) wi = gsl_vector_get(w, i);
775
+ else wi = 1.0;
776
+ gsl_vector_set(f, i, (A*exp(-(xi - x0)*(xi - x0)/var/2.0) + y0 - yi)*wi);
777
+ }
778
+ return GSL_SUCCESS;
779
+ }
780
+
781
+ static int Gaussian_df(const gsl_vector *v, void *data, gsl_matrix *J)
782
+ {
783
+ double A, x0, var, xi, yy, wi;
784
+ size_t i;
785
+ struct fitting_xydata *xydata;
786
+ gsl_vector *x, *y, *w;
787
+ xydata = (struct fitting_xydata*) data;
788
+ x = xydata->x;
789
+ y = xydata->y;
790
+ w = xydata->w;
791
+ var = gsl_vector_get(v, 3);
792
+ x0 = gsl_vector_get(v, 2);
793
+ A = gsl_vector_get(v, 1);
794
+ for (i = 0; i < x->size; i++) {
795
+ xi = gsl_vector_get(x, i);
796
+ if (w) wi = gsl_vector_get(w, i);
797
+ else wi = 1.0;
798
+ yy = exp(-(xi - x0)*(xi - x0)/var/2.0);
799
+ gsl_matrix_set(J, i, 3, A*yy*(xi - x0)*(xi - x0)/2/var/var*wi);
800
+ gsl_matrix_set(J, i, 2, A*yy*(xi - x0)/var*wi);
801
+ gsl_matrix_set(J, i, 1, yy*wi);
802
+ gsl_matrix_set(J, i, 0, 1.0*wi);
803
+ }
804
+ return GSL_SUCCESS;
805
+ }
806
+
807
+ static int Gaussian_fdf(const gsl_vector *v, void *data,
808
+ gsl_vector *f, gsl_matrix *J)
809
+ {
810
+ Gaussian_f(v, data, f);
811
+ Gaussian_df(v, data, J);
812
+ return GSL_SUCCESS;
813
+ }
814
+
815
+ /* 2 Gaussian fit
816
+ y = y0 + A1 exp(-(x-x01/sigma1)^2) + A2 exp(-(x-x02/sigma2)^2)
817
+ v[0] = y0
818
+ v[1] = A1
819
+ v[2] = x01
820
+ v[3] = var1 = sigma1^2
821
+ v[4] = A2
822
+ v[5] = x02
823
+ v[6] = var2 = sigma2^2
824
+ */
825
+ static int Gaussian_2peaks_f(const gsl_vector *v, void *data, gsl_vector *f)
826
+ {
827
+ gsl_vector *x, *y, *w;
828
+ double y0, A1, x01, var1, A2, x02, var2, xi, yi, wi;
829
+ size_t i;
830
+ struct fitting_xydata *xydata;
831
+ xydata = (struct fitting_xydata*) data;
832
+ x = xydata->x;
833
+ y = xydata->y;
834
+ w = xydata->w;
835
+ y0 = gsl_vector_get(v, 0);
836
+ A1 = gsl_vector_get(v, 1);
837
+ x01 = gsl_vector_get(v, 2);
838
+ var1 = gsl_vector_get(v, 3);
839
+ A2 = gsl_vector_get(v, 4);
840
+ x02 = gsl_vector_get(v, 5);
841
+ var2 = gsl_vector_get(v, 6);
842
+ for (i = 0; i < x->size; i++) {
843
+ xi = gsl_vector_get(x, i);
844
+ yi = gsl_vector_get(y, i);
845
+ if (w) wi = gsl_vector_get(w, i);
846
+ else wi = 1.0;
847
+ gsl_vector_set(f, i, (A1*exp(-(xi - x01)*(xi - x01)/var1/2.0) + A2*exp(-(xi - x02)*(xi - x02)/var2/2.0) + y0 - yi)*wi);
848
+ }
849
+ return GSL_SUCCESS;
850
+ }
851
+
852
+ static int Gaussian_2peaks_df(const gsl_vector *v, void *data, gsl_matrix *J)
853
+ {
854
+ double A1, x01, var1, A2, x02, var2, xi, yy, wi;
855
+ size_t i;
856
+ struct fitting_xydata *xydata;
857
+ gsl_vector *x, *y, *w;
858
+ xydata = (struct fitting_xydata*) data;
859
+ x = xydata->x;
860
+ y = xydata->y;
861
+ w = xydata->w;
862
+ A1 = gsl_vector_get(v, 1);
863
+ x01 = gsl_vector_get(v, 2);
864
+ var1 = gsl_vector_get(v, 3);
865
+ A2 = gsl_vector_get(v, 4);
866
+ x02 = gsl_vector_get(v, 5);
867
+ var2 = gsl_vector_get(v, 6);
868
+ for (i = 0; i < x->size; i++) {
869
+ xi = gsl_vector_get(x, i);
870
+ if (w) wi = gsl_vector_get(w, i);
871
+ else wi = 1.0;
872
+ yy = exp(-(xi - x01)*(xi - x01)/var1/2.0);
873
+ gsl_matrix_set(J, i, 0, 1.0*wi);
874
+ gsl_matrix_set(J, i, 1, yy*wi);
875
+ gsl_matrix_set(J, i, 2, A1*yy*(xi - x01)/var1*wi);
876
+ gsl_matrix_set(J, i, 3, A1*yy*(xi - x01)*(xi - x01)/2/var1/var1*wi);
877
+
878
+ yy = exp(-(xi - x02)*(xi - x02)/var2/2.0);
879
+ gsl_matrix_set(J, i, 4, yy*wi);
880
+ gsl_matrix_set(J, i, 5, A2*yy*(xi - x02)/var2*wi);
881
+ gsl_matrix_set(J, i, 6, A2*yy*(xi - x02)*(xi - x02)/2/var2/var2*wi);
882
+ }
883
+ return GSL_SUCCESS;
884
+ }
885
+
886
+ static int Gaussian_2peaks_fdf(const gsl_vector *v, void *data,
887
+ gsl_vector *f, gsl_matrix *J)
888
+ {
889
+ Gaussian_2peaks_f(v, data, f);
890
+ Gaussian_2peaks_df(v, data, J);
891
+ return GSL_SUCCESS;
892
+ }
893
+
894
+ /* Exponential fit
895
+ y = y0 + A exp(-bx)
896
+ v[0] = y0
897
+ v[1] = A
898
+ v[2] = b
899
+ */
900
+ static int Exponential_f(const gsl_vector *v, void *data, gsl_vector *f)
901
+ {
902
+ gsl_vector *x, *y, *w;
903
+ double y0, A, b, xi, yi, wi;
904
+ size_t i;
905
+ struct fitting_xydata *xydata;
906
+ xydata = (struct fitting_xydata*) data;
907
+ x = xydata->x;
908
+ y = xydata->y;
909
+ w = xydata->w;
910
+ y0 = gsl_vector_get(v, 0);
911
+ A = gsl_vector_get(v, 1);
912
+ b = gsl_vector_get(v, 2);
913
+ for (i = 0; i < x->size; i++) {
914
+ xi = gsl_vector_get(x, i);
915
+ if (w) wi = gsl_vector_get(w, i);
916
+ else wi = 1.0;
917
+ yi = gsl_vector_get(y, i);
918
+ gsl_vector_set(f, i, (A*exp(-b*xi) + y0 - yi)*wi);
919
+ }
920
+ return GSL_SUCCESS;
921
+ }
922
+
923
+ static int Exponential_df(const gsl_vector *v, void *data, gsl_matrix *J)
924
+ {
925
+ double A, b, xi, yy, wi;
926
+ size_t i;
927
+ struct fitting_xydata *xydata;
928
+ gsl_vector *x, *y, *w;
929
+ xydata = (struct fitting_xydata*) data;
930
+ x = xydata->x;
931
+ y = xydata->y;
932
+ w = xydata->w;
933
+ A = gsl_vector_get(v, 1);
934
+ b = gsl_vector_get(v, 2);
935
+ for (i = 0; i < x->size; i++) {
936
+ xi = gsl_vector_get(x, i);
937
+ if (w) wi = gsl_vector_get(w, i);
938
+ else wi = 1.0;
939
+ yy = exp(-xi*b);
940
+ gsl_matrix_set(J, i, 0, 1.0*wi);
941
+ gsl_matrix_set(J, i, 1, yy*wi);
942
+ gsl_matrix_set(J, i, 2, -A*yy*xi*wi);
943
+ }
944
+ return GSL_SUCCESS;
945
+ }
946
+
947
+ static int Exponential_fdf(const gsl_vector *v, void *data,
948
+ gsl_vector *f, gsl_matrix *J)
949
+ {
950
+ Exponential_f(v, data, f);
951
+ Exponential_df(v, data, J);
952
+ return GSL_SUCCESS;
953
+ }
954
+
955
+
956
+ /* Double Exponential fit
957
+ y = y0 + A1 exp(-b1 x) + A2 exp(-b2 x)
958
+ v[0] = y0
959
+ v[1] = A1
960
+ v[2] = b1
961
+ v[3] = A2
962
+ v[4] = b2
963
+ */
964
+ static int DblExponential_f(const gsl_vector *v, void *data, gsl_vector *f)
965
+ {
966
+ gsl_vector *x, *y, *w;
967
+ double y0, A1, b1, A2, b2, xi, yi, wi;
968
+ size_t i;
969
+ struct fitting_xydata *xydata;
970
+ xydata = (struct fitting_xydata*) data;
971
+ x = xydata->x;
972
+ y = xydata->y;
973
+ w = xydata->w;
974
+ y0 = gsl_vector_get(v, 0);
975
+ A1 = gsl_vector_get(v, 1);
976
+ b1 = gsl_vector_get(v, 2);
977
+ A2 = gsl_vector_get(v, 3);
978
+ b2 = gsl_vector_get(v, 4);
979
+ for (i = 0; i < x->size; i++) {
980
+ xi = gsl_vector_get(x, i);
981
+ if (w) wi = gsl_vector_get(w, i);
982
+ else wi = 1.0;
983
+ yi = gsl_vector_get(y, i);
984
+ gsl_vector_set(f, i, (A1*exp(-b1*xi) + A2*exp(-b2*xi) + y0 - yi)*wi);
985
+ }
986
+ return GSL_SUCCESS;
987
+ }
988
+
989
+ static int DblExponential_df(const gsl_vector *v, void *data, gsl_matrix *J)
990
+ {
991
+ double A1, b1, A2, b2, xi, yy1, yy2, wi;
992
+ size_t i;
993
+ struct fitting_xydata *xydata;
994
+ gsl_vector *x, *y, *w;
995
+ xydata = (struct fitting_xydata*) data;
996
+ x = xydata->x;
997
+ y = xydata->y;
998
+ w = xydata->w;
999
+ A1 = gsl_vector_get(v, 1);
1000
+ b1 = gsl_vector_get(v, 2);
1001
+ A2 = gsl_vector_get(v, 3);
1002
+ b2 = gsl_vector_get(v, 4);
1003
+ for (i = 0; i < x->size; i++) {
1004
+ xi = gsl_vector_get(x, i);
1005
+ if (w) wi = gsl_vector_get(w, i);
1006
+ else wi = 1.0;
1007
+ yy1 = exp(-xi*b1);
1008
+ yy2 = exp(-xi*b2);
1009
+ gsl_matrix_set(J, i, 0, 1.0*wi);
1010
+ gsl_matrix_set(J, i, 1, yy1*wi);
1011
+ gsl_matrix_set(J, i, 2, -A1*yy1*xi*wi);
1012
+ gsl_matrix_set(J, i, 3, yy2*wi);
1013
+ gsl_matrix_set(J, i, 4, -A2*yy2*xi*wi);
1014
+ }
1015
+ return GSL_SUCCESS;
1016
+ }
1017
+
1018
+ static int DblExponential_fdf(const gsl_vector *v, void *data,
1019
+ gsl_vector *f, gsl_matrix *J)
1020
+ {
1021
+ DblExponential_f(v, data, f);
1022
+ DblExponential_df(v, data, J);
1023
+ return GSL_SUCCESS;
1024
+ }
1025
+
1026
+ /* Lorentzian fit
1027
+ y = y0 + A/((x-x0)^2 + B)
1028
+ v[0] = y0
1029
+ v[1] = A
1030
+ v[2] = x0
1031
+ v[3] = B
1032
+ */
1033
+ static int Lorentzian_f(const gsl_vector *v, void *data, gsl_vector *f)
1034
+ {
1035
+ gsl_vector *x, *y, *w;
1036
+ double y0, A, x0, B, xi, yi, wi;
1037
+ size_t i;
1038
+ struct fitting_xydata *xydata;
1039
+ xydata = (struct fitting_xydata*) data;
1040
+ x = xydata->x;
1041
+ y = xydata->y;
1042
+ w = xydata->w;
1043
+ y0 = gsl_vector_get(v, 0);
1044
+ A = gsl_vector_get(v, 1);
1045
+ x0 = gsl_vector_get(v, 2);
1046
+ B = gsl_vector_get(v, 3);
1047
+ for (i = 0; i < x->size; i++) {
1048
+ xi = gsl_vector_get(x, i);
1049
+ if (w) wi = gsl_vector_get(w, i);
1050
+ else wi = 1.0;
1051
+ yi = gsl_vector_get(y, i);
1052
+ gsl_vector_set(f, i, (A/(gsl_pow_2(xi-x0)+B) + y0 - yi)*wi);
1053
+ }
1054
+ return GSL_SUCCESS;
1055
+ }
1056
+
1057
+ static int Lorentzian_df(const gsl_vector *v, void *data, gsl_matrix *J)
1058
+ {
1059
+ double A, B, x0, xi, yy, wi;
1060
+ size_t i;
1061
+ struct fitting_xydata *xydata;
1062
+ gsl_vector *x, *y, *w;
1063
+ xydata = (struct fitting_xydata*) data;
1064
+ x = xydata->x;
1065
+ y = xydata->y;
1066
+ w = xydata->w;
1067
+ A = gsl_vector_get(v, 1);
1068
+ x0 = gsl_vector_get(v, 2);
1069
+ B = gsl_vector_get(v, 3);
1070
+ for (i = 0; i < x->size; i++) {
1071
+ xi = gsl_vector_get(x, i);
1072
+ if (w) wi = gsl_vector_get(w, i);
1073
+ else wi = 1.0;
1074
+ yy = gsl_pow_2(xi-x0)+B;
1075
+ gsl_matrix_set(J, i, 0, 1.0*wi);
1076
+ gsl_matrix_set(J, i, 1, 1.0/yy*wi);
1077
+ gsl_matrix_set(J, i, 2, 2.0*A*(xi-x0)/yy/yy*wi);
1078
+ gsl_matrix_set(J, i, 3, -A/yy/yy*wi);
1079
+ }
1080
+ return GSL_SUCCESS;
1081
+ }
1082
+
1083
+ static int Lorentzian_fdf(const gsl_vector *v, void *data,
1084
+ gsl_vector *f, gsl_matrix *J)
1085
+ {
1086
+ Lorentzian_f(v, data, f);
1087
+ Lorentzian_df(v, data, J);
1088
+ return GSL_SUCCESS;
1089
+ }
1090
+
1091
+ /* Sinusoldal fit
1092
+ y = y0 + A sin(fc x + phi)
1093
+ v[0] = y0
1094
+ v[1] = A
1095
+ v[2] = fc
1096
+ v[3] = phi
1097
+ */
1098
+ static int Sin_f(const gsl_vector *v, void *data, gsl_vector *f)
1099
+ {
1100
+ gsl_vector *x, *y, *w;
1101
+ double y0, A, fc, phi, xi, yi, wi;
1102
+ size_t i;
1103
+ struct fitting_xydata *xydata;
1104
+ xydata = (struct fitting_xydata*) data;
1105
+ x = xydata->x;
1106
+ y = xydata->y;
1107
+ w = xydata->w;
1108
+ y0 = gsl_vector_get(v, 0);
1109
+ A = gsl_vector_get(v, 1);
1110
+ fc = gsl_vector_get(v, 2);
1111
+ phi = gsl_vector_get(v, 3);
1112
+ for (i = 0; i < x->size; i++) {
1113
+ xi = gsl_vector_get(x, i);
1114
+ if (w) wi = gsl_vector_get(w, i);
1115
+ else wi = 1.0;
1116
+ yi = gsl_vector_get(y, i);
1117
+ gsl_vector_set(f, i, (A*sin(fc*xi+phi) + y0 - yi)*wi);
1118
+ }
1119
+ return GSL_SUCCESS;
1120
+ }
1121
+
1122
+ static int Sin_df(const gsl_vector *v, void *data, gsl_matrix *J)
1123
+ {
1124
+ double A, fc, phi, xi, ys, yc, wi;
1125
+ size_t i;
1126
+ struct fitting_xydata *xydata;
1127
+ gsl_vector *x, *y, *w;
1128
+ xydata = (struct fitting_xydata*) data;
1129
+ x = xydata->x;
1130
+ y = xydata->y;
1131
+ w = xydata->w;
1132
+ A = gsl_vector_get(v, 1);
1133
+ fc = gsl_vector_get(v, 2);
1134
+ phi = gsl_vector_get(v, 3);
1135
+ for (i = 0; i < x->size; i++) {
1136
+ xi = gsl_vector_get(x, i);
1137
+ if (w) wi = gsl_vector_get(w, i);
1138
+ else wi = 1.0;
1139
+ ys = sin(fc*xi + phi);
1140
+ yc = cos(fc*xi + phi);
1141
+ gsl_matrix_set(J, i, 0, 1.0*wi);
1142
+ gsl_matrix_set(J, i, 1, ys*wi);
1143
+ gsl_matrix_set(J, i, 2, A*yc*xi*wi);
1144
+ gsl_matrix_set(J, i, 3, A*yc*wi);
1145
+ }
1146
+ return GSL_SUCCESS;
1147
+ }
1148
+
1149
+ static int Sin_fdf(const gsl_vector *v, void *data,
1150
+ gsl_vector *f, gsl_matrix *J)
1151
+ {
1152
+ Sin_f(v, data, f);
1153
+ Sin_df(v, data, J);
1154
+ return GSL_SUCCESS;
1155
+ }
1156
+
1157
+ /* Hill's equation fit
1158
+ y = y0 + (m - y0)/(1 + (xhalf/x)^r)
1159
+ v[0] = y0
1160
+ v[1] = m
1161
+ v[2] = xhalf
1162
+ v[3] = r
1163
+ */
1164
+ static int Hill_f(const gsl_vector *v, void *data, gsl_vector *f)
1165
+ {
1166
+ gsl_vector *x, *y, *w;
1167
+ double y0, m, xhalf, r, xi, yi, wi;
1168
+ size_t i;
1169
+ struct fitting_xydata *xydata;
1170
+ xydata = (struct fitting_xydata*) data;
1171
+ x = xydata->x;
1172
+ y = xydata->y;
1173
+ w = xydata->w;
1174
+ y0 = gsl_vector_get(v, 0);
1175
+ m = gsl_vector_get(v, 1);
1176
+ xhalf = gsl_vector_get(v, 2);
1177
+ r = gsl_vector_get(v, 3);
1178
+ for (i = 0; i < x->size; i++) {
1179
+ xi = gsl_vector_get(x, i);
1180
+ if (w) wi = gsl_vector_get(w, i);
1181
+ else wi = 1.0;
1182
+ yi = gsl_vector_get(y, i);
1183
+ gsl_vector_set(f, i, ((m-y0)/(1.0+pow(xhalf/xi, r)) + y0 - yi)*wi);
1184
+ }
1185
+ return GSL_SUCCESS;
1186
+ }
1187
+
1188
+ static int Hill_df(const gsl_vector *v, void *data, gsl_matrix *J)
1189
+ {
1190
+ double y0, m, xhalf, r, yy, xi, wi, a;
1191
+ size_t i;
1192
+ struct fitting_xydata *xydata;
1193
+ gsl_vector *x, *y, *w;
1194
+ xydata = (struct fitting_xydata*) data;
1195
+ x = xydata->x;
1196
+ y = xydata->y;
1197
+ w = xydata->w;
1198
+ y0 = gsl_vector_get(v, 0);
1199
+ m = gsl_vector_get(v, 1);
1200
+ xhalf = gsl_vector_get(v, 2);
1201
+ r = gsl_vector_get(v, 3);
1202
+ for (i = 0; i < x->size; i++) {
1203
+ xi = gsl_vector_get(x, i);
1204
+ if (w) wi = gsl_vector_get(w, i);
1205
+ else wi = 1.0;
1206
+ a = pow(xhalf/xi, r);
1207
+ yy = (1.0 + a);
1208
+ gsl_matrix_set(J, i, 0, (1.0 - 1.0/yy)*wi);
1209
+ gsl_matrix_set(J, i, 1, 1.0/yy*wi);
1210
+ gsl_matrix_set(J, i, 2, -(m-y0)*r/xhalf*a/yy/yy*wi);
1211
+ gsl_matrix_set(J, i, 3, -(m-y0)/yy/yy*a*log(xhalf/xi)*wi);
1212
+ }
1213
+ return GSL_SUCCESS;
1214
+ }
1215
+
1216
+ static int Hill_fdf(const gsl_vector *v, void *data,
1217
+ gsl_vector *f, gsl_matrix *J)
1218
+ {
1219
+ Hill_f(v, data, f);
1220
+ Hill_df(v, data, J);
1221
+ return GSL_SUCCESS;
1222
+ }
1223
+
1224
+ /* Sigmoidal fit
1225
+ y = y0 + m/(1 + exp((x0-x)/r))
1226
+ v[0] = y0
1227
+ v[1] = m
1228
+ v[2] = x0
1229
+ v[3] = r
1230
+ */
1231
+ static int Sigmoid_f(const gsl_vector *v, void *data, gsl_vector *f)
1232
+ {
1233
+ gsl_vector *x, *y, *w;
1234
+ double y0, m, x0, r, xi, yi, wi;
1235
+ size_t i;
1236
+ struct fitting_xydata *xydata;
1237
+ xydata = (struct fitting_xydata*) data;
1238
+ x = xydata->x;
1239
+ y = xydata->y;
1240
+ w = xydata->w;
1241
+ y0 = gsl_vector_get(v, 0);
1242
+ m = gsl_vector_get(v, 1);
1243
+ x0 = gsl_vector_get(v, 2);
1244
+ r = gsl_vector_get(v, 3);
1245
+ for (i = 0; i < x->size; i++) {
1246
+ xi = gsl_vector_get(x, i);
1247
+ if (w) wi = gsl_vector_get(w, i);
1248
+ else wi = 1.0;
1249
+ yi = gsl_vector_get(y, i);
1250
+ gsl_vector_set(f, i, (m/(1.0+exp((x0-xi)/r)) + y0 - yi)*wi);
1251
+ }
1252
+ return GSL_SUCCESS;
1253
+ }
1254
+
1255
+ static int Sigmoid_df(const gsl_vector *v, void *data, gsl_matrix *J)
1256
+ {
1257
+ double m, x0, r, xi, wi, a, yy;
1258
+ size_t i;
1259
+ struct fitting_xydata *xydata;
1260
+ gsl_vector *x, *y, *w;
1261
+ xydata = (struct fitting_xydata*) data;
1262
+ x = xydata->x;
1263
+ y = xydata->y;
1264
+ w = xydata->w;
1265
+ m = gsl_vector_get(v, 1);
1266
+ x0 = gsl_vector_get(v, 2);
1267
+ r = gsl_vector_get(v, 3);
1268
+ for (i = 0; i < x->size; i++) {
1269
+ xi = gsl_vector_get(x, i);
1270
+ if (w) wi = gsl_vector_get(w, i);
1271
+ else wi = 1.0;
1272
+ a = exp((x0 - xi)/r);
1273
+ yy = 1.0 + a;
1274
+ gsl_matrix_set(J, i, 0, wi);
1275
+ gsl_matrix_set(J, i, 1, 1.0/yy*wi);
1276
+ gsl_matrix_set(J, i, 2, -m*a/r/yy/yy*wi);
1277
+ gsl_matrix_set(J, i, 3, m*a*(x0-xi)/r/r/yy/yy*wi);
1278
+ }
1279
+ return GSL_SUCCESS;
1280
+ }
1281
+
1282
+ static int Sigmoid_fdf(const gsl_vector *v, void *data,
1283
+ gsl_vector *f, gsl_matrix *J)
1284
+ {
1285
+ Sigmoid_f(v, data, f);
1286
+ Sigmoid_df(v, data, J);
1287
+ return GSL_SUCCESS;
1288
+ }
1289
+
1290
+
1291
+ /* Power-law fit
1292
+ y = y0 + A x^r
1293
+ v[0] = y0
1294
+ v[1] = A
1295
+ v[2] = r
1296
+ */
1297
+ static int Power_f(const gsl_vector *v, void *data, gsl_vector *f)
1298
+ {
1299
+ gsl_vector *x, *y, *w;
1300
+ double y0, A, r, xi, yi, wi;
1301
+ size_t i;
1302
+ struct fitting_xydata *xydata;
1303
+ xydata = (struct fitting_xydata*) data;
1304
+ x = xydata->x;
1305
+ y = xydata->y;
1306
+ w = xydata->w;
1307
+ y0 = gsl_vector_get(v, 0);
1308
+ A = gsl_vector_get(v, 1);
1309
+ r = gsl_vector_get(v, 2);
1310
+ for (i = 0; i < x->size; i++) {
1311
+ xi = gsl_vector_get(x, i);
1312
+ if (w) wi = gsl_vector_get(w, i);
1313
+ else wi = 1.0;
1314
+ yi = gsl_vector_get(y, i);
1315
+ gsl_vector_set(f, i, (A*pow(xi, r) + y0 - yi)*wi);
1316
+ }
1317
+ return GSL_SUCCESS;
1318
+ }
1319
+
1320
+ static int Power_df(const gsl_vector *v, void *data, gsl_matrix *J)
1321
+ {
1322
+ double A, r, xi, wi, a;
1323
+ size_t i;
1324
+ struct fitting_xydata *xydata;
1325
+ gsl_vector *x, *y, *w;
1326
+ xydata = (struct fitting_xydata*) data;
1327
+ x = xydata->x;
1328
+ y = xydata->y;
1329
+ w = xydata->w;
1330
+ A = gsl_vector_get(v, 1);
1331
+ r = gsl_vector_get(v, 2);
1332
+ for (i = 0; i < x->size; i++) {
1333
+ xi = gsl_vector_get(x, i);
1334
+ if (w) wi = gsl_vector_get(w, i);
1335
+ else wi = 1.0;
1336
+ a = pow(xi, r);
1337
+ gsl_matrix_set(J, i, 0, wi);
1338
+ gsl_matrix_set(J, i, 1, a*wi);
1339
+ gsl_matrix_set(J, i, 2, A*a*log(xi)*wi);
1340
+
1341
+ }
1342
+ return GSL_SUCCESS;
1343
+ }
1344
+
1345
+ static int Power_fdf(const gsl_vector *v, void *data,
1346
+ gsl_vector *f, gsl_matrix *J)
1347
+ {
1348
+ Power_f(v, data, f);
1349
+ Power_df(v, data, J);
1350
+ return GSL_SUCCESS;
1351
+ }
1352
+
1353
+
1354
+ /* Lognormal fit
1355
+ y = y0 + A exp[ -(log(x/x0)/width)^2 ]
1356
+ v[0] = y0
1357
+ v[1] = A
1358
+ v[2] = x0
1359
+ v[3] = width
1360
+ */
1361
+ static int Lognormal_f(const gsl_vector *v, void *data, gsl_vector *f)
1362
+ {
1363
+ gsl_vector *x, *y, *w;
1364
+ double y0, A, x0, width, xi, yi, wi;
1365
+ size_t i;
1366
+ struct fitting_xydata *xydata;
1367
+ xydata = (struct fitting_xydata*) data;
1368
+ x = xydata->x;
1369
+ y = xydata->y;
1370
+ w = xydata->w;
1371
+ y0 = gsl_vector_get(v, 0);
1372
+ A = gsl_vector_get(v, 1);
1373
+ x0 = gsl_vector_get(v, 2);
1374
+ width = gsl_vector_get(v, 3);
1375
+ for (i = 0; i < x->size; i++) {
1376
+ xi = gsl_vector_get(x, i);
1377
+ if (w) wi = gsl_vector_get(w, i);
1378
+ else wi = 1.0;
1379
+ yi = gsl_vector_get(y, i);
1380
+ gsl_vector_set(f, i, (A*exp(-gsl_pow_2(log(xi/x0)/width)) + y0 - yi)*wi);
1381
+ }
1382
+ return GSL_SUCCESS;
1383
+ }
1384
+
1385
+ static int Lognormal_df(const gsl_vector *v, void *data, gsl_matrix *J)
1386
+ {
1387
+ double A, x0, width, xi, wi, a, b;
1388
+ size_t i;
1389
+ struct fitting_xydata *xydata;
1390
+ gsl_vector *x, *y, *w;
1391
+ xydata = (struct fitting_xydata*) data;
1392
+ x = xydata->x;
1393
+ y = xydata->y;
1394
+ w = xydata->w;
1395
+ A = gsl_vector_get(v, 1);
1396
+ x0 = gsl_vector_get(v, 2);
1397
+ width = gsl_vector_get(v, 3);
1398
+ for (i = 0; i < x->size; i++) {
1399
+ xi = gsl_vector_get(x, i);
1400
+ if (w) wi = gsl_vector_get(w, i);
1401
+ else wi = 1.0;
1402
+ a = log(xi/x0)/width;
1403
+ b = exp(-a*a);
1404
+ gsl_matrix_set(J, i, 0, wi);
1405
+ gsl_matrix_set(J, i, 1, b*wi);
1406
+ gsl_matrix_set(J, i, 2, 2.0*A*b*a*a*a/width/x0*wi);
1407
+ gsl_matrix_set(J, i, 3, 2.0*A*b*a*a*a*a/width*wi);
1408
+ }
1409
+ return GSL_SUCCESS;
1410
+ }
1411
+
1412
+ static int Lognormal_fdf(const gsl_vector *v, void *data,
1413
+ gsl_vector *f, gsl_matrix *J)
1414
+ {
1415
+ Lognormal_f(v, data, f);
1416
+ Lognormal_df(v, data, J);
1417
+ return GSL_SUCCESS;
1418
+ }
1419
+
1420
+ /* Rayleigh fit
1421
+ y = A exp(-x*x/2/var)
1422
+ v[0] = A
1423
+ v[1] = var = sigma^2
1424
+ */
1425
+ static int Rayleigh_f(const gsl_vector *v, void *data, gsl_vector *f)
1426
+ {
1427
+ gsl_vector *x, *y, *w;
1428
+ double A, var, xi, yi, wi;
1429
+ size_t i;
1430
+ struct fitting_xydata *xydata;
1431
+ xydata = (struct fitting_xydata*) data;
1432
+ x = xydata->x;
1433
+ y = xydata->y;
1434
+ w = xydata->w;
1435
+ var = gsl_vector_get(v, 1);
1436
+ A = gsl_vector_get(v, 0);
1437
+ for (i = 0; i < x->size; i++) {
1438
+ xi = gsl_vector_get(x, i);
1439
+ yi = gsl_vector_get(y, i);
1440
+ if (w) wi = gsl_vector_get(w, i);
1441
+ else wi = 1.0;
1442
+ gsl_vector_set(f, i, (A*xi*exp(-xi*xi/var/2.0) - yi)*wi);
1443
+ }
1444
+ return GSL_SUCCESS;
1445
+ }
1446
+
1447
+ static int Rayleigh_df(const gsl_vector *v, void *data, gsl_matrix *J)
1448
+ {
1449
+ double A, var, xi, yy, wi;
1450
+ size_t i;
1451
+ struct fitting_xydata *xydata;
1452
+ gsl_vector *x, *y, *w;
1453
+ xydata = (struct fitting_xydata*) data;
1454
+ x = xydata->x;
1455
+ y = xydata->y;
1456
+ w = xydata->w;
1457
+ var = gsl_vector_get(v, 1);
1458
+ A = gsl_vector_get(v, 0);
1459
+ for (i = 0; i < x->size; i++) {
1460
+ xi = gsl_vector_get(x, i);
1461
+ if (w) wi = gsl_vector_get(w, i);
1462
+ else wi = 1.0;
1463
+ yy = xi*exp(-xi*xi/var/2.0);
1464
+ gsl_matrix_set(J, i, 1, A*yy*xi*xi/2/var/var*wi);
1465
+ gsl_matrix_set(J, i, 0, yy*wi);
1466
+ }
1467
+ return GSL_SUCCESS;
1468
+ }
1469
+
1470
+ static int Rayleigh_fdf(const gsl_vector *v, void *data,
1471
+ gsl_vector *f, gsl_matrix *J)
1472
+ {
1473
+ Rayleigh_f(v, data, f);
1474
+ Rayleigh_df(v, data, J);
1475
+ return GSL_SUCCESS;
1476
+ }
1477
+
1478
+ static void set_fittype(gsl_multifit_function_fdf *f, const char *fittype, size_t *p, gsl_vector **v, int *flag)
1479
+ {
1480
+ if (str_tail_grep(fittype, "aussian_2peaks") == 0) {
1481
+ f->f = Gaussian_2peaks_f;
1482
+ f->df = Gaussian_2peaks_df;
1483
+ f->fdf = Gaussian_2peaks_fdf;
1484
+ *p = 7;
1485
+ if (*v == NULL) {
1486
+ *v = gsl_vector_alloc(*p);
1487
+ gsl_vector_set(*v, 0, 0); /* y0 = 0 */
1488
+ gsl_vector_set(*v, 1, 1); /* A = 1 */
1489
+ gsl_vector_set(*v, 2, 0.0); /* x0 = 0 */
1490
+ gsl_vector_set(*v, 3, 1); /* initial values, var = 1 */
1491
+ gsl_vector_set(*v, 4, 1); /* A = 1 */
1492
+ gsl_vector_set(*v, 5, 1.0); /* x0 = 1 */
1493
+ gsl_vector_set(*v, 6, 1); /* initial values, var = 1 */
1494
+ *flag = 1;
1495
+ }
1496
+ } else if (str_head_grep(fittype, "gaus") == 0) {
1497
+ f->f = Gaussian_f;
1498
+ f->df = Gaussian_df;
1499
+ f->fdf = Gaussian_fdf;
1500
+ *p = 4;
1501
+ if (*v == NULL) {
1502
+ *v = gsl_vector_alloc(*p);
1503
+ gsl_vector_set(*v, 3, 1); /* initial values, var = 1 */
1504
+ gsl_vector_set(*v, 2, 0.0); /* x0 = 0 */
1505
+ gsl_vector_set(*v, 1, 1); /* A = 1 */
1506
+ gsl_vector_set(*v, 0, 0); /* y0 = 0 */
1507
+ *flag = 1;
1508
+ }
1509
+ } else if (str_head_grep(fittype, "exp") == 0) {
1510
+ f->f = Exponential_f;
1511
+ f->df = Exponential_df;
1512
+ f->fdf = Exponential_fdf;
1513
+ *p = 3;
1514
+ if (*v == NULL) {
1515
+ *v = gsl_vector_alloc(*p);
1516
+ gsl_vector_set(*v, 0, 0); /* y0 = 0 */
1517
+ gsl_vector_set(*v, 1, 1); /* A = 1 */
1518
+ gsl_vector_set(*v, 2, 1);
1519
+ *flag = 1;
1520
+ }
1521
+ } else if (str_head_grep(fittype, "rayleigh") == 0) {
1522
+ f->f = Rayleigh_f;
1523
+ f->df = Rayleigh_df;
1524
+ f->fdf = Rayleigh_fdf;
1525
+ *p = 2;
1526
+ if (*v == NULL) {
1527
+ *v = gsl_vector_alloc(*p);
1528
+ gsl_vector_set(*v, 0, 1); /* A = 1 */
1529
+ gsl_vector_set(*v, 1, 1); /* sigma = 1 */
1530
+ *flag = 1;
1531
+ }
1532
+ } else if (str_head_grep(fittype, "dblexp") == 0) {
1533
+ f->f = DblExponential_f;
1534
+ f->df = DblExponential_df;
1535
+ f->fdf = DblExponential_fdf;
1536
+ *p = 5;
1537
+ if (*v == NULL) {
1538
+ *v = gsl_vector_alloc(*p);
1539
+ gsl_vector_set(*v, 0, 0); /* y0 = 0 */
1540
+ gsl_vector_set(*v, 1, 1); /* A = 1 */
1541
+ gsl_vector_set(*v, 2, 1);
1542
+ gsl_vector_set(*v, 3, 1); /* A = 1 */
1543
+ gsl_vector_set(*v, 4, 1);
1544
+ *flag = 1;
1545
+ }
1546
+ } else if (str_head_grep(fittype, "lor") == 0) {
1547
+ f->f = Lorentzian_f;
1548
+ f->df = Lorentzian_df;
1549
+ f->fdf = Lorentzian_fdf;
1550
+ *p = 4;
1551
+ if (*v == NULL) {
1552
+ *v = gsl_vector_alloc(*p);
1553
+ gsl_vector_set(*v, 0, 0);
1554
+ gsl_vector_set(*v, 1, 1);
1555
+ gsl_vector_set(*v, 2, 0);
1556
+ gsl_vector_set(*v, 3, 1);
1557
+ *flag = 1;
1558
+ }
1559
+ } else if (str_head_grep(fittype, "sin") == 0) {
1560
+ f->f = Sin_f;
1561
+ f->df = Sin_df;
1562
+ f->fdf = Sin_fdf;
1563
+ *p = 4;
1564
+ if (*v == NULL) {
1565
+ *v = gsl_vector_alloc(*p);
1566
+ gsl_vector_set(*v, 0, 0);
1567
+ gsl_vector_set(*v, 1, 1);
1568
+ gsl_vector_set(*v, 2, 1);
1569
+ gsl_vector_set(*v, 3, 0);
1570
+ *flag = 1;
1571
+ }
1572
+ } else if (str_head_grep(fittype, "hill") == 0) {
1573
+ f->f = Hill_f;
1574
+ f->df = Hill_df;
1575
+ f->fdf = Hill_fdf;
1576
+ *p = 4;
1577
+ if (*v == NULL) {
1578
+ *v = gsl_vector_alloc(*p);
1579
+ gsl_vector_set(*v, 0, 0);
1580
+ gsl_vector_set(*v, 1, 1);
1581
+ gsl_vector_set(*v, 2, 1);
1582
+ gsl_vector_set(*v, 3, 1);
1583
+ *flag = 1;
1584
+ }
1585
+ } else if (str_head_grep(fittype, "sigmoid") == 0 || str_head_grep(fittype, "fermi") == 0) {
1586
+ f->f = Sigmoid_f;
1587
+ f->df = Sigmoid_df;
1588
+ f->fdf = Sigmoid_fdf;
1589
+ *p = 4;
1590
+ if (*v == NULL) {
1591
+ *v = gsl_vector_alloc(*p);
1592
+ gsl_vector_set(*v, 0, 0);
1593
+ gsl_vector_set(*v, 1, 1);
1594
+ gsl_vector_set(*v, 2, 0);
1595
+ gsl_vector_set(*v, 3, 1);
1596
+ *flag = 1;
1597
+ }
1598
+ } else if (str_head_grep(fittype, "power") == 0) {
1599
+ f->f = Power_f;
1600
+ f->df = Power_df;
1601
+ f->fdf = Power_fdf;
1602
+ *p = 3;
1603
+ if (*v == NULL) {
1604
+ *v = gsl_vector_alloc(*p);
1605
+ gsl_vector_set(*v, 0, 0);
1606
+ gsl_vector_set(*v, 1, 1);
1607
+ gsl_vector_set(*v, 2, -1);
1608
+ *flag = 1;
1609
+ }
1610
+ } else if (str_head_grep(fittype, "lognormal") == 0) {
1611
+ f->f = Lognormal_f;
1612
+ f->df = Lognormal_df;
1613
+ f->fdf = Lognormal_fdf;
1614
+ *p = 4;
1615
+ if (*v == NULL) {
1616
+ *v = gsl_vector_alloc(*p);
1617
+ gsl_vector_set(*v, 0, 0);
1618
+ gsl_vector_set(*v, 1, 1);
1619
+ gsl_vector_set(*v, 2, 1);
1620
+ gsl_vector_set(*v, 3, 1);
1621
+ *flag = 1;
1622
+ }
1623
+ } else {
1624
+ rb_raise(rb_eRuntimeError, "Unknown fit type (gaussian expected)");
1625
+ }
1626
+
1627
+ }
1628
+
1629
+ /* Singleton method */
1630
+ static VALUE rb_gsl_multifit_fit(int argc, VALUE *argv, VALUE klass)
1631
+ {
1632
+ const gsl_multifit_fdfsolver_type *T;
1633
+ gsl_multifit_fdfsolver *solver;
1634
+ int status;
1635
+ size_t iter = 0, i;
1636
+ size_t n, dof; /* # of data points */
1637
+ size_t p; /* # of fitting parameters */
1638
+ gsl_multifit_function_fdf f;
1639
+ gsl_matrix *covar = NULL;
1640
+ gsl_vector *v = NULL;
1641
+ gsl_vector *x, *y, *w = NULL;
1642
+ gsl_vector_view xx, yy, ww;
1643
+ gsl_vector *vout, *verr;
1644
+ int flag = 0;
1645
+ double chi2;
1646
+ char fittype[256];
1647
+ struct fitting_xydata xydata;
1648
+ if (argc < 3) rb_raise(rb_eArgError, "too few arguments");
1649
+ switch (TYPE(argv[argc-1])) {
1650
+ case T_ARRAY:
1651
+ v = get_vector(argv[argc-1]);
1652
+ flag = 1;
1653
+ argc--;
1654
+ break;
1655
+ case T_STRING:
1656
+ /* do nothing */
1657
+ break;
1658
+ default:
1659
+ Data_Get_Vector(argv[argc-1], v);
1660
+ flag = 0;
1661
+ argc--;
1662
+ break;
1663
+ }
1664
+ x = &xx.vector;
1665
+ y = &yy.vector;
1666
+ w = &ww.vector;
1667
+ switch (argc) {
1668
+ case 3:
1669
+ Data_Get_Vector(argv[0], x);
1670
+ Data_Get_Vector(argv[1], y);
1671
+ w = NULL;
1672
+ strcpy(fittype, STR2CSTR(argv[2]));
1673
+ break;
1674
+ case 4:
1675
+ Data_Get_Vector(argv[0], x);
1676
+ Data_Get_Vector(argv[1], w);
1677
+ Data_Get_Vector(argv[2], y);
1678
+ strcpy(fittype, STR2CSTR(argv[3]));
1679
+ break;
1680
+ default:
1681
+ rb_raise(rb_eArgError, "wrong number of arguments");
1682
+ break;
1683
+ }
1684
+
1685
+ xydata.x = x;
1686
+ xydata.y = y;
1687
+ xydata.w = w;
1688
+ n = x->size;
1689
+
1690
+ set_fittype(&f, fittype, &p, &v, &flag);
1691
+
1692
+ f.n = n;
1693
+ f.p = p;
1694
+ f.params = &xydata;
1695
+
1696
+ T = gsl_multifit_fdfsolver_lmsder;
1697
+ solver = gsl_multifit_fdfsolver_alloc(T, n, p);
1698
+ gsl_multifit_fdfsolver_set(solver, &f, v);
1699
+
1700
+ do {
1701
+ iter++;
1702
+ status = gsl_multifit_fdfsolver_iterate(solver);
1703
+ if (status) break;
1704
+ status = gsl_multifit_test_delta(solver->dx, solver->x, 1e-6, 1e-6);
1705
+ } while (status == GSL_CONTINUE);
1706
+ vout = gsl_vector_alloc(p);
1707
+ verr = gsl_vector_alloc(p);
1708
+ gsl_vector_memcpy(vout, solver->x);
1709
+ covar = gsl_matrix_alloc(p, p);
1710
+ chi2 = gsl_pow_2(gsl_blas_dnrm2(solver->f)); /* not reduced chi-square */
1711
+ dof = n - p;
1712
+ gsl_multifit_covar(solver->J, 0.0, covar);
1713
+ for (i = 0; i < p; i++)
1714
+ gsl_vector_set(verr, i, sqrt(chi2/dof*gsl_matrix_get(covar, i, i)));
1715
+ gsl_matrix_free(covar);
1716
+ if (flag == 1) gsl_vector_free(v);
1717
+ gsl_multifit_fdfsolver_free(solver);
1718
+ return rb_ary_new3(4,
1719
+ Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vout),
1720
+ Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, verr),
1721
+ rb_float_new(chi2), INT2FIX(dof));
1722
+ }
1723
+
1724
+ #ifdef GSL_1_8_LATER
1725
+ static VALUE rb_gsl_multifit_linear_est(VALUE module, VALUE xx, VALUE cc, VALUE ccov)
1726
+ {
1727
+ gsl_vector *x, *c;
1728
+ gsl_matrix *cov;
1729
+ double y, y_err;
1730
+
1731
+ Data_Get_Vector(xx, x);
1732
+ Data_Get_Vector(cc, c);
1733
+ Data_Get_Matrix(ccov, cov);
1734
+ gsl_multifit_linear_est(x, c, cov, &y, &y_err);
1735
+ return rb_ary_new3(2, rb_float_new(y), rb_float_new(y_err));
1736
+ }
1737
+ #endif
1738
+ #ifdef GSL_1_11_LATER
1739
+ static VALUE rb_gsl_multifit_linear_residuals(int argc, VALUE argv[], VALUE module)
1740
+ {
1741
+ gsl_vector *y, *c, *r;
1742
+ gsl_matrix *X;
1743
+ VALUE ret;
1744
+ switch (argc) {
1745
+ case 3:
1746
+ Data_Get_Matrix(argv[0], X);
1747
+ Data_Get_Vector(argv[1], y);
1748
+ Data_Get_Vector(argv[2], c);
1749
+ r = gsl_vector_alloc(y->size);
1750
+ ret = Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, r);
1751
+ break;
1752
+ case 4:
1753
+ Data_Get_Matrix(argv[0], X);
1754
+ Data_Get_Vector(argv[1], y);
1755
+ Data_Get_Vector(argv[2], c);
1756
+ Data_Get_Vector(argv[3], r);
1757
+ ret = argv[3];
1758
+ break;
1759
+ default:
1760
+ rb_raise(rb_eArgError, "Wrong number of arguments %d (3 or 4).\n", argc);
1761
+ }
1762
+ gsl_multifit_linear_residuals(X, y, c, r);
1763
+ return ret;
1764
+ }
1765
+
1766
+ #endif
1767
+
1768
+ void Init_gsl_multifit(VALUE module)
1769
+ {
1770
+ VALUE mgsl_multifit;
1771
+ VALUE cgsl_multifit_fdfsolver;
1772
+ VALUE cgsl_multifit_solver;
1773
+
1774
+ mgsl_multifit = rb_define_module_under(module, "MultiFit");
1775
+
1776
+ cgsl_multifit_workspace = rb_define_class_under(mgsl_multifit, "Workspace",
1777
+ cGSL_Object);
1778
+ rb_define_singleton_method(cgsl_multifit_workspace, "new",
1779
+ rb_gsl_multifit_workspace_new, 2);
1780
+ rb_define_singleton_method(cgsl_multifit_workspace, "alloc",
1781
+ rb_gsl_multifit_workspace_new, 2);
1782
+ rb_define_singleton_method(mgsl_multifit, "alloc",
1783
+ rb_gsl_multifit_workspace_new, 2);
1784
+ rb_define_module_function(mgsl_multifit, "linear", rb_gsl_multifit_linear, -1);
1785
+ rb_define_module_function(mgsl_multifit, "wlinear", rb_gsl_multifit_wlinear, -1);
1786
+
1787
+ cgsl_multifit_solver = rb_define_class_under(mgsl_multifit, "Solver", cGSL_Object);
1788
+ cgsl_multifit_fdfsolver = rb_define_class_under(mgsl_multifit, "FdfSolver",
1789
+ cgsl_multifit_solver);
1790
+ cgsl_multifit_function_fdf = rb_define_class_under(mgsl_multifit, "Function_fdf",
1791
+ cGSL_Object);
1792
+
1793
+ /*****/
1794
+
1795
+ rb_define_singleton_method(cgsl_multifit_fdfsolver, "new",
1796
+ rb_gsl_multifit_fdfsolver_new, -1);
1797
+ rb_define_singleton_method(cgsl_multifit_fdfsolver, "alloc",
1798
+ rb_gsl_multifit_fdfsolver_new, -1);
1799
+
1800
+ rb_define_singleton_method(cgsl_multifit_function_fdf, "new",
1801
+ rb_gsl_multifit_function_fdf_new, -1);
1802
+ rb_define_singleton_method(cgsl_multifit_function_fdf, "alloc",
1803
+ rb_gsl_multifit_function_fdf_new, -1);
1804
+
1805
+ /*****/
1806
+
1807
+ rb_define_method(cgsl_multifit_fdfsolver, "set", rb_gsl_multifit_fdfsolver_set, 2);
1808
+ rb_define_method(cgsl_multifit_fdfsolver, "name", rb_gsl_multifit_fdfsolver_name, 0);
1809
+ rb_define_method(cgsl_multifit_fdfsolver, "iterate", rb_gsl_multifit_fdfsolver_iterate, 0);
1810
+ rb_define_method(cgsl_multifit_fdfsolver, "position", rb_gsl_multifit_fdfsolver_position, 0);
1811
+ // rb_define_alias(cgsl_multifit_fdfsolver, "x", "position");
1812
+ rb_define_method(cgsl_multifit_fdfsolver, "print_state", rb_gsl_multifit_fdfsolver_print_state, 1);
1813
+ rb_define_method(cgsl_multifit_fdfsolver, "fdf", rb_gsl_multifit_fdfsolver_fdf, 0);
1814
+ rb_define_method(cgsl_multifit_fdfsolver, "test_delta", rb_gsl_multifit_fdfsolver_test_delta, 2);
1815
+ rb_define_method(cgsl_multifit_fdfsolver, "test_gradient", rb_gsl_multifit_fdfsolver_test_gradient, -1);
1816
+ rb_define_method(cgsl_multifit_fdfsolver, "covar", rb_gsl_multifit_fdfsolver_covar, -1);
1817
+ rb_define_method(cgsl_multifit_fdfsolver, "gradient", rb_gsl_multifit_fdfsolver_gradient, -1);
1818
+ rb_define_method(cgsl_multifit_fdfsolver, "x", rb_gsl_multifit_fdfsolver_x, 0);
1819
+ rb_define_method(cgsl_multifit_fdfsolver, "dx", rb_gsl_multifit_fdfsolver_dx, 0);
1820
+ rb_define_method(cgsl_multifit_fdfsolver, "f", rb_gsl_multifit_fdfsolver_f, 0);
1821
+ rb_define_method(cgsl_multifit_fdfsolver, "J", rb_gsl_multifit_fdfsolver_J, 0);
1822
+ rb_define_alias(cgsl_multifit_fdfsolver, "jac", "J");
1823
+ rb_define_alias(cgsl_multifit_fdfsolver, "jacobian", "J");
1824
+ rb_define_alias(cgsl_multifit_fdfsolver, "Jacobian", "J");
1825
+
1826
+ /*****/
1827
+ rb_define_module_function(mgsl_multifit, "polyfit", rb_gsl_multifit_polyfit, -1);
1828
+ rb_define_module_function(mgsl_multifit, "legfit", rb_gsl_multifit_legfit, -1);
1829
+ /*****/
1830
+
1831
+ rb_define_singleton_method(mgsl_multifit, "test_delta", rb_gsl_multifit_test_delta, 4);
1832
+ rb_define_singleton_method(mgsl_multifit, "test_gradient", rb_gsl_multifit_test_gradient, 2);
1833
+ rb_define_singleton_method(mgsl_multifit, "gradient", rb_gsl_multifit_gradient, -1);
1834
+ rb_define_singleton_method(mgsl_multifit, "covar", rb_gsl_multifit_covar, -1);
1835
+
1836
+ rb_gsl_multifit_define_const(cgsl_multifit_fdfsolver);
1837
+
1838
+ rb_define_method(cgsl_multifit_function_fdf, "set_procs",
1839
+ rb_gsl_multifit_function_fdf_set_procs, -1);
1840
+ rb_define_method(cgsl_multifit_function_fdf, "set_data",
1841
+ rb_gsl_multifit_function_fdf_set_data, -1);
1842
+ rb_define_method(cgsl_multifit_function_fdf, "params",
1843
+ rb_gsl_multifit_function_fdf_params, 0);
1844
+ rb_define_alias(cgsl_multifit_function_fdf, "param", "params");
1845
+
1846
+ rb_define_method(cgsl_multifit_function_fdf, "n",
1847
+ rb_gsl_multifit_function_fdf_n, 0);
1848
+ rb_define_method(cgsl_multifit_function_fdf, "set_n",
1849
+ rb_gsl_multifit_function_fdf_set_n, 1);
1850
+ rb_define_alias(cgsl_multifit_function_fdf, "n=", "set_n");
1851
+ rb_define_method(cgsl_multifit_function_fdf, "p",
1852
+ rb_gsl_multifit_function_fdf_p, 0);
1853
+ rb_define_alias(cgsl_multifit_function_fdf, "np", "p");
1854
+
1855
+ /*****/
1856
+ rb_define_singleton_method(cgsl_multifit_fdfsolver, "fit", rb_gsl_multifit_fit, -1);
1857
+
1858
+ /***/
1859
+ #ifdef GSL_1_8_LATER
1860
+ rb_define_module_function(mgsl_multifit, "linear_est", rb_gsl_multifit_linear_est, 3);
1861
+ rb_define_module_function(module, "multifit_linear_est", rb_gsl_multifit_linear_est, 3);
1862
+ #endif
1863
+ #ifdef GSL_1_11_LATER
1864
+ rb_define_module_function(mgsl_multifit, "linear_residuals", rb_gsl_multifit_linear_residuals, -1);
1865
+ rb_define_module_function(module, "multifit_linear_residuals", rb_gsl_multifit_linear_residuals, -1);
1866
+ #endif
1867
+
1868
+ #ifdef HAVE_NDLINEAR_GSL_MULTIFIT_NDLINEAR_H
1869
+ Init_ndlinear(mgsl_multifit);
1870
+ #endif
1871
+
1872
+ }
1873
+
1874
+ #ifdef CHECK_WORKSPACE
1875
+ #undef CHECK_WORKSPACE
1876
+ #endif
1877
+ #ifdef CHECK_MULTIFIT_FUNCTION_FDF
1878
+ #undef CHECK_MULTIFIT_FUNCTION_FDF
1879
+ #endif