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.
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