numo-narray-alt 0.9.4 → 0.9.6

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +22 -3
  4. data/Rakefile +8 -0
  5. data/ext/numo/narray/SFMT-params19937.h +16 -12
  6. data/ext/numo/narray/SFMT.c +12 -5
  7. data/ext/numo/narray/array.c +51 -21
  8. data/ext/numo/narray/data.c +88 -86
  9. data/ext/numo/narray/index.c +51 -28
  10. data/ext/numo/narray/kwargs.c +11 -9
  11. data/ext/numo/narray/math.c +14 -6
  12. data/ext/numo/narray/narray.c +93 -58
  13. data/ext/numo/narray/ndloop.c +52 -63
  14. data/ext/numo/narray/numo/intern.h +9 -3
  15. data/ext/numo/narray/numo/narray.h +20 -20
  16. data/ext/numo/narray/numo/ndloop.h +1 -1
  17. data/ext/numo/narray/numo/template.h +85 -81
  18. data/ext/numo/narray/numo/types/bit.h +76 -0
  19. data/ext/numo/narray/numo/types/complex.h +7 -3
  20. data/ext/numo/narray/numo/types/complex_macro.h +28 -25
  21. data/ext/numo/narray/numo/types/float_macro.h +21 -17
  22. data/ext/numo/narray/numo/types/real_accum.h +22 -22
  23. data/ext/numo/narray/numo/types/robj_macro.h +20 -12
  24. data/ext/numo/narray/numo/types/xint_macro.h +51 -8
  25. data/ext/numo/narray/rand.c +7 -0
  26. data/ext/numo/narray/src/mh/mean.h +102 -0
  27. data/ext/numo/narray/src/mh/rms.h +102 -0
  28. data/ext/numo/narray/src/mh/stddev.h +103 -0
  29. data/ext/numo/narray/src/mh/var.h +102 -0
  30. data/ext/numo/narray/src/t_bit.c +206 -147
  31. data/ext/numo/narray/src/t_dcomplex.c +531 -641
  32. data/ext/numo/narray/src/t_dfloat.c +1341 -1421
  33. data/ext/numo/narray/src/t_int16.c +562 -468
  34. data/ext/numo/narray/src/t_int32.c +562 -468
  35. data/ext/numo/narray/src/t_int64.c +561 -467
  36. data/ext/numo/narray/src/t_int8.c +520 -448
  37. data/ext/numo/narray/src/t_robject.c +519 -619
  38. data/ext/numo/narray/src/t_scomplex.c +524 -659
  39. data/ext/numo/narray/src/t_sfloat.c +1332 -1410
  40. data/ext/numo/narray/src/t_uint16.c +562 -468
  41. data/ext/numo/narray/src/t_uint32.c +562 -468
  42. data/ext/numo/narray/src/t_uint64.c +562 -468
  43. data/ext/numo/narray/src/t_uint8.c +522 -448
  44. data/ext/numo/narray/step.c +7 -2
  45. data/ext/numo/narray/struct.c +31 -24
  46. data/lib/numo/narray/extra.rb +74 -30
  47. data/numo-narray-alt.gemspec +38 -0
  48. metadata +10 -1
@@ -36,7 +36,9 @@ static ID id_beg, id_end, id_len, id_step;
36
36
  * <i>array_sizse</i> is given, negative array index is considered.
37
37
  */
38
38
 
39
- void nary_step_array_index(VALUE obj, size_t ary_size, size_t* plen, ssize_t* pbeg, ssize_t* pstep) {
39
+ void nary_step_array_index(
40
+ VALUE obj, size_t ary_size, size_t* plen, ssize_t* pbeg, ssize_t* pstep
41
+ ) {
40
42
  size_t len;
41
43
  ssize_t beg = 0, step = 1;
42
44
  VALUE vbeg, vend, vstep, vlen;
@@ -178,7 +180,10 @@ void nary_step_array_index(VALUE obj, size_t ary_size, size_t* plen, ssize_t* pb
178
180
  // puts("pass 2");
179
181
 
180
182
  if (beg < 0 || beg >= (ssize_t)ary_size || end < 0 || end >= (ssize_t)ary_size) {
181
- rb_raise(rb_eRangeError, "beg=%" SZF "d,end=%" SZF "d is out of array size (%" SZF "u)", beg, end, ary_size);
183
+ rb_raise(
184
+ rb_eRangeError, "beg=%" SZF "d,end=%" SZF "d is out of array size (%" SZF "u)", beg, end,
185
+ ary_size
186
+ );
182
187
  }
183
188
  if (plen) *plen = len;
184
189
  if (pbeg) *pbeg = beg;
@@ -167,7 +167,10 @@ static VALUE nst_field_view(VALUE self, VALUE idx) {
167
167
  def = nst_definition(self, idx);
168
168
  if (!RTEST(def)) {
169
169
  idx = rb_funcall(idx, rb_intern("to_s"), 0);
170
- rb_raise(rb_eTypeError, "Invalid field: '%s' for struct %s", StringValuePtr(idx), rb_class2name(rb_obj_class(self)));
170
+ rb_raise(
171
+ rb_eTypeError, "Invalid field: '%s' for struct %s", StringValuePtr(idx),
172
+ rb_class2name(rb_obj_class(self))
173
+ );
171
174
  }
172
175
  type = RARRAY_AREF(def, 1);
173
176
  ofs = RARRAY_AREF(def, 2);
@@ -268,7 +271,6 @@ static VALUE nst_s_new(int argc, VALUE* argv, VALUE klass) {
268
271
 
269
272
  size = rb_iv_get(st, "__offset__");
270
273
  members = rb_iv_get(st, "__members__");
271
- // printf("size=%d\n",NUM2INT(size));
272
274
  rb_define_const(st, CONTIGUOUS_STRIDE, size);
273
275
  rb_define_const(st, ELEMENT_BYTE_SIZE, size);
274
276
  rb_define_const(st, ELEMENT_BIT_SIZE, rb_funcall(size, '*', 1, INT2FIX(8)));
@@ -344,7 +346,9 @@ static VALUE nstruct_add_type(VALUE type, int argc, VALUE* argv, VALUE nst) {
344
346
 
345
347
  size = rb_funcall(type, rb_intern("byte_size"), 0);
346
348
  rb_iv_set(nst, "__offset__", rb_funcall(ofs, '+', 1, size));
347
- rb_ary_push(rb_iv_get(nst, "__members__"), rb_ary_new3(4, name, type, ofs, size)); // <- field definition
349
+ rb_ary_push(
350
+ rb_iv_get(nst, "__members__"), rb_ary_new3(4, name, type, ofs, size)
351
+ ); // <- field definition
348
352
  return Qnil;
349
353
  }
350
354
 
@@ -421,9 +425,9 @@ static VALUE nst_create_member_views(VALUE self) {
421
425
 
422
426
  static VALUE nary_struct_to_a(VALUE self) {
423
427
  volatile VALUE opt;
424
- ndfunc_arg_in_t ain[3] = {{Qnil, 0}, {sym_loop_opt}, {sym_option}};
425
- ndfunc_arg_out_t aout[1] = {{rb_cArray, 0}}; // dummy?
426
- ndfunc_t ndf = {iter_nstruct_to_a, NO_LOOP, 3, 1, ain, aout};
428
+ ndfunc_arg_in_t ain[3] = { { Qnil, 0 }, { sym_loop_opt }, { sym_option } };
429
+ ndfunc_arg_out_t aout[1] = { { rb_cArray, 0 } }; // dummy?
430
+ ndfunc_t ndf = { iter_nstruct_to_a, NO_LOOP, 3, 1, ain, aout };
427
431
 
428
432
  opt = nst_create_member_views(self);
429
433
  return na_ndloop_cast_narray_to_rarray(&ndf, self, opt);
@@ -581,19 +585,14 @@ static VALUE nary_struct_cast_array(VALUE klass, VALUE rary) {
581
585
  narray_t* na;
582
586
  // na_compose_t *nc;
583
587
  VALUE opt;
584
- ndfunc_arg_in_t ain[3] = {{OVERWRITE, 0}, {rb_cArray, 0}, {sym_option}};
585
- ndfunc_t ndf = {iter_nstruct_from_a, NO_LOOP, 3, 0, ain, 0};
586
-
587
- // fprintf(stderr,"rary:");rb_p(rary);
588
- // fprintf(stderr,"class_of(rary):");rb_p(rb_obj_class(rary));
588
+ ndfunc_arg_in_t ain[3] = { { OVERWRITE, 0 }, { rb_cArray, 0 }, { sym_option } };
589
+ ndfunc_t ndf = { iter_nstruct_from_a, NO_LOOP, 3, 0, ain, 0 };
589
590
 
590
591
  // vnc = na_ary_composition_for_struct(klass, rary);
591
592
  // Data_Get_Struct(vnc, na_compose_t, nc);
592
593
  // nary = nary_new(klass, nc->ndim, nc->shape);
593
594
  nary = na_s_new_like(klass, rary);
594
595
  GetNArray(nary, na);
595
- // fprintf(stderr,"na->size=%lu\n",na->size);
596
- // fprintf(stderr,"na->ndim=%d\n",na->ndim);
597
596
  if (na->size > 0) {
598
597
  opt = nst_create_member_views(nary);
599
598
  rb_funcall(nary, rb_intern("allocate"), 0);
@@ -657,8 +656,8 @@ static void iter_struct_store_struct(na_loop_t* const lp) {
657
656
  }
658
657
 
659
658
  static VALUE nary_struct_store_struct(VALUE self, VALUE obj) {
660
- ndfunc_arg_in_t ain[2] = {{OVERWRITE, 0}, {Qnil, 0}};
661
- ndfunc_t ndf = {iter_struct_store_struct, FULL_LOOP, 2, 0, ain, 0};
659
+ ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
660
+ ndfunc_t ndf = { iter_struct_store_struct, FULL_LOOP, 2, 0, ain, 0 };
662
661
 
663
662
  na_ndloop(&ndf, 2, self, obj);
664
663
  return self;
@@ -671,8 +670,8 @@ static inline VALUE nary_struct_store_array(VALUE self, VALUE obj) {
671
670
  /*
672
671
  Store elements to Numo::Struct from other.
673
672
  @overload store(other)
674
- @param [Object] other
675
- @return [Numo::Struct] self
673
+ @param [Object] other
674
+ @return [Numo::Struct] self
676
675
  */
677
676
  static VALUE nary_struct_store(VALUE self, VALUE obj) {
678
677
  if (TYPE(obj) == T_ARRAY) {
@@ -683,8 +682,10 @@ static VALUE nary_struct_store(VALUE self, VALUE obj) {
683
682
  nary_struct_store_struct(self, obj);
684
683
  return self;
685
684
  }
686
- rb_raise(nary_eCastError, "unknown conversion from %s to %s", rb_class2name(rb_obj_class(obj)),
687
- rb_class2name(rb_obj_class(self)));
685
+ rb_raise(
686
+ nary_eCastError, "unknown conversion from %s to %s", rb_class2name(rb_obj_class(obj)),
687
+ rb_class2name(rb_obj_class(self))
688
+ );
688
689
  return self;
689
690
  }
690
691
 
@@ -741,10 +742,10 @@ static VALUE nst_s_add_type(int argc, VALUE* argv, VALUE mod) {
741
742
  return Qnil;
742
743
  }
743
744
 
744
- #define NST_TYPEDEF(tpname, tpclass) \
745
- static VALUE nst_s_##tpname(int argc, VALUE* argv, VALUE mod) { \
746
- nstruct_add_type(tpclass, argc, argv, mod); \
747
- return Qnil; \
745
+ #define NST_TYPEDEF(tpname, tpclass) \
746
+ static VALUE nst_s_##tpname(int argc, VALUE* argv, VALUE mod) { \
747
+ nstruct_add_type(tpclass, argc, argv, mod); \
748
+ return Qnil; \
748
749
  }
749
750
 
750
751
  NST_TYPEDEF(int8, numo_cInt8)
@@ -760,9 +761,15 @@ NST_TYPEDEF(dcomplex, numo_cDComplex)
760
761
  NST_TYPEDEF(sfloat, numo_cSFloat)
761
762
  NST_TYPEDEF(scomplex, numo_cSComplex)
762
763
 
763
- #define rb_define_singleton_alias(klass, name1, name2) rb_define_alias(rb_singleton_class(klass), name1, name2)
764
+ #define rb_define_singleton_alias(klass, name1, name2) \
765
+ rb_define_alias(rb_singleton_class(klass), name1, name2)
764
766
 
765
767
  void Init_nary_struct(void) {
768
+ /**
769
+ * Document-class: Numo::Struct
770
+ *
771
+ * Structured array class.
772
+ */
766
773
  cT = rb_define_class_under(mNumo, "Struct", numo_cNArray);
767
774
  // cNStMember = rb_define_class_under(cT, "Member", rb_cObject);
768
775
 
@@ -114,6 +114,7 @@ module Numo
114
114
  end
115
115
  end
116
116
 
117
+ # Convert the argument to an narray.
117
118
  def self.asarray(a)
118
119
  case a
119
120
  when NArray
@@ -710,6 +711,12 @@ module Numo
710
711
  end
711
712
  end
712
713
 
714
+ # Split an array into multiple sub-arrays vertically
715
+ def vsplit(indices_or_sections)
716
+ split(indices_or_sections, axis: 0)
717
+ end
718
+
719
+ # Split an array into multiple sub-arrays horizontally
713
720
  # @example
714
721
  # x = Numo::DFloat.new(4,4).seq
715
722
  # # => Numo::DFloat#shape=[4,4]
@@ -742,15 +749,11 @@ module Numo
742
749
  # # [11],
743
750
  # # [15]],
744
751
  # # Numo::DFloat(view)#shape=[4,0][]]
745
-
746
- def vsplit(indices_or_sections)
747
- split(indices_or_sections, axis: 0)
748
- end
749
-
750
752
  def hsplit(indices_or_sections)
751
753
  split(indices_or_sections, axis: 1)
752
754
  end
753
755
 
756
+ # Split an array into multiple sub-arrays along the depth
754
757
  def dsplit(indices_or_sections)
755
758
  split(indices_or_sections, axis: 2)
756
759
  end
@@ -1086,7 +1089,7 @@ module Numo
1086
1089
  if am > nx && an > nx && bm > nx && bn > nx &&
1087
1090
  size > ns && b.size > ns
1088
1091
  @@warn_slow_dot = true
1089
- warn "\nwarning: Built-in matrix dot is slow. Consider installing Numo::Linalg.\n\n"
1092
+ warn "\nwarning: Built-in matrix dot is slow. Consider installing numo-linalg-alt gem.\n\n"
1090
1093
  end
1091
1094
  end
1092
1095
  self[false, :new].mulsum(b[false, :new, true, true], axis: -2)
@@ -1209,8 +1212,37 @@ module Numo
1209
1212
  (self[*adim] * b[*bdim]).reshape(*shpr)
1210
1213
  end
1211
1214
 
1212
- # under construction
1213
- def cov(y = nil, ddof: 1, fweights: nil, aweights: nil)
1215
+ # Compute a covariance matrix.
1216
+ #
1217
+ # @param y [Numo::NArray] (optional) If not nil, the covariance matrix of `self` and `y` is computed.
1218
+ # @param ddof [Integer] (optional) Delta degrees of freedom. The divisor used in calculations is `N - ddof`,
1219
+ # where `N` represents the number of observations.
1220
+ # @param fweights [Numo::NArray] (optional) 1-D array of integer frequency weights.
1221
+ # @param aweights [Numo::NArray] (optional) 1-D array of observation vector weights.
1222
+ # @return [Numo::NArray] return covariance matrix
1223
+ #
1224
+ # @example
1225
+ # x = Numo::DFloat[4, 5, 6]
1226
+ # x.cov
1227
+ # # => 1.0
1228
+ #
1229
+ # x = Numo::DFloat[[4, 5, 6], [3, 2, 1]]
1230
+ # x.cov
1231
+ # # => Numo::DFloat#shape=[2,2]
1232
+ # # [[1, -1],
1233
+ # # [-1, 1]]
1234
+ #
1235
+ # y = Numo::DFloat[7, 9, 8]
1236
+ # x.cov(y)
1237
+ # # => Numo::DFloat#shape=[3,3]
1238
+ # # [[1, -1, 0.5],
1239
+ # # [-1, 1, -0.5],
1240
+ # # [0.5, -0.5, 1]]
1241
+ def cov(y = nil, ddof: 1, fweights: nil, aweights: nil) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
1242
+ raise Numo::NArray::ShapeError, 'ndim must be <= 2' if ndim > 2
1243
+ raise Numo::NArray::ShapeError, 'y.ndim must be <= 2' if !y.nil? && (y.ndim > 2)
1244
+ raise ArgumentError, 'ddof must be 0 or 1' unless [0, 1].include?(ddof)
1245
+
1214
1246
  m = if y
1215
1247
  NArray.vstack([self, y])
1216
1248
  else
@@ -1218,36 +1250,48 @@ module Numo
1218
1250
  end
1219
1251
  w = nil
1220
1252
  if fweights
1221
- f = fweights
1222
- w = f
1253
+ fweights = Numo::NArray.cast(fweights) unless fweights.is_a?(Numo::NArray)
1254
+ raise ArgumentError, 'fweights must be 1-D array' unless fweights.ndim == 1
1255
+ raise ArgumentError, 'fweights size is wrong' unless fweights.size == m.shape[1]
1256
+ raise ArgumentError, 'fweights must be non-negative' if (fweights < 0).any?
1257
+ raise ArgumentError, 'fweights must be integer' unless fweights == fweights.floor
1258
+
1259
+ w = fweights
1223
1260
  end
1224
1261
  if aweights
1225
- a = aweights
1226
- w = w ? w * a : a
1227
- end
1228
- if w
1229
- w_sum = w.sum(axis: -1, keepdims: true)
1230
- if ddof == 0
1231
- fact = w_sum
1232
- elsif aweights.nil?
1233
- fact = w_sum - ddof
1262
+ aweights = Numo::NArray.cast(aweights) unless aweights.is_a?(Numo::NArray)
1263
+ raise ArgumentError, 'aweights must be 1-D array' unless aweights.ndim == 1
1264
+ raise ArgumentError, 'aweights size is wrong' unless aweights.size == m.shape[1]
1265
+ raise ArgumentError, 'aweights must be non-negative' if (aweights < 0).any?
1266
+
1267
+ if w.nil?
1268
+ w = aweights
1234
1269
  else
1235
- wa_sum = (w * a).sum(axis: -1, keepdims: true)
1236
- fact = w_sum - (ddof * wa_sum / w_sum)
1270
+ w *= aweights
1237
1271
  end
1238
- raise StandardError, 'Degrees of freedom <= 0 for slice' if (fact <= 0).any?
1239
- else
1240
- fact = m.shape[-1] - ddof
1241
1272
  end
1242
- if w
1243
- m -= (m * w).sum(axis: -1, keepdims: true) / w_sum
1244
- mw = m * w
1245
- else
1273
+ fact = if w.nil?
1274
+ m.shape[-1] - ddof
1275
+ elsif ddof == 0
1276
+ w.sum
1277
+ elsif aweights.nil?
1278
+ w.sum - ddof
1279
+ else
1280
+ w_sum = w.sum
1281
+ w_sum - (ddof * (w * aweights).sum / w_sum)
1282
+ end
1283
+ if fact <= 0
1284
+ warn('Degrees of freedom <= 0 for slice')
1285
+ fact = 0.0
1286
+ end
1287
+ if w.nil?
1246
1288
  m -= m.mean(axis: -1, keepdims: true)
1247
1289
  mw = m
1290
+ else
1291
+ m -= (m * w).sum(axis: -1, keepdims: true) / w.sum
1292
+ mw = m * w
1248
1293
  end
1249
- mt = m.ndim < 2 ? m : m.swapaxes(-2, -1)
1250
- mw.dot(mt.conj) / fact
1294
+ m.dot(mw.transpose.conj) / fact
1251
1295
  end
1252
1296
 
1253
1297
  private
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
4
+
5
+ lib = File.expand_path('lib', __dir__)
6
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
7
+
8
+ open('ext/numo/narray/numo/narray.h') do |f|
9
+ f.each_line do |l|
10
+ if /NARRAY_VERSION "([\d.]+)"/ =~ l
11
+ NARRAY_VERSION = Regexp.last_match(1)
12
+ break
13
+ end
14
+ end
15
+ end
16
+
17
+ Gem::Specification.new do |spec|
18
+ spec.name = 'numo-narray-alt'
19
+ spec.version = NARRAY_VERSION
20
+ spec.authors = ['yoshoku']
21
+ spec.email = ['yoshoku@outlook.com']
22
+ spec.description = 'Numo::NArray Alternative is an experimental project forked from Numo::NArray.'
23
+ spec.summary = 'Numo::NArray Alternative is an experimental project forked from Numo::NArray.'
24
+ spec.homepage = 'https://github.com/yoshoku/numo-narray-alt'
25
+ spec.license = 'BSD-3-Clause'
26
+ spec.required_ruby_version = '>= 2.2'
27
+
28
+ spec.metadata['homepage_uri'] = spec.homepage
29
+ spec.metadata['source_code_uri'] = spec.homepage
30
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
31
+ spec.metadata['documentation_uri'] = "https://gemdocs.org/gems/#{spec.name}/#{spec.version}/"
32
+
33
+ spec.files = `git ls-files Gemfile LICENSE README.md Rakefile lib ext numo-narray-alt.gemspec`.split($INPUT_RECORD_SEPARATOR) # rubocop:disable Layout/LineLength
34
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
35
+ spec.require_paths = ['lib']
36
+ spec.extensions = ['ext/numo/narray/extconf.rb']
37
+ spec.metadata['rubygems_mfa_required'] = 'true'
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: numo-narray-alt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - yoshoku
@@ -63,6 +63,10 @@ files:
63
63
  - ext/numo/narray/numo/types/uint_macro.h
64
64
  - ext/numo/narray/numo/types/xint_macro.h
65
65
  - ext/numo/narray/rand.c
66
+ - ext/numo/narray/src/mh/mean.h
67
+ - ext/numo/narray/src/mh/rms.h
68
+ - ext/numo/narray/src/mh/stddev.h
69
+ - ext/numo/narray/src/mh/var.h
66
70
  - ext/numo/narray/src/t_bit.c
67
71
  - ext/numo/narray/src/t_dcomplex.c
68
72
  - ext/numo/narray/src/t_dfloat.c
@@ -81,10 +85,15 @@ files:
81
85
  - ext/numo/narray/struct.c
82
86
  - lib/numo/narray.rb
83
87
  - lib/numo/narray/extra.rb
88
+ - numo-narray-alt.gemspec
84
89
  homepage: https://github.com/yoshoku/numo-narray-alt
85
90
  licenses:
86
91
  - BSD-3-Clause
87
92
  metadata:
93
+ homepage_uri: https://github.com/yoshoku/numo-narray-alt
94
+ source_code_uri: https://github.com/yoshoku/numo-narray-alt
95
+ changelog_uri: https://github.com/yoshoku/numo-narray-alt/blob/main/CHANGELOG.md
96
+ documentation_uri: https://gemdocs.org/gems/numo-narray-alt/0.9.6/
88
97
  rubygems_mfa_required: 'true'
89
98
  rdoc_options: []
90
99
  require_paths: