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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/ext/nmatrix/data/data.cpp +9 -9
  3. data/ext/nmatrix/data/data.h +7 -8
  4. data/ext/nmatrix/data/ruby_object.h +1 -4
  5. data/ext/nmatrix/extconf.rb +9 -127
  6. data/ext/nmatrix/math.cpp +25 -25
  7. data/ext/nmatrix/math/asum.h +10 -31
  8. data/ext/nmatrix/math/cblas_templates_core.h +10 -10
  9. data/ext/nmatrix/math/getrf.h +2 -2
  10. data/ext/nmatrix/math/imax.h +12 -9
  11. data/ext/nmatrix/math/laswp.h +3 -3
  12. data/ext/nmatrix/math/long_dtype.h +16 -3
  13. data/ext/nmatrix/math/magnitude.h +54 -0
  14. data/ext/nmatrix/math/nrm2.h +19 -14
  15. data/ext/nmatrix/math/trsm.h +40 -36
  16. data/ext/nmatrix/math/util.h +14 -0
  17. data/ext/nmatrix/nmatrix.h +39 -1
  18. data/ext/nmatrix/ruby_nmatrix.c +45 -83
  19. data/ext/nmatrix/storage/common.h +9 -3
  20. data/ext/nmatrix/storage/dense/dense.cpp +4 -4
  21. data/ext/nmatrix/storage/list/list.cpp +2 -2
  22. data/ext/nmatrix/storage/yale/class.h +1 -1
  23. data/lib/nmatrix/blas.rb +103 -34
  24. data/lib/nmatrix/io/fortran_format.rb +8 -5
  25. data/lib/nmatrix/io/harwell_boeing.rb +11 -10
  26. data/lib/nmatrix/io/market.rb +9 -6
  27. data/lib/nmatrix/io/mat5_reader.rb +54 -29
  28. data/lib/nmatrix/io/mat_reader.rb +26 -14
  29. data/lib/nmatrix/io/point_cloud.rb +19 -11
  30. data/lib/nmatrix/math.rb +224 -5
  31. data/lib/nmatrix/mkmf.rb +103 -0
  32. data/lib/nmatrix/nmatrix.rb +20 -6
  33. data/lib/nmatrix/shortcuts.rb +415 -0
  34. data/lib/nmatrix/version.rb +1 -1
  35. data/spec/00_nmatrix_spec.rb +50 -1
  36. data/spec/02_slice_spec.rb +21 -21
  37. data/spec/blas_spec.rb +25 -3
  38. data/spec/math_spec.rb +233 -5
  39. data/spec/shortcuts_spec.rb +145 -5
  40. data/spec/spec_helper.rb +24 -1
  41. metadata +20 -4
@@ -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
  *
@@ -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 CheckNMatrixType(v) if (TYPE(v) != T_DATA || (RDATA(v)->dfree != (RUBY_DATA_FUNC)nm_delete && RDATA(v)->dfree != (RUBY_DATA_FUNC)nm_delete_ref)) rb_raise(rb_eTypeError, "expected NMatrix on left-hand side of operation");
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)
@@ -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 (TYPE(initial_ary) == T_ARRAY)
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 (TYPE(initial_ary) == T_ARRAY) v_size = RARRAY_LEN(initial_ary);
1220
- else v_size = 1;
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]) && TYPE(argv[0]) != T_STRING) {
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]) || TYPE(argv[1+offset]) == T_ARRAY) {
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 (TYPE(argv[1+offset]) == T_ARRAY) init_val_len = RARRAY_LEN(argv[1+offset]);
1411
- else init_val_len = 1;
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 (TYPE(right_v) == T_ARRAY) {
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 (TYPE(right_val) != T_DATA || (RDATA(right_val)->dfree != (RUBY_DATA_FUNC)nm_delete && RDATA(right_val)->dfree != (RUBY_DATA_FUNC)nm_delete_ref)) {
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 (TYPE(other) != T_DATA || (RDATA(other)->dfree != (RUBY_DATA_FUNC)nm_delete && RDATA(other)->dfree != (RUBY_DATA_FUNC)nm_delete_ref)) {
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
- switch(TYPE(v)) {
2563
- case T_FIXNUM:
2565
+ if (RB_TYPE_P(v, T_FIXNUM))
2564
2566
  return nm_dtype_min_fixnum(FIX2LONG(v));
2565
- case T_BIGNUM:
2567
+ else if (RB_TYPE_P(v, T_BIGNUM))
2566
2568
  return nm::INT64;
2567
- case T_FLOAT:
2569
+ else if (RB_TYPE_P(v, T_FLOAT))
2568
2570
  return nm::FLOAT32;
2569
- case T_COMPLEX:
2571
+ else if (RB_TYPE_P(v, T_COMPLEX))
2570
2572
  return nm::COMPLEX64;
2571
- case T_STRING:
2573
+ else if (RB_TYPE_P(v, T_STRING))
2572
2574
  return RSTRING_LEN(v) == 1 ? nm::BYTE : nm::RUBYOBJ;
2573
- case T_TRUE:
2574
- case T_FALSE:
2575
- case T_NIL:
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
- switch(TYPE(v)) {
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
- case T_STRING:
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
- case T_COMPLEX:
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
- #else
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, Range, or Hash for slice component instead of %s", rb_obj_classname(v));
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 (TYPE(argv[offset]) == T_STRING) {
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 (TYPE(arg) == T_ARRAY) {
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 (TYPE(arg) == T_ARRAY) {
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 (TYPE(arg) == T_STRING) {
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
- nm_register_values(reinterpret_cast<VALUE*>(result), 1);
3049
- }
3050
- VALUE to_return = nm::rubyobj_from_cval(result, NM_DTYPE(self)).rval;
3051
- if (dtype == nm::RUBYOBJ) {
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, u_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, u_int8_t)
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, u_int8_t)
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 (TYPE(right) == T_ARRAY) {
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 (TYPE(right) == T_DATA && (RDATA(right)->dfree == (RUBY_DATA_FUNC)nm_delete || RDATA(right)->dfree == (RUBY_DATA_FUNC)nm_delete_ref)) {
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 (TYPE(right) == T_DATA) {
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
- register DType complex_conj;
1021
+ DType complex_conj;
1022
1022
 
1023
1023
  const DType* els = (DType*) mat->elements;
1024
1024