gsl 1.16.0.6 → 2.1.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 +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
|