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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -13
  3. data/ChangeLog +6 -0
  4. data/Gemfile +1 -0
  5. data/README.md +77 -1
  6. data/Rakefile +7 -1
  7. data/examples/linalg/QR_solve_narray.rb +2 -1
  8. data/examples/linalg/SV_narray.rb +10 -0
  9. data/examples/linalg/chol_narray.rb +3 -0
  10. data/examples/wavelet/wavelet1.rb +4 -2
  11. data/ext/gsl_native/array.c +10 -0
  12. data/ext/gsl_native/bspline.c +15 -2
  13. data/ext/gsl_native/cheb.c +76 -10
  14. data/ext/gsl_native/common.c +33 -0
  15. data/ext/gsl_native/dht.c +26 -0
  16. data/ext/gsl_native/eigen.c +129 -0
  17. data/ext/gsl_native/extconf.rb +60 -6
  18. data/ext/gsl_native/fft.c +42 -0
  19. data/ext/gsl_native/function.c +18 -0
  20. data/ext/gsl_native/gsl.c +5 -0
  21. data/ext/gsl_native/gsl_nmatrix.c +204 -0
  22. data/ext/gsl_native/histogram.c +42 -0
  23. data/ext/gsl_native/include/rb_gsl.h +4 -0
  24. data/ext/gsl_native/include/rb_gsl_array.h +4 -0
  25. data/ext/gsl_native/include/rb_gsl_common.h +5 -0
  26. data/ext/gsl_native/include/rb_gsl_interp.h +4 -0
  27. data/ext/gsl_native/include/rb_gsl_with_nmatrix.h +28 -0
  28. data/ext/gsl_native/interp.c +14 -0
  29. data/ext/gsl_native/linalg.c +414 -22
  30. data/ext/gsl_native/math.c +64 -0
  31. data/ext/gsl_native/multifit.c +61 -0
  32. data/ext/gsl_native/randist.c +42 -0
  33. data/ext/gsl_native/sf.c +6 -0
  34. data/ext/gsl_native/sf_ellint.c +4 -4
  35. data/ext/gsl_native/sf_mathieu.c +48 -0
  36. data/ext/gsl_native/spline.c +30 -0
  37. data/ext/gsl_native/tamu_anova.c +1 -1
  38. data/gsl.gemspec +8 -1
  39. data/lib/gsl.rb +5 -0
  40. data/lib/gsl/version.rb +1 -1
  41. data/rdoc/nmatrix.rdoc +129 -0
  42. data/rdoc/ref.rdoc +1 -0
  43. data/test.sh +21 -0
  44. data/test/gsl/bspline_test.rb +15 -14
  45. data/test/gsl/combination_test.rb +17 -6
  46. data/test/gsl/dht_test.rb +42 -33
  47. data/test/gsl/nmatrix_tests/nmatrix_cheb_test.rb +34 -0
  48. data/test/gsl/nmatrix_tests/nmatrix_eigen_test.rb +28 -0
  49. data/test/gsl/nmatrix_tests/nmatrix_gsl_test.rb +65 -0
  50. data/test/gsl/nmatrix_tests/nmatrix_interp_test.rb +45 -0
  51. data/test/gsl/nmatrix_tests/nmatrix_linalg_test.rb +100 -0
  52. data/test/gsl/nmatrix_tests/nmatrix_stats_test.rb +88 -0
  53. data/test/gsl/nmatrix_tests/nmatrix_wavelet_test.rb +5 -0
  54. data/test/gsl/randist_test.rb +43 -23
  55. data/test/test_helper.rb +30 -2
  56. metadata +191 -51
@@ -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)));
@@ -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);
@@ -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
- spec = Gem::Specification.find_by_path("#{target}.h")
34
- File.join(spec.full_gem_path, dir) if spec
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
- gsl_gem_config('narray', 'src')
148
+ external_libs = []
149
+ external_libs << 'narray' if ENV['NARRAY']
150
+ external_libs << 'nmatrix' if ENV['NMATRIX']
109
151
 
110
- have_header('narray.h')
111
- have_library('narray') if RUBY_PLATFORM =~ /cygwin|mingw/
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')
@@ -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
  }
@@ -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);
@@ -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