nmatrix 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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