nmatrix 0.2.1 → 0.2.3
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/data.cpp +9 -9
- data/ext/nmatrix/data/data.h +7 -8
- data/ext/nmatrix/data/ruby_object.h +1 -4
- data/ext/nmatrix/extconf.rb +9 -127
- data/ext/nmatrix/math.cpp +25 -25
- data/ext/nmatrix/math/asum.h +10 -31
- data/ext/nmatrix/math/cblas_templates_core.h +10 -10
- data/ext/nmatrix/math/getrf.h +2 -2
- data/ext/nmatrix/math/imax.h +12 -9
- data/ext/nmatrix/math/laswp.h +3 -3
- data/ext/nmatrix/math/long_dtype.h +16 -3
- data/ext/nmatrix/math/magnitude.h +54 -0
- data/ext/nmatrix/math/nrm2.h +19 -14
- data/ext/nmatrix/math/trsm.h +40 -36
- data/ext/nmatrix/math/util.h +14 -0
- data/ext/nmatrix/nmatrix.h +39 -1
- data/ext/nmatrix/ruby_nmatrix.c +45 -83
- data/ext/nmatrix/storage/common.h +9 -3
- data/ext/nmatrix/storage/dense/dense.cpp +4 -4
- data/ext/nmatrix/storage/list/list.cpp +2 -2
- data/ext/nmatrix/storage/yale/class.h +1 -1
- data/lib/nmatrix/blas.rb +103 -34
- data/lib/nmatrix/io/fortran_format.rb +8 -5
- data/lib/nmatrix/io/harwell_boeing.rb +11 -10
- data/lib/nmatrix/io/market.rb +9 -6
- data/lib/nmatrix/io/mat5_reader.rb +54 -29
- data/lib/nmatrix/io/mat_reader.rb +26 -14
- data/lib/nmatrix/io/point_cloud.rb +19 -11
- data/lib/nmatrix/math.rb +224 -5
- data/lib/nmatrix/mkmf.rb +103 -0
- data/lib/nmatrix/nmatrix.rb +20 -6
- data/lib/nmatrix/shortcuts.rb +415 -0
- data/lib/nmatrix/version.rb +1 -1
- data/spec/00_nmatrix_spec.rb +50 -1
- data/spec/02_slice_spec.rb +21 -21
- data/spec/blas_spec.rb +25 -3
- data/spec/math_spec.rb +233 -5
- data/spec/shortcuts_spec.rb +145 -5
- data/spec/spec_helper.rb +24 -1
- metadata +20 -4
data/ext/nmatrix/math/util.h
CHANGED
@@ -70,6 +70,20 @@ static inline enum CBLAS_SIDE blas_side_sym(VALUE op) {
|
|
70
70
|
return CblasLeft;
|
71
71
|
}
|
72
72
|
|
73
|
+
/*
|
74
|
+
* Interprets the LAPACK side argument which could be :left or :right
|
75
|
+
*
|
76
|
+
* Related to obtaining Q in QR factorization after calling lapack_geqrf
|
77
|
+
*/
|
78
|
+
|
79
|
+
static inline char lapacke_side_sym(VALUE op) {
|
80
|
+
ID op_id = rb_to_id(op);
|
81
|
+
if (op_id == nm_rb_left) return 'L';
|
82
|
+
if (op_id == nm_rb_right) return 'R';
|
83
|
+
else rb_raise(rb_eArgError, "Expected :left or :right for side argument");
|
84
|
+
return 'L';
|
85
|
+
}
|
86
|
+
|
73
87
|
/*
|
74
88
|
* Interprets cblas argument which could be :upper or :lower
|
75
89
|
*
|
data/ext/nmatrix/nmatrix.h
CHANGED
@@ -33,6 +33,7 @@
|
|
33
33
|
*/
|
34
34
|
|
35
35
|
#include <ruby.h>
|
36
|
+
#include "ruby_constants.h"
|
36
37
|
|
37
38
|
#ifdef __cplusplus
|
38
39
|
#include <cmath>
|
@@ -57,6 +58,28 @@
|
|
57
58
|
#include "nm_memory.h"
|
58
59
|
#endif
|
59
60
|
|
61
|
+
#ifndef RB_BUILTIN_TYPE
|
62
|
+
# define RB_BUILTIN_TYPE(obj) BUILTIN_TYPE(obj)
|
63
|
+
#endif
|
64
|
+
|
65
|
+
#ifndef RB_FLOAT_TYPE_P
|
66
|
+
/* NOTE: assume flonum doesn't exist */
|
67
|
+
# define RB_FLOAT_TYPE_P(obj) ( \
|
68
|
+
(!SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == T_FLOAT))
|
69
|
+
#endif
|
70
|
+
|
71
|
+
#ifndef RB_TYPE_P
|
72
|
+
# define RB_TYPE_P(obj, type) ( \
|
73
|
+
((type) == T_FIXNUM) ? FIXNUM_P(obj) : \
|
74
|
+
((type) == T_TRUE) ? ((obj) == Qtrue) : \
|
75
|
+
((type) == T_FALSE) ? ((obj) == Qfalse) : \
|
76
|
+
((type) == T_NIL) ? ((obj) == Qnil) : \
|
77
|
+
((type) == T_UNDEF) ? ((obj) == Qundef) : \
|
78
|
+
((type) == T_SYMBOL) ? SYMBOL_P(obj) : \
|
79
|
+
((type) == T_FLOAT) ? RB_FLOAT_TYPE_P(obj) : \
|
80
|
+
(!SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == (type)))
|
81
|
+
#endif
|
82
|
+
|
60
83
|
#ifndef FIX_CONST_VALUE_PTR
|
61
84
|
# if defined(__fcc__) || defined(__fcc_version) || \
|
62
85
|
defined(__FCC__) || defined(__FCC_VERSION)
|
@@ -343,11 +366,25 @@ NM_DEF_STRUCT_POST(NM_GC_HOLDER); // };
|
|
343
366
|
|
344
367
|
#define NM_SRC(val) (NM_STORAGE(val)->src)
|
345
368
|
#define NM_DIM(val) (NM_STORAGE(val)->dim)
|
369
|
+
|
370
|
+
// Returns an int corresponding the data type of the nmatrix. See the dtype_t
|
371
|
+
// enum for a list of possible data types.
|
346
372
|
#define NM_DTYPE(val) (NM_STORAGE(val)->dtype)
|
373
|
+
|
374
|
+
// Returns a number corresponding the storage type of the nmatrix. See the stype_t
|
375
|
+
// enum for a list of possible storage types.
|
347
376
|
#define NM_STYPE(val) (NM_STRUCT(val)->stype)
|
377
|
+
|
378
|
+
// Get the shape of the ith dimension (int)
|
348
379
|
#define NM_SHAPE(val,i) (NM_STORAGE(val)->shape[(i)])
|
380
|
+
|
381
|
+
// Get the shape of the 0th dimension (int)
|
349
382
|
#define NM_SHAPE0(val) (NM_STORAGE(val)->shape[0])
|
383
|
+
|
384
|
+
// Get the shape of the 1st dimenension (int)
|
350
385
|
#define NM_SHAPE1(val) (NM_STORAGE(val)->shape[1])
|
386
|
+
|
387
|
+
// Get the default value assigned to the nmatrix.
|
351
388
|
#define NM_DEFAULT_VAL(val) (NM_STORAGE_LIST(val)->default_val)
|
352
389
|
|
353
390
|
// Number of elements in a dense nmatrix.
|
@@ -366,7 +403,8 @@ NM_DEF_STRUCT_POST(NM_GC_HOLDER); // };
|
|
366
403
|
|
367
404
|
#define RB_FILE_EXISTS(fn) (rb_funcall(rb_const_get(rb_cObject, rb_intern("File")), rb_intern("exists?"), 1, (fn)) == Qtrue)
|
368
405
|
|
369
|
-
#define
|
406
|
+
#define IsNMatrixType(v) (RB_TYPE_P(v, T_DATA) && (RDATA(v)->dfree == (RUBY_DATA_FUNC)nm_delete || RDATA(v)->dfree == (RUBY_DATA_FUNC)nm_delete_ref))
|
407
|
+
#define CheckNMatrixType(v) if (!IsNMatrixType(v)) rb_raise(rb_eTypeError, "expected NMatrix on left-hand side of operation");
|
370
408
|
|
371
409
|
#define NM_IsNMatrix(obj) \
|
372
410
|
(rb_obj_is_kind_of(obj, cNMatrix) == Qtrue)
|
data/ext/nmatrix/ruby_nmatrix.c
CHANGED
@@ -1099,13 +1099,15 @@ static VALUE nm_reshape_bang(VALUE self, VALUE arg){
|
|
1099
1099
|
size_t size = nm_storage_count_max_elements(s);
|
1100
1100
|
size_t new_size = 1;
|
1101
1101
|
size_t* shape = interpret_shape(shape_ary, &dim);
|
1102
|
-
void* elem = s->elements;
|
1103
1102
|
for (size_t index = 0; index < dim; ++index){
|
1104
1103
|
new_size *= shape[index];}
|
1105
1104
|
|
1106
1105
|
if (size == new_size){
|
1107
1106
|
s->shape = shape;
|
1108
1107
|
s->dim = dim;
|
1108
|
+
NM_FREE(s->offset);
|
1109
|
+
s->offset = NM_ALLOC_N(size_t, dim);
|
1110
|
+
memset(s->offset, 0, sizeof(size_t)*dim);
|
1109
1111
|
size_t i, j;
|
1110
1112
|
size_t* stride = NM_ALLOC_N(size_t, dim);
|
1111
1113
|
for (i = 0; i < dim; ++i) {
|
@@ -1113,8 +1115,9 @@ static VALUE nm_reshape_bang(VALUE self, VALUE arg){
|
|
1113
1115
|
for (j = i+1; j < dim; ++j) {
|
1114
1116
|
stride[i] *= shape[j];
|
1115
1117
|
}
|
1116
|
-
s->stride = stride;
|
1117
1118
|
}
|
1119
|
+
NM_FREE(s->stride);
|
1120
|
+
s->stride = stride;
|
1118
1121
|
return self;
|
1119
1122
|
}
|
1120
1123
|
else
|
@@ -1199,7 +1202,7 @@ static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
|
|
1199
1202
|
init = rubyobj_to_cval(default_val_num, dtype);
|
1200
1203
|
else if (NIL_P(initial_ary))
|
1201
1204
|
init = NULL;
|
1202
|
-
else if (
|
1205
|
+
else if (RB_TYPE_P(initial_ary, T_ARRAY))
|
1203
1206
|
init = RARRAY_LEN(initial_ary) == 1 ? rubyobj_to_cval(rb_ary_entry(initial_ary, 0), dtype) : NULL;
|
1204
1207
|
else
|
1205
1208
|
init = rubyobj_to_cval(initial_ary, dtype);
|
@@ -1216,8 +1219,8 @@ static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
|
|
1216
1219
|
|
1217
1220
|
if (!NIL_P(initial_ary)) {
|
1218
1221
|
|
1219
|
-
if (
|
1220
|
-
else
|
1222
|
+
if (RB_TYPE_P(initial_ary, T_ARRAY)) v_size = RARRAY_LEN(initial_ary);
|
1223
|
+
else v_size = 1;
|
1221
1224
|
|
1222
1225
|
v = interpret_initial_value(initial_ary, dtype);
|
1223
1226
|
|
@@ -1365,7 +1368,7 @@ static VALUE nm_init(int argc, VALUE* argv, VALUE nm) {
|
|
1365
1368
|
nm::stype_t stype;
|
1366
1369
|
size_t offset = 0;
|
1367
1370
|
|
1368
|
-
if (!SYMBOL_P(argv[0]) &&
|
1371
|
+
if (!SYMBOL_P(argv[0]) && !RB_TYPE_P(argv[0], T_STRING)) {
|
1369
1372
|
stype = nm::DENSE_STORE;
|
1370
1373
|
|
1371
1374
|
} else {
|
@@ -1397,7 +1400,7 @@ static VALUE nm_init(int argc, VALUE* argv, VALUE nm) {
|
|
1397
1400
|
|
1398
1401
|
size_t init_cap = 0, init_val_len = 0;
|
1399
1402
|
void* init_val = NULL;
|
1400
|
-
if (!SYMBOL_P(argv[1+offset]) ||
|
1403
|
+
if (!SYMBOL_P(argv[1+offset]) || RB_TYPE_P(argv[1+offset], T_ARRAY)) {
|
1401
1404
|
// Initial value provided (could also be initial capacity, if yale).
|
1402
1405
|
|
1403
1406
|
if (stype == nm::YALE_STORE && NM_RUBYVAL_IS_NUMERIC(argv[1+offset])) {
|
@@ -1407,8 +1410,8 @@ static VALUE nm_init(int argc, VALUE* argv, VALUE nm) {
|
|
1407
1410
|
// 4: initial value / dtype
|
1408
1411
|
init_val = interpret_initial_value(argv[1+offset], dtype);
|
1409
1412
|
|
1410
|
-
if (
|
1411
|
-
else
|
1413
|
+
if (RB_TYPE_P(argv[1+offset], T_ARRAY)) init_val_len = RARRAY_LEN(argv[1+offset]);
|
1414
|
+
else init_val_len = 1;
|
1412
1415
|
}
|
1413
1416
|
|
1414
1417
|
} else {
|
@@ -2057,7 +2060,7 @@ static VALUE nm_multiply(VALUE left_v, VALUE right_v) {
|
|
2057
2060
|
return matrix_multiply_scalar(left, right_v);
|
2058
2061
|
}
|
2059
2062
|
|
2060
|
-
else if (
|
2063
|
+
else if (RB_TYPE_P(right_v, T_ARRAY)) {
|
2061
2064
|
NM_CONSERVATIVE(nm_unregister_value(&left_v));
|
2062
2065
|
NM_CONSERVATIVE(nm_unregister_value(&right_v));
|
2063
2066
|
rb_raise(rb_eNotImpError, "please convert array to nx1 or 1xn NMatrix first");
|
@@ -2336,7 +2339,7 @@ static VALUE elementwise_op(nm::ewop_t op, VALUE left_val, VALUE right_val) {
|
|
2336
2339
|
CheckNMatrixType(left_val);
|
2337
2340
|
UnwrapNMatrix(left_val, left);
|
2338
2341
|
|
2339
|
-
if (
|
2342
|
+
if (!IsNMatrixType(right_val)) {
|
2340
2343
|
// This is a matrix-scalar element-wise operation.
|
2341
2344
|
std::string sym;
|
2342
2345
|
switch(left->stype) {
|
@@ -2413,7 +2416,7 @@ static VALUE noncom_elementwise_op(nm::noncom_ewop_t op, VALUE self, VALUE other
|
|
2413
2416
|
CheckNMatrixType(self);
|
2414
2417
|
UnwrapNMatrix(self, self_nm);
|
2415
2418
|
|
2416
|
-
if (
|
2419
|
+
if (!IsNMatrixType(other)) {
|
2417
2420
|
// This is a matrix-scalar element-wise operation.
|
2418
2421
|
std::string sym;
|
2419
2422
|
switch(self_nm->stype) {
|
@@ -2559,23 +2562,20 @@ nm::dtype_t nm_dtype_min_fixnum(int64_t v) {
|
|
2559
2562
|
*/
|
2560
2563
|
nm::dtype_t nm_dtype_min(VALUE v) {
|
2561
2564
|
|
2562
|
-
|
2563
|
-
case T_FIXNUM:
|
2565
|
+
if (RB_TYPE_P(v, T_FIXNUM))
|
2564
2566
|
return nm_dtype_min_fixnum(FIX2LONG(v));
|
2565
|
-
|
2567
|
+
else if (RB_TYPE_P(v, T_BIGNUM))
|
2566
2568
|
return nm::INT64;
|
2567
|
-
|
2569
|
+
else if (RB_TYPE_P(v, T_FLOAT))
|
2568
2570
|
return nm::FLOAT32;
|
2569
|
-
|
2571
|
+
else if (RB_TYPE_P(v, T_COMPLEX))
|
2570
2572
|
return nm::COMPLEX64;
|
2571
|
-
|
2573
|
+
else if (RB_TYPE_P(v, T_STRING))
|
2572
2574
|
return RSTRING_LEN(v) == 1 ? nm::BYTE : nm::RUBYOBJ;
|
2573
|
-
|
2574
|
-
|
2575
|
-
|
2576
|
-
default:
|
2575
|
+
else if (RB_TYPE_P(v, T_TRUE) || RB_TYPE_P(v, T_FALSE) || RB_TYPE_P(v, T_NIL))
|
2576
|
+
return nm::RUBYOBJ;
|
2577
|
+
else
|
2577
2578
|
return nm::RUBYOBJ;
|
2578
|
-
}
|
2579
2579
|
}
|
2580
2580
|
|
2581
2581
|
|
@@ -2585,60 +2585,39 @@ nm::dtype_t nm_dtype_min(VALUE v) {
|
|
2585
2585
|
* TODO: Probably needs some work for Bignum.
|
2586
2586
|
*/
|
2587
2587
|
nm::dtype_t nm_dtype_guess(VALUE v) {
|
2588
|
-
|
2589
|
-
case T_TRUE:
|
2590
|
-
case T_FALSE:
|
2591
|
-
case T_NIL:
|
2588
|
+
if (RB_TYPE_P(v, T_TRUE) || RB_TYPE_P(v, T_FALSE) || RB_TYPE_P(v, T_NIL))
|
2592
2589
|
return nm::RUBYOBJ;
|
2593
|
-
|
2590
|
+
else if (RB_TYPE_P(v, T_STRING))
|
2594
2591
|
return RSTRING_LEN(v) == 1 ? nm::BYTE : nm::RUBYOBJ;
|
2595
|
-
|
2592
|
+
else if (RB_TYPE_P(v, T_FIXNUM))
|
2596
2593
|
#if SIZEOF_INT == 8
|
2597
|
-
case T_FIXNUM:
|
2598
2594
|
return nm::INT64;
|
2599
|
-
|
2600
|
-
#else
|
2601
|
-
# if SIZEOF_INT == 4
|
2602
|
-
case T_FIXNUM:
|
2595
|
+
#elif SIZEOF_INT == 4
|
2603
2596
|
return nm::INT32;
|
2604
|
-
|
2605
2597
|
#else
|
2606
|
-
case T_FIXNUM:
|
2607
2598
|
return nm::INT16;
|
2608
|
-
|
2609
|
-
# endif
|
2610
2599
|
#endif
|
2611
|
-
|
2612
|
-
case T_BIGNUM:
|
2600
|
+
else if (RB_TYPE_P(v, T_BIGNUM))
|
2613
2601
|
return nm::INT64;
|
2614
|
-
|
2615
2602
|
#if SIZEOF_FLOAT == 4
|
2616
|
-
|
2603
|
+
else if (RB_TYPE_P(v, T_COMPLEX))
|
2617
2604
|
return nm::COMPLEX128;
|
2618
|
-
|
2619
|
-
case T_FLOAT:
|
2605
|
+
else if (RB_TYPE_P(v, T_FLOAT))
|
2620
2606
|
return nm::FLOAT64;
|
2621
|
-
|
2622
|
-
|
2623
|
-
# if SIZEOF_FLOAT == 2
|
2624
|
-
case T_COMPLEX:
|
2607
|
+
#elif SIZEOF_FLOAT == 2
|
2608
|
+
else if (RB_TYPE_P(v, T_COMPLEX))
|
2625
2609
|
return nm::COMPLEX64;
|
2626
|
-
|
2627
|
-
case T_FLOAT:
|
2610
|
+
else if (RB_TYPE_P(v, T_FLOAT))
|
2628
2611
|
return nm::FLOAT32;
|
2629
|
-
# endif
|
2630
2612
|
#endif
|
2631
|
-
|
2632
|
-
case T_ARRAY:
|
2613
|
+
else if (RB_TYPE_P(v, T_ARRAY))
|
2633
2614
|
/*
|
2634
2615
|
* May be passed for dense -- for now, just look at the first element.
|
2635
2616
|
*
|
2636
2617
|
* TODO: Look at entire array for most specific type.
|
2637
2618
|
*/
|
2638
|
-
|
2639
2619
|
return nm_dtype_guess(RARRAY_AREF(v, 0));
|
2640
|
-
|
2641
|
-
default:
|
2620
|
+
else {
|
2642
2621
|
RB_P(v);
|
2643
2622
|
rb_raise(rb_eArgError, "Unable to guess a data type from provided parameters; data type must be specified manually.");
|
2644
2623
|
}
|
@@ -2685,23 +2664,6 @@ static SLICE* get_slice(size_t dim, int argc, VALUE* arg, size_t* shape) {
|
|
2685
2664
|
slice->single = false;
|
2686
2665
|
t++;
|
2687
2666
|
|
2688
|
-
} else if (TYPE(arg[t]) == T_HASH) { // 3:5 notation (inclusive)
|
2689
|
-
VALUE begin_end = rb_funcall(v, rb_intern("shift"), 0); // rb_hash_shift
|
2690
|
-
nm_register_value(&begin_end);
|
2691
|
-
|
2692
|
-
if (rb_ary_entry(begin_end, 0) >= 0)
|
2693
|
-
slice->coords[r] = FIX2INT(rb_ary_entry(begin_end, 0));
|
2694
|
-
else
|
2695
|
-
slice->coords[r] = shape[r] + FIX2INT(rb_ary_entry(begin_end, 0));
|
2696
|
-
if (rb_ary_entry(begin_end, 1) >= 0)
|
2697
|
-
slice->lengths[r] = FIX2INT(rb_ary_entry(begin_end, 1)) - slice->coords[r];
|
2698
|
-
else
|
2699
|
-
slice->lengths[r] = shape[r] + FIX2INT(rb_ary_entry(begin_end, 1)) - slice->coords[r];
|
2700
|
-
|
2701
|
-
if (RHASH_EMPTY_P(v)) t++; // go on to the next
|
2702
|
-
slice->single = false;
|
2703
|
-
nm_unregister_value(&begin_end);
|
2704
|
-
|
2705
2667
|
} else if (CLASS_OF(v) == rb_cRange) {
|
2706
2668
|
rb_range_values(arg[t], &beg, &end, &excl);
|
2707
2669
|
|
@@ -2721,7 +2683,7 @@ static SLICE* get_slice(size_t dim, int argc, VALUE* arg, size_t* shape) {
|
|
2721
2683
|
|
2722
2684
|
} else {
|
2723
2685
|
NM_CONSERVATIVE(nm_unregister_values(arg, argc));
|
2724
|
-
rb_raise(rb_eArgError, "expected Fixnum
|
2686
|
+
rb_raise(rb_eArgError, "expected Fixnum or Range for slice component instead of %s", rb_obj_classname(v));
|
2725
2687
|
}
|
2726
2688
|
|
2727
2689
|
if (slice->coords[r] > shape[r] || slice->coords[r] + slice->lengths[r] > shape[r]) {
|
@@ -2773,7 +2735,7 @@ static nm::dtype_t interpret_dtype(int argc, VALUE* argv, nm::stype_t stype) {
|
|
2773
2735
|
if (SYMBOL_P(argv[offset])) {
|
2774
2736
|
return nm_dtype_from_rbsymbol(argv[offset]);
|
2775
2737
|
|
2776
|
-
} else if (
|
2738
|
+
} else if (RB_TYPE_P(argv[offset], T_STRING)) {
|
2777
2739
|
return nm_dtype_from_rbstring(StringValue(argv[offset]));
|
2778
2740
|
|
2779
2741
|
} else if (stype == nm::YALE_STORE) {
|
@@ -2793,7 +2755,7 @@ static void* interpret_initial_value(VALUE arg, nm::dtype_t dtype) {
|
|
2793
2755
|
unsigned int index;
|
2794
2756
|
void* init_val;
|
2795
2757
|
|
2796
|
-
if (
|
2758
|
+
if (RB_TYPE_P(arg, T_ARRAY)) {
|
2797
2759
|
// Array
|
2798
2760
|
init_val = NM_ALLOC_N(char, DTYPE_SIZES[dtype] * RARRAY_LEN(arg));
|
2799
2761
|
NM_CHECK_ALLOC(init_val);
|
@@ -2820,7 +2782,7 @@ static size_t* interpret_shape(VALUE arg, size_t* dim) {
|
|
2820
2782
|
NM_CONSERVATIVE(nm_register_value(&arg));
|
2821
2783
|
size_t* shape;
|
2822
2784
|
|
2823
|
-
if (
|
2785
|
+
if (RB_TYPE_P(arg, T_ARRAY)) {
|
2824
2786
|
*dim = RARRAY_LEN(arg);
|
2825
2787
|
shape = NM_ALLOC_N(size_t, *dim);
|
2826
2788
|
|
@@ -2851,7 +2813,7 @@ static nm::stype_t interpret_stype(VALUE arg) {
|
|
2851
2813
|
if (SYMBOL_P(arg)) {
|
2852
2814
|
return nm_stype_from_rbsymbol(arg);
|
2853
2815
|
|
2854
|
-
} else if (
|
2816
|
+
} else if (RB_TYPE_P(arg, T_STRING)) {
|
2855
2817
|
return nm_stype_from_rbstring(StringValue(arg));
|
2856
2818
|
|
2857
2819
|
} else {
|
@@ -3044,12 +3006,12 @@ static VALUE nm_det_exact(VALUE self) {
|
|
3044
3006
|
nm::dtype_t dtype = NM_DTYPE(self);
|
3045
3007
|
nm_math_det_exact(NM_SHAPE0(self), NM_STORAGE_DENSE(self)->elements, NM_SHAPE0(self), NM_DTYPE(self), result);
|
3046
3008
|
|
3009
|
+
VALUE to_return;
|
3047
3010
|
if (dtype == nm::RUBYOBJ) {
|
3048
|
-
|
3049
|
-
|
3050
|
-
|
3051
|
-
|
3052
|
-
nm_unregister_values(reinterpret_cast<VALUE*>(result), 1);
|
3011
|
+
to_return = *reinterpret_cast<VALUE*>(result);
|
3012
|
+
|
3013
|
+
} else {
|
3014
|
+
to_return = nm::rubyobj_from_cval(result, NM_DTYPE(self)).rval;
|
3053
3015
|
}
|
3054
3016
|
NM_CONSERVATIVE(nm_unregister_value(&self));
|
3055
3017
|
|
@@ -34,6 +34,7 @@
|
|
34
34
|
|
35
35
|
#include <ruby.h>
|
36
36
|
#include <cmath> // pow().
|
37
|
+
#include <type_traits>
|
37
38
|
|
38
39
|
/*
|
39
40
|
* Project Includes
|
@@ -45,6 +46,11 @@
|
|
45
46
|
* Macros
|
46
47
|
*/
|
47
48
|
|
49
|
+
#define u_int8_t static_assert(false, "Please use uint8_t for cross-platform support and consistency."); uint8_t
|
50
|
+
#define u_int16_t static_assert(false, "Please use uint16_t for cross-platform support and consistency."); uint16_t
|
51
|
+
#define u_int32_t static_assert(false, "Please use uint32_t for cross-platform support and consistency."); uint32_t
|
52
|
+
#define u_int64_t static_assert(false, "Please use uint64_t for cross-platform support and consistency."); uint64_t
|
53
|
+
|
48
54
|
extern "C" {
|
49
55
|
|
50
56
|
/*
|
@@ -152,7 +158,7 @@ namespace nm {
|
|
152
158
|
EWOP_INT_INT_DIV(int16_t, int32_t)
|
153
159
|
EWOP_INT_INT_DIV(int16_t, int64_t)
|
154
160
|
EWOP_INT_INT_DIV(int8_t, int8_t)
|
155
|
-
EWOP_INT_UINT_DIV(int8_t,
|
161
|
+
EWOP_INT_UINT_DIV(int8_t, uint8_t)
|
156
162
|
EWOP_INT_INT_DIV(int8_t, int16_t)
|
157
163
|
EWOP_INT_INT_DIV(int8_t, int32_t)
|
158
164
|
EWOP_INT_INT_DIV(int8_t, int64_t)
|
@@ -162,12 +168,12 @@ namespace nm {
|
|
162
168
|
EWOP_UINT_INT_DIV(uint8_t, int32_t)
|
163
169
|
EWOP_UINT_INT_DIV(uint8_t, int64_t)
|
164
170
|
EWOP_FLOAT_INT_DIV(float, int8_t)
|
165
|
-
EWOP_FLOAT_INT_DIV(float,
|
171
|
+
EWOP_FLOAT_INT_DIV(float, uint8_t)
|
166
172
|
EWOP_FLOAT_INT_DIV(float, int16_t)
|
167
173
|
EWOP_FLOAT_INT_DIV(float, int32_t)
|
168
174
|
EWOP_FLOAT_INT_DIV(float, int64_t)
|
169
175
|
EWOP_FLOAT_INT_DIV(double, int8_t)
|
170
|
-
EWOP_FLOAT_INT_DIV(double,
|
176
|
+
EWOP_FLOAT_INT_DIV(double, uint8_t)
|
171
177
|
EWOP_FLOAT_INT_DIV(double, int16_t)
|
172
178
|
EWOP_FLOAT_INT_DIV(double, int32_t)
|
173
179
|
EWOP_FLOAT_INT_DIV(double, int64_t)
|
@@ -140,7 +140,7 @@ namespace nm { namespace dense_storage {
|
|
140
140
|
v = reinterpret_cast<D*>(t->elements);
|
141
141
|
v_size = nm_storage_count_max_elements(t);
|
142
142
|
|
143
|
-
} else if (
|
143
|
+
} else if (RB_TYPE_P(right, T_ARRAY)) {
|
144
144
|
|
145
145
|
v_size = RARRAY_LEN(right);
|
146
146
|
v = NM_ALLOC_N(D, v_size);
|
@@ -875,7 +875,7 @@ namespace nm {
|
|
875
875
|
*/
|
876
876
|
std::pair<NMATRIX*,bool> interpret_arg_as_dense_nmatrix(VALUE right, nm::dtype_t dtype) {
|
877
877
|
NM_CONSERVATIVE(nm_register_value(&right));
|
878
|
-
if (
|
878
|
+
if (IsNMatrixType(right)) {
|
879
879
|
NMATRIX *r;
|
880
880
|
if (NM_STYPE(right) != DENSE_STORE || NM_DTYPE(right) != dtype || NM_SRC(right) != NM_STORAGE(right)) {
|
881
881
|
UnwrapNMatrix( right, r );
|
@@ -888,7 +888,7 @@ std::pair<NMATRIX*,bool> interpret_arg_as_dense_nmatrix(VALUE right, nm::dtype_t
|
|
888
888
|
return std::make_pair(r, false);
|
889
889
|
}
|
890
890
|
// Do not set v_alloc = true for either of these. It is the responsibility of r/ldtype_r
|
891
|
-
} else if (
|
891
|
+
} else if (RB_TYPE_P(right, T_DATA)) {
|
892
892
|
NM_CONSERVATIVE(nm_unregister_value(&right));
|
893
893
|
rb_raise(rb_eTypeError, "unrecognized type for slice assignment");
|
894
894
|
}
|
@@ -1018,7 +1018,7 @@ bool eqeq(const DENSE_STORAGE* left, const DENSE_STORAGE* right) {
|
|
1018
1018
|
template <typename DType>
|
1019
1019
|
bool is_hermitian(const DENSE_STORAGE* mat, int lda) {
|
1020
1020
|
unsigned int i, j;
|
1021
|
-
|
1021
|
+
DType complex_conj;
|
1022
1022
|
|
1023
1023
|
const DType* els = (DType*) mat->elements;
|
1024
1024
|
|