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