pspline 5.0.2
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.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/README.md +34 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/pspline/basis.cpp +351 -0
- data/ext/pspline/example/exbspline.ps +2194 -0
- data/ext/pspline/example/exbspline.rb +36 -0
- data/ext/pspline/example/excspline.ps +2985 -0
- data/ext/pspline/example/excspline.rb +36 -0
- data/ext/pspline/example/exdspline.ps +2846 -0
- data/ext/pspline/example/exdspline.rb +33 -0
- data/ext/pspline/example/exfspline.rb +66 -0
- data/ext/pspline/example/exfspline1.rb +40 -0
- data/ext/pspline/example/expspline.ps +3299 -0
- data/ext/pspline/example/expspline.rb +29 -0
- data/ext/pspline/example/expspline1.rb +29 -0
- data/ext/pspline/example/expspline2.rb +47 -0
- data/ext/pspline/example/exqspline.ps +2957 -0
- data/ext/pspline/example/exqspline.rb +31 -0
- data/ext/pspline/example/exqspline1.rb +31 -0
- data/ext/pspline/example/exqspline2.rb +50 -0
- data/ext/pspline/example/exqspline3.rb +51 -0
- data/ext/pspline/example/exrspline.ps +2812 -0
- data/ext/pspline/example/exrspline.rb +34 -0
- data/ext/pspline/example/exrspline1.rb +34 -0
- data/ext/pspline/example/exrspline2.rb +44 -0
- data/ext/pspline/example/exsspline.ps +1965 -0
- data/ext/pspline/example/exsspline.rb +35 -0
- data/ext/pspline/example/exsspline1.rb +35 -0
- data/ext/pspline/example/extspline.ps +2767 -0
- data/ext/pspline/example/extspline.rb +32 -0
- data/ext/pspline/extconf.rb +7 -0
- data/ext/pspline/fft.cpp +552 -0
- data/ext/pspline/include/basis/basis.h +137 -0
- data/ext/pspline/include/basis/fft.h +152 -0
- data/ext/pspline/include/basis/poly_array.h +1568 -0
- data/ext/pspline/include/basis/pspline.h +506 -0
- data/ext/pspline/include/basis/uspline.h +210 -0
- data/ext/pspline/include/basis/util.h +656 -0
- data/ext/pspline/include/bspline.h +377 -0
- data/ext/pspline/include/bspline_Config.h +2 -0
- data/ext/pspline/plotsub.cpp +132 -0
- data/ext/pspline/pspline.cpp +897 -0
- data/ext/pspline/util.cpp +483 -0
- data/lib/pspline.rb +6 -0
- data/lib/pspline/version.rb +3 -0
- data/pspline.gemspec +25 -0
- metadata +122 -0
|
@@ -0,0 +1,897 @@
|
|
|
1
|
+
/* Extention for ruby */
|
|
2
|
+
|
|
3
|
+
#include "ruby.h"
|
|
4
|
+
|
|
5
|
+
#ifdef __cplusplus
|
|
6
|
+
# define VALUEFUNC(f) ((VALUE (*)(...))f)
|
|
7
|
+
# define VOIDFUNC(f) ((void (*)(...))f)
|
|
8
|
+
#else
|
|
9
|
+
# define VALUEFUNC(f) (f)
|
|
10
|
+
# define VOIDFUNC(f) (f)
|
|
11
|
+
#endif
|
|
12
|
+
|
|
13
|
+
static VALUE
|
|
14
|
+
_wrap_ary_flatten(VALUE arg)
|
|
15
|
+
{
|
|
16
|
+
VALUE result = rb_ary_new();
|
|
17
|
+
if (TYPE(arg) == T_ARRAY) {
|
|
18
|
+
if(RARRAY_LEN(arg) == 0)
|
|
19
|
+
return result;
|
|
20
|
+
else {
|
|
21
|
+
VALUE last = rb_ary_pop(arg);
|
|
22
|
+
return rb_ary_concat(_wrap_ary_flatten(arg), _wrap_ary_flatten(last));
|
|
23
|
+
}
|
|
24
|
+
} else
|
|
25
|
+
return rb_ary_push(result, arg);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
#include "bspline.h"
|
|
29
|
+
|
|
30
|
+
static VALUE mPspline;
|
|
31
|
+
|
|
32
|
+
static VALUE cBspline;
|
|
33
|
+
|
|
34
|
+
static void Wrap_free_bspline(bspline<double> *arg0) { delete arg0; }
|
|
35
|
+
|
|
36
|
+
#define Wrap_bspline(klass, ptr) (\
|
|
37
|
+
(ptr) ? Data_Wrap_Struct(klass, 0, VOIDFUNC(Wrap_free_bspline), ptr) : Qnil )
|
|
38
|
+
|
|
39
|
+
#define Get_bspline(val, ptr) {\
|
|
40
|
+
if (NIL_P(val)) ptr = NULL;\
|
|
41
|
+
else {\
|
|
42
|
+
if (!rb_obj_is_kind_of(val, cBspline))\
|
|
43
|
+
rb_raise(rb_eTypeError, "wrong argument type (expected bspline)");\
|
|
44
|
+
Data_Get_Struct(val, bspline<double>, ptr);\
|
|
45
|
+
if (!ptr) rb_raise(rb_eRuntimeError, "This bspline already released");\
|
|
46
|
+
}\
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// bspline#new()
|
|
50
|
+
|
|
51
|
+
static VALUE
|
|
52
|
+
_wrap_new_bspline(int argc, VALUE *argv, VALUE klass)
|
|
53
|
+
{
|
|
54
|
+
VALUE self = Data_Wrap_Struct(klass, 0, VOIDFUNC(Wrap_free_bspline), 0);
|
|
55
|
+
rb_obj_call_init(self, argc, argv);
|
|
56
|
+
return self;
|
|
57
|
+
}
|
|
58
|
+
/*******************************************************************************
|
|
59
|
+
Calculate interpolation of 1 variable M dimension B-spline.
|
|
60
|
+
bspline.new([...,[Xi,Yi0,...,YiM-1],...], N, J, S)
|
|
61
|
+
X0,..,Xi,..,XN-1:点のX座標
|
|
62
|
+
Yi0, ..., YiM-1:点のY座標
|
|
63
|
+
J:スプライン次数(階数K=J+1)
|
|
64
|
+
Result:B-spline object
|
|
65
|
+
*******************************************************************************/
|
|
66
|
+
|
|
67
|
+
// bspline#initialize
|
|
68
|
+
|
|
69
|
+
static VALUE
|
|
70
|
+
_wrap_init_bspline(int argc, VALUE *argv, VALUE self)
|
|
71
|
+
{
|
|
72
|
+
VALUE va, varg, vargn, vargj, vargs, vargd = Qnil;
|
|
73
|
+
int argp, argn, argj, args = 0, k = 1;
|
|
74
|
+
int *argd = NULL;
|
|
75
|
+
double *x, *y;
|
|
76
|
+
|
|
77
|
+
rb_scan_args(argc, argv, "31", &varg, &vargn, &vargj, &vargs);
|
|
78
|
+
|
|
79
|
+
Check_Type(varg, T_ARRAY);
|
|
80
|
+
argp = RARRAY_LEN(varg);
|
|
81
|
+
argn = NUM2INT(vargn);
|
|
82
|
+
argj = NUM2INT(vargj);
|
|
83
|
+
int D = argp - argn;
|
|
84
|
+
if (D < 0)
|
|
85
|
+
rb_raise(rb_eArgError, "Data points %d < Data size %d", argp, argn);
|
|
86
|
+
if (D >= argj)
|
|
87
|
+
rb_raise(rb_eArgError, "Additional points %d >= Degree %d", D, argj);
|
|
88
|
+
if (argn <= argj)
|
|
89
|
+
rb_raise(rb_eArgError, "Data points %d <= Degree %d", argn, argj);
|
|
90
|
+
if (argc > 3) {
|
|
91
|
+
vargd = argv[3];
|
|
92
|
+
if (TYPE(vargd) == T_ARRAY) {
|
|
93
|
+
int d = RARRAY_LEN(vargd);
|
|
94
|
+
if (d != D)
|
|
95
|
+
rb_raise(rb_eArgError, "Differential orders = %d, it should be %d", d, D);
|
|
96
|
+
argd = ALLOC_N(int, argn + D);
|
|
97
|
+
for (int i = 0; i < argn; ++i)
|
|
98
|
+
argd[i] = 0;
|
|
99
|
+
for (int i = 0; i < D; ++i)
|
|
100
|
+
argd[argn + i] = NUM2INT(RARRAY_PTR(vargd)[i]);
|
|
101
|
+
} else
|
|
102
|
+
args = NUM2INT(vargs);
|
|
103
|
+
}
|
|
104
|
+
va = RARRAY_PTR(varg)[0];
|
|
105
|
+
Check_Type(va, T_ARRAY);
|
|
106
|
+
k = RARRAY_LEN(va) - 1;
|
|
107
|
+
x = ALLOC_N(double, argp);
|
|
108
|
+
y = ALLOC_N(double, argp * k);
|
|
109
|
+
for (int i = 0; i < argp; i++) {
|
|
110
|
+
if (i > 0) {
|
|
111
|
+
va = RARRAY_PTR(varg)[i];
|
|
112
|
+
Check_Type(va, T_ARRAY);
|
|
113
|
+
if (RARRAY_LEN(va) - 1 != k)
|
|
114
|
+
rb_raise(rb_eArgError, "Dimension should be %d", k);
|
|
115
|
+
}
|
|
116
|
+
for (int j = 0; j <= k; ++j)
|
|
117
|
+
if (j == 0) x[i] = NUM2DBL(RARRAY_PTR(va)[0]);
|
|
118
|
+
else y[i*k+j-1] = NUM2DBL(RARRAY_PTR(va)[j]);
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
Int s(Colon, argp - args%2, k);
|
|
122
|
+
poly_array<double> argy(y, s);
|
|
123
|
+
// printf("n = %d, j = %d, s = %d\n", argn, argj, args);
|
|
124
|
+
// argy.print("\n");
|
|
125
|
+
DATA_PTR(self) = new bspline<double>(argy, argn + args%2, x, argj, args, argd);
|
|
126
|
+
} catch (const char *c) {
|
|
127
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
128
|
+
}
|
|
129
|
+
free(y);
|
|
130
|
+
free(x);
|
|
131
|
+
if (argd) free(argd);
|
|
132
|
+
return self;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static VALUE
|
|
136
|
+
make_list(int argc, VALUE *argv)
|
|
137
|
+
{
|
|
138
|
+
VALUE vargs = rb_ary_new();
|
|
139
|
+
for (int i = 0; i < argc; i++) {
|
|
140
|
+
if (TYPE(argv[i]) == T_ARRAY) {
|
|
141
|
+
VALUE val = rb_obj_dup(argv[i]);
|
|
142
|
+
vargs = rb_ary_concat(vargs, _wrap_ary_flatten(val));
|
|
143
|
+
}
|
|
144
|
+
else
|
|
145
|
+
rb_ary_push(vargs, argv[i]);
|
|
146
|
+
}
|
|
147
|
+
return vargs;
|
|
148
|
+
}
|
|
149
|
+
/*******************************************************************************
|
|
150
|
+
関数値
|
|
151
|
+
|
|
152
|
+
bspline#[x[, ...]]
|
|
153
|
+
x:点のX座標(数値,または数値の配列)
|
|
154
|
+
|
|
155
|
+
Result:補間値
|
|
156
|
+
*******************************************************************************/
|
|
157
|
+
static VALUE
|
|
158
|
+
_wrap_bspline_bracket(int argc, VALUE *argv, VALUE self)
|
|
159
|
+
{
|
|
160
|
+
bspline<double> *bsp;
|
|
161
|
+
double arg;
|
|
162
|
+
VALUE val, vargs;
|
|
163
|
+
VALUE vresult = Qnil;
|
|
164
|
+
|
|
165
|
+
Get_bspline(self, bsp);
|
|
166
|
+
int K = bsp->Unit_size();
|
|
167
|
+
|
|
168
|
+
vargs = make_list(argc, argv);
|
|
169
|
+
argc = RARRAY_LEN(vargs);
|
|
170
|
+
try {
|
|
171
|
+
vresult = rb_ary_new();
|
|
172
|
+
for (int i = 0; i < argc; i++) {
|
|
173
|
+
arg = NUM2DBL(RARRAY_PTR(vargs)[i]);
|
|
174
|
+
poly_array<double> result = (*bsp)[arg];
|
|
175
|
+
if (K == 1)
|
|
176
|
+
val = rb_float_new(result[0]);
|
|
177
|
+
else {
|
|
178
|
+
val = rb_ary_new();
|
|
179
|
+
for (int j = 0; j < K; ++j)
|
|
180
|
+
rb_ary_push(val, rb_float_new(result[j]));
|
|
181
|
+
}
|
|
182
|
+
rb_ary_push(vresult, val);
|
|
183
|
+
}
|
|
184
|
+
} catch (const char *c) {
|
|
185
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
186
|
+
}
|
|
187
|
+
return argc == 1 ? rb_ary_shift(vresult) : vresult;
|
|
188
|
+
}
|
|
189
|
+
/*******************************************************************************
|
|
190
|
+
関数値
|
|
191
|
+
bspline#value(x, d = 0)
|
|
192
|
+
x:点のX座標
|
|
193
|
+
d:微分階数(省略可)
|
|
194
|
+
Result:補間値,または微分値
|
|
195
|
+
*******************************************************************************/
|
|
196
|
+
static VALUE
|
|
197
|
+
_wrap_bspline_value(int argc, VALUE *argv, VALUE self)
|
|
198
|
+
{
|
|
199
|
+
VALUE varg1, varg2 ;
|
|
200
|
+
bspline<double> *arg0 ;
|
|
201
|
+
double arg1 ;
|
|
202
|
+
int arg2 = 0 ;
|
|
203
|
+
VALUE vresult = Qnil;
|
|
204
|
+
|
|
205
|
+
rb_scan_args(argc, argv, "11", &varg1, &varg2);
|
|
206
|
+
Get_bspline(self, arg0);
|
|
207
|
+
int K = arg0->Unit_size();
|
|
208
|
+
arg1 = NUM2DBL(varg1);
|
|
209
|
+
if (argc > 1) arg2 = NUM2INT(varg2);
|
|
210
|
+
try {
|
|
211
|
+
poly_array<double> result = (*arg0)(arg1, arg2);
|
|
212
|
+
if (K == 1)
|
|
213
|
+
vresult = rb_float_new(result[0]);
|
|
214
|
+
else {
|
|
215
|
+
vresult = rb_ary_new();
|
|
216
|
+
for (int j = 0; j < K; ++j)
|
|
217
|
+
rb_ary_push(vresult, rb_float_new(result[j]));
|
|
218
|
+
}
|
|
219
|
+
} catch (const char *c) {
|
|
220
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
221
|
+
}
|
|
222
|
+
return vresult;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
static VALUE
|
|
226
|
+
_wrap_bspline_sekibun(VALUE self, VALUE varg)
|
|
227
|
+
{
|
|
228
|
+
bspline<double> *arg0 ;
|
|
229
|
+
VALUE vresult = Qnil;
|
|
230
|
+
|
|
231
|
+
Get_bspline(self, arg0);
|
|
232
|
+
int K = arg0->Unit_size();
|
|
233
|
+
try {
|
|
234
|
+
poly_array<double> result = arg0->sekibun(NUM2DBL(varg));
|
|
235
|
+
if (K == 1)
|
|
236
|
+
vresult = rb_float_new(result[0]);
|
|
237
|
+
else {
|
|
238
|
+
vresult = rb_ary_new();
|
|
239
|
+
for (int j = 0; j < K; ++j)
|
|
240
|
+
rb_ary_push(vresult, rb_float_new(result[j]));
|
|
241
|
+
}
|
|
242
|
+
} catch (const char *c) {
|
|
243
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
244
|
+
}
|
|
245
|
+
return vresult;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
static VALUE
|
|
249
|
+
_wrap_bspline_plot(int argc, VALUE *argv, VALUE self)
|
|
250
|
+
{
|
|
251
|
+
bspline<double> *arg0; // bspline object
|
|
252
|
+
VALUE varg1; // list of point
|
|
253
|
+
VALUE varg3; int arg3; // number of division
|
|
254
|
+
VALUE varg4; int arg4 = 0; // order differential
|
|
255
|
+
rb_scan_args(argc, argv, "21", &varg1, &varg3, &varg4);
|
|
256
|
+
Check_Type(varg1, T_ARRAY);
|
|
257
|
+
arg3 = NUM2INT(varg3);
|
|
258
|
+
if (argc > 2) arg4 = NUM2INT(varg4);
|
|
259
|
+
Get_bspline(self, arg0);
|
|
260
|
+
int argn = RARRAY_LEN(varg1);
|
|
261
|
+
double *argx = ALLOC_N(double, argn);
|
|
262
|
+
for (int i = 0; i < argn; ++i) {
|
|
263
|
+
VALUE x = rb_ary_shift(varg1);
|
|
264
|
+
argx[i] = NUM2DBL(x);
|
|
265
|
+
}
|
|
266
|
+
int K = arg0->Unit_size();
|
|
267
|
+
double *arg1, *arg2[K];
|
|
268
|
+
int result;
|
|
269
|
+
try {
|
|
270
|
+
result = plot<double>(*arg0, argn, argx, &arg1, arg2, arg3, arg4);
|
|
271
|
+
} catch (const char *c) {
|
|
272
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
273
|
+
}
|
|
274
|
+
for (int i = 0; i < result; i++) {
|
|
275
|
+
VALUE v1 = rb_float_new(arg1[i]);
|
|
276
|
+
VALUE v2 = rb_ary_new();
|
|
277
|
+
for (int k = 0; k < K; ++k)
|
|
278
|
+
rb_ary_push(v2, rb_float_new(arg2[k][i]));
|
|
279
|
+
VALUE vv = rb_ary_new();
|
|
280
|
+
rb_ary_push(vv, v1);
|
|
281
|
+
rb_ary_push(vv, v2);
|
|
282
|
+
rb_ary_push(varg1, vv);
|
|
283
|
+
if (rb_block_given_p()) rb_yield(vv);
|
|
284
|
+
}
|
|
285
|
+
free(arg1);
|
|
286
|
+
for (int i = 0; i < K; ++i) free(arg2[i]);
|
|
287
|
+
free(argx);
|
|
288
|
+
return INT2NUM(result);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
static VALUE
|
|
292
|
+
_wrap_complex_trans(VALUE self, VALUE varg1, VALUE varg2)
|
|
293
|
+
{
|
|
294
|
+
VALUE varg, vargx, vargy, vresult = Qnil;
|
|
295
|
+
Check_Type(varg1, T_ARRAY);
|
|
296
|
+
int argn = RARRAY_LEN(varg1);
|
|
297
|
+
int argf = NUM2INT(varg2);
|
|
298
|
+
if (argf != 1) {
|
|
299
|
+
if (argn != 2) rb_raise(rb_eArgError, "Argument is not Complex");
|
|
300
|
+
vargx = RARRAY_PTR(varg1)[0]; Check_Type(vargx, T_ARRAY);
|
|
301
|
+
vargy = RARRAY_PTR(varg1)[1]; Check_Type(vargy, T_ARRAY);
|
|
302
|
+
argn = RARRAY_LEN(vargx);
|
|
303
|
+
if (argn != RARRAY_LEN(vargy)) rb_raise(rb_eArgError, "Argument is not Complex");
|
|
304
|
+
}
|
|
305
|
+
double *dfft = ALLOC_N(double, argn << 1);
|
|
306
|
+
double *data = ALLOC_N(double, argn << 1);
|
|
307
|
+
if (argf == 1) {
|
|
308
|
+
for (int i = 0; i < argn; i++) {
|
|
309
|
+
varg = RARRAY_PTR(varg1)[i];
|
|
310
|
+
Check_Type(varg, T_ARRAY);
|
|
311
|
+
if (RARRAY_LEN(varg) != 2) rb_raise(rb_eArgError, "Argument is not Complex");
|
|
312
|
+
dfft[2*i] = NUM2DBL(RARRAY_PTR(varg)[0]);
|
|
313
|
+
dfft[2*i+1] = NUM2DBL(RARRAY_PTR(varg)[1]);
|
|
314
|
+
}
|
|
315
|
+
try {
|
|
316
|
+
fft<>::complex_transform(dfft, argn, argf);
|
|
317
|
+
fft<>::half_en_pack(data, argn, dfft);
|
|
318
|
+
} catch (const char *c) {
|
|
319
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
320
|
+
}
|
|
321
|
+
vresult = rb_ary_new();
|
|
322
|
+
vargx = rb_ary_new();
|
|
323
|
+
vargy = rb_ary_new();
|
|
324
|
+
rb_ary_push(vresult, vargx);
|
|
325
|
+
rb_ary_push(vresult, vargy);
|
|
326
|
+
for (int i = 0; i < argn; i++) {
|
|
327
|
+
rb_ary_push(vargx, rb_float_new(data[i]));
|
|
328
|
+
rb_ary_push(vargy, rb_float_new(data[i+argn]));
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
for (int i = 0; i < argn; i++) {
|
|
332
|
+
data[i] = NUM2DBL(RARRAY_PTR(vargx)[i]);
|
|
333
|
+
data[i+argn] = NUM2DBL(RARRAY_PTR(vargy)[i]);
|
|
334
|
+
}
|
|
335
|
+
try {
|
|
336
|
+
fft<>::half_de_pack(dfft, argn, data);
|
|
337
|
+
fft<>::complex_transform(dfft, argn, argf);
|
|
338
|
+
} catch (const char *c) {
|
|
339
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
340
|
+
}
|
|
341
|
+
vresult = rb_ary_new();
|
|
342
|
+
for (int i = 0; i < argn; i++) {
|
|
343
|
+
varg = rb_ary_new();
|
|
344
|
+
rb_ary_push(vresult, varg);
|
|
345
|
+
rb_ary_push(varg, rb_float_new(dfft[2*i]));
|
|
346
|
+
rb_ary_push(varg, rb_float_new(dfft[2*i+1]));
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
free(data);
|
|
350
|
+
free(dfft);
|
|
351
|
+
return vresult;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
static VALUE
|
|
355
|
+
_wrap_complex_get(VALUE self, VALUE varg1, VALUE varg2)
|
|
356
|
+
{
|
|
357
|
+
VALUE vargx, vargy, vresult = Qnil;
|
|
358
|
+
Check_Type(varg1, T_ARRAY);
|
|
359
|
+
int argn = RARRAY_LEN(varg1);
|
|
360
|
+
int args = NUM2INT(varg2);
|
|
361
|
+
if (argn != 2) rb_raise(rb_eArgError, "Argument is not Complex");
|
|
362
|
+
vargx = RARRAY_PTR(varg1)[0];
|
|
363
|
+
vargy = RARRAY_PTR(varg1)[1];
|
|
364
|
+
argn = RARRAY_LEN(vargx);
|
|
365
|
+
if (RARRAY_LEN(vargy) != argn) rb_raise(rb_eArgError, "Argument is not Complex");
|
|
366
|
+
double *data = ALLOC_N(double, argn << 1);
|
|
367
|
+
for (int i = 0; i < argn; i++) {
|
|
368
|
+
data[i] = NUM2DBL(RARRAY_PTR(vargx)[i]);
|
|
369
|
+
data[i+argn] =NUM2DBL(RARRAY_PTR(vargy)[i]);
|
|
370
|
+
}
|
|
371
|
+
double w[2];
|
|
372
|
+
fft<>::half_get(data, argn, args, w);
|
|
373
|
+
vresult = rb_ary_new();
|
|
374
|
+
rb_ary_push(vresult, rb_float_new(w[0]));
|
|
375
|
+
rb_ary_push(vresult, rb_float_new(w[1]));
|
|
376
|
+
free(data);
|
|
377
|
+
return vresult;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
static VALUE
|
|
381
|
+
_wrap_real_trans(VALUE self, VALUE varg1, VALUE varg2)
|
|
382
|
+
{
|
|
383
|
+
VALUE vresult = Qnil;
|
|
384
|
+
Check_Type(varg1, T_ARRAY);
|
|
385
|
+
int argn = RARRAY_LEN(varg1);
|
|
386
|
+
int argf = NUM2INT(varg2);
|
|
387
|
+
double *data = ALLOC_N(double, argn);
|
|
388
|
+
for (int i = 0; i < argn; i++)
|
|
389
|
+
data[i] = NUM2DBL(RARRAY_PTR(varg1)[i]);
|
|
390
|
+
try {
|
|
391
|
+
fft<>::real_transform(data, argn, argf);
|
|
392
|
+
} catch (const char *c) {
|
|
393
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
394
|
+
}
|
|
395
|
+
vresult = rb_ary_new();
|
|
396
|
+
for (int i = 0; i < argn; i++)
|
|
397
|
+
rb_ary_push(vresult, rb_float_new(data[i]));
|
|
398
|
+
free(data);
|
|
399
|
+
return vresult;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
static VALUE
|
|
403
|
+
_wrap_real_get(VALUE self, VALUE varg1, VALUE varg2)
|
|
404
|
+
{
|
|
405
|
+
VALUE vresult = Qnil;
|
|
406
|
+
Check_Type(varg1, T_ARRAY);
|
|
407
|
+
int argn = RARRAY_LEN(varg1);
|
|
408
|
+
int args = NUM2INT(varg2);
|
|
409
|
+
double *data = ALLOC_N(double, argn);
|
|
410
|
+
for (int i = 0; i < argn; i++)
|
|
411
|
+
data[i] = NUM2DBL(RARRAY_PTR(varg1)[i]);
|
|
412
|
+
double w[2];
|
|
413
|
+
fft<>::real_get(data, argn, args, w);
|
|
414
|
+
vresult = rb_ary_new();
|
|
415
|
+
rb_ary_push(vresult, rb_float_new(w[0]));
|
|
416
|
+
rb_ary_push(vresult, rb_float_new(w[1]));
|
|
417
|
+
free(data);
|
|
418
|
+
return vresult;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
static VALUE
|
|
422
|
+
_wrap_complex_bspline(VALUE self, VALUE varg1, VALUE varg2)
|
|
423
|
+
{
|
|
424
|
+
Check_Type(varg1, T_ARRAY);
|
|
425
|
+
int argn = RARRAY_LEN(varg1);
|
|
426
|
+
if (argn != 2) rb_raise(rb_eArgError, "Argument is not Complex");
|
|
427
|
+
VALUE vargx = RARRAY_PTR(varg1)[0];
|
|
428
|
+
VALUE vargy = RARRAY_PTR(varg1)[1];
|
|
429
|
+
Check_Type(vargx, T_ARRAY);
|
|
430
|
+
Check_Type(vargy, T_ARRAY);
|
|
431
|
+
argn = RARRAY_LEN(vargx);
|
|
432
|
+
if (RARRAY_LEN(vargy) != argn) rb_raise(rb_eArgError, "Argument is not Complex");
|
|
433
|
+
double *data = ALLOC_N(double, argn << 1);
|
|
434
|
+
for (int i = 0; i < argn; i++) {
|
|
435
|
+
data[i] = NUM2DBL(RARRAY_PTR(vargx)[i]);
|
|
436
|
+
data[i+argn] = NUM2DBL(RARRAY_PTR(vargy)[i]);
|
|
437
|
+
}
|
|
438
|
+
double *dfft = ALLOC_N(double, argn << 1);
|
|
439
|
+
fft<>::half_de_pack(dfft, argn, data);
|
|
440
|
+
int argj = NUM2INT(varg2);
|
|
441
|
+
bspline<> *result;
|
|
442
|
+
try {
|
|
443
|
+
result = fft<>::cfft(dfft, argn, argj);
|
|
444
|
+
} catch (const char *c) {
|
|
445
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
446
|
+
}
|
|
447
|
+
if (rb_block_given_p()) {
|
|
448
|
+
double val[2]; int N = argn / 2;
|
|
449
|
+
for (int i = -N; i <= N + argn%2; i++) {
|
|
450
|
+
fft<>::half_get(data, argn, i, val);
|
|
451
|
+
VALUE vv = rb_ary_new();
|
|
452
|
+
rb_ary_push(vv, INT2NUM(i));
|
|
453
|
+
VALUE xy = rb_ary_new();
|
|
454
|
+
rb_ary_push(xy, rb_float_new(val[0]));
|
|
455
|
+
rb_ary_push(xy, rb_float_new(val[1]));
|
|
456
|
+
rb_ary_push(vv, xy);
|
|
457
|
+
rb_yield(vv);
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
free(dfft);
|
|
461
|
+
free(data);
|
|
462
|
+
return Wrap_bspline(cBspline, result);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
static VALUE
|
|
466
|
+
_wrap_real_bspline(VALUE self, VALUE varg1, VALUE varg2)
|
|
467
|
+
{
|
|
468
|
+
Check_Type(varg1, T_ARRAY);
|
|
469
|
+
int argn = RARRAY_LEN(varg1);
|
|
470
|
+
double *data = ALLOC_N(double, argn);
|
|
471
|
+
for (int i = 0; i < argn; i++)
|
|
472
|
+
data[i] = NUM2DBL(RARRAY_PTR(varg1)[i]);
|
|
473
|
+
int argj = NUM2INT(varg2);
|
|
474
|
+
bspline<> *result;
|
|
475
|
+
try {
|
|
476
|
+
result = fft<>::rfft(data, argn, argj);
|
|
477
|
+
} catch (const char *c) {
|
|
478
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
479
|
+
}
|
|
480
|
+
if (rb_block_given_p()) {
|
|
481
|
+
double val[2]; int N = argn / 2;
|
|
482
|
+
for (int i = -N; i <= N + argn%2; i++) {
|
|
483
|
+
fft<>::real_get(data, argn, i, val);
|
|
484
|
+
VALUE vv = rb_ary_new();
|
|
485
|
+
rb_ary_push(vv, INT2NUM(i));
|
|
486
|
+
VALUE xy = rb_ary_new();
|
|
487
|
+
rb_ary_push(vv, xy);
|
|
488
|
+
rb_ary_push(xy, rb_float_new(val[0]));
|
|
489
|
+
rb_ary_push(xy, rb_float_new(val[1]));
|
|
490
|
+
rb_yield(vv);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
free(data);
|
|
494
|
+
return Wrap_bspline(cBspline, result);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
static void
|
|
498
|
+
_wrap_Init_bspline(void)
|
|
499
|
+
{
|
|
500
|
+
cBspline = rb_define_class_under(mPspline, "Bspline", rb_cObject);
|
|
501
|
+
rb_include_module(cBspline, rb_mEnumerable);
|
|
502
|
+
rb_define_singleton_method(cBspline, "new", VALUEFUNC(_wrap_new_bspline), -1);
|
|
503
|
+
rb_define_method(cBspline, "initialize", VALUEFUNC(_wrap_init_bspline), -1);
|
|
504
|
+
rb_define_method(cBspline, "[]", VALUEFUNC(_wrap_bspline_bracket), -1);
|
|
505
|
+
rb_define_method(cBspline, "value", VALUEFUNC(_wrap_bspline_value), -1);
|
|
506
|
+
rb_define_method(cBspline, "sekibun", VALUEFUNC(_wrap_bspline_sekibun), 1);
|
|
507
|
+
rb_define_method(cBspline, "plot", VALUEFUNC(_wrap_bspline_plot), -1);
|
|
508
|
+
rb_define_module_function(mPspline, "fft_complex_transform", VALUEFUNC(_wrap_complex_trans), 2);
|
|
509
|
+
rb_define_module_function(mPspline, "fft_complex_get", VALUEFUNC(_wrap_complex_get), 2);
|
|
510
|
+
rb_define_module_function(mPspline, "fft_complex_bspline", VALUEFUNC(_wrap_complex_bspline), 2);
|
|
511
|
+
rb_define_module_function(mPspline, "fft_real_transform", VALUEFUNC(_wrap_real_trans), 2);
|
|
512
|
+
rb_define_module_function(mPspline, "fft_real_get", VALUEFUNC(_wrap_real_get), 2);
|
|
513
|
+
rb_define_module_function(mPspline, "fft_real_bspline", VALUEFUNC(_wrap_real_bspline), 2);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
static VALUE cPspline;
|
|
517
|
+
|
|
518
|
+
static void Wrap_free_pspline(pspline<double> *arg0) { delete arg0; }
|
|
519
|
+
|
|
520
|
+
#define Wrap_pspline(klass, ptr) (\
|
|
521
|
+
(ptr) ? Data_Wrap_Struct(klass, 0, VOIDFUNC(Wrap_free_pspline), ptr) : Qnil )
|
|
522
|
+
|
|
523
|
+
#define Get_pspline(val, ptr) {\
|
|
524
|
+
if (NIL_P(val)) ptr = NULL;\
|
|
525
|
+
else {\
|
|
526
|
+
if (!rb_obj_is_kind_of(val, cPspline))\
|
|
527
|
+
rb_raise(rb_eTypeError, "wrong argument type (expected pspline)");\
|
|
528
|
+
Data_Get_Struct(val, pspline<double>, ptr);\
|
|
529
|
+
if (!ptr) rb_raise(rb_eRuntimeError, "This pspline already released");\
|
|
530
|
+
}\
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// Pspline#new()
|
|
534
|
+
|
|
535
|
+
static VALUE
|
|
536
|
+
_wrap_new_pspline(int argc, VALUE *argv, VALUE klass)
|
|
537
|
+
{
|
|
538
|
+
VALUE self = Data_Wrap_Struct(klass, 0, VOIDFUNC(Wrap_free_pspline), 0);
|
|
539
|
+
rb_obj_call_init(self, argc, argv);
|
|
540
|
+
return self;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
#define Get_param(N, varg, ptr, str) {\
|
|
544
|
+
Check_Type(varg, T_ARRAY);\
|
|
545
|
+
int k = RARRAY_LEN(varg);\
|
|
546
|
+
if (k != N)\
|
|
547
|
+
rb_raise(rb_eArgError, "%s list length = %d, it should be %d", str, k, N);\
|
|
548
|
+
ptr = ALLOC_N(int, k);\
|
|
549
|
+
for (int i = 0; i < k; ++i) ptr[i] = NUM2INT(RARRAY_PTR(varg)[i]);\
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
static comb_array<double> make_var(int N, VALUE var, int *n = NULL, int *m = NULL)
|
|
553
|
+
{
|
|
554
|
+
int M = 0, s[N]; VALUE vs[N];
|
|
555
|
+
for (int i = 0; i < N; ++i) {
|
|
556
|
+
vs[i] = RARRAY_PTR(var)[i];
|
|
557
|
+
Check_Type(vs[i], T_ARRAY);
|
|
558
|
+
s[i] = RARRAY_LEN(vs[i]);
|
|
559
|
+
if (n != NULL && m != NULL) {
|
|
560
|
+
int vars = n[i] + m[i]%2;
|
|
561
|
+
if (s[i] != vars)
|
|
562
|
+
rb_raise(rb_eArgError, "Elements = %d, it should be %d", s[i], vars);
|
|
563
|
+
}
|
|
564
|
+
M += s[i];
|
|
565
|
+
}
|
|
566
|
+
double v[M], *p = v;
|
|
567
|
+
for (int i = 0; i < N; ++i)
|
|
568
|
+
for (int j = 0; j < s[i]; ++j)
|
|
569
|
+
*p++ = NUM2DBL(RARRAY_PTR(vs[i])[j]);
|
|
570
|
+
return comb_array<double>(v, N, s, 1);
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
static VALUE make_flat(int K, VALUE val, int N, int *n)
|
|
574
|
+
{
|
|
575
|
+
if (N == 0) return val;
|
|
576
|
+
if (K != n[0]) rb_raise(rb_eArgError, "Wrong argument Array");
|
|
577
|
+
VALUE vals = rb_ary_new();
|
|
578
|
+
for (int i = 0; i < K; ++i) {
|
|
579
|
+
VALUE va = RARRAY_PTR(val)[i];
|
|
580
|
+
if (TYPE(va) == T_ARRAY) {
|
|
581
|
+
VALUE vb = rb_obj_dup(va);
|
|
582
|
+
vals = rb_ary_concat(vals, make_flat(RARRAY_LEN(va), vb, N-1, n+1));
|
|
583
|
+
}
|
|
584
|
+
else
|
|
585
|
+
rb_ary_push(vals, va);
|
|
586
|
+
}
|
|
587
|
+
return vals;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
static poly_array<double> make_val(int &K, VALUE val, int N, int *n)
|
|
591
|
+
{
|
|
592
|
+
if (K != n[0]) rb_raise(rb_eArgError, "Member size = %d, it should be %d", K, n[0]);
|
|
593
|
+
VALUE vals = rb_ary_new();
|
|
594
|
+
for (int i = 0; i < K; ++i) {
|
|
595
|
+
VALUE va = RARRAY_PTR(val)[i];
|
|
596
|
+
if (TYPE(va) == T_ARRAY) {
|
|
597
|
+
VALUE vb = rb_obj_dup(va);
|
|
598
|
+
vals = rb_ary_concat(vals, make_flat(RARRAY_LEN(va), vb, N-1, n+1));
|
|
599
|
+
}
|
|
600
|
+
else
|
|
601
|
+
rb_ary_push(vals, va);
|
|
602
|
+
}
|
|
603
|
+
int M = RARRAY_LEN(vals);
|
|
604
|
+
K = M;
|
|
605
|
+
for (int i = 0; i < N; ++i) K /= n[i];
|
|
606
|
+
double v[M];
|
|
607
|
+
for (int i = 0; i < M; ++i) v[i] = NUM2DBL(RARRAY_PTR(vals)[i]);
|
|
608
|
+
return poly_array<double>(v, N, n, K);
|
|
609
|
+
}
|
|
610
|
+
/*******************************************************************************
|
|
611
|
+
Calculate interpolation of N variable M dimension P-spline.
|
|
612
|
+
Pspline.new([X^Y^...], [S,T,...], N, J, S)
|
|
613
|
+
X^Y^...:点の座標
|
|
614
|
+
S,T,...:変数の座標
|
|
615
|
+
N:
|
|
616
|
+
J:スプライン次数(階数K=J+1)
|
|
617
|
+
S:
|
|
618
|
+
Result:P-spline object
|
|
619
|
+
*******************************************************************************/
|
|
620
|
+
|
|
621
|
+
// Pspline#initialize
|
|
622
|
+
|
|
623
|
+
static VALUE
|
|
624
|
+
_wrap_init_pspline(int argc, VALUE *argv, VALUE self)
|
|
625
|
+
{
|
|
626
|
+
VALUE vxyz, vstu, vargn, vargj, vargs;
|
|
627
|
+
|
|
628
|
+
int N, K, *n, *j, *s;
|
|
629
|
+
|
|
630
|
+
rb_scan_args(argc, argv, "5", &vxyz, &vstu, &vargn, &vargj, &vargs);
|
|
631
|
+
|
|
632
|
+
Check_Type(vstu, T_ARRAY);
|
|
633
|
+
N = RARRAY_LEN(vstu);
|
|
634
|
+
|
|
635
|
+
Get_param(N, vargs, s, "Type");
|
|
636
|
+
|
|
637
|
+
Get_param(N, vargj, j, "Degree");
|
|
638
|
+
|
|
639
|
+
Get_param(N, vargn, n, "Size");
|
|
640
|
+
|
|
641
|
+
Check_Type(vxyz, T_ARRAY);
|
|
642
|
+
K = RARRAY_LEN(vxyz);
|
|
643
|
+
|
|
644
|
+
try {
|
|
645
|
+
|
|
646
|
+
comb_array<double> stu = make_var(N, vstu, n, s);
|
|
647
|
+
poly_array<double> xyz = make_val(K, vxyz, N, n);
|
|
648
|
+
|
|
649
|
+
Int argn(N, n, K);
|
|
650
|
+
Int argj(N, j, 0);
|
|
651
|
+
Int args(N, s, 0);
|
|
652
|
+
// argn.print(", "); argj.print(", "); args.print("\n");
|
|
653
|
+
// stu.print("\n"); xyz.print("\n");
|
|
654
|
+
DATA_PTR(self) = new pspline<double>(xyz, stu, argj, args);
|
|
655
|
+
|
|
656
|
+
} catch (const char *c) {
|
|
657
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
658
|
+
}
|
|
659
|
+
free(n);
|
|
660
|
+
free(j);
|
|
661
|
+
free(s);
|
|
662
|
+
return self;
|
|
663
|
+
}
|
|
664
|
+
/*******************************************************************************
|
|
665
|
+
関数値
|
|
666
|
+
|
|
667
|
+
pspline#[x[, ...]]
|
|
668
|
+
x:点のX座標(数値,または数値の配列)
|
|
669
|
+
|
|
670
|
+
Result:補間値
|
|
671
|
+
*******************************************************************************/
|
|
672
|
+
static VALUE
|
|
673
|
+
_wrap_pspline_bracket(int argc, VALUE *argv, VALUE self)
|
|
674
|
+
{
|
|
675
|
+
pspline<double> *bsp;
|
|
676
|
+
VALUE vargs, vresult, mresult = Qnil;
|
|
677
|
+
|
|
678
|
+
Get_pspline(self, bsp);
|
|
679
|
+
int N = bsp->Grid();
|
|
680
|
+
int K = bsp->Unit_size();
|
|
681
|
+
|
|
682
|
+
vargs = make_list(argc, argv);
|
|
683
|
+
argc = RARRAY_LEN(vargs);
|
|
684
|
+
int M = argc / N;
|
|
685
|
+
try {
|
|
686
|
+
if (argc % N == 0) {
|
|
687
|
+
mresult = rb_ary_new();
|
|
688
|
+
for (int m = 0; m < M; ++m) {
|
|
689
|
+
double args[N+1];
|
|
690
|
+
for (int i = 0; i < N; ++i)
|
|
691
|
+
args[i] = NUM2DBL(RARRAY_PTR(vargs)[N*m+i]);
|
|
692
|
+
poly<double> arg(args, N);
|
|
693
|
+
poly_array<double> val = (*bsp)[arg];
|
|
694
|
+
if (K == 1)
|
|
695
|
+
vresult = rb_float_new(val[0]);
|
|
696
|
+
else {
|
|
697
|
+
vresult = rb_ary_new();
|
|
698
|
+
for (int j = 0; j < K; ++j)
|
|
699
|
+
rb_ary_push(vresult, rb_float_new(val[j]));
|
|
700
|
+
}
|
|
701
|
+
rb_ary_push(mresult, vresult);
|
|
702
|
+
}
|
|
703
|
+
} else rb_raise(rb_eArgError, "wrong argument []");
|
|
704
|
+
} catch (const char *c) {
|
|
705
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
706
|
+
}
|
|
707
|
+
return M == 1 ? rb_ary_shift(mresult) : mresult;
|
|
708
|
+
}
|
|
709
|
+
/*******************************************************************************
|
|
710
|
+
関数値
|
|
711
|
+
pspline#value(x, d = 0)
|
|
712
|
+
x:点のX座標
|
|
713
|
+
d:微分階数(省略可)
|
|
714
|
+
Result:補間値,または微分値
|
|
715
|
+
*******************************************************************************/
|
|
716
|
+
static VALUE
|
|
717
|
+
_wrap_pspline_value(int argc, VALUE *argv, VALUE self)
|
|
718
|
+
{
|
|
719
|
+
VALUE varg1, varg2, varg3;
|
|
720
|
+
pspline<double> *arg0;
|
|
721
|
+
int argn, arg2 = 0, *carg2 = NULL;
|
|
722
|
+
double *carg3 = NULL;
|
|
723
|
+
VALUE vargs, vresult = Qnil;
|
|
724
|
+
|
|
725
|
+
rb_scan_args(argc, argv, "12", &varg1, &varg2, &varg3);
|
|
726
|
+
|
|
727
|
+
Get_pspline(self, arg0);
|
|
728
|
+
int N = arg0->Grid();
|
|
729
|
+
int K = arg0->Unit_size();
|
|
730
|
+
// 全微分
|
|
731
|
+
if (argc == 3) {
|
|
732
|
+
arg2 = NUM2INT(varg2);
|
|
733
|
+
carg3 = new double[N];
|
|
734
|
+
Check_Type(varg3, T_ARRAY);
|
|
735
|
+
for (int i = 0; i < N; ++i)
|
|
736
|
+
carg3[i] = NUM2DBL(RARRAY_PTR(varg3)[i]);
|
|
737
|
+
}
|
|
738
|
+
// 偏微分
|
|
739
|
+
if (argc == 2) {
|
|
740
|
+
carg2 = new int[N];
|
|
741
|
+
Check_Type(varg2, T_ARRAY);
|
|
742
|
+
for (int i = 0; i < N; ++i)
|
|
743
|
+
carg2[i] = NUM2INT(RARRAY_PTR(varg2)[i]);
|
|
744
|
+
}
|
|
745
|
+
// Argument list
|
|
746
|
+
Check_Type(varg1, T_ARRAY);
|
|
747
|
+
argn = RARRAY_LEN(varg1);
|
|
748
|
+
vargs = make_list(argn, RARRAY_PTR(varg1));
|
|
749
|
+
argn = RARRAY_LEN(vargs);
|
|
750
|
+
if (argn == N) {
|
|
751
|
+
double args[N+1];
|
|
752
|
+
for (int i = 0; i < N; ++i)
|
|
753
|
+
args[i] = NUM2DBL(RARRAY_PTR(vargs)[i]);
|
|
754
|
+
poly_array<double> val;
|
|
755
|
+
try {
|
|
756
|
+
poly<double> arg(args, N);
|
|
757
|
+
switch (argc) {
|
|
758
|
+
case 1: // 関数値
|
|
759
|
+
val = (*arg0)(arg);
|
|
760
|
+
break;
|
|
761
|
+
case 2: // 偏微分 (partial derivative)
|
|
762
|
+
val = (*arg0)(arg, carg2);
|
|
763
|
+
delete[] carg2;
|
|
764
|
+
break;
|
|
765
|
+
case 3: // 全微分 (total derivative)
|
|
766
|
+
val = (*arg0)(arg, arg2, carg3);
|
|
767
|
+
delete[] carg3;
|
|
768
|
+
}
|
|
769
|
+
} catch (const char *c) {
|
|
770
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
771
|
+
}
|
|
772
|
+
if (K == 1)
|
|
773
|
+
vresult = rb_float_new(val[0]);
|
|
774
|
+
else {
|
|
775
|
+
vresult = rb_ary_new();
|
|
776
|
+
for (int j = 0; j < K; ++j)
|
|
777
|
+
rb_ary_push(vresult, rb_float_new(val[j]));
|
|
778
|
+
}
|
|
779
|
+
} else rb_raise(rb_eArgError, "wrong argument value");
|
|
780
|
+
return vresult;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
static VALUE
|
|
784
|
+
_wrap_pspline_sekibun(int argc, VALUE *argv, VALUE self)
|
|
785
|
+
{
|
|
786
|
+
pspline<double> *bsp;
|
|
787
|
+
VALUE vargs, vresult = Qnil;
|
|
788
|
+
|
|
789
|
+
Get_pspline(self, bsp);
|
|
790
|
+
int N = bsp->Grid();
|
|
791
|
+
int K = bsp->Unit_size();
|
|
792
|
+
|
|
793
|
+
vargs = make_list(argc, argv);
|
|
794
|
+
argc = RARRAY_LEN(vargs);
|
|
795
|
+
try {
|
|
796
|
+
if (argc == N) {
|
|
797
|
+
double s[N+1];
|
|
798
|
+
for (int i = 0; i < N; ++i)
|
|
799
|
+
s[i] = NUM2DBL(RARRAY_PTR(vargs)[i]);
|
|
800
|
+
poly<double> args(s, N);
|
|
801
|
+
poly_array<double> val = bsp->sekibun(args);
|
|
802
|
+
if (K == 1)
|
|
803
|
+
vresult = rb_float_new(val[0]);
|
|
804
|
+
else {
|
|
805
|
+
vresult = rb_ary_new();
|
|
806
|
+
for (int j = 0; j < K; ++j)
|
|
807
|
+
rb_ary_push(vresult, rb_float_new(val[j]));
|
|
808
|
+
}
|
|
809
|
+
} else rb_raise(rb_eArgError, "wrong argument Sekibun");
|
|
810
|
+
} catch (const char *c) {
|
|
811
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
812
|
+
}
|
|
813
|
+
return vresult;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
static VALUE
|
|
817
|
+
_wrap_pspline_plot(int argc, VALUE *argv, VALUE self)
|
|
818
|
+
{
|
|
819
|
+
pspline<double> *arg0;
|
|
820
|
+
VALUE vstu, varg, vdp, vjbn;
|
|
821
|
+
int arg3, *arg4 = NULL;
|
|
822
|
+
|
|
823
|
+
rb_scan_args(argc, argv, "21", &varg, &vdp, &vjbn);
|
|
824
|
+
|
|
825
|
+
Get_pspline(self, arg0);
|
|
826
|
+
int N = arg0->Grid();
|
|
827
|
+
int K = arg0->Unit_size();
|
|
828
|
+
double *arg1[N], *arg2[K];
|
|
829
|
+
arg3 = NUM2INT(vdp);
|
|
830
|
+
if (argc > 2) {
|
|
831
|
+
Check_Type(vjbn, T_ARRAY);
|
|
832
|
+
int n = RARRAY_LEN(vjbn);
|
|
833
|
+
if (n != N)
|
|
834
|
+
rb_raise(rb_eArgError, "Differential orders = %d, it should be %d", n, N);
|
|
835
|
+
arg4 = new int[N];
|
|
836
|
+
for (int i = 0; i < N; ++i)
|
|
837
|
+
arg4[i] = NUM2INT(RARRAY_PTR(vjbn)[i]);
|
|
838
|
+
}
|
|
839
|
+
Check_Type(varg, T_ARRAY);
|
|
840
|
+
N = RARRAY_LEN(varg);
|
|
841
|
+
vstu = rb_ary_new();
|
|
842
|
+
int result;
|
|
843
|
+
for (int i = 0; i < N; ++i) rb_ary_push(vstu, rb_ary_shift(varg));
|
|
844
|
+
try {
|
|
845
|
+
comb_array<double> stu = make_var(N, vstu);
|
|
846
|
+
// printf("dp = %d, jbn = %d\n", arg3, arg4);
|
|
847
|
+
// stu.print("\n");
|
|
848
|
+
result = plot<double>(*arg0, stu, arg1, arg2, arg3, arg4);
|
|
849
|
+
} catch (const char *c) {
|
|
850
|
+
rb_raise(rb_eRuntimeError, "%s", c);
|
|
851
|
+
}
|
|
852
|
+
delete[] arg4;
|
|
853
|
+
for (int i = 0; i < result; i++) {
|
|
854
|
+
VALUE v1 = rb_ary_new();
|
|
855
|
+
for (int j = 0; j < N; ++j) rb_ary_push(v1, rb_float_new(arg1[j][i]));
|
|
856
|
+
VALUE v2 = rb_ary_new();
|
|
857
|
+
for (int k = 0; k < K; ++k) rb_ary_push(v2, rb_float_new(arg2[k][i]));
|
|
858
|
+
VALUE vv = rb_ary_new();
|
|
859
|
+
rb_ary_push(vv, v1);
|
|
860
|
+
rb_ary_push(vv, v2);
|
|
861
|
+
rb_ary_push(varg, vv);
|
|
862
|
+
if (rb_block_given_p()) rb_yield(vv);
|
|
863
|
+
}
|
|
864
|
+
for (int i = 0; i < N; ++i) FREE(arg1[i]);
|
|
865
|
+
for (int i = 0; i < K; ++i) FREE(arg2[i]);
|
|
866
|
+
return INT2NUM(result);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
static void
|
|
870
|
+
_wrap_Init_pspline(void)
|
|
871
|
+
{
|
|
872
|
+
cPspline = rb_define_class_under(mPspline, "Pspline", rb_cObject);
|
|
873
|
+
rb_include_module(cPspline, rb_mEnumerable);
|
|
874
|
+
rb_define_singleton_method(cPspline, "new", VALUEFUNC(_wrap_new_pspline), -1);
|
|
875
|
+
rb_define_method(cPspline, "initialize", VALUEFUNC(_wrap_init_pspline), -1);
|
|
876
|
+
rb_define_method(cPspline, "[]", VALUEFUNC(_wrap_pspline_bracket), -1);
|
|
877
|
+
rb_define_method(cPspline, "value", VALUEFUNC(_wrap_pspline_value), -1);
|
|
878
|
+
rb_define_method(cPspline, "sekibun", VALUEFUNC(_wrap_pspline_sekibun), -1);
|
|
879
|
+
rb_define_method(cPspline, "plot", VALUEFUNC(_wrap_pspline_plot), -1);
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
#ifdef __cplusplus
|
|
883
|
+
extern "C" {
|
|
884
|
+
#endif
|
|
885
|
+
|
|
886
|
+
void Init_pspline(void)
|
|
887
|
+
{
|
|
888
|
+
mPspline = rb_define_module("PSPLINE");
|
|
889
|
+
|
|
890
|
+
_wrap_Init_bspline();
|
|
891
|
+
_wrap_Init_pspline();
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
#ifdef __cplusplus
|
|
895
|
+
}
|
|
896
|
+
#endif
|
|
897
|
+
|