nmatrix 0.1.0.rc4 → 0.1.0.rc5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7aab05ad51eae5a3ccba6312f79d75b624ccb6a2
4
- data.tar.gz: d8a2d31cdf2290857458256724102588c4ef8da6
3
+ metadata.gz: 101aa626bcac374a9e9d435b01f81ce119df0589
4
+ data.tar.gz: 003a943f6e7a84371460c36cf7eec4b6e5edc732
5
5
  SHA512:
6
- metadata.gz: b242f8f8603d5ff19c525c4f1ced681bf7766bff43d273e61de7497dc724867d74613da98fabe444dda4360d05bc4973d296422af62fe6013c75feec0f3c8f3c
7
- data.tar.gz: ca9c9ac8ef252a35fcff3c3e9a405090711c47ecbc3ffe387e3e18861e6f1ddbf85654350e2c09616c11356705e8a2c234dd512fc9fb9780c60acb9dd08dd317
6
+ metadata.gz: 8caa3986e557c54d6040e86201537dce92c3db161a27d545059244a4e32b7dab2dd396962d1ac77724dffb499d9076aa6c9637dee688149fae7a072e2a03890e
7
+ data.tar.gz: 20fb3e32a7f7d59a02e20435ea80430ddddd20f6d479862ebc52e2dbc180ed17e0c1d35a3d9e7a7d65675ac0d382bed83b43a5cc3a1e9ea1478fbf66ba60dc52
data/Gemfile CHANGED
@@ -2,8 +2,3 @@ source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
4
  gem 'packable', ">= 1.3.5" # for Matlab IO
5
-
6
- group :development do
7
- #gem 'narray', :path => "../narray"
8
- #gem 'pry-debugger'
9
- end
data/History.txt CHANGED
@@ -603,7 +603,7 @@
603
603
 
604
604
  * No major enhancements.
605
605
 
606
- * 1 minor enhancements:
606
+ * 1 minor enhancement:
607
607
 
608
608
  * NMatrix#floor and #ceil implemented (by @v0dro)
609
609
 
@@ -612,3 +612,31 @@
612
612
  * Disallowed out-of-bounds rank calls (by @andrewcsmith)
613
613
 
614
614
  * Fixed rspec 3.0 conflict with rspec-longrun 1.0.1
615
+
616
+ === 0.1.0.rc5 / 2014-08-01
617
+
618
+ * No major enhancements.
619
+
620
+ * 1 minor enhancements:
621
+
622
+ * Added optional extension for generating homogeneous
623
+ transformation matrices for rotations and translations in three
624
+ dimensions
625
+
626
+ * 3 bug fixes:
627
+
628
+ * Fixed rake install (by @duggiefresh)
629
+
630
+ * Fixed API problems which prevented NMatrix from working with
631
+ the SciRuby rb-gsl fork
632
+
633
+ * Fixed Yale #inject behavior (by @yoongkang)
634
+
635
+ === 0.1.0.rc6 / 2014-08-??
636
+
637
+ * No major enhancements.
638
+
639
+ * No minor enhancements.
640
+
641
+ * No bug fixes.
642
+
data/Manifest.txt CHANGED
@@ -16,6 +16,7 @@ lib/nmatrix/io/mat_reader.rb
16
16
  lib/nmatrix/io/point_cloud.rb
17
17
  lib/nmatrix/blas.rb
18
18
  lib/nmatrix/enumerate.rb
19
+ lib/nmatrix/homogeneous.rb
19
20
  lib/nmatrix/lapack.rb
20
21
  lib/nmatrix/math.rb
21
22
  lib/nmatrix/monkeys.rb
data/README.rdoc CHANGED
@@ -41,7 +41,7 @@ If you want to obtain the latest (development) code, you should generally do:
41
41
  bundle install
42
42
  bundle exec rake compile
43
43
  bundle exec rake repackage
44
- gem install pkg/nmatrix-0.1.0.rc4.gem
44
+ gem install pkg/nmatrix-0.1.0.rc5.gem
45
45
 
46
46
  Detailed instructions are available for {Mac}[https://github.com/SciRuby/nmatrix/wiki/Installation#mac-os-x] and {Linux}[https://github.com/SciRuby/nmatrix/wiki/Installation#linux].
47
47
  We are currently working on Mavericks (Mac OS X) installation instructions, but in general, you'll need Homebrew and should
data/Rakefile CHANGED
@@ -3,6 +3,9 @@
3
3
  require 'rubygems'
4
4
  require 'rubygems/package_task'
5
5
  require 'bundler'
6
+
7
+ Bundler::GemHelper.install_tasks
8
+
6
9
  begin
7
10
  Bundler.setup(:default, :development)
8
11
  rescue Bundler::BundlerError => e
@@ -14,21 +17,16 @@ end
14
17
  require 'rake'
15
18
  require "rake/extensiontask"
16
19
  Rake::ExtensionTask.new do |ext|
17
- ext.name = 'nmatrix'
18
- ext.ext_dir = 'ext/nmatrix'
19
- ext.lib_dir = 'lib/'
20
- ext.source_pattern = "**/*.{c,cpp, h}"
20
+ ext.name = 'nmatrix'
21
+ ext.ext_dir = 'ext/nmatrix'
22
+ ext.lib_dir = 'lib/'
23
+ ext.source_pattern = "**/*.{c,cpp, h}"
21
24
  end
22
25
 
23
26
  gemspec = eval(IO.read("nmatrix.gemspec"))
24
27
 
25
28
  Gem::PackageTask.new(gemspec).define
26
29
 
27
- desc "install the gem locally"
28
- task :install => [:package] do
29
- sh %{gem install pkg/nmatrix-#{NMatrix::VERSION}.gem}
30
- end
31
-
32
30
  require 'rspec/core/rake_task'
33
31
  require 'rspec/core'
34
32
  require 'rspec/core/rake_task'
@@ -283,11 +283,11 @@ nm::RubyObject rubyobj_from_cval(void* val, nm::dtype_t dtype) {
283
283
  */
284
284
  void* rubyobj_to_cval(VALUE val, nm::dtype_t dtype) {
285
285
  size_t size = DTYPE_SIZES[dtype];
286
- NM_CONSERVATIVE(nm_register_value(val));
286
+ NM_CONSERVATIVE(nm_register_value(&val));
287
287
  void* ret_val = NM_ALLOC_N(char, size);
288
288
 
289
289
  rubyval_to_cval(val, dtype, ret_val);
290
- NM_CONSERVATIVE(nm_unregister_value(val));
290
+ NM_CONSERVATIVE(nm_unregister_value(&val));
291
291
  return ret_val;
292
292
  }
293
293
 
@@ -86,7 +86,7 @@ end
86
86
  if RUBY_VERSION < '1.9'
87
87
  raise(NotImplementedError, "Sorry, you need at least Ruby 1.9!")
88
88
  else
89
- $INSTALLFILES = [['nmatrix.h', '$(archdir)'], ['nmatrix.hpp', '$(archdir)'], ['nmatrix_config.h', '$(archdir)']]
89
+ $INSTALLFILES = [['nmatrix.h', '$(archdir)'], ['nmatrix.hpp', '$(archdir)'], ['nmatrix_config.h', '$(archdir)'], ['nm_memory.h', '$(archdir)']]
90
90
  if /cygwin|mingw/ =~ RUBY_PLATFORM
91
91
  $INSTALLFILES << ['libnmatrix.a', '$(archdir)']
92
92
  end
data/ext/nmatrix/math.cpp CHANGED
@@ -586,8 +586,8 @@ static VALUE nm_cblas_rotg(VALUE self, VALUE ab) {
586
586
  return Qnil;
587
587
 
588
588
  } else {
589
- NM_CONSERVATIVE(nm_register_value(self));
590
- NM_CONSERVATIVE(nm_register_value(ab));
589
+ NM_CONSERVATIVE(nm_register_value(&self));
590
+ NM_CONSERVATIVE(nm_register_value(&ab));
591
591
  void *pC = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]),
592
592
  *pS = NM_ALLOCA_N(char, DTYPE_SIZES[dtype]);
593
593
 
@@ -607,8 +607,8 @@ static VALUE nm_cblas_rotg(VALUE self, VALUE ab) {
607
607
  rb_ary_store(result, 0, rubyobj_from_cval(pC, dtype).rval);
608
608
  rb_ary_store(result, 1, rubyobj_from_cval(pS, dtype).rval);
609
609
  }
610
- NM_CONSERVATIVE(nm_unregister_value(ab));
611
- NM_CONSERVATIVE(nm_unregister_value(self));
610
+ NM_CONSERVATIVE(nm_unregister_value(&ab));
611
+ NM_CONSERVATIVE(nm_unregister_value(&self));
612
612
  return result;
613
613
  }
614
614
  }
@@ -53,7 +53,9 @@
53
53
  #endif
54
54
  #endif
55
55
 
56
- #include "nm_memory.h"
56
+ #ifdef __cplusplus
57
+ #include "nm_memory.h"
58
+ #endif
57
59
 
58
60
  /*
59
61
  * Macros
@@ -288,15 +290,15 @@ NM_DEF_STRUCT_POST(NMATRIX); // };
288
290
 
289
291
  /* Structs for dealing with VALUEs in use so that they don't get GC'd */
290
292
 
291
- typedef struct __NM_GC_LL_NODE {
292
- VALUE* val;
293
- size_t n;
294
- __NM_GC_LL_NODE* next;
295
- } nm_gc_ll_node;
293
+ NM_DEF_STRUCT_PRE(NM_GC_LL_NODE); // struct NM_GC_LL_NODE {
294
+ VALUE* val; // VALUE* val;
295
+ size_t n; // size_t n;
296
+ NM_DECL_STRUCT(NM_GC_LL_NODE*, next); // NM_GC_LL_NODE* next;
297
+ NM_DEF_STRUCT_POST(NM_GC_LL_NODE); // };
296
298
 
297
- typedef struct __NM_GC_HOLDER {
298
- __NM_GC_LL_NODE* start;
299
- } nm_gc_holder;
299
+ NM_DEF_STRUCT_PRE(NM_GC_HOLDER); // struct NM_GC_HOLDER {
300
+ NM_DECL_STRUCT(NM_GC_LL_NODE*, start); // NM_GC_LL_NODE* start;
301
+ NM_DEF_STRUCT_POST(NM_GC_HOLDER); // };
300
302
 
301
303
  #define NM_MAX_RANK 15
302
304
 
@@ -382,16 +384,17 @@ extern "C" {
382
384
  void nm_delete(NMATRIX* mat);
383
385
  void nm_delete_ref(NMATRIX* mat);
384
386
  void nm_register_values(VALUE* vals, size_t n);
387
+ void nm_register_value(VALUE* val);
388
+ void nm_unregister_value(VALUE* val);
385
389
  void nm_unregister_values(VALUE* vals, size_t n);
386
- void nm_register_value(VALUE& val);
387
- void nm_unregister_value(VALUE& val);
388
- void nm_register_storage(nm::stype_t stype, const STORAGE* storage);
389
- void nm_unregister_storage(nm::stype_t stype, const STORAGE* storage);
390
+ void nm_register_storage(NM_DECL_ENUM(stype_t, stype), const STORAGE* storage);
391
+ void nm_unregister_storage(NM_DECL_ENUM(stype_t, stype), const STORAGE* storage);
390
392
  void nm_register_nmatrix(NMATRIX* nmatrix);
391
393
  void nm_unregister_nmatrix(NMATRIX* nmatrix);
392
- void nm_completely_unregister_value(VALUE& val);
394
+ void nm_completely_unregister_value(VALUE* val);
393
395
  #ifdef __cplusplus
394
396
  }
397
+
395
398
  #endif
396
399
 
397
400
  #endif // NMATRIX_H
@@ -428,7 +428,7 @@ static VALUE nm_alloc(VALUE klass) {
428
428
  * just return the original matrix's capacity.
429
429
  */
430
430
  static VALUE nm_capacity(VALUE self) {
431
- NM_CONSERVATIVE(nm_register_value(self));
431
+ NM_CONSERVATIVE(nm_register_value(&self));
432
432
  VALUE cap;
433
433
 
434
434
  switch(NM_STYPE(self)) {
@@ -497,15 +497,15 @@ void nm_delete_ref(NMATRIX* mat) {
497
497
  * use by nmatrix so that they can be marked when GC runs.
498
498
  */
499
499
  static VALUE* gc_value_holder = NULL;
500
- static nm_gc_holder* gc_value_holder_struct = NULL;
501
- static nm_gc_holder* allocated_pool = NULL; // an object pool for linked list nodes; using pooling is in some cases a substantial performance improvement
500
+ static NM_GC_HOLDER* gc_value_holder_struct = NULL;
501
+ static NM_GC_HOLDER* allocated_pool = NULL; // an object pool for linked list nodes; using pooling is in some cases a substantial performance improvement
502
502
 
503
503
  /**
504
504
  * GC Marking function for the values that have been registered.
505
505
  */
506
- static void __nm_mark_value_container(nm_gc_holder* gc_value_holder_struct) {
506
+ static void __nm_mark_value_container(NM_GC_HOLDER* gc_value_holder_struct) {
507
507
  if (gc_value_holder_struct && gc_value_holder_struct->start) {
508
- nm_gc_ll_node* curr = gc_value_holder_struct->start;
508
+ NM_GC_LL_NODE* curr = gc_value_holder_struct->start;
509
509
  while (curr) {
510
510
  rb_gc_mark_locations(curr->val, curr->val + curr->n);
511
511
  curr = curr->next;
@@ -519,8 +519,8 @@ static void __nm_mark_value_container(nm_gc_holder* gc_value_holder_struct) {
519
519
  */
520
520
  static void __nm_initialize_value_container() {
521
521
  if (gc_value_holder == NULL) {
522
- gc_value_holder_struct = NM_ALLOC_NONRUBY(nm_gc_holder);
523
- allocated_pool = NM_ALLOC_NONRUBY(nm_gc_holder);
522
+ gc_value_holder_struct = NM_ALLOC_NONRUBY(NM_GC_HOLDER);
523
+ allocated_pool = NM_ALLOC_NONRUBY(NM_GC_HOLDER);
524
524
  gc_value_holder = NM_ALLOC_NONRUBY(VALUE);
525
525
  gc_value_holder_struct->start = NULL;
526
526
  allocated_pool->start = NULL;
@@ -537,12 +537,12 @@ void nm_register_values(VALUE* values, size_t n) {
537
537
  if (!gc_value_holder_struct)
538
538
  __nm_initialize_value_container();
539
539
  if (values) {
540
- nm_gc_ll_node* to_insert = NULL;
540
+ NM_GC_LL_NODE* to_insert = NULL;
541
541
  if (allocated_pool->start) {
542
542
  to_insert = allocated_pool->start;
543
543
  allocated_pool->start = to_insert->next;
544
544
  } else {
545
- to_insert = NM_ALLOC_NONRUBY(nm_gc_ll_node);
545
+ to_insert = NM_ALLOC_NONRUBY(NM_GC_LL_NODE);
546
546
  }
547
547
  to_insert->val = values;
548
548
  to_insert->n = n;
@@ -558,8 +558,8 @@ void nm_register_values(VALUE* values, size_t n) {
558
558
  void nm_unregister_values(VALUE* values, size_t n) {
559
559
  if (values) {
560
560
  if (gc_value_holder_struct) {
561
- nm_gc_ll_node* curr = gc_value_holder_struct->start;
562
- nm_gc_ll_node* last = NULL;
561
+ NM_GC_LL_NODE* curr = gc_value_holder_struct->start;
562
+ NM_GC_LL_NODE* last = NULL;
563
563
  while (curr) {
564
564
  if (curr->val == values) {
565
565
  if (last) {
@@ -580,18 +580,19 @@ void nm_unregister_values(VALUE* values, size_t n) {
580
580
  }
581
581
  }
582
582
 
583
+
583
584
  /**
584
585
  * Register a single VALUE as in use to avoid garbage collection.
585
586
  */
586
- void nm_register_value(VALUE& val) {
587
- nm_register_values(&val, 1);
587
+ void nm_register_value(VALUE* val) {
588
+ nm_register_values(val, 1);
588
589
  }
589
590
 
590
591
  /**
591
592
  * Unregister a single VALUE to allow normal garbage collection.
592
593
  */
593
- void nm_unregister_value(VALUE& val) {
594
- nm_unregister_values(&val, 1);
594
+ void nm_unregister_value(VALUE* val) {
595
+ nm_unregister_values(val, 1);
595
596
  }
596
597
 
597
598
  /**
@@ -600,26 +601,26 @@ void nm_unregister_value(VALUE& val) {
600
601
  * freed and replaced so that and residual registrations won't access after
601
602
  * free.
602
603
  **/
603
- void nm_completely_unregister_value(VALUE& val) {
604
+ void nm_completely_unregister_value(VALUE* val) {
604
605
  if (gc_value_holder_struct) {
605
- nm_gc_ll_node* curr = gc_value_holder_struct->start;
606
- nm_gc_ll_node* last = NULL;
606
+ NM_GC_LL_NODE* curr = gc_value_holder_struct->start;
607
+ NM_GC_LL_NODE* last = NULL;
607
608
  while (curr) {
608
- if (curr->val == &val) {
609
- if (last) {
610
- last->next = curr->next;
611
- } else {
612
- gc_value_holder_struct->start = curr->next;
613
- }
614
- nm_gc_ll_node* temp_next = curr->next;
615
- curr->next = allocated_pool->start;
616
- curr->val = NULL;
617
- curr->n = 0;
618
- allocated_pool->start = curr;
619
- curr = temp_next;
609
+ if (curr->val == val) {
610
+ if (last) {
611
+ last->next = curr->next;
612
+ } else {
613
+ gc_value_holder_struct->start = curr->next;
614
+ }
615
+ NM_GC_LL_NODE* temp_next = curr->next;
616
+ curr->next = allocated_pool->start;
617
+ curr->val = NULL;
618
+ curr->n = 0;
619
+ allocated_pool->start = curr;
620
+ curr = temp_next;
620
621
  } else {
621
- last = curr;
622
- curr = curr->next;
622
+ last = curr;
623
+ curr = curr->next;
623
624
  }
624
625
  }
625
626
  }
@@ -725,7 +726,7 @@ static VALUE nm_default_value(VALUE self) {
725
726
  * Iterate over all entries of any matrix in standard storage order (as with #each), and include the indices.
726
727
  */
727
728
  static VALUE nm_each_with_indices(VALUE nmatrix) {
728
- NM_CONSERVATIVE(nm_register_value(nmatrix));
729
+ NM_CONSERVATIVE(nm_register_value(&nmatrix));
729
730
  VALUE to_return = Qnil;
730
731
 
731
732
  switch(NM_STYPE(nmatrix)) {
@@ -756,7 +757,7 @@ static VALUE nm_each_with_indices(VALUE nmatrix) {
756
757
  * i, j, ..., and the entry itself.
757
758
  */
758
759
  static VALUE nm_each_stored_with_indices(VALUE nmatrix) {
759
- NM_CONSERVATIVE(nm_register_value(nmatrix));
760
+ NM_CONSERVATIVE(nm_register_value(&nmatrix));
760
761
  VALUE to_return = Qnil;
761
762
 
762
763
  switch(NM_STYPE(nmatrix)) {
@@ -788,7 +789,7 @@ static VALUE nm_each_stored_with_indices(VALUE nmatrix) {
788
789
  * i, j, ..., and the entry itself.
789
790
  */
790
791
  static VALUE nm_map_stored(VALUE nmatrix) {
791
- NM_CONSERVATIVE(nm_register_value(nmatrix));
792
+ NM_CONSERVATIVE(nm_register_value(&nmatrix));
792
793
  VALUE to_return = Qnil;
793
794
 
794
795
  switch(NM_STYPE(nmatrix)) {
@@ -818,7 +819,7 @@ static VALUE nm_map_stored(VALUE nmatrix) {
818
819
  * than storage ordering, which only matters if your matrix is Yale.
819
820
  */
820
821
  static VALUE nm_each_ordered_stored_with_indices(VALUE nmatrix) {
821
- NM_CONSERVATIVE(nm_register_value(nmatrix));
822
+ NM_CONSERVATIVE(nm_register_value(&nmatrix));
822
823
  VALUE to_return = Qnil;
823
824
 
824
825
  switch(NM_STYPE(nmatrix)) {
@@ -852,8 +853,8 @@ static VALUE nm_each_ordered_stored_with_indices(VALUE nmatrix) {
852
853
  * When stypes differ, this function calls a protected Ruby method.
853
854
  */
854
855
  static VALUE nm_eqeq(VALUE left, VALUE right) {
855
- NM_CONSERVATIVE(nm_register_value(left));
856
- NM_CONSERVATIVE(nm_register_value(right));
856
+ NM_CONSERVATIVE(nm_register_value(&left));
857
+ NM_CONSERVATIVE(nm_register_value(&right));
857
858
 
858
859
  NMATRIX *l, *r;
859
860
 
@@ -889,8 +890,8 @@ static VALUE nm_eqeq(VALUE left, VALUE right) {
889
890
  }
890
891
  }
891
892
 
892
- NM_CONSERVATIVE(nm_unregister_value(left));
893
- NM_CONSERVATIVE(nm_unregister_value(right));
893
+ NM_CONSERVATIVE(nm_unregister_value(&left));
894
+ NM_CONSERVATIVE(nm_unregister_value(&right));
894
895
 
895
896
  return result ? Qtrue : Qfalse;
896
897
  }
@@ -1104,7 +1105,7 @@ NMATRIX* nm_create(nm::stype_t stype, STORAGE* storage) {
1104
1105
  */
1105
1106
  static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
1106
1107
  NM_CONSERVATIVE(nm_register_values(argv, argc));
1107
- NM_CONSERVATIVE(nm_register_value(self));
1108
+ NM_CONSERVATIVE(nm_register_value(&self));
1108
1109
  VALUE shape_ary, initial_ary, hash;
1109
1110
  //VALUE shape_ary, default_val, capacity, initial_ary, dtype_sym, stype_sym;
1110
1111
  // Mandatory args: shape, dtype, stype
@@ -1126,9 +1127,9 @@ static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
1126
1127
  }
1127
1128
  }
1128
1129
  #endif
1129
- NM_CONSERVATIVE(nm_register_value(shape_ary));
1130
- NM_CONSERVATIVE(nm_register_value(initial_ary));
1131
- NM_CONSERVATIVE(nm_register_value(hash));
1130
+ NM_CONSERVATIVE(nm_register_value(&shape_ary));
1131
+ NM_CONSERVATIVE(nm_register_value(&initial_ary));
1132
+ NM_CONSERVATIVE(nm_register_value(&hash));
1132
1133
  // Get the shape.
1133
1134
  size_t dim;
1134
1135
  size_t* shape = interpret_shape(shape_ary, &dim);
@@ -1144,9 +1145,9 @@ static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
1144
1145
  dtype_sym = rb_hash_aref(hash, ID2SYM(nm_rb_dtype));
1145
1146
  stype_sym = rb_hash_aref(hash, ID2SYM(nm_rb_stype));
1146
1147
  capacity_num = rb_hash_aref(hash, ID2SYM(nm_rb_capacity));
1147
- NM_CONSERVATIVE(nm_register_value(capacity_num));
1148
+ NM_CONSERVATIVE(nm_register_value(&capacity_num));
1148
1149
  default_val_num = rb_hash_aref(hash, ID2SYM(nm_rb_default));
1149
- NM_CONSERVATIVE(nm_register_value(default_val_num));
1150
+ NM_CONSERVATIVE(nm_register_value(&default_val_num));
1150
1151
  }
1151
1152
 
1152
1153
  // stype ||= :dense
@@ -1250,7 +1251,7 @@ static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
1250
1251
  nm_register_nmatrix(tmp);
1251
1252
  VALUE rb_tmp = Data_Wrap_Struct(CLASS_OF(self), nm_mark, nm_delete, tmp);
1252
1253
  nm_unregister_nmatrix(tmp);
1253
- nm_register_value(rb_tmp);
1254
+ nm_register_value(&rb_tmp);
1254
1255
  if (stype == nm::YALE_STORE) nm_yale_storage_set(self, slice, rb_tmp);
1255
1256
  else nm_list_storage_set(self, slice, rb_tmp);
1256
1257
 
@@ -1262,7 +1263,7 @@ static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
1262
1263
 
1263
1264
  // nm_delete(tmp); // This seems to enrage the garbage collector (because rb_tmp is still available). It'd be better if we could force it to free immediately, but no sweat.
1264
1265
 
1265
- nm_unregister_value(rb_tmp);
1266
+ nm_unregister_value(&rb_tmp);
1266
1267
  nm_unregister_values(slice_argv, dim);
1267
1268
  }
1268
1269
 
@@ -1275,15 +1276,15 @@ static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
1275
1276
  }
1276
1277
 
1277
1278
  if (!NIL_P(hash)) {
1278
- NM_CONSERVATIVE(nm_unregister_value(capacity_num));
1279
- NM_CONSERVATIVE(nm_unregister_value(default_val_num));
1279
+ NM_CONSERVATIVE(nm_unregister_value(&capacity_num));
1280
+ NM_CONSERVATIVE(nm_unregister_value(&default_val_num));
1280
1281
  }
1281
1282
 
1282
- NM_CONSERVATIVE(nm_unregister_value(shape_ary));
1283
- NM_CONSERVATIVE(nm_unregister_value(initial_ary));
1284
- NM_CONSERVATIVE(nm_unregister_value(hash));
1283
+ NM_CONSERVATIVE(nm_unregister_value(&shape_ary));
1284
+ NM_CONSERVATIVE(nm_unregister_value(&initial_ary));
1285
+ NM_CONSERVATIVE(nm_unregister_value(&hash));
1285
1286
 
1286
- NM_CONSERVATIVE(nm_unregister_value(self));
1287
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1287
1288
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1288
1289
  nm_unregister_storage(stype, nmatrix->storage);
1289
1290
 
@@ -1327,12 +1328,12 @@ static VALUE nm_init_new_version(int argc, VALUE* argv, VALUE self) {
1327
1328
  * shortcuts.rb.
1328
1329
  */
1329
1330
  static VALUE nm_init(int argc, VALUE* argv, VALUE nm) {
1330
- NM_CONSERVATIVE(nm_register_value(nm));
1331
+ NM_CONSERVATIVE(nm_register_value(&nm));
1331
1332
  NM_CONSERVATIVE(nm_register_values(argv, argc));
1332
1333
 
1333
1334
  if (argc <= 3) { // Call the new constructor unless all four arguments are given (or the 7-arg version is given)
1334
1335
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1335
- NM_CONSERVATIVE(nm_unregister_value(nm));
1336
+ NM_CONSERVATIVE(nm_unregister_value(&nm));
1336
1337
  return nm_init_new_version(argc, argv, nm);
1337
1338
  }
1338
1339
 
@@ -1353,12 +1354,12 @@ static VALUE nm_init(int argc, VALUE* argv, VALUE nm) {
1353
1354
  if (argc == 7) {
1354
1355
  if (stype == nm::YALE_STORE) {
1355
1356
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1356
- NM_CONSERVATIVE(nm_unregister_value(nm));
1357
+ NM_CONSERVATIVE(nm_unregister_value(&nm));
1357
1358
  return nm_init_yale_from_old_yale(argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], nm);
1358
1359
 
1359
1360
  } else {
1360
1361
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1361
- NM_CONSERVATIVE(nm_unregister_value(nm));
1362
+ NM_CONSERVATIVE(nm_unregister_value(&nm));
1362
1363
  rb_raise(rb_eArgError, "Expected 2-4 arguments (or 7 for internal Yale creation)");
1363
1364
  }
1364
1365
  }
@@ -1440,7 +1441,7 @@ static VALUE nm_init(int argc, VALUE* argv, VALUE nm) {
1440
1441
  }
1441
1442
 
1442
1443
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1443
- NM_CONSERVATIVE(nm_unregister_value(nm));
1444
+ NM_CONSERVATIVE(nm_unregister_value(&nm));
1444
1445
 
1445
1446
  return nm;
1446
1447
  }
@@ -1474,8 +1475,8 @@ NMATRIX* nm_cast_with_ctype_args(NMATRIX* self, nm::stype_t new_stype, nm::dtype
1474
1475
  * Copy constructor for changing dtypes and stypes.
1475
1476
  */
1476
1477
  VALUE nm_cast(VALUE self, VALUE new_stype_symbol, VALUE new_dtype_symbol, VALUE init) {
1477
- NM_CONSERVATIVE(nm_register_value(self));
1478
- NM_CONSERVATIVE(nm_register_value(init));
1478
+ NM_CONSERVATIVE(nm_register_value(&self));
1479
+ NM_CONSERVATIVE(nm_register_value(&init));
1479
1480
 
1480
1481
  nm::dtype_t new_dtype = nm_dtype_from_rbsymbol(new_dtype_symbol);
1481
1482
  nm::stype_t new_stype = nm_stype_from_rbsymbol(new_stype_symbol);
@@ -1494,8 +1495,8 @@ VALUE nm_cast(VALUE self, VALUE new_stype_symbol, VALUE new_dtype_symbol, VALUE
1494
1495
  VALUE to_return = Data_Wrap_Struct(CLASS_OF(self), nm_mark, nm_delete, m);
1495
1496
 
1496
1497
  nm_unregister_nmatrix(m);
1497
- NM_CONSERVATIVE(nm_unregister_value(self));
1498
- NM_CONSERVATIVE(nm_unregister_value(init));
1498
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1499
+ NM_CONSERVATIVE(nm_unregister_value(&init));
1499
1500
  return to_return;
1500
1501
 
1501
1502
  }
@@ -1504,7 +1505,7 @@ VALUE nm_cast(VALUE self, VALUE new_stype_symbol, VALUE new_dtype_symbol, VALUE
1504
1505
  * Copy constructor for transposing.
1505
1506
  */
1506
1507
  static VALUE nm_init_transposed(VALUE self) {
1507
- NM_CONSERVATIVE(nm_register_value(self));
1508
+ NM_CONSERVATIVE(nm_register_value(&self));
1508
1509
 
1509
1510
  static STORAGE* (*storage_copy_transposed[nm::NUM_STYPES])(const STORAGE* rhs_base) = {
1510
1511
  nm_dense_storage_copy_transposed,
@@ -1519,7 +1520,7 @@ static VALUE nm_init_transposed(VALUE self) {
1519
1520
  VALUE to_return = Data_Wrap_Struct(CLASS_OF(self), nm_mark, nm_delete, lhs);
1520
1521
 
1521
1522
  nm_unregister_nmatrix(lhs);
1522
- NM_CONSERVATIVE(nm_unregister_value(self));
1523
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1523
1524
  return to_return;
1524
1525
  }
1525
1526
 
@@ -1527,16 +1528,16 @@ static VALUE nm_init_transposed(VALUE self) {
1527
1528
  * Copy constructor for no change of dtype or stype (used for #initialize_copy hook).
1528
1529
  */
1529
1530
  static VALUE nm_init_copy(VALUE copy, VALUE original) {
1530
- NM_CONSERVATIVE(nm_register_value(copy));
1531
- NM_CONSERVATIVE(nm_register_value(original));
1531
+ NM_CONSERVATIVE(nm_register_value(&copy));
1532
+ NM_CONSERVATIVE(nm_register_value(&original));
1532
1533
 
1533
1534
  NMATRIX *lhs, *rhs;
1534
1535
 
1535
1536
  CheckNMatrixType(original);
1536
1537
 
1537
1538
  if (copy == original) {
1538
- NM_CONSERVATIVE(nm_unregister_value(copy));
1539
- NM_CONSERVATIVE(nm_unregister_value(original));
1539
+ NM_CONSERVATIVE(nm_unregister_value(&copy));
1540
+ NM_CONSERVATIVE(nm_unregister_value(&original));
1540
1541
  return copy;
1541
1542
  }
1542
1543
 
@@ -1549,8 +1550,8 @@ static VALUE nm_init_copy(VALUE copy, VALUE original) {
1549
1550
  CAST_TABLE(ttable);
1550
1551
  lhs->storage = ttable[lhs->stype][rhs->stype](rhs->storage, rhs->storage->dtype, NULL);
1551
1552
 
1552
- NM_CONSERVATIVE(nm_unregister_value(copy));
1553
- NM_CONSERVATIVE(nm_unregister_value(original));
1553
+ NM_CONSERVATIVE(nm_unregister_value(&copy));
1554
+ NM_CONSERVATIVE(nm_unregister_value(&original));
1554
1555
 
1555
1556
  return copy;
1556
1557
  }
@@ -1687,7 +1688,7 @@ static VALUE nm_write(int argc, VALUE* argv, VALUE self) {
1687
1688
  }
1688
1689
 
1689
1690
  NM_CONSERVATIVE(nm_register_values(argv, argc));
1690
- NM_CONSERVATIVE(nm_register_value(self));
1691
+ NM_CONSERVATIVE(nm_register_value(&self));
1691
1692
 
1692
1693
  VALUE file = argv[0],
1693
1694
  symm = argc == 1 ? Qnil : argv[1];
@@ -1699,7 +1700,7 @@ static VALUE nm_write(int argc, VALUE* argv, VALUE self) {
1699
1700
 
1700
1701
  if (nmatrix->storage->dtype == nm::RUBYOBJ) {
1701
1702
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1702
- NM_CONSERVATIVE(nm_unregister_value(self));
1703
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1703
1704
  rb_raise(rb_eNotImpError, "Ruby Object writing is not implemented yet");
1704
1705
  }
1705
1706
 
@@ -1714,12 +1715,12 @@ static VALUE nm_write(int argc, VALUE* argv, VALUE self) {
1714
1715
  // Check arguments before starting to write.
1715
1716
  if (nmatrix->stype == nm::LIST_STORE) {
1716
1717
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1717
- NM_CONSERVATIVE(nm_unregister_value(self));
1718
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1718
1719
  rb_raise(nm_eStorageTypeError, "cannot save list matrix; cast to yale or dense first");
1719
1720
  }
1720
1721
  if (symm_ != nm::NONSYMM) {
1721
1722
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1722
- NM_CONSERVATIVE(nm_unregister_value(self));
1723
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1723
1724
 
1724
1725
  if (dim != 2) rb_raise(rb_eArgError, "symmetry/triangularity not defined for a non-2D matrix");
1725
1726
  if (nmatrix->storage->shape[0] != nmatrix->storage->shape[1])
@@ -1768,7 +1769,7 @@ static VALUE nm_write(int argc, VALUE* argv, VALUE self) {
1768
1769
  f.close();
1769
1770
 
1770
1771
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1771
- NM_CONSERVATIVE(nm_unregister_value(self));
1772
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1772
1773
 
1773
1774
  return Qtrue;
1774
1775
  }
@@ -1788,7 +1789,7 @@ static VALUE nm_read(int argc, VALUE* argv, VALUE self) {
1788
1789
  using std::ifstream;
1789
1790
 
1790
1791
  NM_CONSERVATIVE(nm_register_values(argv, argc));
1791
- NM_CONSERVATIVE(nm_register_value(self));
1792
+ NM_CONSERVATIVE(nm_register_value(&self));
1792
1793
 
1793
1794
  VALUE file, force_;
1794
1795
 
@@ -1799,7 +1800,7 @@ static VALUE nm_read(int argc, VALUE* argv, VALUE self) {
1799
1800
 
1800
1801
  if (!RB_FILE_EXISTS(file)) { // FIXME: Errno::ENOENT
1801
1802
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1802
- NM_CONSERVATIVE(nm_unregister_value(self));
1803
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1803
1804
  rb_raise(rb_get_errno_exc("ENOENT"), "%s", RSTRING_PTR(file));
1804
1805
  }
1805
1806
 
@@ -1821,7 +1822,7 @@ static VALUE nm_read(int argc, VALUE* argv, VALUE self) {
1821
1822
  fver = fmajor * 10000 + fminor * 100 + release;
1822
1823
  if (fver > ver && force == false) {
1823
1824
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1824
- NM_CONSERVATIVE(nm_unregister_value(self));
1825
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1825
1826
  rb_raise(rb_eIOError, "File was created in newer version of NMatrix than current (%u.%u.%u)", fmajor, fminor, frelease);
1826
1827
  }
1827
1828
  if (null16 != 0) rb_warn("nm_read: Expected zero padding was not zero (0)\n");
@@ -1868,7 +1869,7 @@ static VALUE nm_read(int argc, VALUE* argv, VALUE self) {
1868
1869
  read_padded_yale_elements(f, reinterpret_cast<YALE_STORAGE*>(s), length, symm, dtype);
1869
1870
  } else {
1870
1871
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1871
- NM_CONSERVATIVE(nm_unregister_value(self));
1872
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1872
1873
  rb_raise(nm_eStorageTypeError, "please convert to yale or dense before saving");
1873
1874
  }
1874
1875
 
@@ -1882,7 +1883,7 @@ static VALUE nm_read(int argc, VALUE* argv, VALUE self) {
1882
1883
 
1883
1884
  nm_unregister_nmatrix(nm);
1884
1885
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
1885
- NM_CONSERVATIVE(nm_unregister_value(self));
1886
+ NM_CONSERVATIVE(nm_unregister_value(&self));
1886
1887
  nm_unregister_storage(stype, s);
1887
1888
 
1888
1889
  switch(stype) {
@@ -1987,7 +1988,7 @@ static VALUE nm_mset(int argc, VALUE* argv, VALUE self) {
1987
1988
  if ((size_t)(argc) > NM_DIM(self)+1) {
1988
1989
  rb_raise(rb_eArgError, "wrong number of arguments (%d for %lu)", argc, effective_dim(NM_STORAGE(self))+1);
1989
1990
  } else {
1990
- NM_CONSERVATIVE(nm_register_value(self));
1991
+ NM_CONSERVATIVE(nm_register_value(&self));
1991
1992
  NM_CONSERVATIVE(nm_register_values(argv, argc));
1992
1993
 
1993
1994
  SLICE* slice = get_slice(dim, argc-1, argv, NM_STORAGE(self)->shape);
@@ -2004,7 +2005,7 @@ static VALUE nm_mset(int argc, VALUE* argv, VALUE self) {
2004
2005
 
2005
2006
  to_return = argv[argc-1];
2006
2007
 
2007
- NM_CONSERVATIVE(nm_unregister_value(self));
2008
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2008
2009
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
2009
2010
  }
2010
2011
 
@@ -2019,22 +2020,22 @@ static VALUE nm_mset(int argc, VALUE* argv, VALUE self) {
2019
2020
  * The two matrices must be of the same stype (for now). If dtype differs, an upcast will occur.
2020
2021
  */
2021
2022
  static VALUE nm_multiply(VALUE left_v, VALUE right_v) {
2022
- NM_CONSERVATIVE(nm_register_value(left_v));
2023
- NM_CONSERVATIVE(nm_register_value(right_v));
2023
+ NM_CONSERVATIVE(nm_register_value(&left_v));
2024
+ NM_CONSERVATIVE(nm_register_value(&right_v));
2024
2025
 
2025
2026
  NMATRIX *left, *right;
2026
2027
 
2027
2028
  UnwrapNMatrix( left_v, left );
2028
2029
 
2029
2030
  if (NM_RUBYVAL_IS_NUMERIC(right_v)) {
2030
- NM_CONSERVATIVE(nm_unregister_value(left_v));
2031
- NM_CONSERVATIVE(nm_unregister_value(right_v));
2031
+ NM_CONSERVATIVE(nm_unregister_value(&left_v));
2032
+ NM_CONSERVATIVE(nm_unregister_value(&right_v));
2032
2033
  return matrix_multiply_scalar(left, right_v);
2033
2034
  }
2034
2035
 
2035
2036
  else if (TYPE(right_v) == T_ARRAY) {
2036
- NM_CONSERVATIVE(nm_unregister_value(left_v));
2037
- NM_CONSERVATIVE(nm_unregister_value(right_v));
2037
+ NM_CONSERVATIVE(nm_unregister_value(&left_v));
2038
+ NM_CONSERVATIVE(nm_unregister_value(&right_v));
2038
2039
  rb_raise(rb_eNotImpError, "please convert array to nx1 or 1xn NMatrix first");
2039
2040
  }
2040
2041
 
@@ -2045,38 +2046,38 @@ static VALUE nm_multiply(VALUE left_v, VALUE right_v) {
2045
2046
  // work like vector dot product for 1dim
2046
2047
  if (left->storage->dim == 1 && right->storage->dim == 1) {
2047
2048
  if (left->storage->shape[0] != right->storage->shape[0]) {
2048
- NM_CONSERVATIVE(nm_unregister_value(left_v));
2049
- NM_CONSERVATIVE(nm_unregister_value(right_v));
2049
+ NM_CONSERVATIVE(nm_unregister_value(&left_v));
2050
+ NM_CONSERVATIVE(nm_unregister_value(&right_v));
2050
2051
  rb_raise(rb_eArgError, "The left- and right-hand sides of the operation must have the same dimensionality.");
2051
2052
  } else {
2052
2053
  VALUE result = elementwise_op(nm::EW_MUL, left_v, right_v);
2053
2054
  VALUE to_return = rb_funcall(result, rb_intern("sum"),0);
2054
- NM_CONSERVATIVE(nm_unregister_value(left_v));
2055
- NM_CONSERVATIVE(nm_unregister_value(right_v));
2055
+ NM_CONSERVATIVE(nm_unregister_value(&left_v));
2056
+ NM_CONSERVATIVE(nm_unregister_value(&right_v));
2056
2057
  return to_return;
2057
2058
  }
2058
2059
  }
2059
2060
 
2060
2061
  if (left->storage->shape[1] != right->storage->shape[0]) {
2061
- NM_CONSERVATIVE(nm_unregister_value(left_v));
2062
- NM_CONSERVATIVE(nm_unregister_value(right_v));
2062
+ NM_CONSERVATIVE(nm_unregister_value(&left_v));
2063
+ NM_CONSERVATIVE(nm_unregister_value(&right_v));
2063
2064
  rb_raise(rb_eArgError, "incompatible dimensions");
2064
2065
  }
2065
2066
 
2066
2067
  if (left->stype != right->stype) {
2067
- NM_CONSERVATIVE(nm_unregister_value(left_v));
2068
- NM_CONSERVATIVE(nm_unregister_value(right_v));
2068
+ NM_CONSERVATIVE(nm_unregister_value(&left_v));
2069
+ NM_CONSERVATIVE(nm_unregister_value(&right_v));
2069
2070
  rb_raise(rb_eNotImpError, "matrices must have same stype");
2070
2071
  }
2071
2072
 
2072
- NM_CONSERVATIVE(nm_unregister_value(left_v));
2073
- NM_CONSERVATIVE(nm_unregister_value(right_v));
2073
+ NM_CONSERVATIVE(nm_unregister_value(&left_v));
2074
+ NM_CONSERVATIVE(nm_unregister_value(&right_v));
2074
2075
  return matrix_multiply(left, right);
2075
2076
 
2076
2077
  }
2077
2078
 
2078
- NM_CONSERVATIVE(nm_unregister_value(left_v));
2079
- NM_CONSERVATIVE(nm_unregister_value(right_v));
2079
+ NM_CONSERVATIVE(nm_unregister_value(&left_v));
2080
+ NM_CONSERVATIVE(nm_unregister_value(&right_v));
2080
2081
 
2081
2082
  return Qnil;
2082
2083
  }
@@ -2104,7 +2105,7 @@ static VALUE nm_dim(VALUE self) {
2104
2105
  * Get the shape (dimensions) of a matrix.
2105
2106
  */
2106
2107
  static VALUE nm_shape(VALUE self) {
2107
- NM_CONSERVATIVE(nm_register_value(self));
2108
+ NM_CONSERVATIVE(nm_register_value(&self));
2108
2109
  STORAGE* s = NM_STORAGE(self);
2109
2110
 
2110
2111
  // Copy elements into a VALUE array and then use those to create a Ruby array with rb_ary_new4.
@@ -2114,7 +2115,7 @@ static VALUE nm_shape(VALUE self) {
2114
2115
  shape[index] = INT2FIX(s->shape[index]);
2115
2116
 
2116
2117
  nm_unregister_values(shape, s->dim);
2117
- NM_CONSERVATIVE(nm_unregister_value(self));
2118
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2118
2119
  return rb_ary_new4(s->dim, shape);
2119
2120
  }
2120
2121
 
@@ -2126,7 +2127,7 @@ static VALUE nm_shape(VALUE self) {
2126
2127
  * Get the offset (slice position) of a matrix. Typically all zeros, unless you have a reference slice.
2127
2128
  */
2128
2129
  static VALUE nm_offset(VALUE self) {
2129
- NM_CONSERVATIVE(nm_register_value(self));
2130
+ NM_CONSERVATIVE(nm_register_value(&self));
2130
2131
  STORAGE* s = NM_STORAGE(self);
2131
2132
 
2132
2133
  // Copy elements into a VALUE array and then use those to create a Ruby array with rb_ary_new4.
@@ -2136,7 +2137,7 @@ static VALUE nm_offset(VALUE self) {
2136
2137
  offset[index] = INT2FIX(s->offset[index]);
2137
2138
 
2138
2139
  nm_unregister_values(offset, s->dim);
2139
- NM_CONSERVATIVE(nm_unregister_value(self));
2140
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2140
2141
  return rb_ary_new4(s->dim, offset);
2141
2142
  }
2142
2143
 
@@ -2155,7 +2156,7 @@ static VALUE nm_supershape(VALUE self) {
2155
2156
  }
2156
2157
  else s = s->src;
2157
2158
 
2158
- NM_CONSERVATIVE(nm_register_value(self));
2159
+ NM_CONSERVATIVE(nm_register_value(&self));
2159
2160
 
2160
2161
  VALUE* shape = NM_ALLOCA_N(VALUE, s->dim);
2161
2162
  nm_register_values(shape, s->dim);
@@ -2163,7 +2164,7 @@ static VALUE nm_supershape(VALUE self) {
2163
2164
  shape[index] = INT2FIX(s->shape[index]);
2164
2165
 
2165
2166
  nm_unregister_values(shape, s->dim);
2166
- NM_CONSERVATIVE(nm_unregister_value(self));
2167
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2167
2168
  return rb_ary_new4(s->dim, shape);
2168
2169
  }
2169
2170
 
@@ -2174,9 +2175,9 @@ static VALUE nm_supershape(VALUE self) {
2174
2175
  * Get the storage type (stype) of a matrix, e.g., :yale, :dense, or :list.
2175
2176
  */
2176
2177
  static VALUE nm_stype(VALUE self) {
2177
- NM_CONSERVATIVE(nm_register_value(self));
2178
+ NM_CONSERVATIVE(nm_register_value(&self));
2178
2179
  VALUE stype = ID2SYM(rb_intern(STYPE_NAMES[NM_STYPE(self)]));
2179
- NM_CONSERVATIVE(nm_unregister_value(self));
2180
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2180
2181
  return stype;
2181
2182
  }
2182
2183
 
@@ -2227,9 +2228,9 @@ static VALUE nm_xslice(int argc, VALUE* argv, void* (*slice_func)(const STORAGE*
2227
2228
  } else {
2228
2229
 
2229
2230
  NM_CONSERVATIVE(nm_register_values(argv, argc));
2230
- NM_CONSERVATIVE(nm_register_value(self));
2231
+ NM_CONSERVATIVE(nm_register_value(&self));
2231
2232
 
2232
- nm_register_value(result);
2233
+ nm_register_value(&result);
2233
2234
 
2234
2235
  SLICE* slice = get_slice(NM_DIM(self), argc, argv, s->shape);
2235
2236
 
@@ -2256,9 +2257,9 @@ static VALUE nm_xslice(int argc, VALUE* argv, void* (*slice_func)(const STORAGE*
2256
2257
  free_slice(slice);
2257
2258
  }
2258
2259
 
2259
- nm_unregister_value(result);
2260
+ nm_unregister_value(&result);
2260
2261
  NM_CONSERVATIVE(nm_unregister_values(argv, argc));
2261
- NM_CONSERVATIVE(nm_unregister_value(self));
2262
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2262
2263
 
2263
2264
  return result;
2264
2265
  }
@@ -2268,7 +2269,7 @@ static VALUE nm_xslice(int argc, VALUE* argv, void* (*slice_func)(const STORAGE*
2268
2269
  //////////////////////
2269
2270
 
2270
2271
  static VALUE unary_op(nm::unaryop_t op, VALUE self) {
2271
- NM_CONSERVATIVE(nm_register_value(self));
2272
+ NM_CONSERVATIVE(nm_register_value(&self));
2272
2273
  NMATRIX* left;
2273
2274
  UnwrapNMatrix(self, left);
2274
2275
  std::string sym;
@@ -2285,7 +2286,7 @@ static VALUE unary_op(nm::unaryop_t op, VALUE self) {
2285
2286
  break;
2286
2287
  }
2287
2288
 
2288
- NM_CONSERVATIVE(nm_unregister_value(self));
2289
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2289
2290
  return rb_funcall(self, rb_intern(sym.c_str()), 0);
2290
2291
  }
2291
2292
 
@@ -2302,8 +2303,8 @@ static void check_dims_and_shape(VALUE left_val, VALUE right_val) {
2302
2303
 
2303
2304
  static VALUE elementwise_op(nm::ewop_t op, VALUE left_val, VALUE right_val) {
2304
2305
 
2305
- NM_CONSERVATIVE(nm_register_value(left_val));
2306
- NM_CONSERVATIVE(nm_register_value(right_val));
2306
+ NM_CONSERVATIVE(nm_register_value(&left_val));
2307
+ NM_CONSERVATIVE(nm_register_value(&right_val));
2307
2308
 
2308
2309
  NMATRIX* left;
2309
2310
  NMATRIX* result;
@@ -2325,13 +2326,13 @@ static VALUE elementwise_op(nm::ewop_t op, VALUE left_val, VALUE right_val) {
2325
2326
  sym = "__list_scalar_" + nm::EWOP_NAMES[op] + "__";
2326
2327
  break;
2327
2328
  default:
2328
- NM_CONSERVATIVE(nm_unregister_value(left_val));
2329
- NM_CONSERVATIVE(nm_unregister_value(right_val));
2329
+ NM_CONSERVATIVE(nm_unregister_value(&left_val));
2330
+ NM_CONSERVATIVE(nm_unregister_value(&right_val));
2330
2331
  rb_raise(rb_eNotImpError, "unknown storage type requested scalar element-wise operation");
2331
2332
  }
2332
2333
  VALUE symv = rb_intern(sym.c_str());
2333
- NM_CONSERVATIVE(nm_unregister_value(left_val));
2334
- NM_CONSERVATIVE(nm_unregister_value(right_val));
2334
+ NM_CONSERVATIVE(nm_unregister_value(&left_val));
2335
+ NM_CONSERVATIVE(nm_unregister_value(&right_val));
2335
2336
  return rb_funcall(left_val, symv, 1, right_val);
2336
2337
 
2337
2338
  } else {
@@ -2355,32 +2356,32 @@ static VALUE elementwise_op(nm::ewop_t op, VALUE left_val, VALUE right_val) {
2355
2356
  sym = "__list_elementwise_" + nm::EWOP_NAMES[op] + "__";
2356
2357
  break;
2357
2358
  default:
2358
- NM_CONSERVATIVE(nm_unregister_value(left_val));
2359
- NM_CONSERVATIVE(nm_unregister_value(right_val));
2359
+ NM_CONSERVATIVE(nm_unregister_value(&left_val));
2360
+ NM_CONSERVATIVE(nm_unregister_value(&right_val));
2360
2361
  rb_raise(rb_eNotImpError, "unknown storage type requested element-wise operation");
2361
2362
  }
2362
2363
 
2363
2364
  VALUE symv = rb_intern(sym.c_str());
2364
- NM_CONSERVATIVE(nm_unregister_value(left_val));
2365
- NM_CONSERVATIVE(nm_unregister_value(right_val));
2365
+ NM_CONSERVATIVE(nm_unregister_value(&left_val));
2366
+ NM_CONSERVATIVE(nm_unregister_value(&right_val));
2366
2367
  return rb_funcall(left_val, symv, 1, right_val);
2367
2368
 
2368
2369
  } else {
2369
- NM_CONSERVATIVE(nm_unregister_value(left_val));
2370
- NM_CONSERVATIVE(nm_unregister_value(right_val));
2370
+ NM_CONSERVATIVE(nm_unregister_value(&left_val));
2371
+ NM_CONSERVATIVE(nm_unregister_value(&right_val));
2371
2372
  rb_raise(rb_eArgError, "Element-wise operations are not currently supported between matrices with differing stypes.");
2372
2373
  }
2373
2374
  }
2374
2375
 
2375
- NM_CONSERVATIVE(nm_unregister_value(left_val));
2376
- NM_CONSERVATIVE(nm_unregister_value(right_val));
2376
+ NM_CONSERVATIVE(nm_unregister_value(&left_val));
2377
+ NM_CONSERVATIVE(nm_unregister_value(&right_val));
2377
2378
  return Data_Wrap_Struct(CLASS_OF(left_val), nm_mark, nm_delete, result);
2378
2379
  }
2379
2380
 
2380
2381
  static VALUE noncom_elementwise_op(nm::noncom_ewop_t op, VALUE self, VALUE other, VALUE flip) {
2381
2382
 
2382
- NM_CONSERVATIVE(nm_register_value(self));
2383
- NM_CONSERVATIVE(nm_register_value(other));
2383
+ NM_CONSERVATIVE(nm_register_value(&self));
2384
+ NM_CONSERVATIVE(nm_register_value(&other));
2384
2385
 
2385
2386
  NMATRIX* self_nm;
2386
2387
  NMATRIX* result;
@@ -2402,12 +2403,12 @@ static VALUE noncom_elementwise_op(nm::noncom_ewop_t op, VALUE self, VALUE other
2402
2403
  sym = "__list_scalar_" + nm::NONCOM_EWOP_NAMES[op] + "__";
2403
2404
  break;
2404
2405
  default:
2405
- NM_CONSERVATIVE(nm_unregister_value(self));
2406
- NM_CONSERVATIVE(nm_unregister_value(other));
2406
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2407
+ NM_CONSERVATIVE(nm_unregister_value(&other));
2407
2408
  rb_raise(rb_eNotImpError, "unknown storage type requested scalar element-wise operation");
2408
2409
  }
2409
- NM_CONSERVATIVE(nm_unregister_value(self));
2410
- NM_CONSERVATIVE(nm_unregister_value(other));
2410
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2411
+ NM_CONSERVATIVE(nm_unregister_value(&other));
2411
2412
  return rb_funcall(self, rb_intern(sym.c_str()), 2, other, flip);
2412
2413
 
2413
2414
  } else {
@@ -2431,22 +2432,22 @@ static VALUE noncom_elementwise_op(nm::noncom_ewop_t op, VALUE self, VALUE other
2431
2432
  sym = "__list_elementwise_" + nm::NONCOM_EWOP_NAMES[op] + "__";
2432
2433
  break;
2433
2434
  default:
2434
- NM_CONSERVATIVE(nm_unregister_value(self));
2435
- NM_CONSERVATIVE(nm_unregister_value(other));
2435
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2436
+ NM_CONSERVATIVE(nm_unregister_value(&other));
2436
2437
  rb_raise(rb_eNotImpError, "unknown storage type requested element-wise operation");
2437
2438
  }
2438
- NM_CONSERVATIVE(nm_unregister_value(self));
2439
- NM_CONSERVATIVE(nm_unregister_value(other));
2439
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2440
+ NM_CONSERVATIVE(nm_unregister_value(&other));
2440
2441
  return rb_funcall(self, rb_intern(sym.c_str()), 2, other, flip);
2441
2442
 
2442
2443
  } else {
2443
- nm_unregister_value(self);
2444
- nm_unregister_value(other);
2444
+ nm_unregister_value(&self);
2445
+ nm_unregister_value(&other);
2445
2446
  rb_raise(rb_eArgError, "Element-wise operations are not currently supported between matrices with differing stypes.");
2446
2447
  }
2447
2448
  }
2448
- NM_CONSERVATIVE(nm_unregister_value(self));
2449
- NM_CONSERVATIVE(nm_unregister_value(other));
2449
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2450
+ NM_CONSERVATIVE(nm_unregister_value(&other));
2450
2451
  return Data_Wrap_Struct(CLASS_OF(self), nm_mark, nm_delete, result);
2451
2452
  }
2452
2453
 
@@ -2461,7 +2462,7 @@ bool is_ref(const NMATRIX* matrix) {
2461
2462
  * Helper function for nm_symmetric and nm_hermitian.
2462
2463
  */
2463
2464
  static VALUE is_symmetric(VALUE self, bool hermitian) {
2464
- NM_CONSERVATIVE(nm_register_value(self));
2465
+ NM_CONSERVATIVE(nm_register_value(&self));
2465
2466
 
2466
2467
  NMATRIX* m;
2467
2468
  UnwrapNMatrix(self, m);
@@ -2477,12 +2478,12 @@ static VALUE is_symmetric(VALUE self, bool hermitian) {
2477
2478
 
2478
2479
  } else {
2479
2480
  // TODO: Implement, at the very least, yale_is_symmetric. Model it after yale/transp.template.c.
2480
- NM_CONSERVATIVE(nm_unregister_value(self));
2481
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2481
2482
  rb_raise(rb_eNotImpError, "symmetric? and hermitian? only implemented for dense currently");
2482
2483
  }
2483
2484
 
2484
2485
  }
2485
- NM_CONSERVATIVE(nm_unregister_value(self));
2486
+ NM_CONSERVATIVE(nm_unregister_value(&self));
2486
2487
  return Qfalse;
2487
2488
  }
2488
2489
 
@@ -2524,10 +2525,10 @@ nm::dtype_t nm_dtype_min_fixnum(int64_t v) {
2524
2525
  * Helper for nm_dtype_min(), handling rationals.
2525
2526
  */
2526
2527
  nm::dtype_t nm_dtype_min_rational(VALUE vv) {
2527
- NM_CONSERVATIVE(nm_register_value(vv));
2528
+ NM_CONSERVATIVE(nm_register_value(&vv));
2528
2529
  nm::Rational128* v = NM_ALLOCA_N(nm::Rational128, 1);
2529
2530
  rubyval_to_cval(vv, nm::RATIONAL128, v);
2530
- NM_CONSERVATIVE(nm_unregister_value(vv));
2531
+ NM_CONSERVATIVE(nm_unregister_value(&vv));
2531
2532
  int64_t i = std::max(std::abs(v->n), v->d);
2532
2533
  if (i <= SHRT_MAX) return nm::INT16;
2533
2534
  else if (i <= INT_MAX) return nm::INT32;
@@ -2685,7 +2686,7 @@ static SLICE* get_slice(size_t dim, int argc, VALUE* arg, size_t* shape) {
2685
2686
 
2686
2687
  } else if (TYPE(arg[t]) == T_HASH) { // 3:5 notation (inclusive)
2687
2688
  VALUE begin_end = rb_funcall(v, rb_intern("shift"), 0); // rb_hash_shift
2688
- nm_register_value(begin_end);
2689
+ nm_register_value(&begin_end);
2689
2690
 
2690
2691
  if (rb_ary_entry(begin_end, 0) >= 0)
2691
2692
  slice->coords[r] = FIX2INT(rb_ary_entry(begin_end, 0));
@@ -2698,7 +2699,7 @@ static SLICE* get_slice(size_t dim, int argc, VALUE* arg, size_t* shape) {
2698
2699
 
2699
2700
  if (RHASH_EMPTY_P(v)) t++; // go on to the next
2700
2701
  slice->single = false;
2701
- nm_unregister_value(begin_end);
2702
+ nm_unregister_value(&begin_end);
2702
2703
 
2703
2704
  } else if (CLASS_OF(v) == rb_cRange) {
2704
2705
  rb_range_values(arg[t], &beg, &end, &excl);
@@ -2786,7 +2787,7 @@ static nm::dtype_t interpret_dtype(int argc, VALUE* argv, nm::stype_t stype) {
2786
2787
  * Convert an Ruby value or an array of Ruby values into initial C values.
2787
2788
  */
2788
2789
  static void* interpret_initial_value(VALUE arg, nm::dtype_t dtype) {
2789
- NM_CONSERVATIVE(nm_register_value(arg));
2790
+ NM_CONSERVATIVE(nm_register_value(&arg));
2790
2791
 
2791
2792
  unsigned int index;
2792
2793
  void* init_val;
@@ -2804,7 +2805,7 @@ static void* interpret_initial_value(VALUE arg, nm::dtype_t dtype) {
2804
2805
  init_val = rubyobj_to_cval(arg, dtype);
2805
2806
  }
2806
2807
 
2807
- NM_CONSERVATIVE(nm_unregister_value(arg));
2808
+ NM_CONSERVATIVE(nm_unregister_value(&arg));
2808
2809
  return init_val;
2809
2810
  }
2810
2811
 
@@ -2815,7 +2816,7 @@ static void* interpret_initial_value(VALUE arg, nm::dtype_t dtype) {
2815
2816
  * array describing the shape, which must be freed manually.
2816
2817
  */
2817
2818
  static size_t* interpret_shape(VALUE arg, size_t* dim) {
2818
- NM_CONSERVATIVE(nm_register_value(arg));
2819
+ NM_CONSERVATIVE(nm_register_value(&arg));
2819
2820
  size_t* shape;
2820
2821
 
2821
2822
  if (TYPE(arg) == T_ARRAY) {
@@ -2834,11 +2835,11 @@ static size_t* interpret_shape(VALUE arg, size_t* dim) {
2834
2835
  shape[1] = FIX2UINT(arg);
2835
2836
 
2836
2837
  } else {
2837
- nm_unregister_value(arg);
2838
+ nm_unregister_value(&arg);
2838
2839
  rb_raise(rb_eArgError, "Expected an array of numbers or a single Fixnum for matrix shape");
2839
2840
  }
2840
2841
 
2841
- NM_CONSERVATIVE(nm_unregister_value(arg));
2842
+ NM_CONSERVATIVE(nm_unregister_value(&arg));
2842
2843
  return shape;
2843
2844
  }
2844
2845
 
@@ -2987,7 +2988,7 @@ static VALUE nm_det_exact(VALUE self) {
2987
2988
  return Qnil;
2988
2989
  }
2989
2990
 
2990
- NM_CONSERVATIVE(nm_register_value(self));
2991
+ NM_CONSERVATIVE(nm_register_value(&self));
2991
2992
 
2992
2993
  // Calculate the determinant and then assign it to the return value
2993
2994
  void* result = NM_ALLOCA_N(char, DTYPE_SIZES[NM_DTYPE(self)]);
@@ -3001,7 +3002,7 @@ static VALUE nm_det_exact(VALUE self) {
3001
3002
  if (dtype == nm::RUBYOBJ) {
3002
3003
  nm_unregister_values(reinterpret_cast<VALUE*>(result), 1);
3003
3004
  }
3004
- NM_CONSERVATIVE(nm_unregister_value(self));
3005
+ NM_CONSERVATIVE(nm_unregister_value(&self));
3005
3006
 
3006
3007
  return to_return;
3007
3008
  }