gsl 2.1.0.1 → 2.1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/ChangeLog +8 -0
- data/ext/gsl_native/complex.c +11 -1
- data/ext/gsl_native/error.c +2 -2
- data/ext/gsl_native/gsl.c +4 -0
- data/ext/gsl_native/include/rb_gsl.h +6 -0
- data/ext/gsl_native/include/rb_gsl_interp2d.h +40 -0
- data/ext/gsl_native/interp2d.c +266 -0
- data/ext/gsl_native/spline2d.c +211 -0
- data/lib/gsl.rb +3 -2
- data/lib/gsl/interp2d_fix.rb +64 -0
- data/lib/gsl/version.rb +1 -1
- data/rdoc/interp2d.rdoc +0 -0
- data/test/gsl/complex_test.rb +12 -1
- data/test/gsl/interp2d_test.rb +108 -0
- data/test/gsl/spline2d_test.rb +81 -0
- metadata +168 -158
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 867207d0bcbf91b9e09347e0ff88f94e33eb25c0
|
4
|
+
data.tar.gz: 49cb32046c2852fee2d42af5626842a4c9564d86
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca492e6d20fd79de8c8f9c902083876f9d987923673a9f8575cad9a9f13ae059785ee84c4af08473b2fdf1eacb17a374fd4e6764f25ece46d0ee0a212182a91a
|
7
|
+
data.tar.gz: ada482645b5ce72b16c27b79915378942599d90b9b7ef18d7636f4da50d7439d7d71fdd9d486430017896be64c802250db8f14f8bbb4c99e760263d8f2ff0874
|
data/.travis.yml
CHANGED
data/ChangeLog
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# markup: rd
|
2
2
|
|
3
|
+
== Mon January 30 2017
|
4
|
+
- Enhancements
|
5
|
+
* Support for assigning Ruby Complex types to GSL::Matrix::Complex. (@v0dro)
|
6
|
+
* Support for 2D interpolation by exposing GSLs interp2d and spline2d. (@v0dro)
|
7
|
+
* Support for Ruby 2.4. (@badlamer)
|
8
|
+
- Fixes
|
9
|
+
* Fix NArray superclass mismatch problem. (@v0dro)
|
10
|
+
|
3
11
|
== Fri March 4 2016
|
4
12
|
* Added compatibility for NMatrix interconversion with GSL::Vector and GSL::Matrix
|
5
13
|
* Added NMatrix compatibility to various to make them compatible with NMatrix data types.
|
data/ext/gsl_native/complex.c
CHANGED
@@ -41,6 +41,11 @@ gsl_complex rb_gsl_obj_to_gsl_complex(VALUE obj, gsl_complex *z)
|
|
41
41
|
if (!NIL_P(vre)) GSL_SET_REAL(z, NUM2DBL(vre));
|
42
42
|
if (!NIL_P(vim)) GSL_SET_IMAG(z, NUM2DBL(vim));
|
43
43
|
break;
|
44
|
+
case T_COMPLEX:
|
45
|
+
vre = rb_funcall(obj, rb_intern("real"), 0);
|
46
|
+
vim = rb_funcall(obj, rb_intern("imag"), 0);
|
47
|
+
*z = gsl_complex_rect(NUM2DBL(vre), NUM2DBL(vim));
|
48
|
+
break;
|
44
49
|
case T_FLOAT:
|
45
50
|
case T_FIXNUM:
|
46
51
|
case T_BIGNUM:
|
@@ -63,7 +68,7 @@ gsl_complex rb_gsl_obj_to_gsl_complex(VALUE obj, gsl_complex *z)
|
|
63
68
|
static VALUE rb_gsl_complex_new(int argc, VALUE *argv, VALUE klass)
|
64
69
|
{
|
65
70
|
gsl_complex *c = NULL;
|
66
|
-
VALUE obj;
|
71
|
+
VALUE obj, vre, vim;
|
67
72
|
obj = Data_Make_Struct(klass, gsl_complex, 0, free, c);
|
68
73
|
switch (argc) {
|
69
74
|
case 1:
|
@@ -71,6 +76,11 @@ static VALUE rb_gsl_complex_new(int argc, VALUE *argv, VALUE klass)
|
|
71
76
|
case T_ARRAY:
|
72
77
|
*c = ary2complex(argv[0]);
|
73
78
|
break;
|
79
|
+
case T_COMPLEX:
|
80
|
+
vre = rb_funcall(argv[0], rb_intern("real"), 0);
|
81
|
+
vim = rb_funcall(argv[0], rb_intern("imag"), 0);
|
82
|
+
*c = gsl_complex_rect(NUM2DBL(vre), NUM2DBL(vim));
|
83
|
+
break;
|
74
84
|
case T_FLOAT:
|
75
85
|
case T_FIXNUM:
|
76
86
|
case T_BIGNUM:
|
data/ext/gsl_native/error.c
CHANGED
@@ -80,9 +80,9 @@ static void rb_gsl_define_exceptions(VALUE module)
|
|
80
80
|
VALUE mgsl_error;
|
81
81
|
mgsl_error = rb_define_module_under(module, "ERROR");
|
82
82
|
pgsl_error = &cgsl_error[2];
|
83
|
-
pgsl_error[-2] = rb_define_class_under(mgsl_error, "CONTINUE",
|
83
|
+
pgsl_error[-2] = rb_define_class_under(mgsl_error, "CONTINUE", rb_cInteger);
|
84
84
|
pgsl_error[-1] = rb_define_class_under(mgsl_error, "FAILURE", rb_eRuntimeError);
|
85
|
-
pgsl_error[0] = rb_define_class_under(mgsl_error, "SUCCESS",
|
85
|
+
pgsl_error[0] = rb_define_class_under(mgsl_error, "SUCCESS", rb_cInteger);
|
86
86
|
pgsl_error[1] = rb_define_class_under(mgsl_error, "EDOM", rb_eRangeError);
|
87
87
|
pgsl_error[2] = rb_define_class_under(mgsl_error, "ERANGE", rb_eRangeError);
|
88
88
|
pgsl_error[3] = rb_define_class_under(mgsl_error, "EFAULT", rb_eRuntimeError);
|
data/ext/gsl_native/gsl.c
CHANGED
@@ -118,6 +118,10 @@ void Init_gsl_native()
|
|
118
118
|
|
119
119
|
Init_gsl_odeiv(mgsl);
|
120
120
|
Init_gsl_interp(mgsl);
|
121
|
+
#ifdef GSL_2_0_LATER
|
122
|
+
Init_gsl_interp2d(mgsl);
|
123
|
+
Init_gsl_spline2d(mgsl);
|
124
|
+
#endif
|
121
125
|
Init_gsl_spline(mgsl);
|
122
126
|
Init_gsl_diff(mgsl);
|
123
127
|
Init_gsl_deriv(mgsl);
|
@@ -66,6 +66,12 @@ void Init_gsl_siman(VALUE module);
|
|
66
66
|
void Init_gsl_odeiv(VALUE module);
|
67
67
|
void Init_gsl_interp(VALUE module);
|
68
68
|
void Init_gsl_spline(VALUE module);
|
69
|
+
|
70
|
+
#ifdef GSL_2_0_LATER
|
71
|
+
void Init_gsl_interp2d(VALUE module);
|
72
|
+
void Init_gsl_spline2d(VALUE module);
|
73
|
+
#endif
|
74
|
+
|
69
75
|
void Init_gsl_diff(VALUE module);
|
70
76
|
void Init_gsl_deriv(VALUE module);
|
71
77
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
/*
|
2
|
+
rb_gsl_interp2d.h
|
3
|
+
Ruby/GSL: Ruby extension library for GSL (GNU Scientific Library)
|
4
|
+
(C) Copyright 2001-2004 by Yoshiki Tsunesada
|
5
|
+
(C) Copyright 2015 - by Ruby Science Foundation
|
6
|
+
|
7
|
+
Ruby/GSL is free software: you can redistribute it and/or modify it
|
8
|
+
under the terms of the GNU General Public License.
|
9
|
+
This library is distributed in the hope that it will be useful, but
|
10
|
+
WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
MERCHANTABILITY or INTERPOLATIONNESS FOR A PARTICULAR PURPOSE.
|
12
|
+
*/
|
13
|
+
#ifdef GSL_2_0_LATER
|
14
|
+
#ifndef ___RB_GSL_INTERP2D_H___
|
15
|
+
#define ___RB_GSL_INTERP2D_H___
|
16
|
+
|
17
|
+
#include "rb_gsl.h"
|
18
|
+
#include <gsl/gsl_interp2d.h>
|
19
|
+
#include <gsl/gsl_spline2d.h>
|
20
|
+
|
21
|
+
typedef struct {
|
22
|
+
gsl_interp2d *p;
|
23
|
+
gsl_interp_accel *xacc, *yacc;
|
24
|
+
} rb_gsl_interp2d;
|
25
|
+
|
26
|
+
typedef struct {
|
27
|
+
gsl_spline2d *s;
|
28
|
+
gsl_interp_accel *xacc, *yacc;
|
29
|
+
} rb_gsl_spline2d;
|
30
|
+
|
31
|
+
enum {
|
32
|
+
GSL_INTERP2D_BICUBIC,
|
33
|
+
GSL_INTERP2D_BILINEAR
|
34
|
+
};
|
35
|
+
|
36
|
+
const gsl_interp2d_type* get_interp2d_type(VALUE);
|
37
|
+
static void rb_gsl_interp2d_free(rb_gsl_interp2d*);
|
38
|
+
|
39
|
+
#endif
|
40
|
+
#endif
|
@@ -0,0 +1,266 @@
|
|
1
|
+
/*
|
2
|
+
interp2d.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
|
+
#ifdef GSL_2_0_LATER
|
12
|
+
#include "include/rb_gsl_interp2d.h"
|
13
|
+
|
14
|
+
VALUE cgsl_interp2d_accel; /* this is used also in spline2d.c */
|
15
|
+
EXTERN VALUE cgsl_vector, cgsl_matrix;
|
16
|
+
|
17
|
+
static VALUE rb_gsl_interp2d_alloc(int argc, VALUE *argv, VALUE self)
|
18
|
+
{
|
19
|
+
rb_gsl_interp2d *sp = NULL;
|
20
|
+
const gsl_interp2d_type *T = NULL;
|
21
|
+
double *xptr = NULL, *yptr = NULL, *zptr = NULL;
|
22
|
+
size_t sizex = 0, sizey = 0, sizez = 0, stride = 1;
|
23
|
+
|
24
|
+
T = get_interp2d_type(argv[0]);
|
25
|
+
if (argc == 3) { // type, sizex, sizey
|
26
|
+
sizex = FIX2INT(argv[1]);
|
27
|
+
sizey = FIX2INT(argv[2]);
|
28
|
+
}
|
29
|
+
else if (argc == 4) { // type, xarr, yarr, zarr
|
30
|
+
xptr = get_vector_ptr(argv[1], &stride, &sizex);
|
31
|
+
yptr = get_vector_ptr(argv[2], &stride, &sizey);
|
32
|
+
zptr = get_vector_ptr(argv[3], &stride, &sizez);
|
33
|
+
}
|
34
|
+
else {
|
35
|
+
rb_raise(rb_eRuntimeError, "Expected args: (type, xn, yn) \
|
36
|
+
or (type, xarr, yarr, zarr");
|
37
|
+
}
|
38
|
+
|
39
|
+
if (sizex == 0 || sizey == 0) rb_raise(rb_eRuntimeError, "Interp2d size not given.");
|
40
|
+
sp = ALLOC(rb_gsl_interp2d);
|
41
|
+
sp->p = gsl_interp2d_alloc(T, sizex, sizey);
|
42
|
+
sp->xacc = gsl_interp_accel_alloc();
|
43
|
+
sp->yacc = gsl_interp_accel_alloc();
|
44
|
+
|
45
|
+
if (xptr && yptr && zptr) gsl_interp2d_init(sp->p, xptr, yptr, zptr, sizex, sizey);
|
46
|
+
|
47
|
+
return Data_Wrap_Struct(self, 0, rb_gsl_interp2d_free, sp);
|
48
|
+
}
|
49
|
+
|
50
|
+
static VALUE rb_gsl_interp2d_init(VALUE self, VALUE xarr, VALUE yarr, VALUE zarr)
|
51
|
+
{
|
52
|
+
rb_gsl_interp2d *rgi = NULL;
|
53
|
+
double *xptr = NULL, *yptr = NULL, *zptr = NULL;
|
54
|
+
size_t xsize, ysize, zsize, stride;
|
55
|
+
xptr = get_vector_ptr(xarr, &stride, &xsize);
|
56
|
+
yptr = get_vector_ptr(yarr, &stride, &ysize);
|
57
|
+
zptr = get_vector_ptr(zarr, &stride, &zsize);
|
58
|
+
|
59
|
+
Data_Get_Struct(self, rb_gsl_interp2d, rgi);
|
60
|
+
gsl_interp2d_init(rgi->p, xptr, yptr, zptr, xsize, ysize);
|
61
|
+
|
62
|
+
return self;
|
63
|
+
}
|
64
|
+
|
65
|
+
static VALUE rb_gsl_interp_evaluate(
|
66
|
+
VALUE self, VALUE xarr, VALUE yarr, VALUE zarr, VALUE xx, VALUE yy,
|
67
|
+
double (*eval)(const gsl_interp2d * interp,
|
68
|
+
const double xa[], const double ya[], const double za[],
|
69
|
+
const double x, const double y, gsl_interp_accel * xacc,
|
70
|
+
gsl_interp_accel * yacc))
|
71
|
+
{
|
72
|
+
VALUE is_swapped = rb_cvar_get(CLASS_OF(self), rb_intern("@@swapped"));
|
73
|
+
VALUE temp;
|
74
|
+
|
75
|
+
if (is_swapped != Qnil && is_swapped == Qtrue) {
|
76
|
+
temp = xx;
|
77
|
+
xx = yy;
|
78
|
+
yy = temp;
|
79
|
+
}
|
80
|
+
|
81
|
+
rb_gsl_interp2d *rgi = NULL;
|
82
|
+
double *xptr = NULL, *yptr = NULL, *zptr = NULL;
|
83
|
+
gsl_vector *vx = NULL, *vy = NULL, *vnew = NULL;
|
84
|
+
gsl_matrix *mx = NULL, *my = NULL, *mnew = NULL;
|
85
|
+
VALUE ary, x, y;
|
86
|
+
double val;
|
87
|
+
size_t i, j, xsize, ysize, zsize, stridex, stridey, stridez;
|
88
|
+
|
89
|
+
Data_Get_Struct(self, rb_gsl_interp2d, rgi);
|
90
|
+
xptr = get_vector_ptr(xarr, &stridex, &xsize);
|
91
|
+
if (xsize != rgi->p->xsize ) {
|
92
|
+
rb_raise(rb_eTypeError, "size mismatch (xa:%d != %d)", (int) xsize,
|
93
|
+
(int) rgi->p->xsize);
|
94
|
+
}
|
95
|
+
|
96
|
+
yptr = get_vector_ptr(yarr, &stridey, &ysize);
|
97
|
+
if (ysize != rgi->p->ysize ) {
|
98
|
+
rb_raise(rb_eTypeError, "size mismatch (ya:%d != %d)", (int) ysize,
|
99
|
+
(int) rgi->p->ysize);
|
100
|
+
}
|
101
|
+
|
102
|
+
zptr = get_vector_ptr(zarr, &stridez, &zsize);
|
103
|
+
if (zsize != xsize*ysize ) {
|
104
|
+
rb_raise(rb_eTypeError, "size mismatch (za:%d != %d)", (int) zsize,
|
105
|
+
(int) xsize*ysize);
|
106
|
+
}
|
107
|
+
|
108
|
+
if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
|
109
|
+
if (CLASS_OF(yy) == rb_cRange) yy = rb_gsl_range2ary(yy);
|
110
|
+
|
111
|
+
if (TYPE(xx) != TYPE(yy)) {
|
112
|
+
rb_raise(rb_eTypeError,"xx and yy must be same type. xx = %d yy = %d.",
|
113
|
+
TYPE(xx), TYPE(yy));
|
114
|
+
}
|
115
|
+
|
116
|
+
switch (TYPE(xx)) {
|
117
|
+
case T_FIXNUM: case T_BIGNUM: case T_FLOAT:
|
118
|
+
Need_Float(xx);
|
119
|
+
return rb_float_new((*eval)(rgi->p, xptr, yptr, zptr, NUM2DBL(xx), NUM2DBL(yy),
|
120
|
+
rgi->xacc, rgi->yacc));
|
121
|
+
case T_ARRAY:
|
122
|
+
if (RARRAY_LEN(xx) != RARRAY_LEN(yy)) {
|
123
|
+
rb_raise(rb_eRuntimeError, "xx and yy must be same sized Array.");
|
124
|
+
}
|
125
|
+
ary = rb_ary_new2(RARRAY_LEN(xx));
|
126
|
+
|
127
|
+
for (i = 0; i < (unsigned)RARRAY_LEN(xx); i++) {
|
128
|
+
x = rb_ary_entry(xx, i);
|
129
|
+
y = rb_ary_entry(yy, i);
|
130
|
+
Need_Float(x);
|
131
|
+
Need_Float(y);
|
132
|
+
|
133
|
+
val = (*eval)(rgi->p, xptr, yptr, zptr, NUM2DBL(x), NUM2DBL(y), rgi->xacc,
|
134
|
+
rgi->yacc);
|
135
|
+
rb_ary_store(ary, i, rb_float_new(val));
|
136
|
+
}
|
137
|
+
return ary;
|
138
|
+
default:
|
139
|
+
if (VECTOR_P(xx)) {
|
140
|
+
Data_Get_Struct(xx, gsl_vector, vx);
|
141
|
+
Data_Get_Struct(yy, gsl_vector, vy);
|
142
|
+
if (vx->size != vy->size) {
|
143
|
+
rb_raise(rb_eRuntimeError, "xx and yy must be same sized Vectors.");
|
144
|
+
}
|
145
|
+
vnew = gsl_vector_alloc(vx->size);
|
146
|
+
|
147
|
+
for (i = 0; i < vx->size; i++) {
|
148
|
+
val = (*eval)(rgi->p, xptr, yptr, zptr, gsl_vector_get(vx, i),
|
149
|
+
gsl_vector_get(vy, i), rgi->xacc, rgi->yacc);
|
150
|
+
gsl_vector_set(vnew, i, val);
|
151
|
+
}
|
152
|
+
return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew);
|
153
|
+
} else if (MATRIX_P(xx)) {
|
154
|
+
Data_Get_Struct(xx, gsl_matrix, mx);
|
155
|
+
Data_Get_Struct(xx, gsl_matrix, my);
|
156
|
+
|
157
|
+
if ((mx->size1 != my->size1) || (mx->size2 != my->size2)) {
|
158
|
+
rb_raise(rb_eRuntimeError, "xx and yy must be same sized Matrices.");
|
159
|
+
}
|
160
|
+
mnew = gsl_matrix_alloc(mx->size1, mx->size2);
|
161
|
+
for (i = 0; i < mx->size1; i++) {
|
162
|
+
for (j = 0; j < mx->size2; j++) {
|
163
|
+
val = (*eval)(rgi->p, xptr, yptr, zptr, gsl_matrix_get(mx, i, j),
|
164
|
+
gsl_matrix_get(my, i, j), rgi->xacc, rgi->yacc);
|
165
|
+
gsl_matrix_set(mnew, i, j, val);
|
166
|
+
}
|
167
|
+
}
|
168
|
+
return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew);
|
169
|
+
} else {
|
170
|
+
rb_raise(rb_eTypeError, "wrong argument type %s", rb_class2name(CLASS_OF(xx)));
|
171
|
+
}
|
172
|
+
}
|
173
|
+
}
|
174
|
+
|
175
|
+
static VALUE rb_gsl_interp2d_eval(VALUE self, VALUE xarr, VALUE yarr, VALUE zarr,
|
176
|
+
VALUE xx, VALUE yy)
|
177
|
+
{
|
178
|
+
return rb_gsl_interp_evaluate(self, xarr, yarr, zarr, xx, yy, gsl_interp2d_eval);
|
179
|
+
}
|
180
|
+
|
181
|
+
/*
|
182
|
+
Function that is called by the Ruby GC for cleaning up this structure.
|
183
|
+
*/
|
184
|
+
static void rb_gsl_interp2d_free(rb_gsl_interp2d *fr)
|
185
|
+
{
|
186
|
+
gsl_interp2d_free(fr->p);
|
187
|
+
gsl_interp_accel_free(fr->xacc);
|
188
|
+
gsl_interp_accel_free(fr->yacc);
|
189
|
+
free((rb_gsl_interp2d*) fr);
|
190
|
+
}
|
191
|
+
|
192
|
+
/*
|
193
|
+
Define constants for deciding type of interpolation.
|
194
|
+
*/
|
195
|
+
static void rb_gsl_interp2d_define_const(VALUE self)
|
196
|
+
{
|
197
|
+
rb_define_const(self, "BICUBIC", INT2FIX(GSL_INTERP2D_BICUBIC));
|
198
|
+
rb_define_const(self, "BILINEAR", INT2FIX(GSL_INTERP2D_BILINEAR));
|
199
|
+
}
|
200
|
+
|
201
|
+
const gsl_interp2d_type* get_interp2d_type(VALUE t)
|
202
|
+
{
|
203
|
+
int type;
|
204
|
+
char name[32];
|
205
|
+
|
206
|
+
switch(TYPE(t)) {
|
207
|
+
case T_FIXNUM:
|
208
|
+
type = FIX2INT(t);
|
209
|
+
|
210
|
+
switch (type) {
|
211
|
+
case 0: return gsl_interp2d_bicubic; break;
|
212
|
+
case 1: return gsl_interp2d_bilinear; break;
|
213
|
+
default:
|
214
|
+
rb_raise(rb_eRuntimeError, "Cannot recognize type %d.\n", type);
|
215
|
+
}
|
216
|
+
case T_STRING:
|
217
|
+
strcpy(name, STR2CSTR(t));
|
218
|
+
|
219
|
+
if (str_tail_grep("bicubic", name) == 0) {
|
220
|
+
return gsl_interp2d_bicubic;
|
221
|
+
}
|
222
|
+
else if (str_tail_grep("bicubic", name) == 0) {
|
223
|
+
return gsl_interp2d_bilinear;
|
224
|
+
}
|
225
|
+
else {
|
226
|
+
rb_raise(rb_eRuntimeError, "Cannot recognize type %s.\n", name);
|
227
|
+
}
|
228
|
+
default:
|
229
|
+
rb_raise(rb_eRuntimeError, "Unknown type.");
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
static VALUE rb_gsl_interp2d_info(VALUE self)
|
234
|
+
{
|
235
|
+
rb_gsl_interp2d *p;
|
236
|
+
char buf[256];
|
237
|
+
Data_Get_Struct(self, rb_gsl_interp2d, p);
|
238
|
+
sprintf(buf, "Class: %s\n", rb_class2name(CLASS_OF(self)));
|
239
|
+
sprintf(buf, "%sSuperClass: %s\n", buf, rb_class2name(RCLASS_SUPER(CLASS_OF(self))));
|
240
|
+
sprintf(buf, "%sType: %s\n", buf, gsl_interp2d_name(p->p));
|
241
|
+
sprintf(buf, "%sxmin: %f\n", buf, p->p->xmin);
|
242
|
+
sprintf(buf, "%sxmax: %f\n", buf, p->p->xmax);
|
243
|
+
sprintf(buf, "%symin: %f\n", buf, p->p->ymin);
|
244
|
+
sprintf(buf, "%symax: %f\n", buf, p->p->ymax);
|
245
|
+
sprintf(buf, "%sxsize: %d\n", buf, (int) p->p->xsize);
|
246
|
+
sprintf(buf, "%sysize: %d\n", buf, (int) p->p->ysize);
|
247
|
+
|
248
|
+
return rb_str_new2(buf);
|
249
|
+
}
|
250
|
+
|
251
|
+
void Init_gsl_interp2d(VALUE module)
|
252
|
+
{
|
253
|
+
VALUE cgsl_interp2d;
|
254
|
+
|
255
|
+
cgsl_interp2d = rb_define_class_under(module, "Interp2d", cGSL_Object);
|
256
|
+
cgsl_interp2d_accel = rb_define_class_under(cgsl_interp2d, "Accel", cGSL_Object);
|
257
|
+
|
258
|
+
rb_define_singleton_method(cgsl_interp2d, "alloc", rb_gsl_interp2d_alloc, -1);
|
259
|
+
rb_gsl_interp2d_define_const(cgsl_interp2d);
|
260
|
+
|
261
|
+
rb_define_method(cgsl_interp2d, "init", rb_gsl_interp2d_init, 3);
|
262
|
+
rb_define_method(cgsl_interp2d, "eval", rb_gsl_interp2d_eval, 5);
|
263
|
+
rb_define_method(cgsl_interp2d, "info", rb_gsl_interp2d_info, 0);
|
264
|
+
}
|
265
|
+
|
266
|
+
#endif
|
@@ -0,0 +1,211 @@
|
|
1
|
+
/*
|
2
|
+
spline2d.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
|
+
#ifdef GSL_2_0_LATER
|
12
|
+
#include "include/rb_gsl_interp2d.h"
|
13
|
+
|
14
|
+
EXTERN VALUE cgsl_interp2d_accel; /* defined in interp2d.c */
|
15
|
+
static void rb_gsl_spline2d_free(rb_gsl_spline2d *fr);
|
16
|
+
|
17
|
+
static VALUE rb_gsl_spline2d_alloc(int argc, VALUE *argv, VALUE self)
|
18
|
+
{
|
19
|
+
rb_gsl_spline2d *sp = NULL;
|
20
|
+
const gsl_interp2d_type *T = NULL;
|
21
|
+
double *xptr = NULL, *yptr = NULL, *zptr = NULL;
|
22
|
+
size_t sizex = 0, sizey = 0, sizez = 0, stride = 1;
|
23
|
+
|
24
|
+
T = get_interp2d_type(argv[0]);
|
25
|
+
if (argc == 3) { // type, sizex, sizey
|
26
|
+
sizex = FIX2INT(argv[1]);
|
27
|
+
sizey = FIX2INT(argv[2]);
|
28
|
+
}
|
29
|
+
else if (argc == 4) { // type, xarr, yarr, zarr
|
30
|
+
xptr = get_vector_ptr(argv[1], &stride, &sizex);
|
31
|
+
yptr = get_vector_ptr(argv[2], &stride, &sizey);
|
32
|
+
zptr = get_vector_ptr(argv[3], &stride, &sizez);
|
33
|
+
}
|
34
|
+
else {
|
35
|
+
rb_raise(rb_eRuntimeError, "Expected args: (interp2d type, xn, yn) \
|
36
|
+
or (interp2d type, xarr, yarr, zarr");
|
37
|
+
}
|
38
|
+
|
39
|
+
if (sizex == 0 || sizey == 0) rb_raise(rb_eRuntimeError, "Spline2d size not given.");
|
40
|
+
sp = ALLOC(rb_gsl_spline2d);
|
41
|
+
sp->s = gsl_spline2d_alloc(T, sizex, sizey);
|
42
|
+
sp->xacc = gsl_interp_accel_alloc();
|
43
|
+
sp->yacc = gsl_interp_accel_alloc();
|
44
|
+
|
45
|
+
if (xptr && yptr && zptr) gsl_spline2d_init(sp->s, xptr, yptr, zptr, sizex, sizey);
|
46
|
+
|
47
|
+
return Data_Wrap_Struct(self, 0, rb_gsl_spline2d_free, sp);
|
48
|
+
}
|
49
|
+
|
50
|
+
static void rb_gsl_spline2d_free(rb_gsl_spline2d *fr)
|
51
|
+
{
|
52
|
+
gsl_spline2d_free(fr->s);
|
53
|
+
gsl_interp_accel_free(fr->xacc);
|
54
|
+
gsl_interp_accel_free(fr->yacc);
|
55
|
+
free((rb_gsl_interp2d*) fr);
|
56
|
+
}
|
57
|
+
|
58
|
+
static VALUE rb_gsl_spline2d_init(VALUE self, VALUE xarr, VALUE yarr, VALUE zarr)
|
59
|
+
{
|
60
|
+
rb_gsl_spline2d *rgs = NULL;
|
61
|
+
double *xptr = NULL, *yptr = NULL, *zptr = NULL;
|
62
|
+
size_t xsize, ysize, zsize, stride;
|
63
|
+
xptr = get_vector_ptr(xarr, &stride, &xsize);
|
64
|
+
yptr = get_vector_ptr(yarr, &stride, &ysize);
|
65
|
+
zptr = get_vector_ptr(zarr, &stride, &zsize);
|
66
|
+
|
67
|
+
Data_Get_Struct(self, rb_gsl_spline2d, rgs);
|
68
|
+
gsl_spline2d_init(rgs->s, xptr, yptr, zptr, xsize, ysize);
|
69
|
+
|
70
|
+
return self;
|
71
|
+
}
|
72
|
+
|
73
|
+
static VALUE rb_gsl_spline2d_accel(VALUE self)
|
74
|
+
{
|
75
|
+
rb_gsl_spline2d *rgs = NULL;
|
76
|
+
VALUE ary = rb_ary_new();
|
77
|
+
Data_Get_Struct(self, rb_gsl_spline2d, rgs);
|
78
|
+
|
79
|
+
rb_ary_push(ary, Data_Wrap_Struct(cgsl_interp2d_accel, 0, NULL, rgs->xacc));
|
80
|
+
rb_ary_push(ary, Data_Wrap_Struct(cgsl_interp2d_accel, 0, NULL, rgs->yacc));
|
81
|
+
|
82
|
+
return ary;
|
83
|
+
}
|
84
|
+
|
85
|
+
static VALUE rb_gsl_spline2d_evaluate(VALUE self, VALUE xx, VALUE yy,
|
86
|
+
double (*eval)(const gsl_spline2d *, double, double, gsl_interp_accel *,
|
87
|
+
gsl_interp_accel *))
|
88
|
+
{
|
89
|
+
VALUE is_swapped = rb_cvar_get(CLASS_OF(self), rb_intern("@@swapped"));
|
90
|
+
VALUE temp;
|
91
|
+
|
92
|
+
if (is_swapped != Qnil && is_swapped == Qtrue) {
|
93
|
+
temp = xx;
|
94
|
+
xx = yy;
|
95
|
+
yy = temp;
|
96
|
+
}
|
97
|
+
|
98
|
+
rb_gsl_spline2d *rgs = NULL;
|
99
|
+
gsl_vector *vx = NULL, *vy = NULL, *vnew = NULL;
|
100
|
+
gsl_matrix *mx = NULL, *my = NULL, *mnew = NULL;
|
101
|
+
VALUE ary, x, y;
|
102
|
+
double val;
|
103
|
+
size_t i, j;
|
104
|
+
|
105
|
+
Data_Get_Struct(self, rb_gsl_spline2d, rgs);
|
106
|
+
|
107
|
+
if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
|
108
|
+
if (CLASS_OF(yy) == rb_cRange) yy = rb_gsl_range2ary(yy);
|
109
|
+
|
110
|
+
if (TYPE(xx) != TYPE(yy)) {
|
111
|
+
rb_raise(rb_eTypeError,"xx and yy must be same type. xx = %d yy = %d.",
|
112
|
+
TYPE(xx), TYPE(yy));
|
113
|
+
}
|
114
|
+
|
115
|
+
switch (TYPE(xx)) {
|
116
|
+
case T_FIXNUM: case T_BIGNUM: case T_FLOAT:
|
117
|
+
Need_Float(xx);
|
118
|
+
return rb_float_new((*eval)(rgs->s, NUM2DBL(xx), NUM2DBL(yy),
|
119
|
+
rgs->xacc, rgs->yacc));
|
120
|
+
case T_ARRAY:
|
121
|
+
if (RARRAY_LEN(xx) != RARRAY_LEN(yy)) {
|
122
|
+
rb_raise(rb_eRuntimeError, "xx and yy must be same sized Array.");
|
123
|
+
}
|
124
|
+
ary = rb_ary_new2(RARRAY_LEN(xx));
|
125
|
+
|
126
|
+
for (i = 0; i < (unsigned)RARRAY_LEN(xx); i++) {
|
127
|
+
x = rb_ary_entry(xx, i);
|
128
|
+
y = rb_ary_entry(yy, i);
|
129
|
+
Need_Float(x);
|
130
|
+
Need_Float(y);
|
131
|
+
|
132
|
+
val = (*eval)(rgs->s, NUM2DBL(x), NUM2DBL(y), rgs->xacc, rgs->yacc);
|
133
|
+
rb_ary_store(ary, i, rb_float_new(val));
|
134
|
+
}
|
135
|
+
return ary;
|
136
|
+
default:
|
137
|
+
if (VECTOR_P(xx)) {
|
138
|
+
Data_Get_Struct(xx, gsl_vector, vx);
|
139
|
+
Data_Get_Struct(yy, gsl_vector, vy);
|
140
|
+
if (vx->size != vy->size) {
|
141
|
+
rb_raise(rb_eRuntimeError, "xx and yy must be same size Vectors.");
|
142
|
+
}
|
143
|
+
vnew = gsl_vector_alloc(vx->size);
|
144
|
+
|
145
|
+
for (i = 0; i < vx->size; i++) {
|
146
|
+
val = (*eval)(rgs->s, gsl_vector_get(vx, i), gsl_vector_get(vy, i),
|
147
|
+
rgs->xacc, rgs->yacc);
|
148
|
+
gsl_vector_set(vnew, i, val);
|
149
|
+
}
|
150
|
+
return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew);
|
151
|
+
} else if (MATRIX_P(xx)) {
|
152
|
+
Data_Get_Struct(xx, gsl_matrix, mx);
|
153
|
+
Data_Get_Struct(xx, gsl_matrix, my);
|
154
|
+
|
155
|
+
if ((mx->size1 != my->size1) || (mx->size2 != my->size2)) {
|
156
|
+
rb_raise(rb_eRuntimeError, "xx and yy must be same sized Matrices.");
|
157
|
+
}
|
158
|
+
mnew = gsl_matrix_alloc(mx->size1, mx->size2);
|
159
|
+
for (i = 0; i < mx->size1; i++) {
|
160
|
+
for (j = 0; j < mx->size2; j++) {
|
161
|
+
val = (*eval)(rgs->s, gsl_matrix_get(mx, i, j),
|
162
|
+
gsl_matrix_get(my, i, j), rgs->xacc, rgs->yacc);
|
163
|
+
gsl_matrix_set(mnew, i, j, val);
|
164
|
+
}
|
165
|
+
}
|
166
|
+
return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew);
|
167
|
+
} else {
|
168
|
+
rb_raise(rb_eTypeError, "wrong argument type %s", rb_class2name(CLASS_OF(xx)));
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
static VALUE rb_gsl_spline2d_eval(VALUE self, VALUE xx, VALUE yy)
|
174
|
+
{
|
175
|
+
return rb_gsl_spline2d_evaluate(self, xx, yy, gsl_spline2d_eval);
|
176
|
+
}
|
177
|
+
|
178
|
+
static VALUE rb_gsl_spline2d_info(VALUE self)
|
179
|
+
{
|
180
|
+
rb_gsl_spline2d *p = NULL;
|
181
|
+
char buf[256];
|
182
|
+
Data_Get_Struct(self, rb_gsl_spline2d, p);
|
183
|
+
sprintf(buf, "Class: %s\n", rb_class2name(CLASS_OF(self)));
|
184
|
+
sprintf(buf, "%sSuperClass: %s\n", buf, rb_class2name(RCLASS_SUPER(CLASS_OF(self))));
|
185
|
+
sprintf(buf, "%sType: %s\n", buf, gsl_interp2d_name(&p->s->interp_object));
|
186
|
+
sprintf(buf, "%sxmin: %f\n", buf, p->s->interp_object.xmin);
|
187
|
+
sprintf(buf, "%sxmax: %f\n", buf, p->s->interp_object.xmax);
|
188
|
+
sprintf(buf, "%symin: %f\n", buf, p->s->interp_object.ymin);
|
189
|
+
sprintf(buf, "%symax: %f\n", buf, p->s->interp_object.ymax);
|
190
|
+
sprintf(buf, "%sxSize: %d\n", buf, (int) p->s->interp_object.xsize);
|
191
|
+
sprintf(buf, "%sySize: %d\n", buf, (int) p->s->interp_object.ysize);
|
192
|
+
return rb_str_new2(buf);
|
193
|
+
}
|
194
|
+
|
195
|
+
void Init_gsl_spline2d(VALUE module)
|
196
|
+
{
|
197
|
+
VALUE cgsl_spline2d;
|
198
|
+
|
199
|
+
cgsl_spline2d = rb_define_class_under(module, "Spline2d", cGSL_Object);
|
200
|
+
|
201
|
+
rb_define_singleton_method(cgsl_spline2d, "alloc", rb_gsl_spline2d_alloc, -1);
|
202
|
+
|
203
|
+
/*****/
|
204
|
+
|
205
|
+
rb_define_method(cgsl_spline2d, "init", rb_gsl_spline2d_init, 3);
|
206
|
+
rb_define_method(cgsl_spline2d, "accel", rb_gsl_spline2d_accel, 0);
|
207
|
+
rb_define_method(cgsl_spline2d, "eval", rb_gsl_spline2d_eval, 2);
|
208
|
+
rb_define_alias(cgsl_spline2d, "[]", "eval");
|
209
|
+
rb_define_method(cgsl_spline2d, "info", rb_gsl_spline2d_info, 0);
|
210
|
+
}
|
211
|
+
#endif
|