carray 1.3.5 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSES +22 -0
- data/README.md +18 -21
- data/Rakefile +31 -0
- data/carray.gemspec +13 -26
- data/{ca_iter_block.c → ext/ca_iter_block.c} +13 -13
- data/{ca_iter_dimension.c → ext/ca_iter_dimension.c} +16 -16
- data/{ca_iter_window.c → ext/ca_iter_window.c} +10 -10
- data/{ca_obj_array.c → ext/ca_obj_array.c} +60 -55
- data/{ca_obj_bitarray.c → ext/ca_obj_bitarray.c} +12 -12
- data/{ca_obj_bitfield.c → ext/ca_obj_bitfield.c} +7 -7
- data/{ca_obj_block.c → ext/ca_obj_block.c} +42 -42
- data/{ca_obj_fake.c → ext/ca_obj_fake.c} +7 -7
- data/{ca_obj_farray.c → ext/ca_obj_farray.c} +18 -18
- data/{ca_obj_field.c → ext/ca_obj_field.c} +15 -15
- data/{ca_obj_grid.c → ext/ca_obj_grid.c} +27 -27
- data/{ca_obj_mapping.c → ext/ca_obj_mapping.c} +9 -9
- data/{ca_obj_object.c → ext/ca_obj_object.c} +37 -37
- data/{ca_obj_reduce.c → ext/ca_obj_reduce.c} +1 -1
- data/{ca_obj_refer.c → ext/ca_obj_refer.c} +33 -33
- data/{ca_obj_repeat.c → ext/ca_obj_repeat.c} +43 -43
- data/{ca_obj_select.c → ext/ca_obj_select.c} +2 -2
- data/{ca_obj_shift.c → ext/ca_obj_shift.c} +23 -23
- data/{ca_obj_transpose.c → ext/ca_obj_transpose.c} +23 -23
- data/{ca_obj_unbound_repeat.c → ext/ca_obj_unbound_repeat.c} +55 -55
- data/{ca_obj_window.c → ext/ca_obj_window.c} +26 -26
- data/{carray.h → ext/carray.h} +77 -51
- data/{carray_access.c → ext/carray_access.c} +133 -91
- data/{carray_attribute.c → ext/carray_attribute.c} +12 -12
- data/{carray_call_cfunc.c → ext/carray_call_cfunc.c} +0 -0
- data/{carray_cast.c → ext/carray_cast.c} +6 -6
- data/{carray_cast_func.rb → ext/carray_cast_func.rb} +0 -0
- data/{carray_class.c → ext/carray_class.c} +0 -0
- data/{carray_conversion.c → ext/carray_conversion.c} +11 -13
- data/{carray_copy.c → ext/carray_copy.c} +19 -19
- data/{carray_core.c → ext/carray_core.c} +2 -2
- data/ext/carray_data_type.c +66 -0
- data/{carray_element.c → ext/carray_element.c} +9 -9
- data/{carray_generate.c → ext/carray_generate.c} +67 -1
- data/{carray_iterator.c → ext/carray_iterator.c} +40 -38
- data/{carray_loop.c → ext/carray_loop.c} +24 -24
- data/{carray_mask.c → ext/carray_mask.c} +17 -6
- data/{carray_math.rb → ext/carray_math.rb} +25 -25
- data/ext/{mathfunc/carray_mathfunc.c → carray_mathfunc.c} +0 -0
- data/{carray_numeric.c → ext/carray_numeric.c} +1 -1
- data/{carray_operator.c → ext/carray_operator.c} +32 -9
- data/{carray_order.c → ext/carray_order.c} +2 -153
- data/{carray_sort_addr.c → ext/carray_sort_addr.c} +0 -0
- data/{carray_stat.c → ext/carray_stat.c} +5 -5
- data/{carray_stat_proc.rb → ext/carray_stat_proc.rb} +23 -23
- data/{carray_test.c → ext/carray_test.c} +22 -21
- data/{carray_undef.c → ext/carray_undef.c} +0 -0
- data/{carray_utils.c → ext/carray_utils.c} +0 -0
- data/{extconf.rb → ext/extconf.rb} +0 -5
- data/{mkmath.rb → ext/mkmath.rb} +12 -2
- data/{ruby_carray.c → ext/ruby_carray.c} +9 -2
- data/{ruby_ccomplex.c → ext/ruby_ccomplex.c} +0 -0
- data/{ruby_float_func.c → ext/ruby_float_func.c} +0 -0
- data/{version.h → ext/version.h} +5 -5
- data/{version.rb → ext/version.rb} +0 -0
- data/lib/carray.rb +49 -7
- data/lib/carray/{base/autoload.rb → autoload.rb} +48 -6
- data/lib/carray/autoload/autoload_base.rb +1 -5
- data/lib/carray/autoload/autoload_gem_cairo.rb +9 -0
- data/lib/carray/autoload/autoload_gem_ffi.rb +9 -0
- data/lib/carray/autoload/autoload_gem_gnuplot.rb +2 -0
- data/lib/carray/autoload/autoload_gem_io_csv.rb +14 -0
- data/lib/carray/autoload/autoload_gem_io_pg.rb +6 -0
- data/lib/carray/autoload/autoload_gem_io_sqlite3.rb +12 -0
- data/lib/carray/autoload/autoload_gem_narray.rb +10 -0
- data/lib/carray/autoload/autoload_gem_numo_narray.rb +15 -0
- data/lib/carray/autoload/autoload_gem_opencv.rb +16 -0
- data/lib/carray/autoload/autoload_gem_random.rb +8 -0
- data/lib/carray/autoload/autoload_gem_rmagick.rb +23 -0
- data/lib/carray/autoload/{autoload_graphics_zimg.rb → autoload_gem_zimg.rb} +0 -0
- data/lib/carray/basic.rb +193 -0
- data/lib/carray/compose.rb +291 -0
- data/lib/carray/construct.rb +445 -0
- data/lib/carray/convert.rb +115 -0
- data/lib/carray/{base/inspect.rb → inspect.rb} +6 -6
- data/lib/carray/io/imagemagick.rb +1 -1
- data/lib/carray/{base/iterator.rb → iterator.rb} +3 -3
- data/lib/carray/mask.rb +91 -0
- data/lib/carray/{base/math.rb → math.rb} +17 -47
- data/lib/carray/math/histogram.rb +7 -7
- data/lib/carray/mkmf.rb +8 -0
- data/lib/carray/object/ca_obj_pack.rb +8 -8
- data/lib/carray/obsolete.rb +272 -0
- data/lib/carray/ordering.rb +157 -0
- data/lib/carray/{base/serialize.rb → serialize.rb} +28 -53
- data/lib/carray/string.rb +190 -0
- data/lib/carray/{base/struct.rb → struct.rb} +20 -20
- data/lib/carray/{io/table.rb → table.rb} +1 -9
- data/lib/carray/testing.rb +56 -0
- data/lib/carray/time.rb +78 -0
- data/lib/carray/transform.rb +100 -0
- data/misc/Methods.ja.md +182 -0
- data/{NOTE → misc/NOTE} +0 -0
- data/test/test_ALL.rb +0 -2
- data/test/test_order.rb +7 -7
- data/test/test_ref_store.rb +13 -13
- data/test/test_stat.rb +7 -15
- data/{devel → utils}/guess_shape.rb +0 -0
- data/utils/{diff_method.rb → monkey_patch_methods.rb} +17 -7
- metadata +100 -254
- data/COPYING +0 -56
- data/GPL +0 -340
- data/Gemfile +0 -8
- data/Gemfile.lock +0 -33
- data/LEGAL +0 -50
- data/TODO +0 -5
- data/carray_random.c +0 -531
- data/ext/calculus/carray_calculus.c +0 -931
- data/ext/calculus/carray_interp.c +0 -358
- data/ext/calculus/extconf.rb +0 -12
- data/ext/calculus/lib/autoload/autoload_math_calculus.rb +0 -2
- data/ext/calculus/lib/math/calculus.rb +0 -119
- data/ext/calculus/lib/math/interp/adapter_interp1d.rb +0 -31
- data/ext/fortio/extconf.rb +0 -3
- data/ext/fortio/lib/carray/autoload/autoload_fortran_format.rb +0 -5
- data/ext/fortio/lib/carray/io/fortran_format.rb +0 -43
- data/ext/fortio/lib/fortio.rb +0 -3
- data/ext/fortio/lib/fortio/fortran_format.rb +0 -605
- data/ext/fortio/lib/fortio/fortran_format.tab.rb +0 -536
- data/ext/fortio/lib/fortio/fortran_format.y +0 -215
- data/ext/fortio/lib/fortio/fortran_namelist.rb +0 -151
- data/ext/fortio/lib/fortio/fortran_namelist.tab.rb +0 -470
- data/ext/fortio/lib/fortio/fortran_namelist.y +0 -213
- data/ext/fortio/lib/fortio/fortran_sequential.rb +0 -345
- data/ext/fortio/ruby_fortio.c +0 -182
- data/ext/fortio/test/test_H.rb +0 -5
- data/ext/fortio/test/test_T.rb +0 -7
- data/ext/fortio/test/test_fortran_format.rb +0 -86
- data/ext/fortio/test/test_namelist.rb +0 -25
- data/ext/fortio/test/test_namelist_write.rb +0 -10
- data/ext/fortio/test/test_sequential.rb +0 -13
- data/ext/fortio/test/test_sequential2.rb +0 -13
- data/ext/fortio/work/test.rb +0 -10
- data/ext/fortio/work/test_e.rb +0 -19
- data/ext/fortio/work/test_ep.rb +0 -10
- data/ext/fortio/work/test_parse.rb +0 -12
- data/ext/imagemap/carray_imagemap.c +0 -495
- data/ext/imagemap/doc/call_graph.dot +0 -28
- data/ext/imagemap/draw.c +0 -567
- data/ext/imagemap/extconf.rb +0 -13
- data/ext/imagemap/lib/autoload/autoload_graphics_imagemap.rb +0 -1
- data/ext/imagemap/lib/graphics/imagemap.rb +0 -273
- data/ext/imagemap/lib/image_map.rb +0 -4
- data/ext/imagemap/test/swath_index.rb +0 -83
- data/ext/imagemap/test/swath_warp.rb +0 -99
- data/ext/imagemap/test/test.rb +0 -23
- data/ext/imagemap/test/test_image.rb +0 -42
- data/ext/imagemap/test/test_line.rb +0 -14
- data/ext/imagemap/test/test_rotate.rb +0 -17
- data/ext/imagemap/test/test_triangle.rb +0 -20
- data/ext/imagemap/test/test_warp.rb +0 -26
- data/ext/mathfunc/extconf.rb +0 -18
- data/ext/mathfunc/lib/autoload/autoload_math_mathfunc.rb +0 -1
- data/ext/mathfunc/lib/math/mathfunc.rb +0 -15
- data/ext/mathfunc/test/test_hypot.rb +0 -5
- data/ext/mathfunc/test/test_j0.rb +0 -22
- data/ext/mathfunc/test/test_jn.rb +0 -8
- data/ext/mathfunc/test/test_sph.rb +0 -9
- data/ext/narray/README +0 -22
- data/ext/narray/ca_wrap_narray.c +0 -500
- data/ext/narray/carray_narray.c +0 -21
- data/ext/narray/extconf.rb +0 -57
- data/ext/narray/lib/autoload/autoload_math_narray.rb +0 -1
- data/ext/narray/lib/autoload/autoload_math_narray_miss.rb +0 -11
- data/ext/narray/lib/math/narray.rb +0 -17
- data/ext/narray/lib/math/narray_miss.rb +0 -45
- data/lib/carray/autoload/autoload_graphics_gnuplot.rb +0 -2
- data/lib/carray/autoload/autoload_io_csv.rb +0 -14
- data/lib/carray/autoload/autoload_io_pg.rb +0 -6
- data/lib/carray/autoload/autoload_io_sqlite3.rb +0 -12
- data/lib/carray/autoload/autoload_io_table.rb +0 -1
- data/lib/carray/autoload/autoload_math_interp.rb +0 -4
- data/lib/carray/base/basic.rb +0 -1090
- data/lib/carray/base/obsolete.rb +0 -131
- data/lib/carray/graphics/gnuplot.rb +0 -2131
- data/lib/carray/graphics/zimg.rb +0 -296
- data/lib/carray/io/csv.rb +0 -572
- data/lib/carray/io/pg.rb +0 -101
- data/lib/carray/io/sqlite3.rb +0 -215
- data/lib/carray/math/interp.rb +0 -57
- data/lib/carray/math/interp/adapter_gsl_spline.rb +0 -47
- data/mt19937ar.c +0 -182
- data/mt19937ar.h +0 -86
- data/rdoc_main.rb +0 -27
- data/rdoc_math.rb +0 -5
- data/rdoc_stat.rb +0 -31
- data/test/test_narray.rb +0 -64
- data/test/test_random.rb +0 -15
- data/utils/create_rdoc.sh +0 -9
- data/utils/make_tgz.sh +0 -3
@@ -0,0 +1,291 @@
|
|
1
|
+
# ----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# carray/composition.rb
|
4
|
+
#
|
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
|
+
#
|
9
|
+
# Copyright (C) 2005 Hiroki Motoyoshi
|
10
|
+
#
|
11
|
+
# ----------------------------------------------------------------------------
|
12
|
+
|
13
|
+
class CArray
|
14
|
+
|
15
|
+
# Returns the array resized to the dimension given as `newdim`.
|
16
|
+
# The new area is filled by the value returned by the block.
|
17
|
+
def resize (*newdim, &block)
|
18
|
+
if newdim.size != ndim
|
19
|
+
raise "ndim mismatch"
|
20
|
+
end
|
21
|
+
offset = Array.new(ndim){0}
|
22
|
+
ndim.times do |i|
|
23
|
+
d = newdim[i]
|
24
|
+
case d
|
25
|
+
when nil
|
26
|
+
newdim[i] = dim[i]
|
27
|
+
when Integer
|
28
|
+
if d < 0
|
29
|
+
newdim[i] *= -1
|
30
|
+
offset[i] = newdim[i] - dim[i]
|
31
|
+
end
|
32
|
+
else
|
33
|
+
raise "invalid dimension size"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
out = CArray.new(data_type, newdim, &block)
|
37
|
+
if out.has_mask?
|
38
|
+
out.mask.paste(offset, self.false)
|
39
|
+
end
|
40
|
+
out.paste(offset, self)
|
41
|
+
return out
|
42
|
+
end
|
43
|
+
|
44
|
+
# insert
|
45
|
+
def insert_block (offset, bsize, &block)
|
46
|
+
if offset.size != ndim or
|
47
|
+
bsize.size != ndim
|
48
|
+
raise "ndim mismatch"
|
49
|
+
end
|
50
|
+
newdim = dim
|
51
|
+
grids = dim.map{|d| CArray.int32(d) }
|
52
|
+
ndim.times do |i|
|
53
|
+
if offset[i] < 0
|
54
|
+
offset[i] += dim[i]
|
55
|
+
end
|
56
|
+
if offset[i] < 0 or offset[i] >= dim[i] or bsize[i] < 0
|
57
|
+
raise "invalid offset or size"
|
58
|
+
end
|
59
|
+
if bsize[i] > 0
|
60
|
+
newdim[i] += bsize[i]
|
61
|
+
end
|
62
|
+
grids[i][0...offset[i]].seq!
|
63
|
+
grids[i][offset[i]..-1].seq!(offset[i]+bsize[i])
|
64
|
+
end
|
65
|
+
out = CArray.new(data_type, newdim)
|
66
|
+
if block_given?
|
67
|
+
sel = out.true
|
68
|
+
sel[*grids] = 0
|
69
|
+
out[sel] = block.call
|
70
|
+
end
|
71
|
+
out[*grids] = self
|
72
|
+
return out
|
73
|
+
end
|
74
|
+
|
75
|
+
def delete_block (offset, bsize)
|
76
|
+
if offset.size != ndim or
|
77
|
+
bsize.size != ndim
|
78
|
+
raise "ndim mismatch"
|
79
|
+
end
|
80
|
+
newdim = dim
|
81
|
+
grids = []
|
82
|
+
ndim.times do |i|
|
83
|
+
if offset[i] < 0
|
84
|
+
offset[i] += dim[i]
|
85
|
+
end
|
86
|
+
if bsize[i] >= 0
|
87
|
+
if offset[i] < 0 or offset[i] >= dim[i]
|
88
|
+
raise "invalid offset or size"
|
89
|
+
end
|
90
|
+
newdim[i] -= bsize[i]
|
91
|
+
else
|
92
|
+
if offset[i] + bsize[i] + 1 < 0 or offset[i] + bsize[i] > dim[i]
|
93
|
+
raise "invalid offset or size"
|
94
|
+
end
|
95
|
+
newdim[i] += bsize[i]
|
96
|
+
end
|
97
|
+
grids[i] = CArray.int32(newdim[i])
|
98
|
+
if bsize[i] >= 0
|
99
|
+
if offset[i] > 0
|
100
|
+
grids[i][0...offset[i]].seq!
|
101
|
+
end
|
102
|
+
if offset[i] + bsize[i] < dim[i]
|
103
|
+
grids[i][offset[i]..-1].seq!(offset[i]+bsize[i])
|
104
|
+
end
|
105
|
+
else
|
106
|
+
if offset[i]+bsize[i] > 0
|
107
|
+
grids[i][0..offset[i]+bsize[i]].seq!
|
108
|
+
end
|
109
|
+
if offset[i]+bsize[i]+1 < dim[i]-1
|
110
|
+
grids[i][offset[i]+bsize[i]+1..-1].seq!(offset[i]+1)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
return self[*grids].to_ca
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.combine (data_type, tdim, list, at = 0)
|
118
|
+
has_fill_value = false
|
119
|
+
if block_given?
|
120
|
+
fill_value = yield
|
121
|
+
has_fill_value = true
|
122
|
+
end
|
123
|
+
if not tdim.is_a?(Array) or tdim.size == 0
|
124
|
+
raise "invalid binding dimension"
|
125
|
+
end
|
126
|
+
if not list.is_a?(Array) or list.size == 0
|
127
|
+
raise "invalid list"
|
128
|
+
end
|
129
|
+
list = list.map{|x| CArray.wrap_readonly(x, data_type) }
|
130
|
+
ref = list.detect{|x| x.is_a?(CArray) or not x.scalar? }
|
131
|
+
unless ref
|
132
|
+
raise "at least one element in list should be a carray"
|
133
|
+
end
|
134
|
+
dim = ref.dim
|
135
|
+
ndim = ref.ndim
|
136
|
+
tndim = tdim.size
|
137
|
+
if at < 0
|
138
|
+
at += ndim - tndim + 1
|
139
|
+
end
|
140
|
+
unless at.between?(0, ndim - tndim)
|
141
|
+
raise "concatnating position out of range"
|
142
|
+
end
|
143
|
+
list.map! do |x|
|
144
|
+
if x.scalar?
|
145
|
+
rdim = dim.clone
|
146
|
+
rdim[at] = :%
|
147
|
+
x = x[*rdim] # convert CScalar to CARepeat
|
148
|
+
end
|
149
|
+
x
|
150
|
+
end
|
151
|
+
block = CArray.object(*tdim){ list }
|
152
|
+
edim = tdim.clone
|
153
|
+
idx = Array.new(tdim)
|
154
|
+
offset = Array.new(tdim.size) { [] }
|
155
|
+
tdim.each_with_index do |td, i|
|
156
|
+
edim[i] = 0
|
157
|
+
idx.map!{0}
|
158
|
+
idx[i] = nil
|
159
|
+
block[*idx].each do |e|
|
160
|
+
offset[i] << edim[i]
|
161
|
+
edim[i] += e.dim[at+i] # extended dimension size
|
162
|
+
end
|
163
|
+
end
|
164
|
+
newdim = dim.clone
|
165
|
+
newdim[at,tndim] = edim # extended dimension size
|
166
|
+
if has_fill_value
|
167
|
+
obj = CArray.new(data_type, newdim) { fill_value }
|
168
|
+
else
|
169
|
+
obj = CArray.new(data_type, newdim)
|
170
|
+
end
|
171
|
+
idx = newdim.map{0}
|
172
|
+
block.each_with_index do |item, tidx|
|
173
|
+
(at...at+tndim).each_with_index do |d,i|
|
174
|
+
idx[d] = offset[i][tidx[i]]
|
175
|
+
end
|
176
|
+
obj.paste(idx, item)
|
177
|
+
end
|
178
|
+
obj
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.bind (data_type, list, at = 0)
|
182
|
+
return CArray.combine(data_type, [list.size], list, at)
|
183
|
+
end
|
184
|
+
|
185
|
+
def self.composite (data_type, tdim, list, at = 0)
|
186
|
+
if not tdim.is_a?(Array) or tdim.size == 0
|
187
|
+
raise "invalid tiling dimension"
|
188
|
+
end
|
189
|
+
if not list.is_a?(Array) or list.size == 0
|
190
|
+
raise "invalid carray list"
|
191
|
+
end
|
192
|
+
list = list.map{|x| CArray.wrap_readonly(x, data_type) }
|
193
|
+
ref = list.detect{|x| x.is_a?(CArray) or not x.scalar? }
|
194
|
+
unless ref
|
195
|
+
raise "at least one element in list should be a carray"
|
196
|
+
end
|
197
|
+
dim = ref.dim
|
198
|
+
ndim = ref.ndim
|
199
|
+
if at < 0
|
200
|
+
at += ndim + 1 # "+ 1" is needed here
|
201
|
+
end
|
202
|
+
unless at.between?(0,ndim)
|
203
|
+
raise "tiling position is out of range"
|
204
|
+
end
|
205
|
+
tndim = tdim.size
|
206
|
+
list.map! do |x|
|
207
|
+
if x.scalar?
|
208
|
+
rdim = dim.clone
|
209
|
+
rdim[at] = :%
|
210
|
+
x = x[*rdim] # convert CScalar to CARepeat
|
211
|
+
end
|
212
|
+
x
|
213
|
+
end
|
214
|
+
newdim = dim.clone
|
215
|
+
newdim[at,0] = tdim
|
216
|
+
obj = CArray.new(data_type, newdim)
|
217
|
+
idx = Array.new(ndim+tndim) { nil }
|
218
|
+
CArray.each_index(*tdim) do |*tidx|
|
219
|
+
idx[at,tndim] = tidx
|
220
|
+
obj[*idx] = list.shift
|
221
|
+
end
|
222
|
+
obj
|
223
|
+
end
|
224
|
+
|
225
|
+
def self.merge (data_type, list, at = -1)
|
226
|
+
return CArray.composite(data_type, [list.size], list, at)
|
227
|
+
end
|
228
|
+
|
229
|
+
def self.join (*argv)
|
230
|
+
# get options
|
231
|
+
case argv.first
|
232
|
+
when Integer, Symbol, String
|
233
|
+
type, = *CArray.guess_type_and_bytes(argv.shift, 0)
|
234
|
+
else
|
235
|
+
type = argv.flatten.first.data_type
|
236
|
+
end
|
237
|
+
# process
|
238
|
+
conc = argv.map do |list|
|
239
|
+
case list
|
240
|
+
when CArray
|
241
|
+
if list.ndim == 1
|
242
|
+
list[:%,1]
|
243
|
+
else
|
244
|
+
list
|
245
|
+
end
|
246
|
+
when Array
|
247
|
+
x0 = list.first
|
248
|
+
if list.size == 1 and
|
249
|
+
x0.is_a?(CArray) and
|
250
|
+
x0.ndim == 1
|
251
|
+
list = [x0[:%,1]]
|
252
|
+
else
|
253
|
+
list = list.map { |x|
|
254
|
+
case x
|
255
|
+
when CArray
|
256
|
+
if x.ndim == 1
|
257
|
+
x[:%,1]
|
258
|
+
else
|
259
|
+
x
|
260
|
+
end
|
261
|
+
when Array
|
262
|
+
y = x.first
|
263
|
+
if x.size == 1 and
|
264
|
+
y.is_a?(CArray) and
|
265
|
+
y.ndim == 1
|
266
|
+
y[1,:%]
|
267
|
+
else
|
268
|
+
CArray.join(*x)
|
269
|
+
end
|
270
|
+
else
|
271
|
+
x
|
272
|
+
end
|
273
|
+
}
|
274
|
+
end
|
275
|
+
if block_given?
|
276
|
+
CArray.bind(type, list, 1, &block)
|
277
|
+
else
|
278
|
+
CArray.bind(type, list, 1)
|
279
|
+
end
|
280
|
+
else
|
281
|
+
list
|
282
|
+
end
|
283
|
+
end
|
284
|
+
if conc.size > 1
|
285
|
+
return CArray.bind(type, conc)
|
286
|
+
else
|
287
|
+
return conc.first
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
@@ -0,0 +1,445 @@
|
|
1
|
+
# ----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# carray/constructor.rb
|
4
|
+
#
|
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
|
+
#
|
9
|
+
# Copyright (C) 2005 Hiroki Motoyoshi
|
10
|
+
#
|
11
|
+
# ----------------------------------------------------------------------------
|
12
|
+
|
13
|
+
class CArray
|
14
|
+
|
15
|
+
#
|
16
|
+
# CArray.span(data_type, range[, step])
|
17
|
+
# CArray.span(range[, step]) -> data_type guessed by range.first type
|
18
|
+
#
|
19
|
+
|
20
|
+
def self.span (*argv)
|
21
|
+
if argv.first.is_a?(Range)
|
22
|
+
type = nil
|
23
|
+
else
|
24
|
+
type, = *CArray.guess_type_and_bytes(argv.shift, nil)
|
25
|
+
end
|
26
|
+
range, step = argv[0], argv[1]
|
27
|
+
start, stop = range.begin, range.end
|
28
|
+
if step == 0
|
29
|
+
raise "step should not be 0"
|
30
|
+
end
|
31
|
+
if not type
|
32
|
+
case start
|
33
|
+
when Integer
|
34
|
+
type = CA_INT32
|
35
|
+
when Float
|
36
|
+
type = CA_FLOAT64
|
37
|
+
else
|
38
|
+
type = CA_OBJECT
|
39
|
+
end
|
40
|
+
end
|
41
|
+
if type == CA_OBJECT and not step
|
42
|
+
return CA_OBJECT(range.to_a)
|
43
|
+
else
|
44
|
+
step ||= 1
|
45
|
+
if range.exclude_end?
|
46
|
+
n = ((stop - start).abs/step).floor
|
47
|
+
else
|
48
|
+
n = ((stop - start).abs/step).floor + 1
|
49
|
+
end
|
50
|
+
if start <= stop
|
51
|
+
return CArray.new(type, [n]).seq(start, step)
|
52
|
+
else
|
53
|
+
return CArray.new(type, [n]).seq(start, -step.abs)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def span! (range)
|
59
|
+
first = range.begin.to_r
|
60
|
+
last = range.end.to_r
|
61
|
+
if range.exclude_end?
|
62
|
+
seq!(first, (last-first)/elements)
|
63
|
+
else
|
64
|
+
seq!(first, (last-first)/(elements-1))
|
65
|
+
end
|
66
|
+
return self
|
67
|
+
end
|
68
|
+
|
69
|
+
def span (range)
|
70
|
+
return template.span!(range)
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
#
|
75
|
+
#
|
76
|
+
|
77
|
+
def scale! (xa, xb)
|
78
|
+
xa = xa.to_f
|
79
|
+
xb = xb.to_f
|
80
|
+
seq!(xa, (xb-xa)/(elements-1))
|
81
|
+
end
|
82
|
+
|
83
|
+
def scale (xa, xb)
|
84
|
+
template.scale!(xa, xb)
|
85
|
+
end
|
86
|
+
|
87
|
+
# @private
|
88
|
+
# Create new CArray object from the return value of the block
|
89
|
+
# with data type +type+. The dimensional size and the initialization value
|
90
|
+
# are guessed from the return value of the block.
|
91
|
+
# The block should return one of the following objects.
|
92
|
+
#
|
93
|
+
# * Numeric
|
94
|
+
# * Array
|
95
|
+
# * CArray
|
96
|
+
# * an object that has either method +to_ca+ or +to_a+ or +map+
|
97
|
+
#
|
98
|
+
# When the return value of the block is a Numeric or CScalar object,
|
99
|
+
# CScalar object is returned.
|
100
|
+
#
|
101
|
+
def self.__new__ (type, *args) # :nodoc:
|
102
|
+
case v = args.first
|
103
|
+
when CArray
|
104
|
+
return ( v.data_type == type ) ? v.to_ca : v.to_type(type)
|
105
|
+
when Array
|
106
|
+
return CArray.new(type, CArray.guess_array_shape(v)) { v }
|
107
|
+
when Range
|
108
|
+
return CArray.span(type, *args)
|
109
|
+
when String
|
110
|
+
if type == CA_OBJECT
|
111
|
+
return CScalar.new(CA_OBJECT) { v }
|
112
|
+
elsif type == CA_BOOLEAN
|
113
|
+
v = v.dup
|
114
|
+
v.tr!('^01',"1")
|
115
|
+
v.tr!('01',"\x0\x1")
|
116
|
+
return CArray.boolean(v.length).load_binary(v)
|
117
|
+
else
|
118
|
+
case v
|
119
|
+
when /;/
|
120
|
+
v = v.strip.split(/\s*;\s*/).
|
121
|
+
map{|s| s.split(/\s+|\s*,\s*/).map{|x| x=='_' ? UNDEF : x} }
|
122
|
+
else
|
123
|
+
v = v.strip.split(/\s+|\s*,\s*/).map{|x| x=='_' ? UNDEF : x}
|
124
|
+
end
|
125
|
+
return CArray.new(type, CArray.guess_array_shape(v)) { v }
|
126
|
+
end
|
127
|
+
when NilClass
|
128
|
+
return CArray.new(type, [0])
|
129
|
+
else
|
130
|
+
if v.respond_to?(:to_ca)
|
131
|
+
ca = v.to_ca
|
132
|
+
return ( ca.data_type == type ) ? ca : ca.to_type(type)
|
133
|
+
else
|
134
|
+
return CScalar.new(type) { v }
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# @private
|
140
|
+
def self.__new_fixlen__ (bytes, v) # :nodoc:
|
141
|
+
case v
|
142
|
+
when CArray
|
143
|
+
return ( v.data_type == :fixlen ) ? v.to_ca : v.to_type(:fixlen, :bytes=>bytes)
|
144
|
+
when Array
|
145
|
+
unless bytes
|
146
|
+
bytes = v.map{|s| s.length}.max
|
147
|
+
end
|
148
|
+
return CArray.new(:fixlen, CArray.guess_array_shape(v), :bytes=>bytes) { v }
|
149
|
+
when NilClass
|
150
|
+
return CArray.new(type, [0])
|
151
|
+
else
|
152
|
+
if v.respond_to?(:to_ca)
|
153
|
+
ca = v.to_ca
|
154
|
+
return ( ca.data_type == :fixlen ) ? ca : ca.to_type(:fixlen, :bytes=>bytes)
|
155
|
+
else
|
156
|
+
return CScalar.new(:fixlen, :bytes=>bytes) { v }
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
#
|
164
|
+
# CA_INT8(data)
|
165
|
+
# :
|
166
|
+
# CA_CMPLX256(data)
|
167
|
+
#
|
168
|
+
# Create new CArray object from +data+ with data type
|
169
|
+
# which is guessed from the method name. +data+ should be one of the following
|
170
|
+
# objects.
|
171
|
+
#
|
172
|
+
# * Numeric
|
173
|
+
# * Array
|
174
|
+
# * CArray
|
175
|
+
# * an object that has either method +to_ca+ or +to_a+ or +map+
|
176
|
+
#
|
177
|
+
# When the block returns a Numeric or CScalar object,
|
178
|
+
# the resulted array is a CScalar object.
|
179
|
+
|
180
|
+
[
|
181
|
+
"CA_BOOLEAN",
|
182
|
+
"CA_INT8",
|
183
|
+
"CA_UINT8",
|
184
|
+
"CA_INT16",
|
185
|
+
"CA_UINT16",
|
186
|
+
"CA_INT32",
|
187
|
+
"CA_UINT32",
|
188
|
+
"CA_INT64",
|
189
|
+
"CA_UINT64",
|
190
|
+
"CA_FLOAT32",
|
191
|
+
"CA_FLOAT64",
|
192
|
+
"CA_FLOAT128",
|
193
|
+
"CA_CMPLX64",
|
194
|
+
"CA_CMPLX128",
|
195
|
+
"CA_CMPLX256",
|
196
|
+
"CA_OBJECT",
|
197
|
+
"CA_BYTE",
|
198
|
+
"CA_SHORT",
|
199
|
+
"CA_INT",
|
200
|
+
"CA_FLOAT",
|
201
|
+
"CA_DOUBLE",
|
202
|
+
"CA_COMPLEX",
|
203
|
+
"CA_DCOMPLEX",
|
204
|
+
"CA_SIZE",
|
205
|
+
].each do |name|
|
206
|
+
eval %{
|
207
|
+
def #{name} (*val)
|
208
|
+
CArray.__new__(#{name}, *val)
|
209
|
+
end
|
210
|
+
}
|
211
|
+
end
|
212
|
+
|
213
|
+
def CA_FIXLEN (val, options = {})
|
214
|
+
CArray.__new_fixlen__(options[:bytes], val)
|
215
|
+
end
|
216
|
+
|
217
|
+
class CArray
|
218
|
+
|
219
|
+
module DataTypeNewConstructor
|
220
|
+
end
|
221
|
+
|
222
|
+
module DataTypeExtension
|
223
|
+
end
|
224
|
+
|
225
|
+
class Boolean
|
226
|
+
extend DataTypeNewConstructor
|
227
|
+
extend DataTypeExtension
|
228
|
+
TypeSymbol = :boolean
|
229
|
+
DataType = CA_BOOLEAN
|
230
|
+
end
|
231
|
+
|
232
|
+
class UInt8
|
233
|
+
extend DataTypeNewConstructor
|
234
|
+
extend DataTypeExtension
|
235
|
+
TypeSymbol = :uint8
|
236
|
+
DataType = CA_UINT8
|
237
|
+
end
|
238
|
+
|
239
|
+
class UInt16
|
240
|
+
extend DataTypeNewConstructor
|
241
|
+
extend DataTypeExtension
|
242
|
+
TypeSymbol = :uint16
|
243
|
+
DataType = CA_UINT16
|
244
|
+
end
|
245
|
+
|
246
|
+
class UInt32
|
247
|
+
extend DataTypeNewConstructor
|
248
|
+
extend DataTypeExtension
|
249
|
+
TypeSymbol = :uint32
|
250
|
+
DataType = CA_UINT32
|
251
|
+
end
|
252
|
+
|
253
|
+
class UInt64
|
254
|
+
extend DataTypeNewConstructor
|
255
|
+
extend DataTypeExtension
|
256
|
+
TypeSymbol = :uint64
|
257
|
+
DataType = CA_UINT64
|
258
|
+
end
|
259
|
+
|
260
|
+
class Int8
|
261
|
+
extend DataTypeNewConstructor
|
262
|
+
extend DataTypeExtension
|
263
|
+
TypeSymbol = :int8
|
264
|
+
DataType = CA_INT8
|
265
|
+
end
|
266
|
+
|
267
|
+
class Int16
|
268
|
+
extend DataTypeNewConstructor
|
269
|
+
extend DataTypeExtension
|
270
|
+
TypeSymbol = :int16
|
271
|
+
DataType = CA_INT16
|
272
|
+
end
|
273
|
+
|
274
|
+
class Int32
|
275
|
+
extend DataTypeNewConstructor
|
276
|
+
extend DataTypeExtension
|
277
|
+
TypeSymbol = :int32
|
278
|
+
DataType = CA_INT32
|
279
|
+
end
|
280
|
+
|
281
|
+
class Int64
|
282
|
+
extend DataTypeNewConstructor
|
283
|
+
extend DataTypeExtension
|
284
|
+
TypeSymbol = :int64
|
285
|
+
DataType = CA_INT64
|
286
|
+
end
|
287
|
+
|
288
|
+
class Float32
|
289
|
+
extend DataTypeNewConstructor
|
290
|
+
extend DataTypeExtension
|
291
|
+
TypeSymbol = :float32
|
292
|
+
DataType = CA_FLOAT32
|
293
|
+
end
|
294
|
+
|
295
|
+
SFloat = Float32
|
296
|
+
|
297
|
+
class Float64
|
298
|
+
extend DataTypeNewConstructor
|
299
|
+
extend DataTypeExtension
|
300
|
+
TypeSymbol = :float64
|
301
|
+
DataType = CA_FLOAT64
|
302
|
+
end
|
303
|
+
|
304
|
+
DFloat = Float64
|
305
|
+
|
306
|
+
class Complex64
|
307
|
+
extend DataTypeNewConstructor
|
308
|
+
extend DataTypeExtension
|
309
|
+
TypeSymbol = :complex64
|
310
|
+
DataType = CA_CMPLX64
|
311
|
+
end
|
312
|
+
|
313
|
+
SComplex = Complex64
|
314
|
+
|
315
|
+
class Complex128
|
316
|
+
extend DataTypeNewConstructor
|
317
|
+
extend DataTypeExtension
|
318
|
+
TypeSymbol = :complex128
|
319
|
+
DataType = CA_CMPLX128
|
320
|
+
end
|
321
|
+
|
322
|
+
DComplex = Complex128
|
323
|
+
|
324
|
+
class Object
|
325
|
+
extend DataTypeNewConstructor
|
326
|
+
extend DataTypeExtension
|
327
|
+
TypeSymbol = :object
|
328
|
+
DataType = CA_OBJECT
|
329
|
+
end
|
330
|
+
|
331
|
+
RObject = Object
|
332
|
+
|
333
|
+
class Fixlen
|
334
|
+
extend DataTypeNewConstructor
|
335
|
+
extend DataTypeExtension
|
336
|
+
TypeSymbol = :fixlen
|
337
|
+
DataType = CA_FIXLEN
|
338
|
+
end
|
339
|
+
|
340
|
+
end
|
341
|
+
|
342
|
+
class CArray
|
343
|
+
extend DataTypeExtension
|
344
|
+
TypeSymbol = nil
|
345
|
+
DataType = nil
|
346
|
+
end
|
347
|
+
|
348
|
+
class CArray
|
349
|
+
|
350
|
+
module DataTypeNewConstructor
|
351
|
+
|
352
|
+
def new (*shape)
|
353
|
+
CArray.new(self::DataType, shape)
|
354
|
+
end
|
355
|
+
|
356
|
+
end
|
357
|
+
|
358
|
+
module DataTypeExtension
|
359
|
+
|
360
|
+
def guess_data_type_from_values (*values)
|
361
|
+
if values.all? {|v| v == true || v == false }
|
362
|
+
CA_BOOLEAN
|
363
|
+
elsif values.all? { |v| v.is_a?(Integer) }
|
364
|
+
CA_INT64
|
365
|
+
elsif values.all? { |v| v.is_a?(Float) }
|
366
|
+
CA_FLOAT64
|
367
|
+
elsif values.all? { |v| v.is_a?(Complex) }
|
368
|
+
CA_CMPLX128
|
369
|
+
else
|
370
|
+
CA_OBJECT
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
private :guess_data_type_from_values
|
375
|
+
|
376
|
+
def zeros (*shape)
|
377
|
+
CArray.new(self::DataType || CA_FLOAT64, shape).zero
|
378
|
+
end
|
379
|
+
|
380
|
+
def ones (*shape)
|
381
|
+
CArray.new(self::DataType || CA_FLOAT64 , shape).one
|
382
|
+
end
|
383
|
+
|
384
|
+
def eye (n, m = nil, k = 0)
|
385
|
+
m ||= n
|
386
|
+
mat = CArray.new(self::DataType || CA_FLOAT64, [n, m])
|
387
|
+
start = k > 0 ? k : m - k - 1
|
388
|
+
mat[[start..-1,m+1]] = 1
|
389
|
+
mat
|
390
|
+
end
|
391
|
+
|
392
|
+
def identity (n)
|
393
|
+
mat = CArray.new(self::DataType || CA_FLOAT64, [n, n])
|
394
|
+
mat[[nil,n+1]] = 1
|
395
|
+
mat
|
396
|
+
end
|
397
|
+
|
398
|
+
def linspace (x1, x2, n = 100)
|
399
|
+
data_type = self::DataType
|
400
|
+
data_type ||= guess_data_type_from_values(x1, x2)
|
401
|
+
CArray.new(data_type, [n]).span(x1..x2)
|
402
|
+
end
|
403
|
+
|
404
|
+
def arange (*args)
|
405
|
+
case args.size
|
406
|
+
when 3
|
407
|
+
start, stop, step = *args
|
408
|
+
when 2
|
409
|
+
start, stop = *args
|
410
|
+
step = 1
|
411
|
+
when 1
|
412
|
+
start = 0
|
413
|
+
stop, = *args
|
414
|
+
step = 1
|
415
|
+
end
|
416
|
+
data_type = self::DataType
|
417
|
+
data_type ||= guess_data_type_from_values(start, stop, step)
|
418
|
+
CArray.__new__(data_type, start..stop, step)
|
419
|
+
end
|
420
|
+
|
421
|
+
def full (shape, fill_value)
|
422
|
+
data_type = self::DataType
|
423
|
+
data_type ||= guess_data_type_from_values(fill_value)
|
424
|
+
shape = [shape] unless shape.is_a?(Array)
|
425
|
+
CArray.new(data_type, shape).fill(fill_value)
|
426
|
+
end
|
427
|
+
|
428
|
+
end
|
429
|
+
|
430
|
+
end
|
431
|
+
|
432
|
+
class CArray
|
433
|
+
|
434
|
+
def self.meshgrid (*args)
|
435
|
+
dim = args.map(&:size)
|
436
|
+
out = []
|
437
|
+
args.each_with_index do |arg, i|
|
438
|
+
newdim = dim.dup
|
439
|
+
newdim[i] = :%
|
440
|
+
out[i] = arg[*newdim].to_ca
|
441
|
+
end
|
442
|
+
return *out
|
443
|
+
end
|
444
|
+
|
445
|
+
end
|