carray-calculus 1.0.0
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/Rakefile +11 -0
- data/carray-calculus.gemspec +25 -0
- data/ext/Makefile +264 -0
- data/ext/carray_calculus.c +864 -0
- data/ext/carray_interp.c +357 -0
- data/ext/extconf.rb +7 -0
- data/ext/mkmf.log +24 -0
- data/lib/carray-calculus.rb +3 -0
- data/lib/carray-calculus/core.rb +119 -0
- metadata +72 -0
data/ext/carray_interp.c
ADDED
@@ -0,0 +1,357 @@
|
|
1
|
+
/* ---------------------------------------------------------------------------
|
2
|
+
|
3
|
+
carray/carray_interp.c
|
4
|
+
|
5
|
+
This file is part of Ruby/CArray extension library.
|
6
|
+
You can redistribute it and/or modify it under the terms of
|
7
|
+
the Ruby Licence.
|
8
|
+
|
9
|
+
Copyright (C) 2005 Hiroki Motoyoshi
|
10
|
+
|
11
|
+
---------------------------------------------------------------------------- */
|
12
|
+
|
13
|
+
#include "ruby.h"
|
14
|
+
#include "carray.h"
|
15
|
+
#include <math.h>
|
16
|
+
|
17
|
+
static int
|
18
|
+
find_index (ca_size_t n, double *y, double yy, ca_size_t *major, double *frac)
|
19
|
+
{
|
20
|
+
ca_size_t a, b, c, x1;
|
21
|
+
double ya, yb, yc;
|
22
|
+
double y1, y2;
|
23
|
+
|
24
|
+
if ( yy <= y[0] ) {
|
25
|
+
x1 = 0;
|
26
|
+
goto label;
|
27
|
+
}
|
28
|
+
|
29
|
+
if ( yy >= y[n-1] ) {
|
30
|
+
x1 = n-2;
|
31
|
+
goto label;
|
32
|
+
}
|
33
|
+
|
34
|
+
/* check for equally spaced scale */
|
35
|
+
|
36
|
+
a = (ca_size_t)((yy-y[0])/(y[n-1]-y[0])*(n-1));
|
37
|
+
|
38
|
+
if ( a >= 0 && a < n-1 ) {
|
39
|
+
if ( (y[a] - yy) * (y[a+1] - yy) <= 0 ) {
|
40
|
+
x1 = a;
|
41
|
+
goto label;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
/* binary section method */
|
46
|
+
|
47
|
+
a = 0;
|
48
|
+
b = n-1;
|
49
|
+
|
50
|
+
ya = y[a];
|
51
|
+
yb = y[b];
|
52
|
+
|
53
|
+
if ( ya > yb ) {
|
54
|
+
return -1; /* input scale array should have accending order */
|
55
|
+
}
|
56
|
+
|
57
|
+
while ( (b - a) >= 1 ) {
|
58
|
+
c = (a + b)/2;
|
59
|
+
yc = y[c];
|
60
|
+
if ( a == c ) {
|
61
|
+
break;
|
62
|
+
}
|
63
|
+
|
64
|
+
if ( yc == yy ) {
|
65
|
+
a = c;
|
66
|
+
break;
|
67
|
+
}
|
68
|
+
else if ( (ya - yy) * (yc - yy) <= 0 ) {
|
69
|
+
b = c;
|
70
|
+
yb = yc;
|
71
|
+
}
|
72
|
+
else {
|
73
|
+
a = c;
|
74
|
+
ya = yc;
|
75
|
+
}
|
76
|
+
|
77
|
+
if ( ya > yb ) {
|
78
|
+
return -1; /* input scale array should have accending order */
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
x1 = a;
|
83
|
+
|
84
|
+
label:
|
85
|
+
|
86
|
+
y1 = y[x1];
|
87
|
+
y2 = y[x1+1];
|
88
|
+
|
89
|
+
*major = x1;
|
90
|
+
|
91
|
+
if ( y2 - y1 == 0 ) {
|
92
|
+
*frac = 0.0;
|
93
|
+
}
|
94
|
+
else {
|
95
|
+
*frac = (yy-y1)/(y2-y1);
|
96
|
+
}
|
97
|
+
|
98
|
+
return 0;
|
99
|
+
}
|
100
|
+
|
101
|
+
|
102
|
+
/*
|
103
|
+
|
104
|
+
n-dimensional linear interpolation
|
105
|
+
|
106
|
+
y[i+fi, j+fj, ..., n+fn]
|
107
|
+
|
108
|
+
1 1 1
|
109
|
+
= Sigma Sigma ... Sigma wi[si]*wj[sj]*...*wn[sn]*y[i+si,j+sj,...,n+sn]
|
110
|
+
si=0 sj=0 sn=0
|
111
|
+
|
112
|
+
i , j, ..., n : major integer value
|
113
|
+
fi, fj, ..., fn : fractional value
|
114
|
+
|
115
|
+
wi[0] = 1-fi, wj[0] = 1-fj, ..., wn[0] = 1-fn
|
116
|
+
wi[1] = fi, wj[1] = fj, ..., wn[1] = fn
|
117
|
+
|
118
|
+
*/
|
119
|
+
|
120
|
+
static int
|
121
|
+
linear_interp_loop (CArray *ca, ca_size_t *major, double *frac,
|
122
|
+
int level, ca_size_t *idx, double wt, double *valp)
|
123
|
+
{
|
124
|
+
double tmp;
|
125
|
+
|
126
|
+
if ( level == ca->ndim-1 ) {
|
127
|
+
|
128
|
+
idx[level] = major[level];
|
129
|
+
ca_fetch_index(ca, idx, &tmp);
|
130
|
+
*valp += (1.0 - frac[level]) * wt * tmp;
|
131
|
+
|
132
|
+
idx[level] = major[level] + 1;
|
133
|
+
ca_fetch_index(ca, idx, &tmp);
|
134
|
+
*valp += frac[level] * wt * tmp;
|
135
|
+
|
136
|
+
}
|
137
|
+
else {
|
138
|
+
|
139
|
+
if ( frac[level] != 1.0 ) { /* condition for performance issue */
|
140
|
+
idx[level] = major[level];
|
141
|
+
linear_interp_loop(ca, major, frac,
|
142
|
+
level+1, idx, (1.0 - frac[level])*wt, valp);
|
143
|
+
}
|
144
|
+
|
145
|
+
if ( frac[level] != 0.0 ) { /* condition for performance issue */
|
146
|
+
idx[level] = major[level] + 1;
|
147
|
+
linear_interp_loop(ca, major, frac,
|
148
|
+
level+1, idx, frac[level]*wt, valp);
|
149
|
+
}
|
150
|
+
|
151
|
+
}
|
152
|
+
|
153
|
+
return 0;
|
154
|
+
}
|
155
|
+
|
156
|
+
static double
|
157
|
+
linear_interp (CArray *ca, ca_size_t *major, double *frac)
|
158
|
+
{
|
159
|
+
ca_size_t idx[CA_RANK_MAX];
|
160
|
+
double value = 0;
|
161
|
+
linear_interp_loop(ca, major, frac, 0, idx, 1, &value);
|
162
|
+
return value;
|
163
|
+
}
|
164
|
+
|
165
|
+
/*
|
166
|
+
|
167
|
+
If value[n] is NaN, the interpolation will be made for each index of the dimension n. So you must prepare the buffer sufficient to store these values.
|
168
|
+
|
169
|
+
*/
|
170
|
+
|
171
|
+
static int
|
172
|
+
ca_interpolate_loop (CArray *ca, double **scale,
|
173
|
+
CArray **value,
|
174
|
+
ca_size_t *major, double *frac,
|
175
|
+
int level, double **dstp)
|
176
|
+
{
|
177
|
+
double val, frc;
|
178
|
+
ca_size_t maj;
|
179
|
+
ca_size_t i;
|
180
|
+
|
181
|
+
if ( level == ca->ndim-1 ) {
|
182
|
+
if ( ! value[level] ) {
|
183
|
+
for (i=0; i<ca->dim[level]; i++) {
|
184
|
+
major[level] = i;
|
185
|
+
frac[level] = 0.0;
|
186
|
+
**dstp = linear_interp(ca, major, frac);
|
187
|
+
*dstp += 1;
|
188
|
+
}
|
189
|
+
}
|
190
|
+
else {
|
191
|
+
for (i=0; i<value[level]->elements; i++) {
|
192
|
+
ca_fetch_addr(value[level], i, &val);
|
193
|
+
find_index(ca->dim[level], scale[level], val, &maj, &frc);
|
194
|
+
major[level] = maj;
|
195
|
+
frac[level] = frc;
|
196
|
+
**dstp = linear_interp(ca, major, frac);
|
197
|
+
*dstp += 1;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
}
|
201
|
+
else {
|
202
|
+
if ( ! value[level] ) {
|
203
|
+
for (i=0; i<ca->dim[level]; i++) {
|
204
|
+
major[level] = i;
|
205
|
+
frac[level] = 0.0;
|
206
|
+
ca_interpolate_loop(ca, scale, value, major, frac, level+1, dstp);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
else {
|
210
|
+
for (i=0; i<value[level]->elements; i++) {
|
211
|
+
ca_fetch_addr(value[level], i, &val);
|
212
|
+
find_index(ca->dim[level], scale[level], val, &maj, &frc);
|
213
|
+
major[level] = maj;
|
214
|
+
frac[level] = frc;
|
215
|
+
ca_interpolate_loop(ca, scale, value, major, frac, level+1, dstp);
|
216
|
+
}
|
217
|
+
}
|
218
|
+
}
|
219
|
+
return 0; /* normal exit */
|
220
|
+
}
|
221
|
+
|
222
|
+
int
|
223
|
+
ca_interpolate (CArray *ca, double **scale, CArray **value, double *outp)
|
224
|
+
{
|
225
|
+
ca_size_t major[CA_RANK_MAX];
|
226
|
+
double frac[CA_RANK_MAX];
|
227
|
+
int status;
|
228
|
+
|
229
|
+
status = ca_interpolate_loop(ca, scale, value, major, frac, 0, &outp);
|
230
|
+
|
231
|
+
return status;
|
232
|
+
}
|
233
|
+
|
234
|
+
|
235
|
+
static VALUE
|
236
|
+
rb_ca_interpolate_bilinear (int argc, VALUE *argv, volatile VALUE self)
|
237
|
+
{
|
238
|
+
volatile VALUE vscales, vvalues, vs, out;
|
239
|
+
CArray *ca, *co, *cs;
|
240
|
+
double *scales[CA_RANK_MAX];
|
241
|
+
CArray *values[CA_RANK_MAX];
|
242
|
+
CArray *scales_ca[CA_RANK_MAX];
|
243
|
+
int8_t out_ndim;
|
244
|
+
ca_size_t out_dim[CA_RANK_MAX];
|
245
|
+
int i;
|
246
|
+
|
247
|
+
rb_scan_args(argc, argv, "2", &vscales, &vvalues);
|
248
|
+
|
249
|
+
Check_Type(vscales, T_ARRAY);
|
250
|
+
Check_Type(vvalues, T_ARRAY);
|
251
|
+
|
252
|
+
if ( RARRAY_LEN(vscales) != RARRAY_LEN(vvalues) ) {
|
253
|
+
rb_raise(rb_eArgError, "invalid number of values or scales");
|
254
|
+
}
|
255
|
+
|
256
|
+
ca = ca_wrap_readonly(self, CA_DOUBLE);
|
257
|
+
|
258
|
+
if ( ca->ndim != RARRAY_LEN(vvalues) ) {
|
259
|
+
rb_raise(rb_eArgError, "invalid number of values");
|
260
|
+
}
|
261
|
+
|
262
|
+
for (i=0; i<ca->ndim; i++) {
|
263
|
+
vs = rb_ary_entry(vscales, i);
|
264
|
+
if ( NIL_P(vs) ) {
|
265
|
+
scales[i] = NULL;
|
266
|
+
}
|
267
|
+
else {
|
268
|
+
cs = ca_wrap_readonly(vs, CA_DOUBLE);
|
269
|
+
scales_ca[i] = cs;
|
270
|
+
ca_attach(cs);
|
271
|
+
scales[i] = (double *) cs->ptr;
|
272
|
+
rb_ary_store(vscales, i, vs);
|
273
|
+
}
|
274
|
+
}
|
275
|
+
|
276
|
+
out_ndim = 0;
|
277
|
+
for (i=0; i<ca->ndim; i++) {
|
278
|
+
vs = rb_ary_entry(vvalues, i);
|
279
|
+
if ( NIL_P(vs) ) {
|
280
|
+
out_dim[out_ndim++] = ca->dim[i];
|
281
|
+
values[i] = NULL;
|
282
|
+
}
|
283
|
+
else {
|
284
|
+
values[i] = ca_wrap_readonly(vs, CA_DOUBLE);
|
285
|
+
if ( values[i]->obj_type != CA_OBJ_SCALAR ) {
|
286
|
+
out_dim[out_ndim++] = values[i]->elements;
|
287
|
+
}
|
288
|
+
rb_ary_store(vvalues, i, vs);
|
289
|
+
}
|
290
|
+
}
|
291
|
+
|
292
|
+
if ( out_ndim == 0 ) {
|
293
|
+
out = rb_cscalar_new(CA_DOUBLE, 0, NULL);
|
294
|
+
}
|
295
|
+
else {
|
296
|
+
out = rb_carray_new(CA_DOUBLE, out_ndim, out_dim, 0, NULL);
|
297
|
+
}
|
298
|
+
|
299
|
+
Data_Get_Struct(out, CArray, co);
|
300
|
+
|
301
|
+
for (i=0; i<ca->ndim; i++) {
|
302
|
+
if ( values[i] ) {
|
303
|
+
ca_attach(values[i]);
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
ca_attach(ca);
|
308
|
+
ca_interpolate(ca, scales, values, (double*) co->ptr);
|
309
|
+
ca_detach(ca);
|
310
|
+
|
311
|
+
for (i=0; i<ca->ndim; i++) {
|
312
|
+
if ( values[i] ) {
|
313
|
+
ca_detach(values[i]);
|
314
|
+
}
|
315
|
+
if ( scales[i] ) {
|
316
|
+
ca_detach(scales_ca[i]);
|
317
|
+
}
|
318
|
+
}
|
319
|
+
|
320
|
+
if ( out_ndim == 0 ) {
|
321
|
+
return rb_ca_fetch_addr(out, 0);
|
322
|
+
}
|
323
|
+
else {
|
324
|
+
return out;
|
325
|
+
}
|
326
|
+
}
|
327
|
+
|
328
|
+
void
|
329
|
+
Init_carray_interpolate ()
|
330
|
+
{
|
331
|
+
rb_define_method(rb_cCArray, "interp_nd_linear",
|
332
|
+
rb_ca_interpolate_bilinear, -1);
|
333
|
+
}
|
334
|
+
|
335
|
+
/*
|
336
|
+
|
337
|
+
scales = [nil, nil, sza, vza, saz]
|
338
|
+
values = [nil, nil, 60, 60, 120]
|
339
|
+
brdf.interp_linear_nd(scales, values)
|
340
|
+
|
341
|
+
interp_1d_linear
|
342
|
+
interp_1d_parabolic
|
343
|
+
interp_1d_cubic
|
344
|
+
interp_1d_akima
|
345
|
+
interp_1d_akima2
|
346
|
+
interp_1d_curv
|
347
|
+
|
348
|
+
interp_2d_natgrid
|
349
|
+
interp_2d_fitpack
|
350
|
+
interp_nd_linear
|
351
|
+
|
352
|
+
gridding_2d_natgrid
|
353
|
+
|
354
|
+
|
355
|
+
*/
|
356
|
+
|
357
|
+
|
data/ext/extconf.rb
ADDED
data/ext/mkmf.log
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
have_header: checking for carray.h... -------------------- yes
|
2
|
+
|
3
|
+
"clang -o conftest -I/Users/himotoyoshi/.rbenv/versions/2.4.2/include/ruby-2.4.0/x86_64-darwin16 -I/Users/himotoyoshi/.rbenv/versions/2.4.2/include/ruby-2.4.0/ruby/backward -I/Users/himotoyoshi/.rbenv/versions/2.4.2/include/ruby-2.4.0 -I. -I/Users/himotoyoshi/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/carray-1.5.0/lib -I/Users/himotoyoshi/.rbenv/versions/2.4.2/include -I/usr/local/opt/qt/include: -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens -pipe conftest.c -L. -L/Users/himotoyoshi/.rbenv/versions/2.4.2/lib -L/Users/himotoyoshi/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/carray-1.5.0/lib -L. -L/Users/himotoyoshi/.rbenv/versions/2.4.2/lib -L/usr/local/opt/qt/lib: -fstack-protector -L/usr/local/lib -lruby-static -framework CoreFoundation -lpthread -lgmp -ldl -lobjc "
|
4
|
+
ld: warning: directory not found for option '-L/usr/local/opt/qt/lib:'
|
5
|
+
checked program was:
|
6
|
+
/* begin */
|
7
|
+
1: #include "ruby.h"
|
8
|
+
2:
|
9
|
+
3: int main(int argc, char **argv)
|
10
|
+
4: {
|
11
|
+
5: return 0;
|
12
|
+
6: }
|
13
|
+
/* end */
|
14
|
+
|
15
|
+
"clang -E -I/Users/himotoyoshi/.rbenv/versions/2.4.2/include/ruby-2.4.0/x86_64-darwin16 -I/Users/himotoyoshi/.rbenv/versions/2.4.2/include/ruby-2.4.0/ruby/backward -I/Users/himotoyoshi/.rbenv/versions/2.4.2/include/ruby-2.4.0 -I. -I/Users/himotoyoshi/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/carray-1.5.0/lib -I/Users/himotoyoshi/.rbenv/versions/2.4.2/include -I/usr/local/opt/qt/include: -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -D_DARWIN_UNLIMITED_SELECT -D_REENTRANT -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wno-tautological-compare -Wno-parentheses-equality -Wno-constant-logical-operand -Wno-self-assign -Wunused-variable -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wshorten-64-to-32 -Wimplicit-function-declaration -Wdivision-by-zero -Wdeprecated-declarations -Wextra-tokens -pipe conftest.c -o conftest.i"
|
16
|
+
checked program was:
|
17
|
+
/* begin */
|
18
|
+
1: #include "ruby.h"
|
19
|
+
2:
|
20
|
+
3: #include <carray.h>
|
21
|
+
/* end */
|
22
|
+
|
23
|
+
--------------------
|
24
|
+
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# ----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# carray/base/calculus.rb
|
4
|
+
#
|
5
|
+
# This file is part of Ruby/CArray extension library.
|
6
|
+
# You can redistribute it and/or modify it under the terms of
|
7
|
+
# the Ruby Licence.
|
8
|
+
#
|
9
|
+
# Copyright (C) 2005 Hiroki Motoyoshi
|
10
|
+
#
|
11
|
+
# ----------------------------------------------------------------------------
|
12
|
+
|
13
|
+
class CArray
|
14
|
+
|
15
|
+
def normalize (scale = nil)
|
16
|
+
if scale
|
17
|
+
return self / self.integrate(scale)
|
18
|
+
else
|
19
|
+
return self / self.sum
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def normalize! (scale = nil)
|
24
|
+
self[] = normalize(scale)
|
25
|
+
return self
|
26
|
+
end
|
27
|
+
|
28
|
+
def solve (sc, val, type: "cubic", eps: 100 * Float::EPSILON)
|
29
|
+
func = self - val
|
30
|
+
list, output = [], []
|
31
|
+
(0...dim0-1).each do |i|
|
32
|
+
if func[i] == UNDEF
|
33
|
+
elsif func[i].abs < eps and not list.include?(i-1)
|
34
|
+
output.push(sc[i])
|
35
|
+
elsif func[i+1] == UNDEF
|
36
|
+
elsif i < dim0 - 1 and func[i]*func[i+1] < 0
|
37
|
+
list.push(i)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
list.each do |i|
|
41
|
+
sx = CArray.double(4)
|
42
|
+
sy = CArray.double(4)
|
43
|
+
sx[0], sx[3] = sc[i], sc[i+1]
|
44
|
+
sy[0], sy[3] = func[i], func[i+1]
|
45
|
+
sx[1], sx[2] = (2.0*sx[0]+sx[3])/3.0, (sx[0]+2.0*sx[3])/3.0
|
46
|
+
sy[1], sy[2] = func.interpolate(sc, sx[1], type: type), func.interpolate(sc, sx[2], type: type)
|
47
|
+
output.push(sx.interpolate(sy, 0, type: type))
|
48
|
+
end
|
49
|
+
return output.uniq
|
50
|
+
end
|
51
|
+
|
52
|
+
def solve2 (sc, eps: 100 * Float::EPSILON)
|
53
|
+
retvals = []
|
54
|
+
self.dim1.times do |j|
|
55
|
+
func = self[nil,j].to_ca
|
56
|
+
list, output = [], []
|
57
|
+
(0...dim0-1).each do |i|
|
58
|
+
if func[i] == UNDEF
|
59
|
+
elsif func[i].abs < eps and not list.include?(i-1)
|
60
|
+
output.push(sc[i])
|
61
|
+
elsif func[i+1] == UNDEF
|
62
|
+
elsif i < dim0 - 1 and func[i]*func[i+1] < 0
|
63
|
+
list.push(i)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
list.each do |i|
|
67
|
+
sx = CArray.double(4)
|
68
|
+
sy = CArray.double(4)
|
69
|
+
sx[0], sx[3] = sc[i], sc[i+1]
|
70
|
+
sy[0], sy[3] = func[i], func[i+1]
|
71
|
+
sx[1], sx[2] = (2*sx[0]+sx[3])/3, (sx[0]+2*sx[3])/3
|
72
|
+
sy[1], sy[2] = func.interpolate(sc, sx[1], :type=>"linear"), func.interpolate(sc, sx[2], :type=>"linear")
|
73
|
+
output.push(sx.interpolate(sy, 0))
|
74
|
+
end
|
75
|
+
retvals << output.uniq
|
76
|
+
end
|
77
|
+
retvals = retvals.map{|s| s.empty? ? [nil] : s}
|
78
|
+
return retvals
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def _interpolate2 (x, y, x0, y0)
|
84
|
+
case x.size
|
85
|
+
when 1
|
86
|
+
return self[0, nil].interpolate(y, y0)
|
87
|
+
when 2, 3
|
88
|
+
return self[:i,nil].interpolate(y, y0).interpolate(x, x0)
|
89
|
+
end
|
90
|
+
ri = x.section(x0)
|
91
|
+
i0 = ri.floor - 1
|
92
|
+
if i0 < 0
|
93
|
+
i0 = 0
|
94
|
+
elsif i0 + 3 > x.size - 1
|
95
|
+
i0 = x.size - 4
|
96
|
+
end
|
97
|
+
return self[i0..i0+3,nil][:i,nil].interpolate(y, y0).
|
98
|
+
interpolate(x[i0..i0+3],x0)
|
99
|
+
end
|
100
|
+
|
101
|
+
public
|
102
|
+
|
103
|
+
def interpolate2 (x, y, x0, y0)
|
104
|
+
if x0.is_a?(Numeric) and y0.is_a?(Numeric)
|
105
|
+
return _interpolate2(x, y, x0, y0)
|
106
|
+
else
|
107
|
+
x0 = CArray.wrap_readonly(x0)
|
108
|
+
y0 = CArray.wrap_readonly(y0)
|
109
|
+
out = CArray.double(x0.size, y0.size)
|
110
|
+
x0.each_with_index do |xi, i|
|
111
|
+
y0.each_with_index do |yj, j|
|
112
|
+
out[i,j] = _interpolate2(x, y, xi, yj)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
return out.compact
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|