nmatrix 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/nmatrix/data/complex.h +20 -55
- data/ext/nmatrix/data/data.cpp +11 -44
- data/ext/nmatrix/data/data.h +174 -311
- data/ext/nmatrix/data/meta.h +1 -7
- data/ext/nmatrix/data/ruby_object.h +3 -85
- data/ext/nmatrix/extconf.rb +2 -73
- data/ext/nmatrix/math.cpp +170 -813
- data/ext/nmatrix/math/asum.h +2 -25
- data/ext/nmatrix/math/{inc.h → cblas_enums.h} +11 -22
- data/ext/nmatrix/math/cblas_templates_core.h +507 -0
- data/ext/nmatrix/math/gemm.h +2 -32
- data/ext/nmatrix/math/gemv.h +1 -35
- data/ext/nmatrix/math/getrf.h +21 -6
- data/ext/nmatrix/math/getrs.h +0 -8
- data/ext/nmatrix/math/imax.h +0 -22
- data/ext/nmatrix/math/long_dtype.h +0 -3
- data/ext/nmatrix/math/math.h +11 -337
- data/ext/nmatrix/math/nrm2.h +2 -23
- data/ext/nmatrix/math/rot.h +1 -25
- data/ext/nmatrix/math/rotg.h +4 -13
- data/ext/nmatrix/math/scal.h +0 -22
- data/ext/nmatrix/math/trsm.h +0 -55
- data/ext/nmatrix/math/util.h +148 -0
- data/ext/nmatrix/nmatrix.cpp +0 -14
- data/ext/nmatrix/nmatrix.h +92 -84
- data/ext/nmatrix/ruby_constants.cpp +0 -2
- data/ext/nmatrix/ruby_constants.h +0 -2
- data/ext/nmatrix/ruby_nmatrix.c +86 -45
- data/ext/nmatrix/storage/dense/dense.cpp +1 -7
- data/ext/nmatrix/storage/storage.h +0 -1
- data/ext/nmatrix/ttable_helper.rb +0 -6
- data/ext/nmatrix/util/io.cpp +1 -1
- data/lib/nmatrix.rb +1 -19
- data/lib/nmatrix/blas.rb +33 -11
- data/lib/nmatrix/io/market.rb +3 -3
- data/lib/nmatrix/lapack_core.rb +181 -0
- data/lib/nmatrix/lapack_plugin.rb +44 -0
- data/lib/nmatrix/math.rb +382 -131
- data/lib/nmatrix/monkeys.rb +2 -3
- data/lib/nmatrix/nmatrix.rb +166 -13
- data/lib/nmatrix/shortcuts.rb +72 -7
- data/lib/nmatrix/version.rb +2 -2
- data/spec/00_nmatrix_spec.rb +154 -5
- data/spec/02_slice_spec.rb +2 -6
- data/spec/03_nmatrix_monkeys_spec.rb +7 -1
- data/spec/blas_spec.rb +60 -33
- data/spec/homogeneous_spec.rb +10 -10
- data/spec/lapack_core_spec.rb +482 -0
- data/spec/math_spec.rb +436 -52
- data/spec/shortcuts_spec.rb +28 -4
- data/spec/spec_helper.rb +14 -2
- data/spec/utm5940.mtx +83844 -0
- metadata +49 -76
- data/.gitignore +0 -27
- data/.rspec +0 -2
- data/.travis.yml +0 -15
- data/CONTRIBUTING.md +0 -82
- data/Gemfile +0 -2
- data/History.txt +0 -677
- data/LICENSE.txt +0 -23
- data/Manifest.txt +0 -92
- data/README.rdoc +0 -150
- data/Rakefile +0 -216
- data/ext/nmatrix/data/rational.h +0 -440
- data/ext/nmatrix/math/geev.h +0 -82
- data/ext/nmatrix/math/ger.h +0 -96
- data/ext/nmatrix/math/gesdd.h +0 -80
- data/ext/nmatrix/math/gesvd.h +0 -78
- data/ext/nmatrix/math/getf2.h +0 -86
- data/ext/nmatrix/math/getri.h +0 -108
- data/ext/nmatrix/math/potrs.h +0 -129
- data/ext/nmatrix/math/swap.h +0 -52
- data/lib/nmatrix/lapack.rb +0 -240
- data/nmatrix.gemspec +0 -55
- data/scripts/mac-brew-gcc.sh +0 -50
- data/scripts/mac-mavericks-brew-gcc.sh +0 -22
- data/spec/lapack_spec.rb +0 -459
data/ext/nmatrix/ruby_nmatrix.c
CHANGED
@@ -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
|
-
|
267
|
-
|
268
|
-
|
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,
|
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",
|
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,
|
684
|
-
*
|
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,
|
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
|
-
|
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 +
|
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
|
|
data/ext/nmatrix/util/io.cpp
CHANGED
@@ -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/
|
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!
|
data/lib/nmatrix.rb
CHANGED
@@ -22,25 +22,7 @@
|
|
22
22
|
#
|
23
23
|
# == nmatrix.rb
|
24
24
|
#
|
25
|
-
# This file
|
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"
|
data/lib/nmatrix/blas.rb
CHANGED
@@ -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
|
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
|
data/lib/nmatrix/io/market.rb
CHANGED
@@ -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
|
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 [:
|
105
|
-
raise(DataTypeError, "MatrixMarket does not support
|
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
|
|