gsl 1.12.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +29 -0
- data/Rakefile +54 -0
- data/VERSION +2 -0
- data/ext/MANIFEST +119 -0
- data/ext/alf.c +206 -0
- data/ext/array.c +666 -0
- data/ext/array_complex.c +247 -0
- data/ext/blas.c +29 -0
- data/ext/blas1.c +731 -0
- data/ext/blas2.c +1093 -0
- data/ext/blas3.c +881 -0
- data/ext/block.c +44 -0
- data/ext/block_source.c +886 -0
- data/ext/bspline.c +130 -0
- data/ext/bundle.c +3 -0
- data/ext/cdf.c +754 -0
- data/ext/cheb.c +542 -0
- data/ext/combination.c +283 -0
- data/ext/common.c +325 -0
- data/ext/complex.c +1004 -0
- data/ext/const.c +673 -0
- data/ext/const_additional.c +120 -0
- data/ext/cqp.c +283 -0
- data/ext/deriv.c +195 -0
- data/ext/dht.c +361 -0
- data/ext/diff.c +166 -0
- data/ext/dirac.c +395 -0
- data/ext/eigen.c +2373 -0
- data/ext/error.c +194 -0
- data/ext/extconf.rb +281 -0
- data/ext/fcmp.c +66 -0
- data/ext/fft.c +1092 -0
- data/ext/fit.c +205 -0
- data/ext/fresnel.c +312 -0
- data/ext/function.c +524 -0
- data/ext/geometry.c +139 -0
- data/ext/graph.c +1638 -0
- data/ext/gsl.c +271 -0
- data/ext/gsl_narray.c +653 -0
- data/ext/histogram.c +1995 -0
- data/ext/histogram2d.c +1068 -0
- data/ext/histogram3d.c +884 -0
- data/ext/histogram3d_source.c +750 -0
- data/ext/histogram_find.c +101 -0
- data/ext/histogram_oper.c +159 -0
- data/ext/ieee.c +98 -0
- data/ext/integration.c +1138 -0
- data/ext/interp.c +512 -0
- data/ext/jacobi.c +739 -0
- data/ext/linalg.c +4047 -0
- data/ext/linalg_complex.c +741 -0
- data/ext/math.c +725 -0
- data/ext/matrix.c +39 -0
- data/ext/matrix_complex.c +1732 -0
- data/ext/matrix_double.c +560 -0
- data/ext/matrix_int.c +256 -0
- data/ext/matrix_source.c +2733 -0
- data/ext/min.c +250 -0
- data/ext/monte.c +992 -0
- data/ext/multifit.c +1879 -0
- data/ext/multimin.c +808 -0
- data/ext/multimin_fsdf.c +156 -0
- data/ext/multiroots.c +955 -0
- data/ext/ndlinear.c +321 -0
- data/ext/nmf.c +167 -0
- data/ext/nmf_wrap.c +72 -0
- data/ext/ntuple.c +469 -0
- data/ext/odeiv.c +959 -0
- data/ext/ool.c +879 -0
- data/ext/oper_complex_source.c +253 -0
- data/ext/permutation.c +596 -0
- data/ext/poly.c +42 -0
- data/ext/poly2.c +265 -0
- data/ext/poly_source.c +1885 -0
- data/ext/qrng.c +171 -0
- data/ext/randist.c +1873 -0
- data/ext/rational.c +480 -0
- data/ext/rng.c +612 -0
- data/ext/root.c +408 -0
- data/ext/sf.c +1494 -0
- data/ext/sf_airy.c +200 -0
- data/ext/sf_bessel.c +867 -0
- data/ext/sf_clausen.c +28 -0
- data/ext/sf_coulomb.c +206 -0
- data/ext/sf_coupling.c +118 -0
- data/ext/sf_dawson.c +29 -0
- data/ext/sf_debye.c +157 -0
- data/ext/sf_dilog.c +42 -0
- data/ext/sf_elementary.c +44 -0
- data/ext/sf_ellint.c +206 -0
- data/ext/sf_elljac.c +29 -0
- data/ext/sf_erfc.c +93 -0
- data/ext/sf_exp.c +164 -0
- data/ext/sf_expint.c +211 -0
- data/ext/sf_fermi_dirac.c +148 -0
- data/ext/sf_gamma.c +344 -0
- data/ext/sf_gegenbauer.c +96 -0
- data/ext/sf_hyperg.c +197 -0
- data/ext/sf_laguerre.c +112 -0
- data/ext/sf_lambert.c +47 -0
- data/ext/sf_legendre.c +367 -0
- data/ext/sf_log.c +104 -0
- data/ext/sf_mathieu.c +238 -0
- data/ext/sf_power.c +46 -0
- data/ext/sf_psi.c +98 -0
- data/ext/sf_synchrotron.c +48 -0
- data/ext/sf_transport.c +76 -0
- data/ext/sf_trigonometric.c +207 -0
- data/ext/sf_zeta.c +119 -0
- data/ext/signal.c +310 -0
- data/ext/siman.c +718 -0
- data/ext/sort.c +208 -0
- data/ext/spline.c +395 -0
- data/ext/stats.c +799 -0
- data/ext/sum.c +168 -0
- data/ext/tamu_anova.c +56 -0
- data/ext/tensor.c +38 -0
- data/ext/tensor_source.c +1123 -0
- data/ext/vector.c +38 -0
- data/ext/vector_complex.c +2236 -0
- data/ext/vector_double.c +1433 -0
- data/ext/vector_int.c +204 -0
- data/ext/vector_source.c +3329 -0
- data/ext/wavelet.c +937 -0
- data/include/rb_gsl.h +151 -0
- data/include/rb_gsl_array.h +238 -0
- data/include/rb_gsl_cheb.h +21 -0
- data/include/rb_gsl_common.h +343 -0
- data/include/rb_gsl_complex.h +25 -0
- data/include/rb_gsl_const.h +29 -0
- data/include/rb_gsl_dirac.h +13 -0
- data/include/rb_gsl_eigen.h +17 -0
- data/include/rb_gsl_fft.h +62 -0
- data/include/rb_gsl_fit.h +25 -0
- data/include/rb_gsl_function.h +27 -0
- data/include/rb_gsl_graph.h +70 -0
- data/include/rb_gsl_histogram.h +63 -0
- data/include/rb_gsl_histogram3d.h +97 -0
- data/include/rb_gsl_integration.h +17 -0
- data/include/rb_gsl_interp.h +46 -0
- data/include/rb_gsl_linalg.h +25 -0
- data/include/rb_gsl_math.h +26 -0
- data/include/rb_gsl_odeiv.h +21 -0
- data/include/rb_gsl_poly.h +71 -0
- data/include/rb_gsl_rational.h +37 -0
- data/include/rb_gsl_rng.h +21 -0
- data/include/rb_gsl_root.h +22 -0
- data/include/rb_gsl_sf.h +119 -0
- data/include/rb_gsl_statistics.h +17 -0
- data/include/rb_gsl_tensor.h +45 -0
- data/include/rb_gsl_with_narray.h +22 -0
- data/include/templates_off.h +87 -0
- data/include/templates_on.h +241 -0
- data/lib/gsl/gnuplot.rb +41 -0
- data/lib/gsl/oper.rb +68 -0
- data/lib/ool.rb +22 -0
- data/lib/ool/conmin.rb +30 -0
- metadata +224 -0
data/ext/function.c
ADDED
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
/*
|
|
2
|
+
function.c
|
|
3
|
+
Ruby/GSL: Ruby extension library for GSL (GNU Scientific Library)
|
|
4
|
+
(C) Copyright 2001-2006 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_function.h"
|
|
13
|
+
#ifdef HAVE_NARRAY_H
|
|
14
|
+
#include "narray.h"
|
|
15
|
+
#endif
|
|
16
|
+
|
|
17
|
+
VALUE cgsl_function;
|
|
18
|
+
VALUE cgsl_function_fdf;
|
|
19
|
+
|
|
20
|
+
void gsl_function_free(gsl_function *f);
|
|
21
|
+
double rb_gsl_function_f(double x, void *p);
|
|
22
|
+
ID RBGSL_ID_call, RBGSL_ID_arity;
|
|
23
|
+
|
|
24
|
+
static VALUE rb_gsl_function_set_f(int argc, VALUE *argv, VALUE obj)
|
|
25
|
+
{
|
|
26
|
+
gsl_function *F = NULL;
|
|
27
|
+
VALUE ary, ary2;
|
|
28
|
+
size_t i;
|
|
29
|
+
Data_Get_Struct(obj, gsl_function, F);
|
|
30
|
+
if (F->params == NULL) {
|
|
31
|
+
ary = rb_ary_new2(2);
|
|
32
|
+
/* (VALUE) F->params = ary;*/
|
|
33
|
+
F->params = (void *) ary;
|
|
34
|
+
} else {
|
|
35
|
+
ary = (VALUE) F->params;
|
|
36
|
+
}
|
|
37
|
+
rb_ary_store(ary, 1, Qnil);
|
|
38
|
+
|
|
39
|
+
switch (argc) {
|
|
40
|
+
case 0:
|
|
41
|
+
break;
|
|
42
|
+
case 1:
|
|
43
|
+
CHECK_PROC(argv[0]);
|
|
44
|
+
rb_ary_store(ary, 0, argv[0]);
|
|
45
|
+
break;
|
|
46
|
+
case 2:
|
|
47
|
+
CHECK_PROC(argv[0]);
|
|
48
|
+
rb_ary_store(ary, 0, argv[0]);
|
|
49
|
+
rb_ary_store(ary, 1, argv[1]);
|
|
50
|
+
break;
|
|
51
|
+
default:
|
|
52
|
+
CHECK_PROC(argv[0]);
|
|
53
|
+
rb_ary_store(ary, 0, argv[0]);
|
|
54
|
+
ary2 = rb_ary_new2(argc-1);
|
|
55
|
+
for (i = 1; i < argc; i++) rb_ary_store(ary2, i-1, argv[i]);
|
|
56
|
+
rb_ary_store(ary, 1, ary2);
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
if (rb_block_given_p()) rb_ary_store(ary, 0, RB_GSL_MAKE_PROC);
|
|
60
|
+
return obj;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
void gsl_function_free(gsl_function *f)
|
|
64
|
+
{
|
|
65
|
+
if (f) free((gsl_function *) f);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
void gsl_function_mark(gsl_function *f)
|
|
69
|
+
{
|
|
70
|
+
rb_gc_mark((VALUE) f->params);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/*
|
|
74
|
+
* Create a Function object
|
|
75
|
+
*/
|
|
76
|
+
static VALUE rb_gsl_function_alloc(int argc, VALUE *argv, VALUE klass)
|
|
77
|
+
{
|
|
78
|
+
gsl_function *f = NULL;
|
|
79
|
+
VALUE obj;
|
|
80
|
+
f = ALLOC(gsl_function);
|
|
81
|
+
f->function = &rb_gsl_function_f;
|
|
82
|
+
/* (VALUE) f->params = rb_ary_new2(2);*/
|
|
83
|
+
f->params = (void *) rb_ary_new2(2);
|
|
84
|
+
rb_ary_store((VALUE) f->params, 1, Qnil);
|
|
85
|
+
obj = Data_Wrap_Struct(klass, gsl_function_mark, gsl_function_free, f);
|
|
86
|
+
rb_gsl_function_set_f(argc, argv, obj);
|
|
87
|
+
return obj;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
double rb_gsl_function_f(double x, void *p)
|
|
91
|
+
{
|
|
92
|
+
VALUE result, ary, proc, params;
|
|
93
|
+
ary = (VALUE) p;
|
|
94
|
+
proc = rb_ary_entry(ary, 0);
|
|
95
|
+
params = rb_ary_entry(ary, 1);
|
|
96
|
+
if (NIL_P(params)) result = rb_funcall(proc, RBGSL_ID_call, 1, rb_float_new(x));
|
|
97
|
+
else result = rb_funcall(proc, RBGSL_ID_call, 2, rb_float_new(x), params);
|
|
98
|
+
return NUM2DBL(result);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
* Calculates a function at x, and returns the rusult.
|
|
103
|
+
*/
|
|
104
|
+
static VALUE rb_gsl_function_eval(VALUE obj, VALUE x)
|
|
105
|
+
{
|
|
106
|
+
gsl_function *F = NULL;
|
|
107
|
+
VALUE ary, proc, params, result, arynew, x2;
|
|
108
|
+
gsl_vector *v = NULL, *vnew = NULL;
|
|
109
|
+
gsl_matrix *m = NULL, *mnew = NULL;
|
|
110
|
+
size_t i, j, n;
|
|
111
|
+
#ifdef HAVE_NARRAY_H
|
|
112
|
+
double *ptr1, *ptr2;
|
|
113
|
+
struct NARRAY *na;
|
|
114
|
+
#endif
|
|
115
|
+
Data_Get_Struct(obj, gsl_function, F);
|
|
116
|
+
ary = (VALUE) F->params;
|
|
117
|
+
proc = rb_ary_entry(ary, 0);
|
|
118
|
+
params = rb_ary_entry(ary, 1);
|
|
119
|
+
if (CLASS_OF(x) == rb_cRange) x = rb_gsl_range2ary(x);
|
|
120
|
+
switch (TYPE(x)) {
|
|
121
|
+
case T_FIXNUM:
|
|
122
|
+
case T_BIGNUM:
|
|
123
|
+
case T_FLOAT:
|
|
124
|
+
if (NIL_P(params)) result = rb_funcall(proc, RBGSL_ID_call, 1, x);
|
|
125
|
+
else result = rb_funcall(proc, RBGSL_ID_call, 2, x, params);
|
|
126
|
+
return result;
|
|
127
|
+
break;
|
|
128
|
+
case T_ARRAY:
|
|
129
|
+
// n = RARRAY(x)->len;
|
|
130
|
+
n = RARRAY_LEN(x);
|
|
131
|
+
arynew = rb_ary_new2(n);
|
|
132
|
+
for (i = 0; i < n; i++) {
|
|
133
|
+
x2 = rb_ary_entry(x, i);
|
|
134
|
+
Need_Float(x2);
|
|
135
|
+
if (NIL_P(params)) result = rb_funcall(proc, RBGSL_ID_call, 1, x2);
|
|
136
|
+
else result = rb_funcall(proc, RBGSL_ID_call, 2, x2, params);
|
|
137
|
+
rb_ary_store(arynew, i, result);
|
|
138
|
+
}
|
|
139
|
+
return arynew;
|
|
140
|
+
break;
|
|
141
|
+
default:
|
|
142
|
+
#ifdef HAVE_NARRAY_H
|
|
143
|
+
if (NA_IsNArray(x)) {
|
|
144
|
+
GetNArray(x, na);
|
|
145
|
+
ptr1 = (double *) na->ptr;
|
|
146
|
+
n = na->total;
|
|
147
|
+
ary = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(x));
|
|
148
|
+
ptr2 = NA_PTR_TYPE(ary, double*);
|
|
149
|
+
for (i = 0; i < n; i++) {
|
|
150
|
+
x2 = rb_float_new(ptr1[i]);
|
|
151
|
+
if (NIL_P(params)) result = rb_funcall(proc, RBGSL_ID_call, 1, x2);
|
|
152
|
+
else result = rb_funcall(proc, RBGSL_ID_call, 2, x2, params);
|
|
153
|
+
ptr2[i] = NUM2DBL(result);
|
|
154
|
+
}
|
|
155
|
+
return ary;
|
|
156
|
+
}
|
|
157
|
+
#endif
|
|
158
|
+
if (VECTOR_P(x)) {
|
|
159
|
+
Data_Get_Struct(x, gsl_vector, v);
|
|
160
|
+
vnew = gsl_vector_alloc(v->size);
|
|
161
|
+
for (i = 0; i < v->size; i++) {
|
|
162
|
+
x2 = rb_float_new(gsl_vector_get(v, i));
|
|
163
|
+
if (NIL_P(params)) result = rb_funcall(proc, RBGSL_ID_call, 1, x2);
|
|
164
|
+
else result = rb_funcall(proc, RBGSL_ID_call, 2, x2, params);
|
|
165
|
+
gsl_vector_set(vnew, i, NUM2DBL(result));
|
|
166
|
+
}
|
|
167
|
+
return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew);
|
|
168
|
+
} else if (MATRIX_P(x)) {
|
|
169
|
+
Data_Get_Struct(x, gsl_matrix, m);
|
|
170
|
+
mnew = gsl_matrix_alloc(m->size1, m->size2);
|
|
171
|
+
for (i = 0; i < m->size1; i++) {
|
|
172
|
+
for (j = 0; j < m->size2; j++) {
|
|
173
|
+
x2 = rb_float_new(gsl_matrix_get(m, i, j));
|
|
174
|
+
if (NIL_P(params)) result = rb_funcall(proc, RBGSL_ID_call, 1, x2);
|
|
175
|
+
else result = rb_funcall(proc, RBGSL_ID_call, 2, x2, params);
|
|
176
|
+
gsl_matrix_set(mnew, i, j, NUM2DBL(result));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew);
|
|
180
|
+
} else {
|
|
181
|
+
rb_raise(rb_eTypeError, "wrong argument type");
|
|
182
|
+
}
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
/* never reach here */
|
|
186
|
+
return Qnil;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
static VALUE rb_gsl_function_arity(VALUE obj)
|
|
190
|
+
{
|
|
191
|
+
gsl_function *F = NULL;
|
|
192
|
+
VALUE proc;
|
|
193
|
+
Data_Get_Struct(obj, gsl_function, F);
|
|
194
|
+
proc = rb_ary_entry((VALUE) F->params, 0);
|
|
195
|
+
return INT2FIX(rb_funcall(proc, RBGSL_ID_arity, 0));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
static VALUE rb_gsl_function_proc(VALUE obj)
|
|
199
|
+
{
|
|
200
|
+
gsl_function *F = NULL;
|
|
201
|
+
Data_Get_Struct(obj, gsl_function, F);
|
|
202
|
+
return rb_ary_entry((VALUE) F->params, 0);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
static VALUE rb_gsl_function_params(VALUE obj)
|
|
206
|
+
{
|
|
207
|
+
gsl_function *F = NULL;
|
|
208
|
+
Data_Get_Struct(obj, gsl_function, F);
|
|
209
|
+
return rb_ary_entry((VALUE) F->params, 1);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
static VALUE rb_gsl_function_set_params(int argc, VALUE *argv, VALUE obj)
|
|
213
|
+
{
|
|
214
|
+
gsl_function *F = NULL;
|
|
215
|
+
VALUE ary, ary2;
|
|
216
|
+
size_t i;
|
|
217
|
+
if (argc == 0) return obj;
|
|
218
|
+
Data_Get_Struct(obj, gsl_function, F);
|
|
219
|
+
ary = (VALUE) F->params;
|
|
220
|
+
if (argc == 1) {
|
|
221
|
+
rb_ary_store(ary, 1, argv[0]);
|
|
222
|
+
} else {
|
|
223
|
+
ary2 = rb_ary_new2(argc);
|
|
224
|
+
for (i = 0; i < argc; i++) rb_ary_store(ary2, i, argv[i]);
|
|
225
|
+
rb_ary_store(ary, 1, ary2);
|
|
226
|
+
}
|
|
227
|
+
return obj;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
static VALUE rb_gsl_function_graph(int argc, VALUE *argv, VALUE obj)
|
|
231
|
+
{
|
|
232
|
+
#ifdef HAVE_GNU_GRAPH
|
|
233
|
+
gsl_function *F = NULL;
|
|
234
|
+
gsl_vector *v = NULL;
|
|
235
|
+
double x, y;
|
|
236
|
+
char opt[256] = "", command[1024];
|
|
237
|
+
size_t i, n;
|
|
238
|
+
int flag = 0;
|
|
239
|
+
FILE *fp = NULL;
|
|
240
|
+
VALUE ary, params, proc;
|
|
241
|
+
switch (argc) {
|
|
242
|
+
case 2:
|
|
243
|
+
Check_Type(argv[1], T_STRING);
|
|
244
|
+
strcpy(opt, STR2CSTR(argv[1]));
|
|
245
|
+
/* no break, do next */
|
|
246
|
+
case 1:
|
|
247
|
+
if (CLASS_OF(argv[0]) == rb_cRange) argv[0] = rb_gsl_range2ary(argv[0]);
|
|
248
|
+
if (TYPE(argv[0]) == T_ARRAY) {
|
|
249
|
+
// n = RARRAY(argv[0])->len;
|
|
250
|
+
n = RARRAY_LEN(argv[0]);
|
|
251
|
+
v = gsl_vector_alloc(n);
|
|
252
|
+
flag = 1;
|
|
253
|
+
for (i = 0; i < n; i++)
|
|
254
|
+
gsl_vector_set(v, i, NUM2DBL(rb_ary_entry(argv[0], i)));
|
|
255
|
+
} else if (rb_obj_is_kind_of(argv[0], cgsl_vector)) {
|
|
256
|
+
Data_Get_Struct(argv[0], gsl_vector, v);
|
|
257
|
+
n = v->size;
|
|
258
|
+
flag = 0;
|
|
259
|
+
} else {
|
|
260
|
+
rb_raise(rb_eTypeError,
|
|
261
|
+
"wrong argument type %s (Array or GSL::Vector expected)",
|
|
262
|
+
rb_class2name(CLASS_OF(argv[0])));
|
|
263
|
+
}
|
|
264
|
+
break;
|
|
265
|
+
default:
|
|
266
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
Data_Get_Struct(obj, gsl_function, F);
|
|
270
|
+
ary = (VALUE) F->params;
|
|
271
|
+
proc = rb_ary_entry(ary, 0);
|
|
272
|
+
params = rb_ary_entry(ary, 1);
|
|
273
|
+
sprintf(command, "graph -T X -g 3 %s", opt);
|
|
274
|
+
fp = popen(command, "w");
|
|
275
|
+
if (fp == NULL)
|
|
276
|
+
rb_raise(rb_eIOError, "GNU graph not found.");
|
|
277
|
+
for (i = 0; i < n; i++) {
|
|
278
|
+
x = gsl_vector_get(v, i);
|
|
279
|
+
if (NIL_P(params)) y = NUM2DBL(rb_funcall(proc, RBGSL_ID_call, 1, rb_float_new(x)));
|
|
280
|
+
else y = NUM2DBL(rb_funcall(proc, RBGSL_ID_call, 2, rb_float_new(x), params));
|
|
281
|
+
fprintf(fp, "%e %e\n", x, y);
|
|
282
|
+
}
|
|
283
|
+
fflush(fp);
|
|
284
|
+
pclose(fp);
|
|
285
|
+
fp = NULL;
|
|
286
|
+
if (flag == 1) gsl_vector_free(v);
|
|
287
|
+
return Qtrue;
|
|
288
|
+
#else
|
|
289
|
+
rb_raise(rb_eNoMethodError, "not implemented");
|
|
290
|
+
return Qfalse;
|
|
291
|
+
#endif
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
static double rb_gsl_function_fdf_f(double x, void *p);
|
|
296
|
+
static void gsl_function_fdf_free(gsl_function_fdf *f);
|
|
297
|
+
|
|
298
|
+
static double rb_gsl_function_fdf_f(double x, void *p);
|
|
299
|
+
static double rb_gsl_function_fdf_df(double x, void *p);
|
|
300
|
+
static void rb_gsl_function_fdf_fdf(double x, void *p, double *f, double *df);
|
|
301
|
+
|
|
302
|
+
static void setfunc(int i, VALUE *argv, gsl_function_fdf *F);
|
|
303
|
+
static void setfunc(int i, VALUE *argv, gsl_function_fdf *F)
|
|
304
|
+
{
|
|
305
|
+
VALUE ary;
|
|
306
|
+
if (F->params == NULL) {
|
|
307
|
+
ary = rb_ary_new2(4);
|
|
308
|
+
/* (VALUE) F->params = ary;*/
|
|
309
|
+
F->params = (void *) ary;
|
|
310
|
+
} else {
|
|
311
|
+
ary = (VALUE) F->params;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (rb_obj_is_kind_of(argv[i], rb_cProc)) {
|
|
315
|
+
rb_ary_store(ary, i, argv[i]);
|
|
316
|
+
} else if (TYPE(argv[i]) == T_ARRAY || rb_obj_is_kind_of(argv[i], cgsl_vector)
|
|
317
|
+
|| TYPE(argv[i]) == T_FIXNUM || TYPE(argv[i]) == T_FLOAT) {
|
|
318
|
+
rb_ary_store(ary, 3, argv[i]);
|
|
319
|
+
} else {
|
|
320
|
+
rb_raise(rb_eArgError,
|
|
321
|
+
"wrong type argument (Proc, Array, GSL::Vector or a number)");
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
static void gsl_function_fdf_mark(gsl_function_fdf *f);
|
|
326
|
+
static VALUE rb_gsl_function_fdf_new(int argc, VALUE *argv, VALUE klass)
|
|
327
|
+
{
|
|
328
|
+
gsl_function_fdf *F = NULL;
|
|
329
|
+
VALUE ary;
|
|
330
|
+
size_t i;
|
|
331
|
+
F = ALLOC(gsl_function_fdf);
|
|
332
|
+
F->f = &rb_gsl_function_fdf_f;
|
|
333
|
+
F->df = &rb_gsl_function_fdf_df;
|
|
334
|
+
F->fdf = &rb_gsl_function_fdf_fdf;
|
|
335
|
+
ary = rb_ary_new2(4);
|
|
336
|
+
/* (VALUE) F->params = ary;*/
|
|
337
|
+
F->params = (void *) ary;
|
|
338
|
+
rb_ary_store(ary, 2, Qnil);
|
|
339
|
+
rb_ary_store(ary, 3, Qnil);
|
|
340
|
+
for (i = 0; i < argc; i++) setfunc(i, argv, F);
|
|
341
|
+
return Data_Wrap_Struct(klass, gsl_function_fdf_mark, gsl_function_fdf_free, F);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
static void gsl_function_fdf_free(gsl_function_fdf *f)
|
|
345
|
+
{
|
|
346
|
+
free((gsl_function_fdf *) f);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
static void gsl_function_fdf_mark(gsl_function_fdf *f)
|
|
350
|
+
{
|
|
351
|
+
rb_gc_mark((VALUE) f->params);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
static VALUE rb_gsl_function_fdf_set(int argc, VALUE *argv, VALUE obj)
|
|
355
|
+
{
|
|
356
|
+
gsl_function_fdf *F = NULL;
|
|
357
|
+
VALUE ary;
|
|
358
|
+
size_t i;
|
|
359
|
+
Data_Get_Struct(obj, gsl_function_fdf, F);
|
|
360
|
+
ary = (VALUE) F->params;
|
|
361
|
+
rb_ary_store(ary, 2, Qnil);
|
|
362
|
+
rb_ary_store(ary, 3, Qnil);
|
|
363
|
+
for (i = 0; i < argc; i++) setfunc(i, argv, F);
|
|
364
|
+
return obj;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
static VALUE rb_gsl_function_fdf_set_f(VALUE obj, VALUE procf)
|
|
368
|
+
{
|
|
369
|
+
gsl_function_fdf *F = NULL;
|
|
370
|
+
VALUE ary;
|
|
371
|
+
CHECK_PROC(procf);
|
|
372
|
+
Data_Get_Struct(obj, gsl_function_fdf, F);
|
|
373
|
+
if (F->params == NULL) {
|
|
374
|
+
ary = rb_ary_new2(4);
|
|
375
|
+
/* (VALUE) F->params = ary;*/
|
|
376
|
+
F->params = (void *) ary;
|
|
377
|
+
} else {
|
|
378
|
+
ary = (VALUE) F->params;
|
|
379
|
+
}
|
|
380
|
+
rb_ary_store(ary, 0, procf);
|
|
381
|
+
return obj;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
static VALUE rb_gsl_function_fdf_set_df(VALUE obj, VALUE procdf)
|
|
385
|
+
{
|
|
386
|
+
gsl_function_fdf *F = NULL;
|
|
387
|
+
VALUE ary;
|
|
388
|
+
CHECK_PROC(procdf);
|
|
389
|
+
Data_Get_Struct(obj, gsl_function_fdf, F);
|
|
390
|
+
if (F->params == NULL) {
|
|
391
|
+
ary = rb_ary_new2(4);
|
|
392
|
+
/* (VALUE) F->params = ary;*/
|
|
393
|
+
F->params = (void *) ary;
|
|
394
|
+
} else {
|
|
395
|
+
ary = (VALUE) F->params;
|
|
396
|
+
}
|
|
397
|
+
rb_ary_store(ary, 1, procdf);
|
|
398
|
+
return obj;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
static VALUE rb_gsl_function_fdf_set_fdf(VALUE obj, VALUE procfdf)
|
|
402
|
+
{
|
|
403
|
+
gsl_function_fdf *F = NULL;
|
|
404
|
+
VALUE ary;
|
|
405
|
+
CHECK_PROC(procfdf);
|
|
406
|
+
Data_Get_Struct(obj, gsl_function_fdf, F);
|
|
407
|
+
if (F->params == NULL) {
|
|
408
|
+
ary = rb_ary_new2(4);
|
|
409
|
+
/* (VALUE) F->params = ary;*/
|
|
410
|
+
F->params = (void *) ary;
|
|
411
|
+
} else {
|
|
412
|
+
ary = (VALUE) F->params;
|
|
413
|
+
}
|
|
414
|
+
rb_ary_store(ary, 2, procfdf);
|
|
415
|
+
return obj;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
static VALUE rb_gsl_function_fdf_set_params(int argc, VALUE *argv, VALUE obj)
|
|
419
|
+
{
|
|
420
|
+
gsl_function_fdf *F = NULL;
|
|
421
|
+
VALUE ary, ary2;
|
|
422
|
+
size_t i;
|
|
423
|
+
Data_Get_Struct(obj, gsl_function_fdf, F);
|
|
424
|
+
ary = (VALUE) F->params;
|
|
425
|
+
if (argc == 0) return obj;
|
|
426
|
+
if (argc == 1) {
|
|
427
|
+
rb_ary_store(ary, 3, argv[0]);
|
|
428
|
+
} else {
|
|
429
|
+
ary2 = rb_ary_new2(argc);
|
|
430
|
+
for (i = 0; i < argc; i++) rb_ary_store(ary2, i, argv[i]);
|
|
431
|
+
rb_ary_store(ary, 3, ary2);
|
|
432
|
+
}
|
|
433
|
+
return obj;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
static double rb_gsl_function_fdf_f(double x, void *p)
|
|
437
|
+
{
|
|
438
|
+
VALUE result, params, proc, ary;
|
|
439
|
+
ary = (VALUE) p;
|
|
440
|
+
proc = rb_ary_entry(ary, 0);
|
|
441
|
+
params = rb_ary_entry(ary, 3);
|
|
442
|
+
if (NIL_P(params)) result = rb_funcall(proc, RBGSL_ID_call, 1, rb_float_new(x));
|
|
443
|
+
else result = rb_funcall(proc, RBGSL_ID_call, 2, rb_float_new(x), params);
|
|
444
|
+
return NUM2DBL(result);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
static double rb_gsl_function_fdf_df(double x, void *p)
|
|
448
|
+
{
|
|
449
|
+
VALUE result, params, proc, ary;
|
|
450
|
+
ary = (VALUE) p;
|
|
451
|
+
proc = rb_ary_entry(ary, 1);
|
|
452
|
+
params = rb_ary_entry(ary, 3);
|
|
453
|
+
if (NIL_P(params)) result = rb_funcall(proc, RBGSL_ID_call, 1, rb_float_new(x));
|
|
454
|
+
else result = rb_funcall(proc, RBGSL_ID_call, 2, rb_float_new(x), params);
|
|
455
|
+
return NUM2DBL(result);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
static void rb_gsl_function_fdf_fdf(double x, void *p, double *f, double *df)
|
|
459
|
+
{
|
|
460
|
+
VALUE result, params, proc_f, proc_df, proc_fdf, ary;
|
|
461
|
+
ary = (VALUE) p;
|
|
462
|
+
proc_f = rb_ary_entry(ary, 0);
|
|
463
|
+
proc_df = rb_ary_entry(ary, 1);
|
|
464
|
+
proc_fdf = rb_ary_entry(ary, 2);
|
|
465
|
+
params = rb_ary_entry(ary, 3);
|
|
466
|
+
if (NIL_P(proc_fdf)) {
|
|
467
|
+
if (NIL_P(params)) {
|
|
468
|
+
result = rb_funcall(proc_f, RBGSL_ID_call, 1, rb_float_new(x));
|
|
469
|
+
*f = NUM2DBL(result);
|
|
470
|
+
result = rb_funcall(proc_df, RBGSL_ID_call, 1, rb_float_new(x));
|
|
471
|
+
*df = NUM2DBL(result);
|
|
472
|
+
} else {
|
|
473
|
+
result = rb_funcall(proc_f, RBGSL_ID_call, 2, rb_float_new(x), params);
|
|
474
|
+
*f = NUM2DBL(result);
|
|
475
|
+
result = rb_funcall(proc_df, RBGSL_ID_call, 2, rb_float_new(x), params);
|
|
476
|
+
*df = NUM2DBL(result);
|
|
477
|
+
}
|
|
478
|
+
} else {
|
|
479
|
+
if (NIL_P(params)) result = rb_funcall(proc_fdf, RBGSL_ID_call, 1, rb_float_new(x));
|
|
480
|
+
else result = rb_funcall(proc_fdf, RBGSL_ID_call, 2, rb_float_new(x), params);
|
|
481
|
+
*f = NUM2DBL(rb_ary_entry(result, 0));
|
|
482
|
+
*df = NUM2DBL(rb_ary_entry(result, 1));
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
void Init_gsl_function(VALUE module)
|
|
487
|
+
{
|
|
488
|
+
VALUE cgsl_function_fdf2;
|
|
489
|
+
RBGSL_ID_call = rb_intern("call");
|
|
490
|
+
RBGSL_ID_arity = rb_intern("arity");
|
|
491
|
+
|
|
492
|
+
cgsl_function = rb_define_class_under(module, "Function", cGSL_Object);
|
|
493
|
+
cgsl_function_fdf = rb_define_class_under(module, "Function_fdf", cGSL_Object);
|
|
494
|
+
cgsl_function_fdf2 = rb_define_class_under(cgsl_function_fdf, "Fdf", cgsl_function_fdf);
|
|
495
|
+
|
|
496
|
+
/* rb_define_singleton_method(cgsl_function, "new", rb_gsl_function_new, -1);*/
|
|
497
|
+
rb_define_singleton_method(cgsl_function, "alloc", rb_gsl_function_alloc, -1);
|
|
498
|
+
|
|
499
|
+
rb_define_method(cgsl_function, "eval", rb_gsl_function_eval, 1);
|
|
500
|
+
rb_define_alias(cgsl_function, "call", "eval");
|
|
501
|
+
rb_define_alias(cgsl_function, "[]", "eval");
|
|
502
|
+
rb_define_alias(cgsl_function, "at", "eval");
|
|
503
|
+
rb_define_method(cgsl_function, "arity", rb_gsl_function_arity, 0);
|
|
504
|
+
rb_define_method(cgsl_function, "proc", rb_gsl_function_proc, 0);
|
|
505
|
+
rb_define_alias(cgsl_function, "f", "proc");
|
|
506
|
+
rb_define_method(cgsl_function, "params", rb_gsl_function_params, 0);
|
|
507
|
+
rb_define_alias(cgsl_function, "param", "params");
|
|
508
|
+
rb_define_method(cgsl_function, "set", rb_gsl_function_set_f, -1);
|
|
509
|
+
rb_define_method(cgsl_function, "set_params", rb_gsl_function_set_params, -1);
|
|
510
|
+
rb_define_alias(cgsl_function, "set_param", "set_params");
|
|
511
|
+
rb_define_alias(cgsl_function, "params=", "set_params");
|
|
512
|
+
rb_define_alias(cgsl_function, "param=", "set_params");
|
|
513
|
+
|
|
514
|
+
rb_define_method(cgsl_function, "graph", rb_gsl_function_graph, -1);
|
|
515
|
+
/*****/
|
|
516
|
+
rb_define_singleton_method(cgsl_function_fdf, "new", rb_gsl_function_fdf_new, -1);
|
|
517
|
+
rb_define_singleton_method(cgsl_function_fdf, "alloc", rb_gsl_function_fdf_new, -1);
|
|
518
|
+
rb_define_method(cgsl_function_fdf, "set", rb_gsl_function_fdf_set, -1);
|
|
519
|
+
rb_define_method(cgsl_function_fdf, "set_f", rb_gsl_function_fdf_set_f, 1);
|
|
520
|
+
rb_define_method(cgsl_function_fdf, "set_df", rb_gsl_function_fdf_set_df, 1);
|
|
521
|
+
rb_define_method(cgsl_function_fdf, "set_fdf", rb_gsl_function_fdf_set_fdf, 1);
|
|
522
|
+
rb_define_method(cgsl_function_fdf, "set_params", rb_gsl_function_fdf_set_params, -1);
|
|
523
|
+
|
|
524
|
+
}
|