nmatrix 0.1.0 → 0.2.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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/ext/nmatrix/data/complex.h +20 -55
  3. data/ext/nmatrix/data/data.cpp +11 -44
  4. data/ext/nmatrix/data/data.h +174 -311
  5. data/ext/nmatrix/data/meta.h +1 -7
  6. data/ext/nmatrix/data/ruby_object.h +3 -85
  7. data/ext/nmatrix/extconf.rb +2 -73
  8. data/ext/nmatrix/math.cpp +170 -813
  9. data/ext/nmatrix/math/asum.h +2 -25
  10. data/ext/nmatrix/math/{inc.h → cblas_enums.h} +11 -22
  11. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  12. data/ext/nmatrix/math/gemm.h +2 -32
  13. data/ext/nmatrix/math/gemv.h +1 -35
  14. data/ext/nmatrix/math/getrf.h +21 -6
  15. data/ext/nmatrix/math/getrs.h +0 -8
  16. data/ext/nmatrix/math/imax.h +0 -22
  17. data/ext/nmatrix/math/long_dtype.h +0 -3
  18. data/ext/nmatrix/math/math.h +11 -337
  19. data/ext/nmatrix/math/nrm2.h +2 -23
  20. data/ext/nmatrix/math/rot.h +1 -25
  21. data/ext/nmatrix/math/rotg.h +4 -13
  22. data/ext/nmatrix/math/scal.h +0 -22
  23. data/ext/nmatrix/math/trsm.h +0 -55
  24. data/ext/nmatrix/math/util.h +148 -0
  25. data/ext/nmatrix/nmatrix.cpp +0 -14
  26. data/ext/nmatrix/nmatrix.h +92 -84
  27. data/ext/nmatrix/ruby_constants.cpp +0 -2
  28. data/ext/nmatrix/ruby_constants.h +0 -2
  29. data/ext/nmatrix/ruby_nmatrix.c +86 -45
  30. data/ext/nmatrix/storage/dense/dense.cpp +1 -7
  31. data/ext/nmatrix/storage/storage.h +0 -1
  32. data/ext/nmatrix/ttable_helper.rb +0 -6
  33. data/ext/nmatrix/util/io.cpp +1 -1
  34. data/lib/nmatrix.rb +1 -19
  35. data/lib/nmatrix/blas.rb +33 -11
  36. data/lib/nmatrix/io/market.rb +3 -3
  37. data/lib/nmatrix/lapack_core.rb +181 -0
  38. data/lib/nmatrix/lapack_plugin.rb +44 -0
  39. data/lib/nmatrix/math.rb +382 -131
  40. data/lib/nmatrix/monkeys.rb +2 -3
  41. data/lib/nmatrix/nmatrix.rb +166 -13
  42. data/lib/nmatrix/shortcuts.rb +72 -7
  43. data/lib/nmatrix/version.rb +2 -2
  44. data/spec/00_nmatrix_spec.rb +154 -5
  45. data/spec/02_slice_spec.rb +2 -6
  46. data/spec/03_nmatrix_monkeys_spec.rb +7 -1
  47. data/spec/blas_spec.rb +60 -33
  48. data/spec/homogeneous_spec.rb +10 -10
  49. data/spec/lapack_core_spec.rb +482 -0
  50. data/spec/math_spec.rb +436 -52
  51. data/spec/shortcuts_spec.rb +28 -4
  52. data/spec/spec_helper.rb +14 -2
  53. data/spec/utm5940.mtx +83844 -0
  54. metadata +49 -76
  55. data/.gitignore +0 -27
  56. data/.rspec +0 -2
  57. data/.travis.yml +0 -15
  58. data/CONTRIBUTING.md +0 -82
  59. data/Gemfile +0 -2
  60. data/History.txt +0 -677
  61. data/LICENSE.txt +0 -23
  62. data/Manifest.txt +0 -92
  63. data/README.rdoc +0 -150
  64. data/Rakefile +0 -216
  65. data/ext/nmatrix/data/rational.h +0 -440
  66. data/ext/nmatrix/math/geev.h +0 -82
  67. data/ext/nmatrix/math/ger.h +0 -96
  68. data/ext/nmatrix/math/gesdd.h +0 -80
  69. data/ext/nmatrix/math/gesvd.h +0 -78
  70. data/ext/nmatrix/math/getf2.h +0 -86
  71. data/ext/nmatrix/math/getri.h +0 -108
  72. data/ext/nmatrix/math/potrs.h +0 -129
  73. data/ext/nmatrix/math/swap.h +0 -52
  74. data/lib/nmatrix/lapack.rb +0 -240
  75. data/nmatrix.gemspec +0 -55
  76. data/scripts/mac-brew-gcc.sh +0 -50
  77. data/scripts/mac-mavericks-brew-gcc.sh +0 -22
  78. data/spec/lapack_spec.rb +0 -459
@@ -86,8 +86,6 @@ VALUE cNMatrix,
86
86
  cNMatrix_IO,
87
87
  cNMatrix_IO_Matlab,
88
88
  cNMatrix_YaleFunctions,
89
- cNMatrix_BLAS,
90
- cNMatrix_LAPACK,
91
89
 
92
90
  cNMatrix_GC_holder,
93
91
 
@@ -88,8 +88,6 @@ extern VALUE cNMatrix,
88
88
  cNMatrix_IO,
89
89
  cNMatrix_IO_Matlab,
90
90
  cNMatrix_YaleFunctions,
91
- cNMatrix_BLAS,
92
- cNMatrix_LAPACK,
93
91
 
94
92
  cNMatrix_GC_holder,
95
93
 
@@ -134,13 +134,13 @@ DECL_UNARY_RUBY_ACCESSOR(gamma)
134
134
  DECL_UNARY_RUBY_ACCESSOR(negate)
135
135
  DECL_UNARY_RUBY_ACCESSOR(floor)
136
136
  DECL_UNARY_RUBY_ACCESSOR(ceil)
137
- DECL_UNARY_RUBY_ACCESSOR(round)
138
137
  DECL_NONCOM_ELEMENTWISE_RUBY_ACCESSOR(atan2)
139
138
  DECL_NONCOM_ELEMENTWISE_RUBY_ACCESSOR(ldexp)
140
139
  DECL_NONCOM_ELEMENTWISE_RUBY_ACCESSOR(hypot)
141
140
 
142
- //log can be unary, but also take a base argument, as with Math.log
141
+ //log/round can be unary, but also take a base argument, as with Math.log
143
142
  static VALUE nm_unary_log(int argc, VALUE* argv, VALUE self);
143
+ static VALUE nm_unary_round(int argc, VALUE* argv, VALUE self);
144
144
 
145
145
  static VALUE elementwise_op(nm::ewop_t op, VALUE left_val, VALUE right_val);
146
146
  static VALUE unary_op(nm::unaryop_t op, VALUE self);
@@ -155,6 +155,7 @@ static VALUE matrix_multiply_scalar(NMATRIX* left, VALUE scalar);
155
155
  static VALUE matrix_multiply(NMATRIX* left, NMATRIX* right);
156
156
  static VALUE nm_multiply(VALUE left_v, VALUE right_v);
157
157
  static VALUE nm_det_exact(VALUE self);
158
+ static VALUE nm_hessenberg(VALUE self, VALUE a);
158
159
  static VALUE nm_inverse(VALUE self, VALUE inverse, VALUE bang);
159
160
  static VALUE nm_inverse_exact(VALUE self, VALUE inverse, VALUE lda, VALUE ldb);
160
161
  static VALUE nm_complex_conjugate_bang(VALUE self);
@@ -263,19 +264,21 @@ void Init_nmatrix() {
263
264
  rb_define_method(cNMatrix, "supershape", (METHOD)nm_supershape, 0);
264
265
  rb_define_method(cNMatrix, "offset", (METHOD)nm_offset, 0);
265
266
  rb_define_method(cNMatrix, "det_exact", (METHOD)nm_det_exact, 0);
266
- rb_define_protected_method(cNMatrix, "__inverse__", (METHOD)nm_inverse, 2);
267
- rb_define_protected_method(cNMatrix, "__inverse_exact__", (METHOD)nm_inverse_exact, 3);
268
- rb_define_method(cNMatrix, "complex_conjugate!", (METHOD)nm_complex_conjugate_bang, 0);
269
- rb_define_method(cNMatrix, "complex_conjugate", (METHOD)nm_complex_conjugate, 0);
267
+ rb_define_method(cNMatrix, "complex_conjugate!", (METHOD)nm_complex_conjugate_bang, 0);
268
+ rb_define_method(cNMatrix, "complex_conjugate", (METHOD)nm_complex_conjugate, 0);
269
+
270
270
  rb_define_protected_method(cNMatrix, "reshape_bang", (METHOD)nm_reshape_bang, 1);
271
271
 
272
+ // Iterators public methods
273
+ rb_define_method(cNMatrix, "each_with_indices", (METHOD)nm_each_with_indices, 0);
274
+ rb_define_method(cNMatrix, "each_stored_with_indices", (METHOD)nm_each_stored_with_indices, 0);
275
+ rb_define_method(cNMatrix, "map_stored", (METHOD)nm_map_stored, 0);
276
+ rb_define_method(cNMatrix, "each_ordered_stored_with_indices", (METHOD)nm_each_ordered_stored_with_indices, 0);
277
+
278
+ // Iterators protected methods
272
279
  rb_define_protected_method(cNMatrix, "__dense_each__", (METHOD)nm_dense_each, 0);
273
280
  rb_define_protected_method(cNMatrix, "__dense_map__", (METHOD)nm_dense_map, 0);
274
281
  rb_define_protected_method(cNMatrix, "__dense_map_pair__", (METHOD)nm_dense_map_pair, 1);
275
- rb_define_method(cNMatrix, "each_with_indices", (METHOD)nm_each_with_indices, 0);
276
- rb_define_method(cNMatrix, "each_stored_with_indices", (METHOD)nm_each_stored_with_indices, 0);
277
- rb_define_method(cNMatrix, "map_stored", (METHOD)nm_map_stored, 0);
278
- rb_define_method(cNMatrix, "each_ordered_stored_with_indices", (METHOD)nm_each_ordered_stored_with_indices, 0);
279
282
  rb_define_protected_method(cNMatrix, "__list_map_merged_stored__", (METHOD)nm_list_map_merged_stored, 2);
280
283
  rb_define_protected_method(cNMatrix, "__list_map_stored__", (METHOD)nm_list_map_stored, 1);
281
284
  rb_define_protected_method(cNMatrix, "__yale_map_merged_stored__", (METHOD)nm_yale_map_merged_stored, 2);
@@ -320,7 +323,7 @@ void Init_nmatrix() {
320
323
  rb_define_method(cNMatrix, "-@", (METHOD)nm_unary_negate,0);
321
324
  rb_define_method(cNMatrix, "floor", (METHOD)nm_unary_floor, 0);
322
325
  rb_define_method(cNMatrix, "ceil", (METHOD)nm_unary_ceil, 0);
323
- rb_define_method(cNMatrix, "round", (METHOD)nm_unary_round, 0);
326
+ rb_define_method(cNMatrix, "round", (METHOD)nm_unary_round, -1);
324
327
 
325
328
 
326
329
  rb_define_method(cNMatrix, "=~", (METHOD)nm_ew_eqeq, 1);
@@ -338,13 +341,18 @@ void Init_nmatrix() {
338
341
  /////////////////////////
339
342
  // Matrix Math Methods //
340
343
  /////////////////////////
341
- rb_define_method(cNMatrix, "dot", (METHOD)nm_multiply, 1);
342
-
344
+ rb_define_method(cNMatrix, "dot", (METHOD)nm_multiply, 1);
343
345
  rb_define_method(cNMatrix, "symmetric?", (METHOD)nm_symmetric, 0);
344
346
  rb_define_method(cNMatrix, "hermitian?", (METHOD)nm_hermitian, 0);
345
-
346
347
  rb_define_method(cNMatrix, "capacity", (METHOD)nm_capacity, 0);
347
348
 
349
+ // protected methods
350
+ rb_define_protected_method(cNMatrix, "__inverse__", (METHOD)nm_inverse, 2);
351
+ rb_define_protected_method(cNMatrix, "__inverse_exact__", (METHOD)nm_inverse_exact, 3);
352
+
353
+ // private methods
354
+ rb_define_private_method(cNMatrix, "__hessenberg__", (METHOD)nm_hessenberg, 1);
355
+
348
356
  /////////////////
349
357
  // FFI Methods //
350
358
  /////////////////
@@ -680,8 +688,8 @@ void nm_unregister_nmatrix(NMATRIX* nmatrix) {
680
688
  * dtype -> Symbol
681
689
  *
682
690
  * Get the data type (dtype) of a matrix, e.g., :byte, :int8, :int16, :int32,
683
- * :int64, :float32, :float64, :complex64, :complex128, :rational32,
684
- * :rational64, :rational128, or :object (the last is a Ruby object).
691
+ * :int64, :float32, :float64, :complex64, :complex128,
692
+ * or :object (the last is a Ruby object).
685
693
  */
686
694
  static VALUE nm_dtype(VALUE self) {
687
695
  ID dtype = rb_intern(DTYPE_NAMES[NM_DTYPE(self)]);
@@ -872,6 +880,22 @@ static VALUE nm_eqeq(VALUE left, VALUE right) {
872
880
 
873
881
  bool result = false;
874
882
 
883
+ // Check that the shapes match before going any further.
884
+ if (l->storage->dim != r->storage->dim) {
885
+ NM_CONSERVATIVE(nm_unregister_value(&left));
886
+ NM_CONSERVATIVE(nm_unregister_value(&right));
887
+ rb_raise(nm_eShapeError, "cannot compare matrices with different dimension");
888
+ }
889
+
890
+ size_t dim = l->storage->dim;
891
+ for (size_t i=0; i<dim; i++) {
892
+ if (l->storage->shape[i] != r->storage->shape[i]) {
893
+ NM_CONSERVATIVE(nm_unregister_value(&left));
894
+ NM_CONSERVATIVE(nm_unregister_value(&right));
895
+ rb_raise(nm_eShapeError, "cannot compare matrices with different shapes");
896
+ }
897
+ }
898
+
875
899
  if (l->stype != r->stype) { // DIFFERENT STYPES
876
900
 
877
901
  if (l->stype == nm::DENSE_STORE)
@@ -938,7 +962,6 @@ DEF_UNARY_RUBY_ACCESSOR(GAMMA, gamma)
938
962
  DEF_UNARY_RUBY_ACCESSOR(NEGATE, negate)
939
963
  DEF_UNARY_RUBY_ACCESSOR(FLOOR, floor)
940
964
  DEF_UNARY_RUBY_ACCESSOR(CEIL, ceil)
941
- DEF_UNARY_RUBY_ACCESSOR(ROUND, round)
942
965
 
943
966
  DEF_NONCOM_ELEMENTWISE_RUBY_ACCESSOR(ATAN2, atan2)
944
967
  DEF_NONCOM_ELEMENTWISE_RUBY_ACCESSOR(LDEXP, ldexp)
@@ -969,6 +992,31 @@ static VALUE nm_unary_log(int argc, VALUE* argv, VALUE self) {
969
992
  return rb_funcall(self, rb_intern(sym.c_str()), 1, nm::RubyObject(default_log_base).rval);
970
993
  }
971
994
 
995
+ static VALUE nm_unary_round(int argc, VALUE* argv, VALUE self) {
996
+ NM_CONSERVATIVE(nm_register_values(argv, argc));
997
+ const int default_precision = 0;
998
+ NMATRIX* left;
999
+ UnwrapNMatrix(self, left);
1000
+ std::string sym;
1001
+
1002
+ switch(left->stype) {
1003
+ case nm::DENSE_STORE:
1004
+ sym = "__dense_unary_round__";
1005
+ break;
1006
+ case nm::YALE_STORE:
1007
+ sym = "__yale_unary_round__";
1008
+ break;
1009
+ case nm::LIST_STORE:
1010
+ sym = "__list_unary_round__";
1011
+ break;
1012
+ }
1013
+ NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1014
+ if (argc > 0) { //supplied precision
1015
+ return rb_funcall(self, rb_intern(sym.c_str()), 1, argv[0]);
1016
+ }
1017
+ return rb_funcall(self, rb_intern(sym.c_str()), 1, nm::RubyObject(default_precision).rval);
1018
+ }
1019
+
972
1020
  //DEF_ELEMENTWISE_RUBY_ACCESSOR(ATAN2, atan2)
973
1021
  //DEF_ELEMENTWISE_RUBY_ACCESSOR(LDEXP, ldexp)
974
1022
  //DEF_ELEMENTWISE_RUBY_ACCESSOR(HYPOT, hypot)
@@ -1306,7 +1354,7 @@ static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
1306
1354
  * default.
1307
1355
  *
1308
1356
  * The data type, or dtype, can be one of: :byte, :int8, :int16, :int32, :int64, :float32, :float64, :complex64,
1309
- * :complex128, :rational128, or :object. The constructor will attempt to guess it from the initial value/array/default
1357
+ * :complex128, or :object. The constructor will attempt to guess it from the initial value/array/default
1310
1358
  * provided, if any. Otherwise, the default is :object, which stores any type of Ruby object.
1311
1359
  *
1312
1360
  * In addition to the above, there is a legacy constructor from the alpha version. To use that version, you must be
@@ -2457,14 +2505,15 @@ static VALUE is_symmetric(VALUE self, bool hermitian) {
2457
2505
 
2458
2506
  NMATRIX* m;
2459
2507
  UnwrapNMatrix(self, m);
2508
+ bool is_symmetric = false;
2460
2509
 
2461
2510
  if (m->storage->shape[0] == m->storage->shape[1] and m->storage->dim == 2) {
2462
2511
  if (NM_STYPE(self) == nm::DENSE_STORE) {
2463
2512
  if (hermitian) {
2464
- nm_dense_storage_is_hermitian((DENSE_STORAGE*)(m->storage), m->storage->shape[0]);
2513
+ is_symmetric = nm_dense_storage_is_hermitian((DENSE_STORAGE*)(m->storage), m->storage->shape[0]);
2465
2514
 
2466
2515
  } else {
2467
- nm_dense_storage_is_symmetric((DENSE_STORAGE*)(m->storage), m->storage->shape[0]);
2516
+ is_symmetric = nm_dense_storage_is_symmetric((DENSE_STORAGE*)(m->storage), m->storage->shape[0]);
2468
2517
  }
2469
2518
 
2470
2519
  } else {
@@ -2475,7 +2524,7 @@ static VALUE is_symmetric(VALUE self, bool hermitian) {
2475
2524
 
2476
2525
  }
2477
2526
  NM_CONSERVATIVE(nm_unregister_value(&self));
2478
- return Qfalse;
2527
+ return is_symmetric ? Qtrue : Qfalse;
2479
2528
  }
2480
2529
 
2481
2530
  ///////////////////////
@@ -2512,20 +2561,6 @@ nm::dtype_t nm_dtype_min_fixnum(int64_t v) {
2512
2561
  }
2513
2562
  }
2514
2563
 
2515
- /*
2516
- * Helper for nm_dtype_min(), handling rationals.
2517
- */
2518
- nm::dtype_t nm_dtype_min_rational(VALUE vv) {
2519
- NM_CONSERVATIVE(nm_register_value(&vv));
2520
- nm::Rational128* v = NM_ALLOCA_N(nm::Rational128, 1);
2521
- rubyval_to_cval(vv, nm::RATIONAL128, v);
2522
- NM_CONSERVATIVE(nm_unregister_value(&vv));
2523
- int64_t i = std::max(std::abs(v->n), v->d);
2524
- if (i <= SHRT_MAX) return nm::INT16;
2525
- else if (i <= INT_MAX) return nm::INT32;
2526
- else return nm::INT64;
2527
- }
2528
-
2529
2564
  /*
2530
2565
  * Return the minimum dtype required to store a given value.
2531
2566
  *
@@ -2548,8 +2583,6 @@ nm::dtype_t nm_dtype_min(VALUE v) {
2548
2583
  return nm::FLOAT32;
2549
2584
  case T_COMPLEX:
2550
2585
  return nm::COMPLEX64;
2551
- case T_RATIONAL:
2552
- return nm_dtype_min_rational(v);
2553
2586
  case T_STRING:
2554
2587
  return RSTRING_LEN(v) == 1 ? nm::BYTE : nm::RUBYOBJ;
2555
2588
  case T_TRUE:
@@ -2579,23 +2612,15 @@ nm::dtype_t nm_dtype_guess(VALUE v) {
2579
2612
  case T_FIXNUM:
2580
2613
  return nm::INT64;
2581
2614
 
2582
- case T_RATIONAL:
2583
- return nm::RATIONAL128;
2584
-
2585
2615
  #else
2586
2616
  # if SIZEOF_INT == 4
2587
2617
  case T_FIXNUM:
2588
2618
  return nm::INT32;
2589
2619
 
2590
- case T_RATIONAL:
2591
- return nm::RATIONAL64;
2592
-
2593
2620
  #else
2594
2621
  case T_FIXNUM:
2595
2622
  return nm::INT16;
2596
2623
 
2597
- case T_RATIONAL:
2598
- return nm::RATIONAL32;
2599
2624
  # endif
2600
2625
  #endif
2601
2626
 
@@ -2937,6 +2962,22 @@ static VALUE matrix_multiply(NMATRIX* left, NMATRIX* right) {
2937
2962
  return to_return;
2938
2963
  }
2939
2964
 
2965
+ /*
2966
+ * Reduce a matrix to hessenberg form.
2967
+ *
2968
+ * == Arguments
2969
+ *
2970
+ * a - The NMatrix to be reduced. This matrix is replaced with the hessenberg form.
2971
+ *
2972
+ * == Notes
2973
+ *
2974
+ * LAPACK free.
2975
+ */
2976
+ static VALUE nm_hessenberg(VALUE self, VALUE a) {
2977
+ nm_math_hessenberg(a);
2978
+
2979
+ return a;
2980
+ }
2940
2981
 
2941
2982
  /*
2942
2983
  * Calculate the inverse of a matrix with in-place Gauss-Jordan elimination.
@@ -976,12 +976,6 @@ bool eqeq(const DENSE_STORAGE* left, const DENSE_STORAGE* right) {
976
976
  tmp1 = NULL; tmp2 = NULL;
977
977
  bool result = true;
978
978
  /* FIXME: Very strange behavior! The GC calls the method directly with non-initialized data. */
979
- if (left->dim != right->dim) {
980
- nm_dense_storage_unregister(right);
981
- nm_dense_storage_unregister(left);
982
-
983
- return false;
984
- }
985
979
 
986
980
  LDType* left_elements = (LDType*)left->elements;
987
981
  RDType* right_elements = (RDType*)right->elements;
@@ -1030,7 +1024,7 @@ bool is_hermitian(const DENSE_STORAGE* mat, int lda) {
1030
1024
 
1031
1025
  for (i = mat->shape[0]; i-- > 0;) {
1032
1026
  for (j = i + 1; j < mat->shape[1]; ++j) {
1033
- complex_conj = els[j*lda + 1];
1027
+ complex_conj = els[j*lda + i];
1034
1028
  complex_conj.i = -complex_conj.i;
1035
1029
 
1036
1030
  if (els[i*lda+j] != complex_conj) {
@@ -56,7 +56,6 @@
56
56
  #define NMATRIX_DTYPE_IS_COMPLEX(s) ((s->dtype == nm::COMPLEX64) or (s->dtype == nm::COMPLEX128))
57
57
  #define NMATRIX_DTYPE_IS_FLOAT(s) ((s->dtype == nm::FLOAT32) or (s->dtype == nm::FLOAT64))
58
58
  #define NMATRIX_DTYPE_IS_INTEGER(s) (s->dtype <= nm::INT64)
59
- #define NMATRIX_DTYPE_IS_RATIONAL(s) ((s->dtype == nm::RATIONAL32) or (s->dtype == nm::RATIONAL64) or (s->dtype == nm::RATIONAL128))
60
59
  #define NMATRIX_DTYPE_IS_RUBYOBJ(s) (s->dtype == nm::RUBYOBJ)
61
60
 
62
61
 
@@ -12,9 +12,6 @@ DTYPES = [
12
12
  :float64_t,
13
13
  :'nm::Complex64',
14
14
  :'nm::Complex128',
15
- :'nm::Rational32',
16
- :'nm::Rational64',
17
- :'nm::Rational128',
18
15
  :'nm::RubyObject'
19
16
  ]
20
17
 
@@ -54,9 +51,6 @@ LR_ALLOWED = {
54
51
  :float64_t => DTYPES,
55
52
  :'nm::Complex64' => DTYPES,
56
53
  :'nm::Complex128' => DTYPES,
57
- :'nm::Rational32' => nullify([:float32_t, :float64_t, :'nm::Complex64', :'nm::Complex128']),
58
- :'nm::Rational64' => nullify([:float32_t, :float64_t, :'nm::Complex64', :'nm::Complex128']),
59
- :'nm::Rational128' => nullify([:float32_t, :float64_t, :'nm::Complex64', :'nm::Complex128']),
60
54
  :'nm::RubyObject' => DTYPES
61
55
  }
62
56
 
@@ -212,7 +212,7 @@ static VALUE nm_rbstring_matlab_repack(VALUE self, VALUE str, VALUE from, VALUE
212
212
 
213
213
  // For next few lines, see explanation above NM_MATLAB_DTYPE_TEMPLATE_TABLE definition in io.h.
214
214
  if (to_type >= static_cast<uint8_t>(nm::COMPLEX64)) {
215
- rb_raise(rb_eArgError, "can only repack into a simple dtype, no complex/rational/VALUE");
215
+ rb_raise(rb_eArgError, "can only repack into a simple dtype, no complex/VALUE");
216
216
  }
217
217
 
218
218
  // Do the actual repacking -- really simple!
@@ -22,25 +22,7 @@
22
22
  #
23
23
  # == nmatrix.rb
24
24
  #
25
- # This file loads the C extension for NMatrix and all the ruby files.
25
+ # This file is a stub that only loads the main NMatrix file.
26
26
  #
27
27
 
28
- # For some reason nmatrix.so ends up in a different place during gem build.
29
- if File.exist?("lib/nmatrix/nmatrix.so") #|| File.exist?("lib/nmatrix/nmatrix.bundle")
30
- # Development
31
- require "nmatrix/nmatrix.so"
32
- else
33
- # Gem
34
- require "nmatrix.so"
35
- end
36
-
37
- require 'nmatrix/io/mat_reader'
38
- require 'nmatrix/io/mat5_reader'
39
- require 'nmatrix/io/market'
40
- require 'nmatrix/io/point_cloud'
41
-
42
28
  require 'nmatrix/nmatrix.rb'
43
- require 'nmatrix/version.rb'
44
- require 'nmatrix/blas.rb'
45
- require 'nmatrix/monkeys'
46
- require "nmatrix/shortcuts.rb"
@@ -28,6 +28,14 @@
28
28
  #++
29
29
 
30
30
  module NMatrix::BLAS
31
+
32
+ #Add functions from C extension to main BLAS module
33
+ class << self
34
+ NMatrix::Internal::BLAS.singleton_methods.each do |m|
35
+ define_method m, NMatrix::Internal::BLAS.method(m).to_proc
36
+ end
37
+ end
38
+
31
39
  class << self
32
40
  #
33
41
  # call-seq:
@@ -137,21 +145,20 @@ module NMatrix::BLAS
137
145
  raise(ArgumentError, 'Expected nil or dense NMatrix as third argument.') unless y.nil? or (y.is_a?(NMatrix) and y.stype == :dense)
138
146
  raise(ArgumentError, 'NMatrix dtype mismatch.') unless a.dtype == x.dtype and (y ? a.dtype == y.dtype : true)
139
147
 
140
- m ||= transpose_a ? a.shape[1] : a.shape[0]
141
- n ||= transpose_a ? a.shape[0] : a.shape[1]
148
+ m ||= transpose_a == :transpose ? a.shape[1] : a.shape[0]
149
+ n ||= transpose_a == :transpose ? a.shape[0] : a.shape[1]
150
+ raise(ArgumentError, "dimensions don't match") unless x.shape[0] == n && x.shape[1] == 1
151
+
152
+ if y
153
+ raise(ArgumentError, "dimensions don't match") unless y.shape[0] == m && y.shape[1] == 1
154
+ else
155
+ y = NMatrix.new([m,1], dtype: a.dtype)
156
+ end
142
157
 
143
158
  lda ||= a.shape[1]
144
159
  incx ||= 1
145
160
  incy ||= 1
146
161
 
147
- # NM_COMPLEX64 and NM_COMPLEX128 both require complex alpha and beta.
148
- if a.dtype == :complex64 or a.dtype == :complex128
149
- alpha = Complex(1.0, 0.0) if alpha == 1.0
150
- beta = Complex(0.0, 0.0) if beta == 0.0
151
- end
152
-
153
- y ||= NMatrix.new([m, n], dtype: a.dtype)
154
-
155
162
  ::NMatrix::BLAS.cblas_gemv(transpose_a, m, n, alpha, a, lda, x, incx, beta, y, incy)
156
163
 
157
164
  return y
@@ -218,7 +225,7 @@ module NMatrix::BLAS
218
225
  #
219
226
  # Apply givens plane rotation to the coordinates (a,b), returning the cosine and sine of the angle theta.
220
227
  #
221
- # Since the givens rotation includes a square root, integers and rationals are disallowed.
228
+ # Since the givens rotation includes a square root, integers are disallowed.
222
229
  #
223
230
  # * *Arguments* :
224
231
  # - +ab+ -> NMatrix with two elements
@@ -279,5 +286,20 @@ module NMatrix::BLAS
279
286
  raise(RangeError, "n out of range") if n*incx > x.size || n*incx <= 0 || n <= 0
280
287
  ::NMatrix::BLAS.cblas_nrm2(n, x, incx)
281
288
  end
289
+
290
+ # The following are functions that used to be implemented in C, but
291
+ # now require nmatrix-atlas or nmatrix-lapcke to run properly, so we can just
292
+ # implemented their stubs in Ruby.
293
+ def cblas_trmm(order, side, uplo, trans_a, diag, m, n, alpha, a, lda, b, ldb)
294
+ raise(NotImplementedError,"cblas_trmm requires either the nmatrix-lapacke or nmatrix-atlas gem")
295
+ end
296
+
297
+ def cblas_syrk(order, uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
298
+ raise(NotImplementedError,"cblas_syrk requires either the nmatrix-lapacke or nmatrix-atlas gem")
299
+ end
300
+
301
+ def cblas_herk(order, uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
302
+ raise(NotImplementedError,"cblas_herk requires either the nmatrix-lapacke or nmatrix-atlas gem")
303
+ end
282
304
  end
283
305
  end
@@ -94,15 +94,15 @@ module NMatrix::IO::Market
94
94
  # - +matrix+ -> NMatrix with the data to be saved.
95
95
  # - +filename+ -> String with the filename to be saved.
96
96
  # * *Raises* :
97
- # - +DataTypeError+ -> MatrixMarket does not support rational or Ruby objects.
97
+ # - +DataTypeError+ -> MatrixMarket does not support Ruby objects.
98
98
  # - +ArgumentError+ -> Expected two-dimensional NMatrix.
99
99
  def save(matrix, filename, options = {})
100
100
  options = {:pattern => false,
101
101
  :symmetry => :general}.merge(options)
102
102
 
103
103
  mode = matrix.stype == :dense ? :array : :coordinate
104
- if [:rational32,:rational64,:rational128,:object].include?(matrix.dtype)
105
- raise(DataTypeError, "MatrixMarket does not support rational or Ruby objects")
104
+ if [:object].include?(matrix.dtype)
105
+ raise(DataTypeError, "MatrixMarket does not support Ruby objects")
106
106
  end
107
107
  entry_type = options[:pattern] ? :pattern : ENTRY_TYPE[matrix.dtype]
108
108