gsl 1.16.0.6 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +5 -13
- data/ChangeLog +6 -0
- data/Gemfile +1 -0
- data/README.md +77 -1
- data/Rakefile +7 -1
- data/examples/linalg/QR_solve_narray.rb +2 -1
- data/examples/linalg/SV_narray.rb +10 -0
- data/examples/linalg/chol_narray.rb +3 -0
- data/examples/wavelet/wavelet1.rb +4 -2
- data/ext/gsl_native/array.c +10 -0
- data/ext/gsl_native/bspline.c +15 -2
- data/ext/gsl_native/cheb.c +76 -10
- data/ext/gsl_native/common.c +33 -0
- data/ext/gsl_native/dht.c +26 -0
- data/ext/gsl_native/eigen.c +129 -0
- data/ext/gsl_native/extconf.rb +60 -6
- data/ext/gsl_native/fft.c +42 -0
- data/ext/gsl_native/function.c +18 -0
- data/ext/gsl_native/gsl.c +5 -0
- data/ext/gsl_native/gsl_nmatrix.c +204 -0
- data/ext/gsl_native/histogram.c +42 -0
- data/ext/gsl_native/include/rb_gsl.h +4 -0
- data/ext/gsl_native/include/rb_gsl_array.h +4 -0
- data/ext/gsl_native/include/rb_gsl_common.h +5 -0
- data/ext/gsl_native/include/rb_gsl_interp.h +4 -0
- data/ext/gsl_native/include/rb_gsl_with_nmatrix.h +28 -0
- data/ext/gsl_native/interp.c +14 -0
- data/ext/gsl_native/linalg.c +414 -22
- data/ext/gsl_native/math.c +64 -0
- data/ext/gsl_native/multifit.c +61 -0
- data/ext/gsl_native/randist.c +42 -0
- data/ext/gsl_native/sf.c +6 -0
- data/ext/gsl_native/sf_ellint.c +4 -4
- data/ext/gsl_native/sf_mathieu.c +48 -0
- data/ext/gsl_native/spline.c +30 -0
- data/ext/gsl_native/tamu_anova.c +1 -1
- data/gsl.gemspec +8 -1
- data/lib/gsl.rb +5 -0
- data/lib/gsl/version.rb +1 -1
- data/rdoc/nmatrix.rdoc +129 -0
- data/rdoc/ref.rdoc +1 -0
- data/test.sh +21 -0
- data/test/gsl/bspline_test.rb +15 -14
- data/test/gsl/combination_test.rb +17 -6
- data/test/gsl/dht_test.rb +42 -33
- data/test/gsl/nmatrix_tests/nmatrix_cheb_test.rb +34 -0
- data/test/gsl/nmatrix_tests/nmatrix_eigen_test.rb +28 -0
- data/test/gsl/nmatrix_tests/nmatrix_gsl_test.rb +65 -0
- data/test/gsl/nmatrix_tests/nmatrix_interp_test.rb +45 -0
- data/test/gsl/nmatrix_tests/nmatrix_linalg_test.rb +100 -0
- data/test/gsl/nmatrix_tests/nmatrix_stats_test.rb +88 -0
- data/test/gsl/nmatrix_tests/nmatrix_wavelet_test.rb +5 -0
- data/test/gsl/randist_test.rb +43 -23
- data/test/test_helper.rb +30 -2
- metadata +191 -51
data/ext/gsl_native/dht.c
CHANGED
@@ -72,6 +72,15 @@ static VALUE rb_gsl_dht_apply(int argc, VALUE *argv, VALUE obj)
|
|
72
72
|
ptr1 = (double*)na->ptr;
|
73
73
|
ary = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(argv[0]));
|
74
74
|
ptr2 = NA_PTR_TYPE(ary, double*);
|
75
|
+
#endif
|
76
|
+
#ifdef HAVE_NMATRIX_H
|
77
|
+
} else if (NM_IsNMatrix(argv[0])) {
|
78
|
+
NM_DENSE_STORAGE *nm;
|
79
|
+
nm = NM_STORAGE_DENSE(argv[0]);
|
80
|
+
ptr1 = (double*)nm->elements;
|
81
|
+
ary = rb_nmatrix_dense_create(FLOAT64, nm->shape, nm->dim, nm->elements,
|
82
|
+
NM_DENSE_COUNT(argv[0]));
|
83
|
+
ptr2 = (double*)NM_DENSE_ELEMENTS(ary);
|
75
84
|
#endif
|
76
85
|
} else {
|
77
86
|
rb_raise(rb_eTypeError, "wrong argument type %s (Vector expected)",
|
@@ -139,6 +148,23 @@ static VALUE rb_gsl_dht_xk_sample(VALUE obj, VALUE n,
|
|
139
148
|
}
|
140
149
|
return ary;
|
141
150
|
#endif
|
151
|
+
#ifdef HAVE_NARRAY_H
|
152
|
+
} else if (NM_IsNMatrix(n)) {
|
153
|
+
NM_DENSE_STORAGE *nm;
|
154
|
+
int *ptr;
|
155
|
+
double *ptr2;
|
156
|
+
nm = NM_STORAGE_DENSE(n);
|
157
|
+
ptr = (int*) nm->elements;
|
158
|
+
size = NM_DENSE_COUNT(n);
|
159
|
+
ary = rb_nmatrix_dense_create(FLOAT64, nm->shape, nm->dim, nm->elements,
|
160
|
+
NM_DENSE_COUNT(n));
|
161
|
+
ptr2 = (double*)NM_DENSE_ELEMENTS(ary);
|
162
|
+
for (i = 0; i < size; i++) {
|
163
|
+
ptr2[i] = (*sample)(t, ptr[i]);
|
164
|
+
}
|
165
|
+
return ary;
|
166
|
+
#endif
|
167
|
+
|
142
168
|
} else {
|
143
169
|
rb_raise(rb_eTypeError, "wrong argument type %s (Vector::Int expected)",
|
144
170
|
rb_class2name(CLASS_OF(n)));
|
data/ext/gsl_native/eigen.c
CHANGED
@@ -19,6 +19,10 @@
|
|
19
19
|
#include <gsl/gsl_math.h>
|
20
20
|
#include <gsl/gsl_eigen.h>
|
21
21
|
|
22
|
+
#ifdef HAVE_NMATRIX_H
|
23
|
+
#include "include/rb_gsl_with_nmatrix.h"
|
24
|
+
#endif
|
25
|
+
|
22
26
|
static VALUE cgsl_eigen_symm_workspace;
|
23
27
|
static VALUE cgsl_eigen_symmv_workspace;
|
24
28
|
static VALUE cgsl_eigen_herm_workspace;
|
@@ -135,6 +139,54 @@ static VALUE rb_gsl_eigen_symm_narray(int argc, VALUE *argv, VALUE obj)
|
|
135
139
|
}
|
136
140
|
#endif
|
137
141
|
|
142
|
+
#ifdef HAVE_NMATRIX_H
|
143
|
+
static VALUE rb_gsl_eigen_symm_nmatrix(int argc, VALUE *argv, VALUE obj)
|
144
|
+
{
|
145
|
+
NM_DENSE_STORAGE *nm;
|
146
|
+
VALUE nmatrix;
|
147
|
+
gsl_matrix *A = NULL;
|
148
|
+
gsl_eigen_symm_workspace *w = NULL;
|
149
|
+
gsl_vector_view vv;
|
150
|
+
unsigned int shape[1];
|
151
|
+
int flagw = 0;
|
152
|
+
|
153
|
+
if (!NM_IsNMatrix(argv[0]))
|
154
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (NMatrix expected)",
|
155
|
+
rb_class2name(CLASS_OF(argv[0])));
|
156
|
+
nm = NM_STORAGE_DENSE(argv[0]);
|
157
|
+
if (nm->shape[0] != nm->shape[1])
|
158
|
+
rb_raise(rb_eRuntimeError, "square matrix required");
|
159
|
+
A = gsl_matrix_alloc(nm->shape[0], nm->shape[1]);
|
160
|
+
memcpy(A->data, (double*) nm->elements, sizeof(double)*A->size1*A->size2);
|
161
|
+
|
162
|
+
switch (argc) {
|
163
|
+
case 2:
|
164
|
+
if (CLASS_OF(argv[1]) != cgsl_eigen_symm_workspace)
|
165
|
+
rb_raise(rb_eTypeError,
|
166
|
+
"argv[1]: wrong argument type %s (Eigen::Symm::Workspace expected",
|
167
|
+
rb_class2name(CLASS_OF(argv[1])));
|
168
|
+
Data_Get_Struct(argv[1], gsl_eigen_symm_workspace, w);
|
169
|
+
flagw = 0;
|
170
|
+
break;
|
171
|
+
case 1:
|
172
|
+
w = gsl_eigen_symm_alloc(A->size1);
|
173
|
+
flagw = 1;
|
174
|
+
break;
|
175
|
+
default:
|
176
|
+
rb_raise(rb_eArgError, "matrix not given");
|
177
|
+
break;
|
178
|
+
}
|
179
|
+
shape[0] = A->size1;
|
180
|
+
nmatrix = rb_nvector_dense_create(FLOAT64, nm->elements, shape[0]);
|
181
|
+
vv = gsl_vector_view_array((double*)NM_DENSE_ELEMENTS(nmatrix), A->size1);
|
182
|
+
gsl_eigen_symm(A, &vv.vector, w);
|
183
|
+
/* gsl_sort_vector(v);*/
|
184
|
+
gsl_matrix_free(A);
|
185
|
+
if (flagw == 1) gsl_eigen_symm_free(w);
|
186
|
+
return nmatrix;
|
187
|
+
}
|
188
|
+
#endif
|
189
|
+
|
138
190
|
static VALUE rb_gsl_eigen_symm(int argc, VALUE *argv, VALUE obj)
|
139
191
|
{
|
140
192
|
gsl_matrix *Atmp = NULL, *A = NULL;
|
@@ -150,6 +202,10 @@ static VALUE rb_gsl_eigen_symm(int argc, VALUE *argv, VALUE obj)
|
|
150
202
|
#ifdef HAVE_NARRAY_H
|
151
203
|
if (NA_IsNArray(argv[0])) return rb_gsl_eigen_symm_narray(argc, argv, obj);
|
152
204
|
#endif
|
205
|
+
|
206
|
+
#ifdef HAVE_NMATRIX_H
|
207
|
+
if (NM_IsNMatrix(argv[0])) return rb_gsl_eigen_symm_nmatrix(argc, argv, obj);
|
208
|
+
#endif
|
153
209
|
CHECK_MATRIX(argv[0]);
|
154
210
|
Data_Get_Struct(argv[0], gsl_matrix, Atmp);
|
155
211
|
if (CLASS_OF(argv[1]) != cgsl_eigen_symm_workspace)
|
@@ -162,6 +218,10 @@ static VALUE rb_gsl_eigen_symm(int argc, VALUE *argv, VALUE obj)
|
|
162
218
|
#ifdef HAVE_NARRAY_H
|
163
219
|
if (NA_IsNArray(argv[0])) return rb_gsl_eigen_symm_narray(argc, argv, obj);
|
164
220
|
#endif
|
221
|
+
|
222
|
+
#ifdef HAVE_NMATRIX_H
|
223
|
+
if (NM_IsNMatrix(argv[0])) return rb_gsl_eigen_symm_nmatrix(argc, argv, obj);
|
224
|
+
#endif
|
165
225
|
CHECK_MATRIX(argv[0]);
|
166
226
|
Data_Get_Struct(argv[0], gsl_matrix, Atmp);
|
167
227
|
w = gsl_eigen_symm_alloc(Atmp->size1);
|
@@ -261,6 +321,67 @@ static VALUE rb_gsl_eigen_symmv_narray(int argc, VALUE *argv, VALUE obj)
|
|
261
321
|
}
|
262
322
|
#endif
|
263
323
|
|
324
|
+
#ifdef HAVE_NMATRIX_H
|
325
|
+
static VALUE rb_gsl_eigen_symmv_nmatrix(int argc, VALUE *argv, VALUE obj)
|
326
|
+
{
|
327
|
+
NM_DENSE_STORAGE *nm;
|
328
|
+
VALUE eval, evec;
|
329
|
+
gsl_matrix *A = NULL;
|
330
|
+
gsl_eigen_symmv_workspace *w = NULL;
|
331
|
+
gsl_matrix_view mv;
|
332
|
+
gsl_vector_view vv;
|
333
|
+
unsigned int shape1[1], shape2[2];
|
334
|
+
int flagw = 0;
|
335
|
+
switch (argc) {
|
336
|
+
case 2:
|
337
|
+
if (!NM_IsNMatrix(argv[0]))
|
338
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (NMatrix expected)",
|
339
|
+
rb_class2name(CLASS_OF(argv[0])));
|
340
|
+
nm = NM_STORAGE_DENSE(argv[0]);
|
341
|
+
if (nm->dim < 2) rb_raise(rb_eRuntimeError, "dim >= 2 required");
|
342
|
+
if (nm->shape[0] != nm->shape[1])
|
343
|
+
rb_raise(rb_eRuntimeError, "square matrix required");
|
344
|
+
A = gsl_matrix_alloc(nm->shape[1], nm->shape[0]);
|
345
|
+
memcpy(A->data, (double*) nm->elements, sizeof(double)*A->size1*A->size2);
|
346
|
+
if (CLASS_OF(argv[1]) != cgsl_eigen_symmv_workspace)
|
347
|
+
rb_raise(rb_eTypeError,
|
348
|
+
"argv[1]: wrong argument type %s (Eigen::Symm::Workspace expected",
|
349
|
+
rb_class2name(CLASS_OF(argv[1])));
|
350
|
+
Data_Get_Struct(argv[1], gsl_eigen_symmv_workspace, w);
|
351
|
+
flagw = 0;
|
352
|
+
break;
|
353
|
+
case 1:
|
354
|
+
if (!NM_IsNMatrix(argv[0]))
|
355
|
+
rb_raise(rb_eTypeError, "wrong argument type %s (NArray expected)",
|
356
|
+
rb_class2name(CLASS_OF(argv[0])));
|
357
|
+
nm = NM_STORAGE_DENSE(argv[0]);
|
358
|
+
if (nm->dim < 2) rb_raise(rb_eRuntimeError, "rank >= 2 required");
|
359
|
+
if (nm->shape[0] != nm->shape[1])
|
360
|
+
rb_raise(rb_eRuntimeError, "square matrix required");
|
361
|
+
A = gsl_matrix_alloc(nm->shape[1], nm->shape[0]);
|
362
|
+
memcpy(A->data, (double*) nm->elements, sizeof(double)*A->size1*A->size2);
|
363
|
+
w = gsl_eigen_symmv_alloc(A->size1);
|
364
|
+
flagw = 1;
|
365
|
+
break;
|
366
|
+
default:
|
367
|
+
rb_raise(rb_eArgError, "matrix not given");
|
368
|
+
break;
|
369
|
+
}
|
370
|
+
shape1[0] = A->size1;
|
371
|
+
shape2[0] = A->size1;
|
372
|
+
shape2[1] = A->size1;
|
373
|
+
eval = rb_nvector_dense_create(FLOAT64, nm->elements, shape1[0]);
|
374
|
+
evec = rb_nmatrix_dense_create(FLOAT64, shape2, 2, nm->elements, shape2[0]*shape2[1]);
|
375
|
+
vv = gsl_vector_view_array((double*)NM_DENSE_ELEMENTS(eval), A->size1);
|
376
|
+
mv = gsl_matrix_view_array((double*)NM_DENSE_ELEMENTS(evec), A->size1, A->size2);
|
377
|
+
gsl_eigen_symmv(A, &vv.vector, &mv.matrix, w);
|
378
|
+
/* gsl_sort_vector(v);*/
|
379
|
+
gsl_matrix_free(A);
|
380
|
+
if (flagw == 1) gsl_eigen_symmv_free(w);
|
381
|
+
return rb_ary_new3(2, eval, evec);
|
382
|
+
}
|
383
|
+
#endif
|
384
|
+
|
264
385
|
static VALUE rb_gsl_eigen_symmv(int argc, VALUE *argv, VALUE obj)
|
265
386
|
{
|
266
387
|
gsl_matrix *Atmp = NULL, *A = NULL, *em = NULL;
|
@@ -277,6 +398,10 @@ static VALUE rb_gsl_eigen_symmv(int argc, VALUE *argv, VALUE obj)
|
|
277
398
|
#ifdef HAVE_NARRAY_H
|
278
399
|
if (NA_IsNArray(argv[0])) return rb_gsl_eigen_symmv_narray(argc, argv, obj);
|
279
400
|
#endif
|
401
|
+
|
402
|
+
#ifdef HAVE_NMATRIX_H
|
403
|
+
if (NM_IsNMatrix(argv[0])) return rb_gsl_eigen_symmv_nmatrix(argc, argv, obj);
|
404
|
+
#endif
|
280
405
|
CHECK_MATRIX(argv[0]);
|
281
406
|
Data_Get_Struct(argv[0], gsl_matrix, Atmp);
|
282
407
|
if (CLASS_OF(argv[1]) != cgsl_eigen_symmv_workspace)
|
@@ -289,6 +414,10 @@ static VALUE rb_gsl_eigen_symmv(int argc, VALUE *argv, VALUE obj)
|
|
289
414
|
#ifdef HAVE_NARRAY_H
|
290
415
|
if (NA_IsNArray(argv[0])) return rb_gsl_eigen_symmv_narray(argc, argv, obj);
|
291
416
|
#endif
|
417
|
+
|
418
|
+
#ifdef HAVE_NMATRIX_H
|
419
|
+
if (NM_IsNMatrix(argv[0])) return rb_gsl_eigen_symmv_nmatrix(argc, argv, obj);
|
420
|
+
#endif
|
292
421
|
CHECK_MATRIX(argv[0]);
|
293
422
|
Data_Get_Struct(argv[0], gsl_matrix, Atmp);
|
294
423
|
w = gsl_eigen_symmv_alloc(Atmp->size1);
|
data/ext/gsl_native/extconf.rb
CHANGED
@@ -9,6 +9,35 @@ rescue => err
|
|
9
9
|
abort "*** ERROR: missing required library to compile this module: #{err}"
|
10
10
|
end
|
11
11
|
|
12
|
+
# Function derived from NArray's extconf.rb.
|
13
|
+
def create_conf_h(file) #:nodoc:
|
14
|
+
print "creating #{file}\n"
|
15
|
+
File.open(file, 'w') do |hfile|
|
16
|
+
header_guard = file.upcase.sub(/\s|\./, '_')
|
17
|
+
|
18
|
+
hfile.puts "#ifndef #{header_guard}"
|
19
|
+
hfile.puts "#define #{header_guard}"
|
20
|
+
hfile.puts
|
21
|
+
|
22
|
+
# FIXME: Find a better way to do this:
|
23
|
+
hfile.puts "#define RUBY_2 1" if RUBY_VERSION >= '2.0'
|
24
|
+
|
25
|
+
for line in $defs
|
26
|
+
line =~ /^-D(.*)/
|
27
|
+
match_data = $1.dup
|
28
|
+
|
29
|
+
if match_data.match(/GSL_VERSION*/)
|
30
|
+
hfile.printf "#define #{match_data.to_s.split('=').join(' ')}\n"
|
31
|
+
else
|
32
|
+
hfile.printf "#define %s 1\n", match_data
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
hfile.puts
|
37
|
+
hfile.puts "#endif"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
12
41
|
def gsl_def(const, value = nil)
|
13
42
|
value = "=#{value}" if value
|
14
43
|
$defs << "-D#{const}#{value}"
|
@@ -30,8 +59,19 @@ def gsl_gem_config(target, dir = 'ext')
|
|
30
59
|
path = begin
|
31
60
|
require 'rubygems'
|
32
61
|
|
33
|
-
|
34
|
-
|
62
|
+
# For some weird reason finding narray and nmatrix headers works with specific
|
63
|
+
# functions only. Might need to fix nmatrix/narray to place headers in correct
|
64
|
+
# locations?
|
65
|
+
if target == 'narray'
|
66
|
+
gem 'narray'
|
67
|
+
spec = Gem::Specification.find_by_path("#{target}")
|
68
|
+
File.join(spec.full_gem_path, dir) if spec
|
69
|
+
else
|
70
|
+
gem 'nmatrix'
|
71
|
+
spec = Gem::Specification.find_all_by_name("#{target}").compact
|
72
|
+
File.join(spec[0].require_path)
|
73
|
+
end
|
74
|
+
|
35
75
|
rescue LoadError
|
36
76
|
end
|
37
77
|
|
@@ -66,7 +106,7 @@ gsl_config_arg(:version) { |version, check|
|
|
66
106
|
|
67
107
|
raise 'Ruby/GSL requires gsl-1.15 or later.' unless later['1.15']
|
68
108
|
|
69
|
-
%w[1.15 1.16].each { |v| later[v] }
|
109
|
+
%w[1.15 1.16 2.0 2.1].each { |v| later[v] }
|
70
110
|
}
|
71
111
|
|
72
112
|
gsl_config_arg(:cflags) { |cflags, check|
|
@@ -105,14 +145,28 @@ gsl_have_library('gsl_poly_solve_quartic')
|
|
105
145
|
|
106
146
|
gsl_def(:HAVE_GNU_GRAPH) if find_executable('graph')
|
107
147
|
|
108
|
-
|
148
|
+
external_libs = []
|
149
|
+
external_libs << 'narray' if ENV['NARRAY']
|
150
|
+
external_libs << 'nmatrix' if ENV['NMATRIX']
|
109
151
|
|
110
|
-
|
111
|
-
|
152
|
+
external_libs.each do |library|
|
153
|
+
gsl_gem_config(library)
|
154
|
+
have_header("#{library}.h")
|
155
|
+
have_library(library) if RUBY_PLATFORM =~ /cygwin|mingw/
|
156
|
+
end
|
112
157
|
|
113
158
|
unless arg_config('--disable-tamu-anova')
|
114
159
|
gsl_dir_config('tamu_anova')
|
115
160
|
gsl_have_header('tamuanova', 'tamu_anova/tamu_anova.h')
|
116
161
|
end
|
117
162
|
|
163
|
+
have_struct_member('gsl_multifit_fdfsolver', 'J', 'gsl/gsl_multifit_nlin.h')
|
164
|
+
have_func('gsl_sf_mathieu_a_e', 'gsl/gsl_sf_mathieu.h');
|
165
|
+
have_func('gsl_sf_mathieu_b_e', 'gsl/gsl_sf_mathieu.h');
|
166
|
+
have_func('gsl_sf_mathieu_ce_e', 'gsl/gsl_sf_mathieu.h');
|
167
|
+
have_func('gsl_sf_mathieu_se_e', 'gsl/gsl_sf_mathieu.h');
|
168
|
+
have_func('gsl_sf_mathieu_Mc_e', 'gsl/gsl_sf_mathieu.h');
|
169
|
+
have_func('gsl_sf_mathieu_Ms_e', 'gsl/gsl_sf_mathieu.h');
|
170
|
+
|
171
|
+
create_conf_h('gsl_config.h')
|
118
172
|
create_makefile('gsl_native')
|
data/ext/gsl_native/fft.c
CHANGED
@@ -618,6 +618,20 @@ static VALUE rb_fft_radix2(VALUE obj,
|
|
618
618
|
ptr2 = NA_PTR_TYPE(ary, double*);
|
619
619
|
}
|
620
620
|
#endif
|
621
|
+
|
622
|
+
#ifdef HAVE_NMATRIX_H
|
623
|
+
} else if (flag == 1) {
|
624
|
+
if (sss == RB_GSL_FFT_COPY) {
|
625
|
+
int shape[1];
|
626
|
+
shape[0] = n;
|
627
|
+
ary = rb_nvector_dense_create(FLOAT64, ptr1, shape[0]);
|
628
|
+
ptr2 = (double*)NM_DENSE_ELEMENTS(ary);
|
629
|
+
stride = 1;
|
630
|
+
} else {
|
631
|
+
ary = obj;
|
632
|
+
ptr2 = (double*)NM_DENSE_ELEMENTS(ary);
|
633
|
+
}
|
634
|
+
#endif
|
621
635
|
} else {
|
622
636
|
rb_raise(rb_eRuntimeError, "something wrong");
|
623
637
|
}
|
@@ -708,6 +722,20 @@ static VALUE rb_fft_real_trans(int argc, VALUE *argv, VALUE obj,
|
|
708
722
|
ary = obj;
|
709
723
|
}
|
710
724
|
#endif
|
725
|
+
|
726
|
+
#ifdef HAVE_NMATRIX_H
|
727
|
+
} else if (naflag == 1) {
|
728
|
+
if (sss == RB_GSL_FFT_COPY) {
|
729
|
+
int shape[1];
|
730
|
+
shape[0] = n;
|
731
|
+
ary = rb_nvector_dense_create(FLOAT64, ptr1, shape[0]);
|
732
|
+
ptr2 = (double*)NM_DENSE_ELEMENTS(ary);
|
733
|
+
stride = 1;
|
734
|
+
} else {
|
735
|
+
ptr2 = ptr1;
|
736
|
+
ary = obj;
|
737
|
+
}
|
738
|
+
#endif
|
711
739
|
} else {
|
712
740
|
rb_raise(rb_eRuntimeError, "something wrong");
|
713
741
|
}
|
@@ -773,6 +801,20 @@ static VALUE rb_fft_halfcomplex_trans(int argc, VALUE *argv, VALUE obj,
|
|
773
801
|
ary = obj;
|
774
802
|
}
|
775
803
|
#endif
|
804
|
+
|
805
|
+
#ifdef HAVE_NMATRIX_H
|
806
|
+
} else if (naflag == 1) {
|
807
|
+
if (sss == RB_GSL_FFT_COPY) {
|
808
|
+
int shape[1];
|
809
|
+
shape[0] = n;
|
810
|
+
ary = rb_nvector_dense_create(FLOAT64, ptr1, shape[0]);
|
811
|
+
ptr2 = (double*)NM_DENSE_ELEMENTS(ary);
|
812
|
+
stride = 1;
|
813
|
+
} else {
|
814
|
+
ptr2 = ptr1;
|
815
|
+
ary = obj;
|
816
|
+
}
|
817
|
+
#endif
|
776
818
|
} else {
|
777
819
|
rb_raise(rb_eRuntimeError, "something wrong");
|
778
820
|
}
|
data/ext/gsl_native/function.c
CHANGED
@@ -149,6 +149,24 @@ static VALUE rb_gsl_function_eval(VALUE obj, VALUE x)
|
|
149
149
|
}
|
150
150
|
return ary;
|
151
151
|
}
|
152
|
+
#endif
|
153
|
+
#ifdef HAVE_NMATRIX_H
|
154
|
+
if (NM_IsNMatrix(x)) {
|
155
|
+
double *ptr1, *ptr2;
|
156
|
+
NM_DENSE_STORAGE *nm;
|
157
|
+
nm = NM_STORAGE_DENSE(x);
|
158
|
+
ptr1 = (double *) nm->elements;
|
159
|
+
n = NM_DENSE_COUNT(x);
|
160
|
+
ary = rb_nmatrix_dense_create(FLOAT64, nm->shape, nm->dim, nm->elements, n);
|
161
|
+
ptr2 = (double*)NM_DENSE_ELEMENTS(ary);
|
162
|
+
for (i = 0; i < n; i++) {
|
163
|
+
x2 = rb_float_new(ptr1[i]);
|
164
|
+
if (NIL_P(params)) result = rb_funcall(proc, RBGSL_ID_call, 1, x2);
|
165
|
+
else result = rb_funcall(proc, RBGSL_ID_call, 2, x2, params);
|
166
|
+
ptr2[i] = NUM2DBL(result);
|
167
|
+
}
|
168
|
+
return ary;
|
169
|
+
}
|
152
170
|
#endif
|
153
171
|
if (VECTOR_P(x)) {
|
154
172
|
Data_Get_Struct(x, gsl_vector, v);
|
data/ext/gsl_native/gsl.c
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
WITHOUT ANY WARRANTY.
|
10
10
|
*/
|
11
11
|
|
12
|
+
#include "gsl_config.h"
|
12
13
|
#include "include/rb_gsl.h"
|
13
14
|
#include <gsl/gsl_machine.h>
|
14
15
|
|
@@ -140,6 +141,10 @@ void Init_gsl_native()
|
|
140
141
|
Init_gsl_narray(mgsl);
|
141
142
|
#endif
|
142
143
|
|
144
|
+
#ifdef HAVE_NMATRIX_H
|
145
|
+
Init_gsl_nmatrix(mgsl);
|
146
|
+
#endif
|
147
|
+
|
143
148
|
Init_wavelet(mgsl);
|
144
149
|
|
145
150
|
rb_gsl_define_const(mgsl);
|
@@ -0,0 +1,204 @@
|
|
1
|
+
/*
|
2
|
+
gsl_nmatrix.c
|
3
|
+
|
4
|
+
Written by Sameer Deshmukh (@v0dro) feb/2016
|
5
|
+
*/
|
6
|
+
#ifdef HAVE_NMATRIX_H
|
7
|
+
|
8
|
+
#include "include/rb_gsl_with_nmatrix.h"
|
9
|
+
|
10
|
+
// functions to convert GSL::Vectors to 1D NMatrix
|
11
|
+
static VALUE rb_gsl_vector_to_nmatrix(VALUE obj);
|
12
|
+
static VALUE rb_gsl_vector_int_to_nmatrix(VALUE obj);
|
13
|
+
static VALUE rb_gsl_vector_complex_to_nmatrix(VALUE obj);
|
14
|
+
|
15
|
+
// functions to convert GSL::Matrix to 2D NMatrix
|
16
|
+
static VALUE rb_gsl_matrix_to_nmatrix(VALUE obj);
|
17
|
+
static VALUE rb_gsl_matrix_int_to_nmatrix(VALUE obj);
|
18
|
+
static VALUE rb_gsl_matrix_complex_to_nmatrix(VALUE obj);
|
19
|
+
|
20
|
+
/* GSL::Vector -> NMatrix */
|
21
|
+
static VALUE rb_gsl_vector_to_nmatrix(VALUE obj) {
|
22
|
+
gsl_vector *v = NULL;
|
23
|
+
Data_Get_Struct(obj, gsl_vector, v);
|
24
|
+
|
25
|
+
return rb_nvector_dense_create(FLOAT64, v->data, v->size);
|
26
|
+
}
|
27
|
+
|
28
|
+
static VALUE rb_gsl_vector_int_to_nmatrix(VALUE obj) {
|
29
|
+
gsl_vector_int *v = NULL;
|
30
|
+
Data_Get_Struct(obj, gsl_vector_int, v);
|
31
|
+
|
32
|
+
return rb_nvector_dense_create(INT32, v->data, v->size);
|
33
|
+
}
|
34
|
+
|
35
|
+
static VALUE rb_gsl_vector_complex_to_nmatrix(VALUE obj) {
|
36
|
+
gsl_vector_complex *v = NULL;
|
37
|
+
Data_Get_Struct(obj, gsl_vector_complex, v);
|
38
|
+
|
39
|
+
return rb_nvector_dense_create(COMPLEX128, v->data, v->size);
|
40
|
+
}
|
41
|
+
|
42
|
+
static VALUE rb_gsl_matrix_to_nmatrix(VALUE obj) {
|
43
|
+
gsl_matrix *m = NULL;
|
44
|
+
Data_Get_Struct(obj, gsl_matrix, m);
|
45
|
+
|
46
|
+
return rb_nmatrix_dense_create(FLOAT64, &(m->size1), 2, m->data, m->size1 * m->size2);
|
47
|
+
}
|
48
|
+
|
49
|
+
static VALUE rb_gsl_matrix_int_to_nmatrix(VALUE obj) {
|
50
|
+
gsl_matrix_int *m = NULL;
|
51
|
+
Data_Get_Struct(obj, gsl_matrix_int, m);
|
52
|
+
|
53
|
+
return rb_nmatrix_dense_create(INT32, &(m->size1), 2, m->data, m->size1 * m->size2);
|
54
|
+
}
|
55
|
+
|
56
|
+
static VALUE rb_gsl_matrix_complex_to_nmatrix(VALUE obj) {
|
57
|
+
gsl_matrix_complex *m = NULL;
|
58
|
+
Data_Get_Struct(obj, gsl_matrix_complex, m);
|
59
|
+
|
60
|
+
return rb_nmatrix_dense_create(COMPLEX128, &(m->size1), 2, m->data, m->size1 * m->size2);
|
61
|
+
}
|
62
|
+
|
63
|
+
// functions called on NMatrix objects. 'nm' is of type NMatrix.
|
64
|
+
gsl_vector* rb_gsl_nmatrix_to_gv(VALUE nm) {
|
65
|
+
NM_DENSE_STORAGE* s = NM_STORAGE_DENSE(nm);
|
66
|
+
// TODO: change this once nmatrix is fixed
|
67
|
+
gsl_vector* v = gsl_vector_alloc( FIX2INT(rb_funcall(nm, rb_intern("count"), 0, NULL)) );
|
68
|
+
|
69
|
+
if (s->dtype != FLOAT64) {
|
70
|
+
rb_raise(rb_eStandardError, "requires dtype of :float64 to convert to a GSL vector");
|
71
|
+
}
|
72
|
+
|
73
|
+
memcpy(v->data, s->elements, v->size*sizeof(double));
|
74
|
+
|
75
|
+
return v;
|
76
|
+
}
|
77
|
+
|
78
|
+
gsl_vector_int* rb_gsl_nmatrix_to_gv_int(VALUE nm) {
|
79
|
+
NM_DENSE_STORAGE* s = NM_STORAGE_DENSE(nm);
|
80
|
+
gsl_vector_int* v = gsl_vector_int_alloc(
|
81
|
+
FIX2INT(rb_funcall(nm, rb_intern("count"), 0, NULL)));
|
82
|
+
|
83
|
+
if (s->dtype != INT32) {
|
84
|
+
rb_raise(rb_eStandardError, "requires dtype of :int32 to convert to a GSL int vector");
|
85
|
+
}
|
86
|
+
|
87
|
+
memcpy(v->data, s->elements, v->size*sizeof(int32_t));
|
88
|
+
|
89
|
+
return v;
|
90
|
+
}
|
91
|
+
|
92
|
+
gsl_vector_complex* rb_gsl_nmatrix_to_gv_complex(VALUE nm) {
|
93
|
+
NM_DENSE_STORAGE* s = NM_STORAGE_DENSE(nm);
|
94
|
+
gsl_vector_complex* v = gsl_vector_complex_alloc(
|
95
|
+
FIX2INT(rb_funcall(nm, rb_intern("count"), 0, NULL)) );
|
96
|
+
|
97
|
+
if (s->dtype != COMPLEX128) {
|
98
|
+
rb_raise(rb_eStandardError, "requires dtype of :complex128 to convert to a GSL complex vector");
|
99
|
+
}
|
100
|
+
|
101
|
+
memcpy(v->data, s->elements, v->size*sizeof(double)*2);
|
102
|
+
|
103
|
+
return v;
|
104
|
+
}
|
105
|
+
|
106
|
+
// NMatrix function to convert NMatrix to GSL::Vector object depending on dtype
|
107
|
+
VALUE rb_gsl_nmatrix_to_gsl_vector_method(VALUE nm) {
|
108
|
+
if (NM_DTYPE(nm) == COMPLEX64 || NM_DTYPE(nm) == COMPLEX128) {
|
109
|
+
return Data_Wrap_Struct(cgsl_vector_complex, 0, gsl_vector_complex_free,
|
110
|
+
rb_gsl_nmatrix_to_gv_complex(nm));
|
111
|
+
}
|
112
|
+
else if (NM_DTYPE(nm) == INT32) {
|
113
|
+
return Data_Wrap_Struct(cgsl_vector_int, 0, gsl_vector_int_free,
|
114
|
+
rb_gsl_nmatrix_to_gv_int(nm));
|
115
|
+
}
|
116
|
+
else if (NM_DTYPE(nm) == FLOAT64) {
|
117
|
+
return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free,
|
118
|
+
rb_gsl_nmatrix_to_gv(nm));
|
119
|
+
}
|
120
|
+
else {
|
121
|
+
rb_raise(rb_eStandardError,
|
122
|
+
"NMatrix should be either :complex64, :complex128, :int32 or :float64 type.");
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
gsl_matrix* rb_gsl_nmatrix_to_gm(VALUE nm) {
|
127
|
+
NM_DENSE_STORAGE* s = NM_STORAGE_DENSE(nm);
|
128
|
+
gsl_matrix* m = gsl_matrix_alloc( s->shape[0], s->shape[1] );
|
129
|
+
|
130
|
+
if (s->dtype != FLOAT64) {
|
131
|
+
rb_raise(rb_eStandardError, "requires dtype of :float64 to convert from a GSL double vector");
|
132
|
+
}
|
133
|
+
|
134
|
+
memcpy(m->data, s->elements, s->shape[0]*s->shape[1]*sizeof(double)); // double is nm :float64
|
135
|
+
return m;
|
136
|
+
}
|
137
|
+
|
138
|
+
gsl_matrix_int* rb_gsl_nmatrix_to_gm_int(VALUE nm) {
|
139
|
+
NM_DENSE_STORAGE* s = NM_STORAGE_DENSE(nm);
|
140
|
+
gsl_matrix_int* m = gsl_matrix_int_alloc( s->shape[0], s->shape[1] );
|
141
|
+
|
142
|
+
if (s->dtype != INT32) {
|
143
|
+
rb_raise(rb_eStandardError, "requires dtype of :int32 to convert from a GSL int vector");
|
144
|
+
}
|
145
|
+
|
146
|
+
memcpy(m->data, s->elements, s->shape[0]*s->shape[1]*sizeof(int32_t)); // int32_t is nm :int32
|
147
|
+
return m;
|
148
|
+
}
|
149
|
+
|
150
|
+
gsl_matrix_complex* rb_gsl_nmatrix_to_gm_complex(VALUE nm) {
|
151
|
+
NM_DENSE_STORAGE* s = NM_STORAGE_DENSE(nm);
|
152
|
+
gsl_matrix_complex* m = gsl_matrix_complex_alloc( s->shape[0], s->shape[1]);
|
153
|
+
|
154
|
+
if (s->dtype != COMPLEX128) {
|
155
|
+
rb_raise(rb_eStandardError, "requires dtype of :complex128 to convert from a GSL complex vector");
|
156
|
+
}
|
157
|
+
|
158
|
+
memcpy(m->data, s->elements, s->shape[0]*s->shape[1]*sizeof(double)*2);
|
159
|
+
return m;
|
160
|
+
}
|
161
|
+
|
162
|
+
// NMatrix to GSL::Matrix conversion based on dtype
|
163
|
+
VALUE rb_gsl_nmatrix_to_gsl_matrix_method(VALUE nmatrix) {
|
164
|
+
if (NM_DIM(nmatrix) > 2) {
|
165
|
+
rb_raise(rb_eStandardError,
|
166
|
+
"NMatrix must not have greater than 2 dimensions.");
|
167
|
+
}
|
168
|
+
|
169
|
+
if (NM_DTYPE(nmatrix) == COMPLEX64 || NM_DTYPE(nmatrix) == COMPLEX128) {
|
170
|
+
return Data_Wrap_Struct(cgsl_matrix_complex, 0, gsl_matrix_complex_free,
|
171
|
+
rb_gsl_nmatrix_to_gm_complex(nmatrix));
|
172
|
+
}
|
173
|
+
else if (NM_DTYPE(nmatrix) == INT32) {
|
174
|
+
return Data_Wrap_Struct(cgsl_matrix_int, 0, gsl_matrix_int_free,
|
175
|
+
rb_gsl_nmatrix_to_gm_int(nmatrix));
|
176
|
+
}
|
177
|
+
else if (NM_DTYPE(nmatrix) == FLOAT64) {
|
178
|
+
return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free,
|
179
|
+
rb_gsl_nmatrix_to_gm(nmatrix));
|
180
|
+
}
|
181
|
+
else {
|
182
|
+
rb_raise(rb_eStandardError,
|
183
|
+
"NMatrix should be either :complex64, :complex128, :int32 or :float64 type.");
|
184
|
+
}
|
185
|
+
}
|
186
|
+
|
187
|
+
void Init_gsl_nmatrix(VALUE module)
|
188
|
+
{
|
189
|
+
// functions to convert GSL::Vector to 1D NMatrix.
|
190
|
+
rb_define_method(cgsl_vector, "to_nm", rb_gsl_vector_to_nmatrix, 0);
|
191
|
+
rb_define_method(cgsl_vector_int, "to_nm", rb_gsl_vector_int_to_nmatrix, 0);
|
192
|
+
rb_define_method(cgsl_vector_complex, "to_nm", rb_gsl_vector_complex_to_nmatrix, 0);
|
193
|
+
|
194
|
+
// functions to convert GSL::Matrix to 2D Nmatrix.
|
195
|
+
rb_define_method(cgsl_matrix, "to_nm", rb_gsl_matrix_to_nmatrix, 0);
|
196
|
+
rb_define_method(cgsl_matrix_int, "to_nm", rb_gsl_matrix_int_to_nmatrix, 0);
|
197
|
+
rb_define_method(cgsl_matrix_complex, "to_nm", rb_gsl_matrix_complex_to_nmatrix, 0);
|
198
|
+
|
199
|
+
// functions on NMatrix to convert to GSL::Vector and GSL::Matrix
|
200
|
+
rb_define_method(cNMatrix, "to_gslv", rb_gsl_nmatrix_to_gsl_vector_method, 0);
|
201
|
+
rb_define_method(cNMatrix, "to_gslm", rb_gsl_nmatrix_to_gsl_matrix_method, 0);
|
202
|
+
}
|
203
|
+
|
204
|
+
#endif
|