carray 1.5.2 → 1.5.7

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +32 -0
  3. data/NEWS.md +56 -3
  4. data/README.md +34 -18
  5. data/Rakefile +1 -1
  6. data/TODO.md +5 -4
  7. data/carray.gemspec +10 -11
  8. data/ext/ca_obj_bitarray.c +4 -7
  9. data/ext/ca_obj_bitfield.c +3 -5
  10. data/ext/ca_obj_block.c +1 -6
  11. data/ext/ca_obj_refer.c +6 -8
  12. data/ext/ca_obj_unbound_repeat.c +21 -52
  13. data/ext/carray.h +4 -0
  14. data/ext/carray_access.c +77 -45
  15. data/ext/carray_attribute.c +16 -1
  16. data/ext/carray_cast.c +1 -1
  17. data/ext/carray_conversion.c +8 -1
  18. data/ext/carray_core.c +22 -16
  19. data/ext/carray_generate.c +3 -3
  20. data/ext/carray_mask.c +12 -2
  21. data/ext/carray_math.rb +20 -2
  22. data/ext/carray_numeric.c +32 -51
  23. data/ext/carray_order.c +159 -0
  24. data/ext/carray_test.c +13 -0
  25. data/ext/carray_undef.c +0 -8
  26. data/ext/carray_utils.c +126 -47
  27. data/ext/extconf.rb +13 -1
  28. data/ext/mkmath.rb +1 -1
  29. data/ext/ruby_carray.c +8 -1
  30. data/ext/ruby_ccomplex.c +1 -1
  31. data/ext/version.h +4 -4
  32. data/lib/carray.rb +7 -9
  33. data/lib/carray/autoload.rb +0 -2
  34. data/lib/carray/basic.rb +3 -5
  35. data/lib/carray/broadcast.rb +78 -22
  36. data/lib/carray/compose.rb +34 -10
  37. data/lib/carray/construct.rb +36 -14
  38. data/lib/carray/info.rb +1 -3
  39. data/lib/carray/inspect.rb +3 -5
  40. data/lib/carray/io/imagemagick.rb +1 -3
  41. data/lib/carray/iterator.rb +2 -3
  42. data/lib/carray/mask.rb +18 -7
  43. data/lib/carray/math.rb +4 -6
  44. data/lib/carray/math/histogram.rb +1 -3
  45. data/lib/carray/math/recurrence.rb +1 -3
  46. data/lib/carray/mkmf.rb +1 -3
  47. data/lib/carray/object/ca_obj_iterator.rb +1 -3
  48. data/lib/carray/object/ca_obj_link.rb +1 -3
  49. data/lib/carray/object/ca_obj_pack.rb +1 -3
  50. data/lib/carray/obsolete.rb +1 -17
  51. data/lib/carray/ordering.rb +1 -3
  52. data/lib/carray/serialize.rb +34 -25
  53. data/lib/carray/string.rb +1 -3
  54. data/lib/carray/struct.rb +3 -5
  55. data/lib/carray/testing.rb +5 -10
  56. data/lib/carray/time.rb +1 -3
  57. data/lib/carray/transform.rb +12 -3
  58. data/misc/NOTE +16 -38
  59. data/spec/Classes/CAUnboudRepeat_spec.rb +24 -0
  60. data/spec/Features/feature_attributes_spec.rb +6 -6
  61. data/spec/Features/feature_boolean_spec.rb +15 -14
  62. data/spec/Features/feature_broadcast.rb +16 -0
  63. data/spec/Features/feature_cast_spec.rb +1 -1
  64. data/spec/Features/feature_mask_spec.rb +6 -0
  65. metadata +10 -11
data/ext/extconf.rb CHANGED
@@ -135,11 +135,23 @@ end
135
135
  # --- check tgmath.h
136
136
 
137
137
  have_header("tgmath.h")
138
+ have_func("atan2", "math.h")
139
+ have_func("hypot", "math.h")
140
+ have_func("lgamma", "math.h")
141
+ have_func("expm1", "math.h")
138
142
 
139
143
  # --- check mergesort routine
140
144
 
141
145
  have_func("mergesort", "stdlib.h")
142
146
 
147
+ # --- check mergesort routine
148
+
149
+ have_func("strptime", "time.h")
150
+
151
+ # --- check raneg object
152
+
153
+ have_func("rb_arithmetic_sequence_extract")
154
+
143
155
  # --- setup install files
144
156
 
145
157
  $INSTALLFILES = []
@@ -153,7 +165,7 @@ $INSTALLFILES << ['carray_config.h', '$(archdir)']
153
165
  #
154
166
 
155
167
  if /cygwin|mingw/ =~ RUBY_PLATFORM
156
- sitearchdir = Config::CONFIG["sitearchdir"]
168
+ sitearchdir = RbConfig::CONFIG["sitearchdir"]
157
169
  $DLDFLAGS << " -L#{sitearchdir} -Wl,--out-implib=libcarray.a "
158
170
  unless File.exist? "libcarray.a"
159
171
  $TOUCHED_LIBCARRAY_A = true
data/ext/mkmath.rb CHANGED
@@ -385,7 +385,7 @@ ca_moncmp_#{name}_#{type} (ca_size_t n, boolean8_t *m, char *ptr1, ca_size_t i1,
385
385
  io.puts "};"
386
386
  io.puts
387
387
  io.print %{
388
- static VALUE rb_ca_#{name} (VALUE self, VALUE other)
388
+ static VALUE rb_ca_#{name} (VALUE self)
389
389
  { return rb_ca_call_moncmp(self, ca_moncmp_#{name}); }
390
390
  }
391
391
  DEFINITIONS << io.string
data/ext/ruby_carray.c CHANGED
@@ -11,6 +11,10 @@
11
11
  #include "carray.h"
12
12
  #include "version.h"
13
13
 
14
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
15
+ VALUE rb_cArithSeq;
16
+ #endif
17
+
14
18
  VALUE rb_eCADataTypeError;
15
19
  VALUE rb_mCA;
16
20
 
@@ -70,13 +74,16 @@ void Init_ca_iter_window ();
70
74
 
71
75
  void Init_carray_mathfunc ();
72
76
 
73
-
74
77
  void
75
78
  Init_carray_ext ()
76
79
  {
77
80
 
78
81
  /* Classes and Modules */
79
82
 
83
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
84
+ rb_cArithSeq = rb_const_get(rb_cEnumerator, rb_intern("ArithmeticSequence"));
85
+ #endif
86
+
80
87
  /* -- CArray class -- */
81
88
 
82
89
  rb_cCArray = rb_define_class("CArray", rb_cObject);
data/ext/ruby_ccomplex.c CHANGED
@@ -460,7 +460,7 @@ Init_ccomplex ()
460
460
  rb_define_method(rb_cCComplex, "coerce", rb_cc_coerce, 1);
461
461
 
462
462
  rb_define_method(rb_cCComplex, "==", rb_cc_equal, 1);
463
- rb_define_method(rb_cCComplex, "-@", rb_cc_uminus, 1);
463
+ rb_define_method(rb_cCComplex, "-@", rb_cc_uminus, 0);
464
464
  rb_define_method(rb_cCComplex, "+", rb_cc_plus, 1);
465
465
  rb_define_method(rb_cCComplex, "-", rb_cc_minus, 1);
466
466
  rb_define_method(rb_cCComplex, "*", rb_cc_asterisk, 1);
data/ext/version.h CHANGED
@@ -8,9 +8,9 @@
8
8
 
9
9
  ---------------------------------------------------------------------------- */
10
10
 
11
- #define CA_VERSION "1.5.2"
12
- #define CA_VERSION_CODE 152
11
+ #define CA_VERSION "1.5.7"
12
+ #define CA_VERSION_CODE 157
13
13
  #define CA_VERSION_MAJOR 1
14
14
  #define CA_VERSION_MINOR 5
15
- #define CA_VERSION_TEENY 2
16
- #define CA_VERSION_DATE "2020/07/22"
15
+ #define CA_VERSION_TEENY 7
16
+ #define CA_VERSION_DATE "2021/06/16"
data/lib/carray.rb CHANGED
@@ -3,10 +3,8 @@
3
3
  # lib/carray.rb
4
4
  #
5
5
  # This file is part of Ruby/CArray extension library.
6
- # You can redistribute it and/or modify it under the terms of
7
- # the Ruby Licence.
8
6
  #
9
- # Copyright (C) 2005 Hiroki Motoyoshi
7
+ # Copyright (C) 2005-2020 Hiroki Motoyoshi
10
8
  #
11
9
  # ----------------------------------------------------------------------------
12
10
 
@@ -61,12 +59,12 @@ unless $CARRAY_NO_AUTOLOAD
61
59
  require 'carray/autoload/autoload_gem_gnuplot'
62
60
  require 'carray/autoload/autoload_gem_narray'
63
61
  require 'carray/autoload/autoload_gem_numo_narray'
64
- require 'carray/autoload/autoload_gem_io_csv'
65
- require 'carray/autoload/autoload_gem_io_sqlite3'
66
- require 'carray/autoload/autoload_gem_rmagick'
67
- require 'carray/autoload/autoload_gem_cairo'
68
- require 'carray/autoload/autoload_gem_opencv'
69
- require 'carray/autoload/autoload_gem_ffi'
62
+ # require 'carray/autoload/autoload_gem_io_csv'
63
+ # require 'carray/autoload/autoload_gem_io_sqlite3'
64
+ # require 'carray/autoload/autoload_gem_rmagick'
65
+ # require 'carray/autoload/autoload_gem_cairo'
66
+ # require 'carray/autoload/autoload_gem_opencv'
67
+ # require 'carray/autoload/autoload_gem_ffi'
70
68
 
71
69
  undef autoload_method
72
70
  end
@@ -3,8 +3,6 @@
3
3
  # carray/autoload.rb
4
4
  #
5
5
  # This file is part of Ruby/CArray extension library.
6
- # You can redistribute it and/or modify it under the terms of
7
- # the Ruby Licence.
8
6
  #
9
7
  # Copyright (C) 2005-2010 Hiroki Motoyoshi
10
8
  #
data/lib/carray/basic.rb CHANGED
@@ -3,10 +3,8 @@
3
3
  # carray/basic.rb
4
4
  #
5
5
  # This file is part of Ruby/CArray extension library.
6
- # You can redistribute it and/or modify it under the terms of
7
- # the Ruby Licence.
8
6
  #
9
- # Copyright (C) 2005 Hiroki Motoyoshi
7
+ # Copyright (C) 2005-2020 Hiroki Motoyoshi
10
8
  #
11
9
  # ----------------------------------------------------------------------------
12
10
 
@@ -85,11 +83,11 @@ class CArray
85
83
  end
86
84
 
87
85
  def first
88
- self[0]
86
+ ( self.elements == 0 ) ? nil : self[0]
89
87
  end
90
88
 
91
89
  def last
92
- self[-1]
90
+ ( self.elements == 0 ) ? nil :self[-1]
93
91
  end
94
92
 
95
93
  # matchup
@@ -1,45 +1,101 @@
1
+ # ----------------------------------------------------------------------------
2
+ #
3
+ # carray/broadcast.rb
4
+ #
5
+ # This file is part of Ruby/CArray extension library.
6
+ #
7
+ # Copyright (C) 2005-2020 Hiroki Motoyoshi
8
+ #
9
+ # ----------------------------------------------------------------------------
1
10
 
2
11
  class CArray
3
- def broadcast_to (*new_dim)
4
- if new_dim.size < ndim
5
- raise "can't broadcast to #{new_dim.inspect} because of mismatch in rank"
12
+
13
+ def broadcast_to (*newdim)
14
+
15
+ if newdim.size < ndim
16
+ raise "(Broadcasting) can't broadcast to #{newdim.inspect} because too small rank is specified"
6
17
  end
7
- flag_unbound_repeat = false
8
- sdim = []
9
- ([1]*(new_dim.size-ndim) + dim).each_with_index do |d, k|
10
- if new_dim[k] == 1
11
- sdim << 1
12
- elsif d == 1
13
- flag_unbound_repeat = true
14
- sdim << :*
15
- elsif d != new_dim[k]
16
- raise "can't broadcast to #{new_dim.inspect} because of mismatch in #{d} for #{new_dim[k]} in #{k}th dim"
18
+
19
+ #
20
+ # Try to build unbound repeat index (includes :*)
21
+ # with broadcasting rule in Numpy.
22
+ #
23
+ repdim = []
24
+ shape = []
25
+
26
+ srcdim = dim.dup
27
+ dstdim = newdim.dup
28
+ sd = srcdim.pop
29
+ dd = dstdim.pop
30
+ while dd
31
+ if sd == dd
32
+ repdim.unshift nil
33
+ shape.unshift(dd)
34
+ sd = srcdim.pop
35
+ elsif dd == 1
36
+ repdim.unshift :*
37
+ elsif sd == 1
38
+ repdim.unshift :*
39
+ sd = srcdim.pop
17
40
  else
18
- sdim << nil
41
+ raise "(Broadcasting) can't broadcast to #{newdim.inspect} "
19
42
  end
43
+ dd = dstdim.pop
20
44
  end
21
- return self[*sdim].bind(*new_dim) if flag_unbound_repeat
22
- return self
45
+
46
+ #
47
+ # Call Unbound repeat's bind
48
+ #
49
+ return self.reshape(*shape)[*repdim].bind(*newdim) if repdim.include?(:*)
50
+
51
+ self
23
52
  end
53
+
24
54
  end
25
55
 
26
56
  class CScalar
27
- def broadcast_to (*new_dim)
28
- return self
57
+
58
+ def broadcast_to (*newdim)
59
+ out = CArray.new(data_type, newdim, bytes: bytes)
60
+ out[] = self
61
+ out
29
62
  end
63
+
30
64
  end
31
65
 
32
66
  class CAUnboundRepeat
67
+
33
68
  alias broadcast_to bind
69
+
34
70
  end
35
71
 
36
- def CArray.broadcast (*argv)
37
- sel = argv.select {|arg| arg.is_a?(CArray) }
72
+ def CArray.broadcast (*argv, expand_scalar: false, &block)
73
+
74
+ sel = argv.select { |arg| arg.is_a?(CArray) }
38
75
  return argv if sel.empty?
76
+
39
77
  dim = []
40
78
  ndim = sel.map(&:ndim).max
41
79
  ndim.times do |k|
42
- dim[k] = sel.map{|arg| arg.dim[k] || 1 }.max
80
+ dim[k] = sel.map { |arg| arg.dim[k] || 1 }.max
81
+ end
82
+
83
+ if not expand_scalar
84
+ list = argv.map { |arg|
85
+ case arg
86
+ when CScalar
87
+ arg
88
+ when CArray
89
+ arg.broadcast_to(*dim)
90
+ else
91
+ arg
92
+ end
93
+ }
94
+ else
95
+ list = argv.map { |arg| arg.is_a?(CArray) ? arg.broadcast_to(*dim) : arg }
43
96
  end
44
- return argv.map{|arg| arg.is_a?(CArray) ? arg.broadcast_to(*dim) : arg }
97
+
98
+ return block.call(*list) if block
99
+ return list
45
100
  end
101
+
@@ -3,10 +3,8 @@
3
3
  # carray/composition.rb
4
4
  #
5
5
  # This file is part of Ruby/CArray extension library.
6
- # You can redistribute it and/or modify it under the terms of
7
- # the Ruby Licence.
8
6
  #
9
- # Copyright (C) 2005 Hiroki Motoyoshi
7
+ # Copyright (C) 2005-2020 Hiroki Motoyoshi
10
8
  #
11
9
  # ----------------------------------------------------------------------------
12
10
 
@@ -34,6 +32,7 @@ class CArray
34
32
  end
35
33
  end
36
34
  out = CArray.new(data_type, newdim, &block)
35
+ out.data_class = data_class if has_data_class?
37
36
  if out.has_mask?
38
37
  out.mask.paste(offset, self.false)
39
38
  end
@@ -63,6 +62,7 @@ class CArray
63
62
  grids[i][offset[i]..-1].seq!(offset[i]+bsize[i])
64
63
  end
65
64
  out = CArray.new(data_type, newdim)
65
+ out.data_class = data_class if has_data_class?
66
66
  if block_given?
67
67
  sel = out.true
68
68
  sel[*grids] = 0
@@ -114,7 +114,14 @@ class CArray
114
114
  return self[*grids].to_ca
115
115
  end
116
116
 
117
- def self.combine (data_type, tdim, list, at = 0)
117
+ def self.combine (data_type, tdim, list, at = 0, bytes: nil)
118
+ if CArray.data_class?(data_type)
119
+ data_class = data_type
120
+ data_type = :fixlen
121
+ bytes = data_class::DATA_SIZE
122
+ else
123
+ data_class = nil
124
+ end
118
125
  has_fill_value = false
119
126
  if block_given?
120
127
  fill_value = yield
@@ -168,6 +175,7 @@ class CArray
168
175
  else
169
176
  obj = CArray.new(data_type, newdim)
170
177
  end
178
+ out.data_class = data_class if data_class
171
179
  idx = newdim.map{0}
172
180
  block.each_with_index do |item, tidx|
173
181
  (at...at+tndim).each_with_index do |d,i|
@@ -178,11 +186,18 @@ class CArray
178
186
  obj
179
187
  end
180
188
 
181
- def self.bind (data_type, list, at = 0)
182
- return CArray.combine(data_type, [list.size], list, at)
189
+ def self.bind (data_type, list, at = 0, bytes: nil)
190
+ return CArray.combine(data_type, [list.size], list, at, bytes: bytes)
183
191
  end
184
192
 
185
- def self.composite (data_type, tdim, list, at = 0)
193
+ def self.composite (data_type, tdim, list, at = 0, bytes: nil)
194
+ if CArray.data_class?(data_type)
195
+ data_class = data_type
196
+ data_type = :fixlen
197
+ bytes = data_class::DATA_SIZE
198
+ else
199
+ data_class = nil
200
+ end
186
201
  if not tdim.is_a?(Array) or tdim.size == 0
187
202
  raise "invalid tiling dimension"
188
203
  end
@@ -213,7 +228,8 @@ class CArray
213
228
  end
214
229
  newdim = dim.clone
215
230
  newdim[at,0] = tdim
216
- obj = CArray.new(data_type, newdim)
231
+ obj = CArray.new(data_type, newdim, bytes: bytes)
232
+ out.data_class = data_class if data_class
217
233
  idx = Array.new(ndim+tndim) { nil }
218
234
  CArray.each_index(*tdim) do |*tidx|
219
235
  idx[at,tndim] = tidx
@@ -222,13 +238,21 @@ class CArray
222
238
  obj
223
239
  end
224
240
 
225
- def self.merge (data_type, list, at = -1)
226
- return CArray.composite(data_type, [list.size], list, at)
241
+ def self.merge (data_type, list, at = -1, bytes: nil)
242
+ return CArray.composite(data_type, [list.size], list, at, bytes: bytes)
227
243
  end
228
244
 
229
245
  def self.join (*argv)
230
246
  # get options
231
247
  case argv.first
248
+ when Class
249
+ if CArray.data_class?(argv.first)
250
+ data_class = argv.shift
251
+ data_type = "fixlen"
252
+ bytes = data_class::DATA_SIZE
253
+ else
254
+ raise "#{argv.first} can not to be a data_class for CArray"
255
+ end
232
256
  when Integer, Symbol, String
233
257
  type, = *CArray.guess_type_and_bytes(argv.shift, 0)
234
258
  else
@@ -3,10 +3,8 @@
3
3
  # carray/constructor.rb
4
4
  #
5
5
  # This file is part of Ruby/CArray extension library.
6
- # You can redistribute it and/or modify it under the terms of
7
- # the Ruby Licence.
8
6
  #
9
- # Copyright (C) 2005 Hiroki Motoyoshi
7
+ # Copyright (C) 2005-2020 Hiroki Motoyoshi
10
8
  #
11
9
  # ----------------------------------------------------------------------------
12
10
 
@@ -397,7 +395,7 @@ class CArray
397
395
  def eye (n, m = nil, k = 0)
398
396
  m ||= n
399
397
  mat = CArray.new(self::DataType || CA_FLOAT64, [n, m])
400
- start = k > 0 ? k : m - k - 1
398
+ start = ( k == 0 ) ? k : ( k > 0 ? k : m - k - 1 )
401
399
  mat[[start..-1,m+1]] = 1
402
400
  mat
403
401
  end
@@ -432,7 +430,7 @@ class CArray
432
430
  end
433
431
  data_type = self::DataType
434
432
  data_type ||= guess_data_type_from_values(start, stop, step)
435
- CArray.__new__(data_type, start..stop, step)
433
+ CArray.__new__(data_type, start..stop-step, step)
436
434
  end
437
435
 
438
436
  def full (shape, fill_value)
@@ -447,16 +445,40 @@ class CArray
447
445
  end
448
446
 
449
447
  class CArray
450
-
451
- def self.meshgrid (*args)
452
- dim = args.map(&:size)
453
- out = []
454
- args.each_with_index do |arg, i|
455
- newdim = dim.dup
456
- newdim[i] = :%
457
- out[i] = arg[*newdim].to_ca
448
+
449
+ def self.meshgrid (*axes, indexing: "xy", copy: true, sparse: false, &block)
450
+ case indexing
451
+ when "xy"
452
+ ### no operation
453
+ when "ij"
454
+ axes = axes.map{|axis| axis.seq }
455
+ else
456
+ raise ArgumentError, %{indexing option should be one of "xy" and "ij"}
457
+ end
458
+ shape = axes.map(&:size).reverse
459
+ if sparse ### => CAUnboundRepeat
460
+ list = axes.map.with_index do |axis, k|
461
+ extended_shape = (shape.size-1).downto(0).map { |i| ( i == k ) ? nil : :* }
462
+ if copy
463
+ axis[*extended_shape].to_ca
464
+ else
465
+ axis[*extended_shape]
466
+ end
467
+ end
468
+ else ### => CARepeat
469
+ naxes = shape.size
470
+ list = axes.map.with_index do |axis, k|
471
+ extended_shape = shape.dup
472
+ extended_shape[naxes - k - 1] = :%
473
+ if copy
474
+ axis[*extended_shape].to_ca
475
+ else
476
+ axis[*extended_shape]
477
+ end
478
+ end
458
479
  end
459
- return *out
480
+ return block.call(*list) if block
481
+ return list
460
482
  end
461
483
 
462
484
  end