nmatrix 0.1.0.rc3 → 0.1.0.rc4
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/CONTRIBUTING.md +22 -21
- data/History.txt +13 -0
- data/Manifest.txt +1 -2
- data/README.rdoc +8 -8
- data/ext/nmatrix/binary_format.txt +1 -1
- data/ext/nmatrix/data/complex.h +21 -21
- data/ext/nmatrix/data/data.cpp +9 -2
- data/ext/nmatrix/data/data.h +4 -2
- data/ext/nmatrix/math.cpp +69 -31
- data/ext/nmatrix/math/getf2.h +2 -2
- data/ext/nmatrix/math/getrf.h +2 -2
- data/ext/nmatrix/math/imax.h +101 -0
- data/ext/nmatrix/math/scal.h +30 -10
- data/ext/nmatrix/math/swap.h +1 -22
- data/ext/nmatrix/nm_memory.h +1 -1
- data/ext/nmatrix/nmatrix.h +2 -2
- data/ext/nmatrix/ruby_constants.cpp +1 -2
- data/ext/nmatrix/ruby_constants.h +6 -7
- data/ext/nmatrix/ruby_nmatrix.c +23 -18
- data/ext/nmatrix/storage/list/list.cpp +48 -47
- data/ext/nmatrix/util/io.cpp +2 -2
- data/lib/nmatrix.rb +0 -1
- data/lib/nmatrix/enumerate.rb +1 -1
- data/lib/nmatrix/io/market.rb +1 -1
- data/lib/nmatrix/io/mat_reader.rb +41 -41
- data/lib/nmatrix/lapack.rb +0 -1
- data/lib/nmatrix/math.rb +43 -0
- data/lib/nmatrix/nmatrix.rb +5 -1
- data/lib/nmatrix/version.rb +1 -1
- data/nmatrix.gemspec +3 -4
- data/spec/00_nmatrix_spec.rb +13 -6
- data/spec/01_enum_spec.rb +17 -25
- data/spec/02_slice_spec.rb +74 -82
- data/spec/blas_spec.rb +21 -6
- data/spec/elementwise_spec.rb +1 -6
- data/spec/io_spec.rb +15 -22
- data/spec/lapack_spec.rb +1 -6
- data/spec/leakcheck.rb +1 -1
- data/spec/math_spec.rb +43 -4
- data/spec/nmatrix_yale_spec.rb +1 -4
- data/spec/rspec_spec.rb +1 -1
- data/spec/shortcuts_spec.rb +1 -6
- data/spec/slice_set_spec.rb +1 -5
- data/spec/stat_spec.rb +46 -51
- metadata +32 -22
- data/Guardfile +0 -6
- data/ext/nmatrix/math/idamax.h +0 -86
- data/lib/nmatrix/nvector.rb +0 -184
@@ -183,7 +183,7 @@ static void map_empty_stored_r(RecurseData& result, RecurseData& s, LIST* x, con
|
|
183
183
|
nm_list_storage_register_list(val, rec-1);
|
184
184
|
temp_vals.push_front(val);
|
185
185
|
nm::list::insert_helper(x, xcurr, curr->key - offset, val);
|
186
|
-
}
|
186
|
+
}
|
187
187
|
curr = curr->next;
|
188
188
|
if (curr && curr->key - offset >= x_shape) curr = NULL;
|
189
189
|
}
|
@@ -191,7 +191,10 @@ static void map_empty_stored_r(RecurseData& result, RecurseData& s, LIST* x, con
|
|
191
191
|
} else {
|
192
192
|
std::list<VALUE*> temp_vals;
|
193
193
|
while (curr) {
|
194
|
-
VALUE val, s_val
|
194
|
+
VALUE val, s_val;
|
195
|
+
if (s.dtype() == nm::RUBYOBJ) s_val = (*reinterpret_cast<nm::RubyObject*>(curr->val)).rval;
|
196
|
+
else s_val = rubyobj_from_cval(curr->val, s.dtype()).rval;
|
197
|
+
|
195
198
|
if (rev) val = rb_yield_values(2, t_init, s_val);
|
196
199
|
else val = rb_yield_values(2, s_val, t_init);
|
197
200
|
|
@@ -262,7 +265,7 @@ static void map_stored_r(RecurseData& result, RecurseData& left, LIST* x, const
|
|
262
265
|
size_t key;
|
263
266
|
VALUE val;
|
264
267
|
|
265
|
-
val = rb_yield_values(1, rubyobj_from_cval(lcurr->val, left.dtype()).rval);
|
268
|
+
val = rb_yield_values(1, left.dtype() == nm::RUBYOBJ ? *reinterpret_cast<VALUE*>(lcurr->val) : rubyobj_from_cval(lcurr->val, left.dtype()).rval);
|
266
269
|
key = lcurr->key - left.offset(rec);
|
267
270
|
lcurr = lcurr->next;
|
268
271
|
|
@@ -535,7 +538,7 @@ void set(VALUE left, SLICE* slice, VALUE right) {
|
|
535
538
|
NM_CONSERVATIVE(nm_register_value(left));
|
536
539
|
NM_CONSERVATIVE(nm_register_value(right));
|
537
540
|
LIST_STORAGE* s = NM_STORAGE_LIST(left);
|
538
|
-
|
541
|
+
|
539
542
|
std::pair<NMATRIX*,bool> nm_and_free =
|
540
543
|
interpret_arg_as_dense_nmatrix(right, NM_DTYPE(left));
|
541
544
|
|
@@ -701,11 +704,11 @@ static void __nm_list_storage_unregister_temp_list_list(std::list<LIST*>& temp_v
|
|
701
704
|
}
|
702
705
|
|
703
706
|
void nm_list_storage_register_node(const NODE* curr) {
|
704
|
-
nm_register_value(*reinterpret_cast<VALUE*>(curr->val));
|
707
|
+
nm_register_value(*reinterpret_cast<VALUE*>(curr->val));
|
705
708
|
}
|
706
709
|
|
707
710
|
void nm_list_storage_unregister_node(const NODE* curr) {
|
708
|
-
nm_unregister_value(*reinterpret_cast<VALUE*>(curr->val));
|
711
|
+
nm_unregister_value(*reinterpret_cast<VALUE*>(curr->val));
|
709
712
|
}
|
710
713
|
|
711
714
|
/**
|
@@ -775,13 +778,13 @@ void nm_list_storage_unregister(const STORAGE* s) {
|
|
775
778
|
* Documentation goes here.
|
776
779
|
*/
|
777
780
|
static NODE* list_storage_get_single_node(LIST_STORAGE* s, SLICE* slice) {
|
778
|
-
|
779
|
-
|
780
|
-
NODE* n;
|
781
|
+
LIST* l = s->rows;
|
782
|
+
NODE* n;
|
781
783
|
|
782
|
-
for (r = 0; r < s->dim; r++) {
|
784
|
+
for (size_t r = 0; r < s->dim; r++) {
|
783
785
|
n = nm::list::find(l, s->offset[r] + slice->coords[r]);
|
784
|
-
|
786
|
+
|
787
|
+
if (n) l = reinterpret_cast<LIST*>(n->val);
|
785
788
|
else return NULL;
|
786
789
|
}
|
787
790
|
|
@@ -798,7 +801,7 @@ static void each_empty_with_indices_r(nm::list_storage::RecurseData& s, size_t r
|
|
798
801
|
NM_CONSERVATIVE(nm_register_value(stack));
|
799
802
|
|
800
803
|
if (rec) {
|
801
|
-
for (long index = 0; index < s.ref_shape(rec); ++index) {
|
804
|
+
for (unsigned long index = 0; index < s.ref_shape(rec); ++index) {
|
802
805
|
// Don't do an unshift/shift here -- we'll let that be handled in the lowest-level iteration (recursions == 0)
|
803
806
|
rb_ary_push(stack, LONG2NUM(index));
|
804
807
|
each_empty_with_indices_r(s, rec-1, stack);
|
@@ -806,7 +809,7 @@ static void each_empty_with_indices_r(nm::list_storage::RecurseData& s, size_t r
|
|
806
809
|
}
|
807
810
|
} else {
|
808
811
|
rb_ary_unshift(stack, empty);
|
809
|
-
for (long index = 0; index < s.ref_shape(rec); ++index) {
|
812
|
+
for (unsigned long index = 0; index < s.ref_shape(rec); ++index) {
|
810
813
|
rb_ary_push(stack, LONG2NUM(index));
|
811
814
|
rb_yield_splat(stack);
|
812
815
|
rb_ary_pop(stack);
|
@@ -833,7 +836,7 @@ static void each_with_indices_r(nm::list_storage::RecurseData& s, const LIST* l,
|
|
833
836
|
|
834
837
|
|
835
838
|
if (rec) {
|
836
|
-
for (long index = 0; index < shape; ++index) { // index in reference
|
839
|
+
for (unsigned long index = 0; index < shape; ++index) { // index in reference
|
837
840
|
rb_ary_push(stack, LONG2NUM(index));
|
838
841
|
if (!curr || index < curr->key - offset) {
|
839
842
|
each_empty_with_indices_r(s, rec-1, stack);
|
@@ -844,7 +847,7 @@ static void each_with_indices_r(nm::list_storage::RecurseData& s, const LIST* l,
|
|
844
847
|
rb_ary_pop(stack);
|
845
848
|
}
|
846
849
|
} else {
|
847
|
-
for (long index = 0; index < shape; ++index) {
|
850
|
+
for (unsigned long index = 0; index < shape; ++index) {
|
848
851
|
|
849
852
|
rb_ary_push(stack, LONG2NUM(index));
|
850
853
|
|
@@ -875,7 +878,7 @@ static void each_stored_with_indices_r(nm::list_storage::RecurseData& s, const L
|
|
875
878
|
if (s.dtype() == nm::RUBYOBJ)
|
876
879
|
nm_list_storage_register_list(l, rec);
|
877
880
|
NM_CONSERVATIVE(nm_register_value(stack));
|
878
|
-
|
881
|
+
|
879
882
|
NODE* curr = l->first;
|
880
883
|
|
881
884
|
size_t offset = s.offset(rec);
|
@@ -919,7 +922,6 @@ static void each_stored_with_indices_r(nm::list_storage::RecurseData& s, const L
|
|
919
922
|
}
|
920
923
|
|
921
924
|
|
922
|
-
|
923
925
|
/*
|
924
926
|
* Each/each-stored iterator, brings along the indices.
|
925
927
|
*/
|
@@ -945,21 +947,19 @@ VALUE nm_list_each_with_indices(VALUE nmatrix, bool stored) {
|
|
945
947
|
|
946
948
|
|
947
949
|
/*
|
948
|
-
* map merged stored iterator. Always returns a matrix containing RubyObjects
|
950
|
+
* map merged stored iterator. Always returns a matrix containing RubyObjects
|
951
|
+
* which probably needs to be casted.
|
949
952
|
*/
|
950
953
|
VALUE nm_list_map_stored(VALUE left, VALUE init) {
|
951
954
|
NM_CONSERVATIVE(nm_register_value(left));
|
952
955
|
NM_CONSERVATIVE(nm_register_value(init));
|
953
956
|
|
954
|
-
|
955
|
-
|
956
|
-
LIST_STORAGE *s = NM_STORAGE_LIST(left);
|
957
|
+
LIST_STORAGE *s = NM_STORAGE_LIST(left);
|
957
958
|
|
958
|
-
// For each matrix, if it's a reference, we want to deal directly with the
|
959
|
+
// For each matrix, if it's a reference, we want to deal directly with the
|
960
|
+
// original (with appropriate offsetting)
|
959
961
|
nm::list_storage::RecurseData sdata(s);
|
960
962
|
|
961
|
-
void* scalar_init = NULL;
|
962
|
-
|
963
963
|
//if (!rb_block_given_p()) {
|
964
964
|
// rb_raise(rb_eNotImpError, "RETURN_SIZED_ENUMERATOR probably won't work for a map_merged since no merged object is created");
|
965
965
|
//}
|
@@ -1077,14 +1077,14 @@ static LIST* slice_copy(const LIST_STORAGE* src, LIST* src_rows, size_t* coords,
|
|
1077
1077
|
nm_list_storage_register(src);
|
1078
1078
|
void *val = NULL;
|
1079
1079
|
int key;
|
1080
|
-
|
1080
|
+
|
1081
1081
|
LIST* dst_rows = nm::list::create();
|
1082
1082
|
NODE* src_node = src_rows->first;
|
1083
1083
|
std::list<VALUE*> temp_vals;
|
1084
1084
|
std::list<LIST*> temp_lists;
|
1085
1085
|
while (src_node) {
|
1086
1086
|
key = src_node->key - (src->offset[n] + coords[n]);
|
1087
|
-
|
1087
|
+
|
1088
1088
|
if (key >= 0 && (size_t)key < lengths[n]) {
|
1089
1089
|
if (src->dim - n > 1) {
|
1090
1090
|
val = slice_copy( src,
|
@@ -1130,7 +1130,6 @@ void* nm_list_storage_get(const STORAGE* storage, SLICE* slice) {
|
|
1130
1130
|
NODE* n = list_storage_get_single_node(s, slice);
|
1131
1131
|
nm_list_storage_unregister(s);
|
1132
1132
|
return (n ? n->val : s->default_val);
|
1133
|
-
|
1134
1133
|
} else {
|
1135
1134
|
void *init_val = NM_ALLOC_N(char, DTYPE_SIZES[s->dtype]);
|
1136
1135
|
memcpy(init_val, s->default_val, DTYPE_SIZES[s->dtype]);
|
@@ -1141,11 +1140,13 @@ void* nm_list_storage_get(const STORAGE* storage, SLICE* slice) {
|
|
1141
1140
|
memcpy(shape, slice->lengths, sizeof(size_t) * s->dim);
|
1142
1141
|
|
1143
1142
|
ns = nm_list_storage_create(s->dtype, shape, s->dim, init_val);
|
1144
|
-
|
1143
|
+
|
1145
1144
|
ns->rows = slice_copy(s, s->rows, slice->coords, slice->lengths, 0);
|
1146
1145
|
|
1147
|
-
if (s->dtype == nm::RUBYOBJ)
|
1146
|
+
if (s->dtype == nm::RUBYOBJ) {
|
1148
1147
|
nm_unregister_value(*reinterpret_cast<VALUE*>(init_val));
|
1148
|
+
}
|
1149
|
+
|
1149
1150
|
nm_list_storage_unregister(s);
|
1150
1151
|
|
1151
1152
|
return ns;
|
@@ -1166,14 +1167,13 @@ void* nm_list_storage_ref(const STORAGE* storage, SLICE* slice) {
|
|
1166
1167
|
NODE* n = list_storage_get_single_node(s, slice);
|
1167
1168
|
nm_list_storage_unregister(s);
|
1168
1169
|
return (n ? n->val : s->default_val);
|
1169
|
-
}
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
ns->
|
1174
|
-
ns->
|
1175
|
-
ns->
|
1176
|
-
ns->shape = NM_ALLOC_N(size_t, ns->dim);
|
1170
|
+
} else {
|
1171
|
+
ns = NM_ALLOC( LIST_STORAGE );
|
1172
|
+
|
1173
|
+
ns->dim = s->dim;
|
1174
|
+
ns->dtype = s->dtype;
|
1175
|
+
ns->offset = NM_ALLOC_N(size_t, ns->dim);
|
1176
|
+
ns->shape = NM_ALLOC_N(size_t, ns->dim);
|
1177
1177
|
|
1178
1178
|
for (size_t i = 0; i < ns->dim; ++i) {
|
1179
1179
|
ns->offset[i] = slice->coords[i] + s->offset[i];
|
@@ -1182,7 +1182,7 @@ void* nm_list_storage_ref(const STORAGE* storage, SLICE* slice) {
|
|
1182
1182
|
|
1183
1183
|
ns->rows = s->rows;
|
1184
1184
|
ns->default_val = s->default_val;
|
1185
|
-
|
1185
|
+
|
1186
1186
|
s->src->count++;
|
1187
1187
|
ns->src = s->src;
|
1188
1188
|
nm_list_storage_unregister(s);
|
@@ -1204,13 +1204,14 @@ static void slice_set_single(LIST_STORAGE* dest, LIST* l, void* val, size_t* coo
|
|
1204
1204
|
// drill down into the structure
|
1205
1205
|
NODE* node = NULL;
|
1206
1206
|
if (dest->dim - n > 1) {
|
1207
|
-
std::list<LIST*> temp_nodes;
|
1207
|
+
std::list<LIST*> temp_nodes;
|
1208
1208
|
for (size_t i = 0; i < lengths[n]; ++i) {
|
1209
1209
|
|
1210
1210
|
size_t key = i + dest->offset[n] + coords[n];
|
1211
1211
|
|
1212
1212
|
if (!node) {
|
1213
|
-
|
1213
|
+
// try to insert list
|
1214
|
+
node = nm::list::insert(l, false, key, nm::list::create());
|
1214
1215
|
} else if (!node->next || (node->next && node->next->key > key)) {
|
1215
1216
|
node = nm::list::insert_after(node, key, nm::list::create());
|
1216
1217
|
} else {
|
@@ -1364,20 +1365,20 @@ VALUE nm_list_storage_to_hash(const LIST_STORAGE* s, const nm::dtype_t dtype) {
|
|
1364
1365
|
size_t nm_list_storage_count_elements_r(const LIST* l, size_t recursions) {
|
1365
1366
|
size_t count = 0;
|
1366
1367
|
NODE* curr = l->first;
|
1367
|
-
|
1368
|
+
|
1368
1369
|
if (recursions) {
|
1369
1370
|
while (curr) {
|
1370
1371
|
count += nm_list_storage_count_elements_r(reinterpret_cast<const LIST*>(curr->val), recursions - 1);
|
1371
1372
|
curr = curr->next;
|
1372
1373
|
}
|
1373
|
-
|
1374
|
+
|
1374
1375
|
} else {
|
1375
1376
|
while (curr) {
|
1376
1377
|
++count;
|
1377
1378
|
curr = curr->next;
|
1378
1379
|
}
|
1379
1380
|
}
|
1380
|
-
|
1381
|
+
|
1381
1382
|
return count;
|
1382
1383
|
}
|
1383
1384
|
|
@@ -1387,7 +1388,7 @@ size_t nm_list_storage_count_elements_r(const LIST* l, size_t recursions) {
|
|
1387
1388
|
size_t nm_list_storage_count_nd_elements(const LIST_STORAGE* s) {
|
1388
1389
|
NODE *i_curr, *j_curr;
|
1389
1390
|
size_t count = 0;
|
1390
|
-
|
1391
|
+
|
1391
1392
|
if (s->dim != 2) {
|
1392
1393
|
rb_raise(rb_eNotImpError, "non-diagonal element counting only defined for dim = 2");
|
1393
1394
|
}
|
@@ -1403,7 +1404,7 @@ size_t nm_list_storage_count_nd_elements(const LIST_STORAGE* s) {
|
|
1403
1404
|
if (i != j) ++count;
|
1404
1405
|
}
|
1405
1406
|
}
|
1406
|
-
|
1407
|
+
|
1407
1408
|
return count;
|
1408
1409
|
}
|
1409
1410
|
|
@@ -1419,7 +1420,7 @@ LIST_STORAGE* nm_list_storage_copy(const LIST_STORAGE* rhs) {
|
|
1419
1420
|
nm_list_storage_register(rhs);
|
1420
1421
|
size_t *shape = NM_ALLOC_N(size_t, rhs->dim);
|
1421
1422
|
memcpy(shape, rhs->shape, sizeof(size_t) * rhs->dim);
|
1422
|
-
|
1423
|
+
|
1423
1424
|
void *init_val = NM_ALLOC_N(char, DTYPE_SIZES[rhs->dtype]);
|
1424
1425
|
memcpy(init_val, rhs->default_val, DTYPE_SIZES[rhs->dtype]);
|
1425
1426
|
|
@@ -1483,7 +1484,7 @@ static LIST_STORAGE* cast_copy(const LIST_STORAGE* rhs, dtype_t new_dtype) {
|
|
1483
1484
|
|
1484
1485
|
nm_list_storage_register(lhs);
|
1485
1486
|
// TODO: Needs optimization. When matrix is reference it is copped twice.
|
1486
|
-
if (rhs->src == rhs)
|
1487
|
+
if (rhs->src == rhs)
|
1487
1488
|
nm::list::cast_copy_contents<LDType, RDType>(lhs->rows, rhs->rows, rhs->dim - 1);
|
1488
1489
|
else {
|
1489
1490
|
LIST_STORAGE *tmp = nm_list_storage_copy(rhs);
|
data/ext/nmatrix/util/io.cpp
CHANGED
@@ -251,7 +251,7 @@ static VALUE nm_rbstring_merge(VALUE self, VALUE rb_real, VALUE rb_imaginary, VA
|
|
251
251
|
size_t merge_pos = 0;
|
252
252
|
|
253
253
|
// Merge the two sequences
|
254
|
-
for (size_t i = 0; i < RSTRING_LEN(rb_real); i += len) {
|
254
|
+
for (size_t i = 0; i < (size_t)RSTRING_LEN(rb_real); i += len) {
|
255
255
|
|
256
256
|
// Copy real number
|
257
257
|
memcpy(merge + merge_pos, real + i, len);
|
@@ -276,4 +276,4 @@ void nm_init_io() {
|
|
276
276
|
|
277
277
|
|
278
278
|
|
279
|
-
}
|
279
|
+
}
|
data/lib/nmatrix.rb
CHANGED
data/lib/nmatrix/enumerate.rb
CHANGED
data/lib/nmatrix/io/market.rb
CHANGED
@@ -210,7 +210,7 @@ module NMatrix::IO::Market
|
|
210
210
|
line.lstrip!
|
211
211
|
line, comment = line.split('%', 2) # ignore comments
|
212
212
|
if line.size > 4
|
213
|
-
shape0, shape1
|
213
|
+
shape0, shape1 = line.split
|
214
214
|
mat = NMatrix.new(:list, [shape0.to_i, shape1.to_i], 0, dtype)
|
215
215
|
break
|
216
216
|
end
|
@@ -38,62 +38,62 @@ module NMatrix::IO::Matlab
|
|
38
38
|
#
|
39
39
|
class MatReader
|
40
40
|
MDTYPE_UNPACK_ARGS = {
|
41
|
-
:miINT8
|
42
|
-
:miUINT8
|
43
|
-
:miINT16
|
44
|
-
:miUINT16
|
45
|
-
:miINT32
|
46
|
-
:miUINT32
|
47
|
-
:miSINGLE
|
48
|
-
:miDOUBLE
|
49
|
-
:miINT64
|
50
|
-
:miUINT64
|
41
|
+
:miINT8 => [Integer, {:signed => true, :bytes => 1}],
|
42
|
+
:miUINT8 => [Integer, {:signed => false, :bytes => 1}],
|
43
|
+
:miINT16 => [Integer, {:signed => true, :bytes => 2}],
|
44
|
+
:miUINT16 => [Integer, {:signed => false, :bytes => 2}],
|
45
|
+
:miINT32 => [Integer, {:signed => true, :bytes => 4}],
|
46
|
+
:miUINT32 => [Integer, {:signed => false, :bytes => 4}],
|
47
|
+
:miSINGLE => [Float, {:precision => :single, :bytes => 4, :endian => :native}],
|
48
|
+
:miDOUBLE => [Float, {:precision => :double, :bytes => 4, :endian => :native}],
|
49
|
+
:miINT64 => [Integer, {:signed => true, :bytes => 8}],
|
50
|
+
:miUINT64 => [Integer, {:signed => false, :bytes => 8}]
|
51
51
|
}
|
52
52
|
|
53
53
|
DTYPE_PACK_ARGS = {
|
54
|
-
:byte
|
55
|
-
:int8
|
56
|
-
:int16
|
57
|
-
:int32
|
58
|
-
:int64
|
59
|
-
:float32
|
60
|
-
:float64
|
61
|
-
:complex64
|
62
|
-
:complex128
|
54
|
+
:byte => [Integer, {:signed => false, :bytes => 1}],
|
55
|
+
:int8 => [Integer, {:signed => true, :bytes => 1}],
|
56
|
+
:int16 => [Integer, {:signed => true, :bytes => 2}],
|
57
|
+
:int32 => [Integer, {:signed => true, :bytes => 4}],
|
58
|
+
:int64 => [Integer, {:signed => true, :bytes => 8}],
|
59
|
+
:float32 => [Float, {:precision => :single, :bytes => 4, :endian => :native}],
|
60
|
+
:float64 => [Float, {:precision => :double, :bytes => 8, :endian => :native}],
|
61
|
+
:complex64 => [Float, {:precision => :single, :bytes => 4, :endian => :native}], #2x
|
62
|
+
:complex128 => [Float, {:precision => :double, :bytes => 8, :endian => :native}]
|
63
63
|
}
|
64
64
|
|
65
65
|
ITYPE_PACK_ARGS = {
|
66
|
-
:uint8
|
67
|
-
:uint16
|
68
|
-
:uint32
|
69
|
-
:uint64
|
66
|
+
:uint8 => [Integer, {:signed => false, :bytes => 1}],
|
67
|
+
:uint16 => [Integer, {:signed => false, :bytes => 2}],
|
68
|
+
:uint32 => [Integer, {:signed => false, :bytes => 4}],
|
69
|
+
:uint64 => [Integer, {:signed => false, :bytes => 8}],
|
70
70
|
}
|
71
71
|
|
72
72
|
NO_REPACK = [:miINT8, :miUINT8, :miINT16, :miINT32, :miSINGLE, :miDOUBLE, :miINT64]
|
73
73
|
|
74
74
|
# Convert from MATLAB dtype to NMatrix dtype.
|
75
75
|
MDTYPE_TO_DTYPE = {
|
76
|
-
:miUINT8
|
77
|
-
:miINT8
|
78
|
-
:miINT16
|
79
|
-
:miUINT16
|
80
|
-
:miINT32
|
81
|
-
:miUINT32
|
82
|
-
:miINT64
|
83
|
-
:miUINT64
|
84
|
-
:miSINGLE
|
85
|
-
:miDOUBLE
|
76
|
+
:miUINT8 => :byte,
|
77
|
+
:miINT8 => :int8,
|
78
|
+
:miINT16 => :int16,
|
79
|
+
:miUINT16 => :int16,
|
80
|
+
:miINT32 => :int32,
|
81
|
+
:miUINT32 => :int32,
|
82
|
+
:miINT64 => :int64,
|
83
|
+
:miUINT64 => :int64,
|
84
|
+
:miSINGLE => :float32,
|
85
|
+
:miDOUBLE => :float64
|
86
86
|
}
|
87
87
|
|
88
88
|
MDTYPE_TO_ITYPE = {
|
89
|
-
:miUINT8
|
90
|
-
:miINT8
|
91
|
-
:miINT16
|
92
|
-
:miUINT16
|
93
|
-
:miINT32
|
94
|
-
:miUINT32
|
95
|
-
:miINT64
|
96
|
-
:miUINT64
|
89
|
+
:miUINT8 => :uint8,
|
90
|
+
:miINT8 => :uint8,
|
91
|
+
:miINT16 => :uint16,
|
92
|
+
:miUINT16 => :uint16,
|
93
|
+
:miINT32 => :uint32,
|
94
|
+
:miUINT32 => :uint32,
|
95
|
+
:miINT64 => :uint64,
|
96
|
+
:miUINT64 => :uint64
|
97
97
|
}
|
98
98
|
|
99
99
|
# Before release v7.1 (release 14) matlab (TM) used the system
|
data/lib/nmatrix/lapack.rb
CHANGED
@@ -193,7 +193,6 @@ class NMatrix
|
|
193
193
|
# Perform eigenvalue decomposition on a matrix using LAPACK's xGEEV function.
|
194
194
|
#
|
195
195
|
def geev(matrix, which=:both)
|
196
|
-
result = alloc_evd_result(matrix)
|
197
196
|
jobvl = (which == :both || which == :left) ? :left : false
|
198
197
|
jobvr = (which == :both || which == :right) ? :right : false
|
199
198
|
|
data/lib/nmatrix/math.rb
CHANGED
@@ -607,6 +607,49 @@ protected
|
|
607
607
|
self.__dense_map__ { |l| -l }.cast(stype, dtype)
|
608
608
|
end
|
609
609
|
|
610
|
+
# These are for calculating the floor or ceil of matrix
|
611
|
+
def dtype_for_floor_or_ceil
|
612
|
+
if self.integer_dtype? or [:complex64, :complex128, :object].include?(self.dtype)
|
613
|
+
return_dtype = dtype
|
614
|
+
elsif [:float32, :float64, :rational32,:rational64, :rational128].include?(self.dtype)
|
615
|
+
return_dtype = :int64
|
616
|
+
end
|
617
|
+
|
618
|
+
return_dtype
|
619
|
+
end
|
620
|
+
|
621
|
+
[:floor, :ceil].each do |meth|
|
622
|
+
define_method("__list_unary_#{meth}__") do
|
623
|
+
return_dtype = dtype_for_floor_or_ceil
|
624
|
+
|
625
|
+
if [:complex64, :complex128].include?(self.dtype)
|
626
|
+
self.__list_map_stored__(nil) { |l| Complex(l.real.send(meth), l.imag.send(meth)) }.cast(stype, return_dtype)
|
627
|
+
else
|
628
|
+
self.__list_map_stored__(nil) { |l| l.send(meth) }.cast(stype, return_dtype)
|
629
|
+
end
|
630
|
+
end
|
631
|
+
|
632
|
+
define_method("__yale_unary_#{meth}__") do
|
633
|
+
return_dtype = dtype_for_floor_or_ceil
|
634
|
+
|
635
|
+
if [:complex64, :complex128].include?(self.dtype)
|
636
|
+
self.__yale_map_stored__ { |l| Complex(l.real.send(meth), l.imag.send(meth)) }.cast(stype, return_dtype)
|
637
|
+
else
|
638
|
+
self.__yale_map_stored__ { |l| l.send(meth) }.cast(stype, return_dtype)
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
define_method("__dense_unary_#{meth}__") do
|
643
|
+
return_dtype = dtype_for_floor_or_ceil
|
644
|
+
|
645
|
+
if [:complex64, :complex128].include?(self.dtype)
|
646
|
+
self.__dense_map__ { |l| Complex(l.real.send(meth), l.imag.send(meth)) }.cast(stype, return_dtype)
|
647
|
+
else
|
648
|
+
self.__dense_map__ { |l| l.send(meth) }.cast(stype, return_dtype)
|
649
|
+
end
|
650
|
+
end
|
651
|
+
end
|
652
|
+
|
610
653
|
# These take two arguments. One might be a matrix, and one might be a scalar.
|
611
654
|
# See also monkeys.rb, which contains Math module patches to let the first
|
612
655
|
# arg be a scalar
|