narray_miss 1.2.1.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +4 -0
- data/LICENSE.txt +34 -0
- data/README.rdoc +40 -0
- data/Rakefile +5 -0
- data/lib/narray_miss.rb +2 -1423
- data/lib/narray_miss/narray_miss.rb +1510 -0
- data/lib/narray_miss/version.rb +3 -0
- data/narray_miss.gemspec +25 -0
- data/test/test_narray_miss.rb +147 -0
- metadata +27 -28
- data/ChangeLog +0 -408
- data/README +0 -46
- data/doc/narray_miss.html +0 -469
- data/setup.rb +0 -1360
@@ -0,0 +1,1510 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
=begin
|
3
|
+
= NArrayMiss Class
|
4
|
+
|
5
|
+
NArrayMiss is a additional class processing of missing value with to
|
6
|
+
((<NArray|URL:http://www.ruby-lang.org/en/raa-list.rhtml?name=NArray>))
|
7
|
+
for Ruby.
|
8
|
+
|
9
|
+
To use NArrayMiss class, you need invoking "require 'narray_miss.rb'" in your script.
|
10
|
+
|
11
|
+
== Index
|
12
|
+
|
13
|
+
* ((<Class Constants>))
|
14
|
+
* ((<Class Methods>))
|
15
|
+
* ((<Class Instance Methods>))
|
16
|
+
* ((<NArrayMiss information>))
|
17
|
+
* ((<Slicing Array>))
|
18
|
+
* ((<Filling values>))
|
19
|
+
* ((<Arithmetic operator>))
|
20
|
+
* ((<Bitwise operator|Bitwise operator (only for byte, sint and int)>))
|
21
|
+
* ((<Comparison>))
|
22
|
+
* ((<Statistics>))
|
23
|
+
* ((<Sort>))
|
24
|
+
* ((<Transpose>))
|
25
|
+
* ((<Changing Shapes of indices>))
|
26
|
+
* ((<Type conversion>))
|
27
|
+
* ((<Iteration>))
|
28
|
+
* ((<Boolean and mask related|Boolean and mask related (only for byte, sint and int)>))
|
29
|
+
* ((<Complex compound number|Complex compound number (only for scomplex and complex)>))
|
30
|
+
* ((<Byte swap>))
|
31
|
+
* ((<Mask and missing value>))
|
32
|
+
* ((<Others>))
|
33
|
+
|
34
|
+
|
35
|
+
=end
|
36
|
+
|
37
|
+
require 'narray'
|
38
|
+
|
39
|
+
|
40
|
+
class NArrayMiss
|
41
|
+
|
42
|
+
=begin
|
43
|
+
== Class Constants
|
44
|
+
--- NArrayMiss::BYTE
|
45
|
+
type code for 1 byte unsigned integer.
|
46
|
+
--- NArrayMiss::SINT
|
47
|
+
type code for 2 byte signed integer.
|
48
|
+
--- NArrayMiss::INT
|
49
|
+
type code for 4 byte signed integer.
|
50
|
+
--- NArrayMiss::SFLOAT
|
51
|
+
type code for single precision float.
|
52
|
+
--- NArrayMiss::FLOAT
|
53
|
+
type code for double precision float.
|
54
|
+
--- NArrayMiss::SCOMPLEX
|
55
|
+
type code for single precision complex.
|
56
|
+
--- NArrayMiss::COMPLEX
|
57
|
+
type code for double precision complex.
|
58
|
+
--- NArrayMiss::OBJECT
|
59
|
+
type code for Ruby object.
|
60
|
+
|
61
|
+
go back to ((<Index>))
|
62
|
+
=end
|
63
|
+
|
64
|
+
BYTE = NArray::BYTE
|
65
|
+
SINT = NArray::SINT
|
66
|
+
INT = NArray::INT
|
67
|
+
SFLOAT = NArray::SFLOAT
|
68
|
+
FLOAT = NArray::FLOAT
|
69
|
+
SCOMPLEX = NArray::SCOMPLEX
|
70
|
+
COMPLEX = NArray::COMPLEX
|
71
|
+
OBJECT = NArray::OBJECT
|
72
|
+
|
73
|
+
class << self
|
74
|
+
alias :__new__ :new
|
75
|
+
private :__new__
|
76
|
+
end
|
77
|
+
|
78
|
+
def initialize(array, mask)
|
79
|
+
if array.shape!=mask.shape
|
80
|
+
raise "array and mask must have the same shape"
|
81
|
+
end
|
82
|
+
@array = array
|
83
|
+
@mask = mask
|
84
|
+
end
|
85
|
+
private :initialize
|
86
|
+
|
87
|
+
=begin
|
88
|
+
== Class Methods
|
89
|
+
--- NArrayMiss.new(typecode, size, ...)
|
90
|
+
create (({NArrayMiss})) of ((|typecode|)).
|
91
|
+
All elements are initialized with 0.
|
92
|
+
--- NArrayMiss.byte(size, ...)
|
93
|
+
same as NArrayMiss.new(NArrayMiss::BYTE, ((|size|)), ...).
|
94
|
+
--- NArrayMiss.sint(size, ...)
|
95
|
+
same as NArrayMiss.new(NArrayMiss::SINT, ((|size|)), ...).
|
96
|
+
--- NArrayMiss.int(size, ...)
|
97
|
+
same as NArrayMiss.new(NArrayMiss::INT, ((|size|)), ...).
|
98
|
+
--- NArrayMiss.sfloat(size, ...)
|
99
|
+
same as NArrayMiss.new(NArrayMiss::SFLOAT, ((|size|)), ...).
|
100
|
+
--- NArrayMiss.float(size, ...)
|
101
|
+
same as NArrayMiss.new(NArrayMiss::FLOAT, ((|size|)), ...).
|
102
|
+
--- NArrayMiss.scomplex(size, ...)
|
103
|
+
same as NArrayMiss.new(NArrayMiss::SCOMPLEX, ((|size|)), ...).
|
104
|
+
--- NArrayMiss.complex(size, ...)
|
105
|
+
same as NArrayMiss.new(NArrayMiss::COMPLEX, ((|size|)), ...).
|
106
|
+
--- NArrayMiss.object(size, ...)
|
107
|
+
same as NArrayMiss.new(NArrayMiss::OBJECT, ((|size|)), ...).
|
108
|
+
--- NArrayMiss[](value, ...)
|
109
|
+
create (({NArrayMiss})) form [((|value|)), ...].
|
110
|
+
--- NArrayMiss.to_nam(array [,mask])
|
111
|
+
create (({NArrayMiss})) from ((|array|)).
|
112
|
+
((|array|)) must be (({Numeric})) (({Array})) or (({NArray})).
|
113
|
+
--- NArrayMiss.to_nam_no_dup(array [,mask])
|
114
|
+
convert from ((|array|)) to (({NArrayMiss})).
|
115
|
+
|
116
|
+
go back to ((<Index>))
|
117
|
+
=end
|
118
|
+
|
119
|
+
def self.new(*arg)
|
120
|
+
array = NArray.new(*arg)
|
121
|
+
mask = NArray.byte(*arg[1..-1])
|
122
|
+
__new__(array, mask)
|
123
|
+
end
|
124
|
+
def self.byte(*arg)
|
125
|
+
NArrayMiss.new(BYTE,*arg)
|
126
|
+
end
|
127
|
+
def self.sint(*arg)
|
128
|
+
NArrayMiss.new(SINT,*arg)
|
129
|
+
end
|
130
|
+
def self.int(*arg)
|
131
|
+
NArrayMiss.new(INT,*arg)
|
132
|
+
end
|
133
|
+
def self.sfloat(*arg)
|
134
|
+
NArrayMiss.new(SFLOAT,*arg)
|
135
|
+
end
|
136
|
+
def self.float(*arg)
|
137
|
+
NArrayMiss.new(FLOAT,*arg)
|
138
|
+
end
|
139
|
+
def self.scomplex(*arg)
|
140
|
+
NArrayMiss.new(SCOMPLEX,*arg)
|
141
|
+
end
|
142
|
+
def self.complex(*arg)
|
143
|
+
NArrayMiss.new(COMPLEX,*arg)
|
144
|
+
end
|
145
|
+
def self.object(*arg)
|
146
|
+
NArrayMiss.new(OBJECT,*arg)
|
147
|
+
end
|
148
|
+
def self.[](*arg)
|
149
|
+
NArrayMiss.to_nam(NArray[*arg])
|
150
|
+
end
|
151
|
+
def self.to_nam_no_dup(*arg)
|
152
|
+
if arg.length > 2 || arg.length==0 then
|
153
|
+
raise("NArrayMiss.to_nar( array [,mask]] )")
|
154
|
+
end
|
155
|
+
|
156
|
+
array = arg[0]
|
157
|
+
if Numeric===array then array = NArray[array] end
|
158
|
+
if Array===array then array = NArray.to_na(array) end
|
159
|
+
if !array.is_a?(NArray) then
|
160
|
+
raise("argument must be Numeric, NArray or Array")
|
161
|
+
end
|
162
|
+
|
163
|
+
if arg.length==2 then
|
164
|
+
mask = arg[1]
|
165
|
+
if Numeric===mask then mask = array.ne(mask) end
|
166
|
+
if Array===mask then
|
167
|
+
mask = NArray.to_na(mask).ne(0)
|
168
|
+
end
|
169
|
+
if mask.class == FalseClass then
|
170
|
+
mask = NArray.byte(*array.shape)
|
171
|
+
end
|
172
|
+
if mask.class == TrueClass then
|
173
|
+
mask = NArray.byte(*array.shape).fill(1)
|
174
|
+
end
|
175
|
+
if !(NArray===mask && mask.typecode==BYTE) then
|
176
|
+
raise("mask must be Numeric, Array, true, false or NArray(byte)")
|
177
|
+
end
|
178
|
+
if mask.length!=array.length
|
179
|
+
raise "mask.length must be same as array.length"
|
180
|
+
end
|
181
|
+
else
|
182
|
+
mask = NArray.byte(*array.shape).fill(1)
|
183
|
+
end
|
184
|
+
__new__(array,mask)
|
185
|
+
end
|
186
|
+
def self.to_nam(*arg)
|
187
|
+
if !(Numeric===arg[0]) && !(Array===arg[0]) && !arg[0].is_a?(NArray)
|
188
|
+
raise "first argument must be Numeric, NArray or Array"
|
189
|
+
end
|
190
|
+
arg[0] = arg[0].dup if !(Numeric===arg[0])
|
191
|
+
if arg.length==2 && !(Numeric===arg[1]) && arg[1].class!=TrueClass && arg[1].class!=FalseClass then
|
192
|
+
arg[1] = arg[1].dup
|
193
|
+
end
|
194
|
+
NArrayMiss.to_nam_no_dup(*arg)
|
195
|
+
end
|
196
|
+
|
197
|
+
|
198
|
+
=begin
|
199
|
+
== Class Instance Methods
|
200
|
+
=end
|
201
|
+
|
202
|
+
|
203
|
+
=begin
|
204
|
+
=== NArrayMiss information
|
205
|
+
--- NArrayMiss#dim
|
206
|
+
return the dimension which is the number of indices.
|
207
|
+
--- NArrayMiss#rank
|
208
|
+
same as (({NArrayMiss#dim})).
|
209
|
+
--- NArrayMiss#shape
|
210
|
+
return the (({Array})) of sizes of each index.
|
211
|
+
--- NArrayMiss#size
|
212
|
+
return the number of total elements.
|
213
|
+
--- NArrayMiss#total
|
214
|
+
alias to size
|
215
|
+
--- NArrayMiss#length
|
216
|
+
alias to size
|
217
|
+
--- NArrayMiss#rank_total
|
218
|
+
return the number of total of the shape.
|
219
|
+
--- NArrayMiss#typecode
|
220
|
+
return the typecode.
|
221
|
+
=end
|
222
|
+
|
223
|
+
def dim
|
224
|
+
@array.dim
|
225
|
+
end
|
226
|
+
def rank
|
227
|
+
@array.rank
|
228
|
+
end
|
229
|
+
def shape
|
230
|
+
@array.shape
|
231
|
+
end
|
232
|
+
def size
|
233
|
+
@array.size
|
234
|
+
end
|
235
|
+
alias :total :size
|
236
|
+
alias :length :size
|
237
|
+
|
238
|
+
def rank_total(*arg)
|
239
|
+
@array.rank_total(*arg)
|
240
|
+
end
|
241
|
+
|
242
|
+
def typecode
|
243
|
+
@array.typecode
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
=begin
|
248
|
+
=== Slicing Array
|
249
|
+
--- NArrayMiss#[](index)
|
250
|
+
return the value at [((|index|))].
|
251
|
+
((|index|)) must be (({Integer, Range, Array, true})).
|
252
|
+
Index order is FORTRAN type.
|
253
|
+
--- NArrayMiss#slice(index)
|
254
|
+
same as (({NArrayMiss#[]})) but keeps the rank of original array by not elimiting dimensions whose length became equal to 1 (which (({NArrayMiss#[]})) dose).
|
255
|
+
This is not the case with the 1-dimensional indexing and masking.
|
256
|
+
--- NArrayMiss#set_without_validation(index,value)
|
257
|
+
replace elements at ((|index|)) by ((|value|)).
|
258
|
+
--- NArrayMiss#[]=(index, value)
|
259
|
+
replace elements at ((|index|)) by ((|value|)) and
|
260
|
+
make replaced elements valid.
|
261
|
+
=end
|
262
|
+
|
263
|
+
def [](*arg)
|
264
|
+
if arg[0].class == NArrayMiss && arg[0].typecode == BYTE
|
265
|
+
obj = @array[arg[0].to_na(0)]
|
266
|
+
if Numeric===obj
|
267
|
+
return obj
|
268
|
+
else
|
269
|
+
return NArrayMiss.to_nam_no_dup(obj)
|
270
|
+
end
|
271
|
+
else
|
272
|
+
obj = @array[*arg]
|
273
|
+
if Numeric===obj
|
274
|
+
return obj
|
275
|
+
else
|
276
|
+
return NArrayMiss.to_nam_no_dup(obj,@mask[*arg])
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
def slice(*arg)
|
281
|
+
NArrayMiss.to_nam_no_dup(@array.slice(*arg),@mask.slice(*arg))
|
282
|
+
end
|
283
|
+
|
284
|
+
def set_without_validation(*arg)
|
285
|
+
if arg.length==1 then
|
286
|
+
if !arg[0] then
|
287
|
+
@mask[] = 0
|
288
|
+
elsif arg[0].class == NArrayMiss then
|
289
|
+
@array[] = arg[0].get_array!
|
290
|
+
@mask[] = arg[0].get_mask!
|
291
|
+
else
|
292
|
+
@array[] = arg[0]
|
293
|
+
end
|
294
|
+
else
|
295
|
+
if !arg[-1] then
|
296
|
+
@mask[*arg[0..-2]] = 0
|
297
|
+
elsif arg[-1].class == NArrayMiss then
|
298
|
+
@array[*arg[0..-2]] = arg[-1].get_array!
|
299
|
+
@mask[*arg[0..-2]] = arg[-1].get_mask!
|
300
|
+
else
|
301
|
+
@array[*arg[0..-2]] = arg[-1]
|
302
|
+
end
|
303
|
+
end
|
304
|
+
return self
|
305
|
+
end
|
306
|
+
|
307
|
+
def []=(*arg)
|
308
|
+
if arg.length == 2 && arg[0].class == NArrayMiss && arg[0].typecode == BYTE
|
309
|
+
idx = arg[0].to_na(0)
|
310
|
+
self.set_without_validation(idx,arg[-1])
|
311
|
+
if arg[-1].class != NArrayMiss && arg[-1] then
|
312
|
+
@mask[idx] = 1
|
313
|
+
end
|
314
|
+
else
|
315
|
+
self.set_without_validation(*arg)
|
316
|
+
if arg[-1].class != NArrayMiss && arg[-1] then
|
317
|
+
if arg.length==1 then
|
318
|
+
@mask=1
|
319
|
+
else
|
320
|
+
@mask[*arg[0..-2]] = 1
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
return self
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
=begin
|
329
|
+
=== Filling values
|
330
|
+
--- NArrayMiss#indgen!([start[,step]])
|
331
|
+
set values from ((|start|)) with ((|step|)) increment.
|
332
|
+
--- NArrayMiss#indgen([start[,step]])
|
333
|
+
same as (({NArrayMiss#indgen!})) but create new object.
|
334
|
+
--- NArrayMiss#fill!(value)
|
335
|
+
fill elements with ((|value|)).
|
336
|
+
--- NArrayMiss#fill(value)
|
337
|
+
same as (({NArrayMiss#fill!})) but create new object.
|
338
|
+
--- NArrayMiss#random!(max)
|
339
|
+
set random values between 0<=x<((|max|)).
|
340
|
+
--- NArrayMiss#random(max)
|
341
|
+
same as (({NArrayMiss#random!})) but create new object.
|
342
|
+
--- NArrayMiss#randomn(max)
|
343
|
+
set normally distributed random values with mean=0, dispersion=1 (Box-Muller)
|
344
|
+
=end
|
345
|
+
|
346
|
+
for operator in ["indgen","fill","random","randomn"]
|
347
|
+
eval(<<-EOL,nil,__FILE__,__LINE__+1)
|
348
|
+
def #{operator}(*arg)
|
349
|
+
obj = self.dup
|
350
|
+
obj.#{operator}!(*arg)
|
351
|
+
obj
|
352
|
+
end
|
353
|
+
def #{operator}!(*arg)
|
354
|
+
@array = @array.#{operator}!(*arg)
|
355
|
+
@mask[true] = 1
|
356
|
+
self
|
357
|
+
end
|
358
|
+
EOL
|
359
|
+
end
|
360
|
+
|
361
|
+
|
362
|
+
=begin
|
363
|
+
=== Arithmetic operator
|
364
|
+
--- NArrayMiss#-@
|
365
|
+
--- NArrayMiss#+(other)
|
366
|
+
--- NArrayMiss#-(other)
|
367
|
+
--- NArrayMiss#*(other)
|
368
|
+
--- NArrayMiss#/(other)
|
369
|
+
--- NArrayMiss#%(other)
|
370
|
+
--- NArrayMiss#**(other)
|
371
|
+
--- NArrayMiss#abs
|
372
|
+
--- NArrayMiss#add!(other)
|
373
|
+
--- NArrayMiss#sbt!(other)
|
374
|
+
--- NArrayMiss#mul!(other)
|
375
|
+
--- NArrayMiss#div!(other)
|
376
|
+
--- NArrayMiss#mod!(other)
|
377
|
+
--- NArrayMiss#mul_add(other, dim, ...)
|
378
|
+
=end
|
379
|
+
|
380
|
+
def -@
|
381
|
+
array = @array.dup
|
382
|
+
array[@mask] = -@array[@mask]
|
383
|
+
NArrayMiss.to_nam_no_dup(array, @mask.dup)
|
384
|
+
end
|
385
|
+
def +(arg)
|
386
|
+
binary_operation(arg, 0){|t1, t2| t1 + t2}
|
387
|
+
end
|
388
|
+
def -(arg)
|
389
|
+
binary_operation(arg, 0){|t1, t2| t1 - t2}
|
390
|
+
end
|
391
|
+
def *(arg)
|
392
|
+
binary_operation(arg, 1){|t1, t2| t1 * t2}
|
393
|
+
end
|
394
|
+
def /(arg)
|
395
|
+
binary_operation(arg, 1){|t1, t2| t1 / t2}
|
396
|
+
end
|
397
|
+
def %(arg)
|
398
|
+
binary_operation(arg, 1){|t1, t2| t1 % t2}
|
399
|
+
end
|
400
|
+
def **(arg)
|
401
|
+
binary_operation(arg, 1){|t1, t2| t1 ** t2}
|
402
|
+
end
|
403
|
+
|
404
|
+
def abs
|
405
|
+
array = @array.dup
|
406
|
+
array[@mask] = @array[@mask].abs
|
407
|
+
NArrayMiss.to_nam_no_dup(array, @mask.dup)
|
408
|
+
end
|
409
|
+
|
410
|
+
def add!(arg)
|
411
|
+
binary_operation(arg, 0){|t1, t2| t1.add!(t2)}
|
412
|
+
end
|
413
|
+
def sbt!(arg)
|
414
|
+
binary_operation(arg, 0){|t1, t2| t1.sbt!(t2)}
|
415
|
+
end
|
416
|
+
def mul!(arg)
|
417
|
+
binary_operation(arg, 1){|t1, t2| t1.mul!(t2)}
|
418
|
+
end
|
419
|
+
def div!(arg)
|
420
|
+
binary_operation(arg, 1){|t1, t2| t1.div!(t2)}
|
421
|
+
end
|
422
|
+
def mod!(arg)
|
423
|
+
binary_operation(arg, 1){|t1, t2| t1.mod!(t2)}
|
424
|
+
end
|
425
|
+
|
426
|
+
def mul_add(*arg)
|
427
|
+
if arg.length==1 then
|
428
|
+
return (self*arg[0]).sum
|
429
|
+
else
|
430
|
+
return (self*arg[0]).sum(*arg[1..-1])
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
|
435
|
+
=begin
|
436
|
+
=== Bitwise operator (only for byte, sint and int)
|
437
|
+
--- NArrayMiss#~@
|
438
|
+
--- NArrayMiss#&(other)
|
439
|
+
--- NArrayMiss#|(other)
|
440
|
+
--- NArrayMiss#^(other)
|
441
|
+
=end
|
442
|
+
|
443
|
+
def ~@
|
444
|
+
NArrayMiss.to_nam_to_dup(~@array, @mask.dup)
|
445
|
+
end
|
446
|
+
def &(arg)
|
447
|
+
binary_operation(arg, 1){|t1, t2| t1 & t2}
|
448
|
+
end
|
449
|
+
def |(arg)
|
450
|
+
binary_operation(arg, 0){|t1, t2| t1 | t2}
|
451
|
+
end
|
452
|
+
def ^(arg)
|
453
|
+
binary_operation(arg, 1){|t1, t2| t1 ^ t2}
|
454
|
+
end
|
455
|
+
|
456
|
+
|
457
|
+
=begin
|
458
|
+
=== Comparison
|
459
|
+
--- NArrayMiss#eq(other)
|
460
|
+
--- NArrayMiss#ne(other)
|
461
|
+
--- NArrayMiss#gt(other)
|
462
|
+
--- NArrayMiss#ge(other)
|
463
|
+
--- NArrayMiss#lt(other)
|
464
|
+
--- NArrayMiss#le(other)
|
465
|
+
--- NArrayMiss#>(other)
|
466
|
+
--- NArrayMiss#>=(other)
|
467
|
+
--- NArrayMiss#<(other)
|
468
|
+
--- NArrayMiss#<=(other)
|
469
|
+
--- NArrayMiss#and(other)
|
470
|
+
--- NArrayMiss#or(other)
|
471
|
+
--- NArrayMiss#xor(other)
|
472
|
+
--- NArrayMiss#not(other)
|
473
|
+
=end
|
474
|
+
|
475
|
+
def eq(arg)
|
476
|
+
binary_operation(arg, 0){|t1, t2| t1.eq t2}
|
477
|
+
end
|
478
|
+
def ne(arg)
|
479
|
+
binary_operation(arg, 0){|t1, t2| t1.ne t2}
|
480
|
+
end
|
481
|
+
def gt(arg)
|
482
|
+
binary_operation(arg, 0){|t1, t2| t1.gt t2}
|
483
|
+
end
|
484
|
+
def ge(arg)
|
485
|
+
binary_operation(arg, 0){|t1, t2| t1.ge t2}
|
486
|
+
end
|
487
|
+
def lt(arg)
|
488
|
+
binary_operation(arg, 0){|t1, t2| t1.lt t2}
|
489
|
+
end
|
490
|
+
def le(arg)
|
491
|
+
binary_operation(arg, 0){|t1, t2| t1.le t2}
|
492
|
+
end
|
493
|
+
|
494
|
+
def and(arg)
|
495
|
+
binary_operation(arg, 1){|t1, t2| t1.and t2}
|
496
|
+
end
|
497
|
+
def or(arg)
|
498
|
+
binary_operation(arg, 0){|t1, t2| t1.or t2}
|
499
|
+
end
|
500
|
+
def xor(arg)
|
501
|
+
binary_operation(arg, 1){|t1, t2| t1.xor t2}
|
502
|
+
end
|
503
|
+
|
504
|
+
def not
|
505
|
+
NArrayMiss.to_nam_no_dup(@array.not, @mask.dup)
|
506
|
+
end
|
507
|
+
|
508
|
+
def ==(arg)
|
509
|
+
if arg.kind_of?(NArrayMiss) then
|
510
|
+
@mask==arg.get_mask! && @array[@mask]==arg.get_array![@mask]
|
511
|
+
else
|
512
|
+
false
|
513
|
+
end
|
514
|
+
end
|
515
|
+
|
516
|
+
|
517
|
+
=begin
|
518
|
+
=== Statistics
|
519
|
+
--- NArrayMiss#sum(dim, ... ["min_count"=>i])
|
520
|
+
return summation of elements in specified dimensions.
|
521
|
+
Elements at which the number of elements for summation is less than ((|i|)) is invalid.
|
522
|
+
--- NArrayMiss#accum(dim, ...)
|
523
|
+
same as (({NArrayMiss#sum})) but not elimiting dimensions whose length became equal to 1.
|
524
|
+
--- NArrayMiss#min(dim, ...)
|
525
|
+
return minimum in specified dimensions.
|
526
|
+
Elements at which the number of valid elements in the dimension is less than ((|i|)) is invalid.
|
527
|
+
--- NArrayMiss#max(dim, ...)
|
528
|
+
return maximum in specified dimensions.
|
529
|
+
Elements at which the number of valid elements in the dimension is less than ((|i|)) is invalid.
|
530
|
+
--- NArrayMiss#median(dim, ...)
|
531
|
+
return median in specified dimensions.
|
532
|
+
Elements at which the number of valid elements in the dimension is less than ((|i|)) is invalid.
|
533
|
+
--- NArrayMiss#mean(dim, ...)
|
534
|
+
return mean of elements in specified dimensions.
|
535
|
+
Elements at which the number of elements for then mean is less than ((|i|)) is invalid.
|
536
|
+
--- NArrayMiss#stddev(dim, ...)
|
537
|
+
return standard deviation of elements in specified dimensions.
|
538
|
+
Elements at which the number of elements for calculation the standard deviation is less than ((|i|)) is invalid.
|
539
|
+
--- NArrayMiss#rms(dim, ...)
|
540
|
+
return root mean square of elements in specified dimensions.
|
541
|
+
Elements at which the number of elements for calculation the RMS is less than ((|i|)) is invalid.
|
542
|
+
--- NArrayMiss#rmsdev(dim, ...)
|
543
|
+
return root mean square deviation of elements in specified dimensions.
|
544
|
+
Elements at which the number of elements for calculation the RMS deviation is less than ((|i|)) is invalid.
|
545
|
+
=end
|
546
|
+
|
547
|
+
def accum(*arg)
|
548
|
+
if @mask.count_true == 0 then
|
549
|
+
return nil
|
550
|
+
else
|
551
|
+
array = @array.dup
|
552
|
+
array[@mask.not] = 0
|
553
|
+
return NArrayMiss.to_nam_no_dup(array.accum(*arg),
|
554
|
+
@mask.to_type(NArray::INT).accum(*arg).ne(0))
|
555
|
+
end
|
556
|
+
end
|
557
|
+
|
558
|
+
def sum(*dims)
|
559
|
+
min_count = NArrayMiss.check_options(dims, 1)
|
560
|
+
# 欠損値に 0 を入れて普通に sum する
|
561
|
+
ary0 = @array.dup
|
562
|
+
ary0[@mask.not] = 0
|
563
|
+
NArrayMiss.reduction(@mask, min_count, dims, false, typecode) do
|
564
|
+
ary0.sum(*dims)
|
565
|
+
end
|
566
|
+
end
|
567
|
+
def min(*dims)
|
568
|
+
min_count = NArrayMiss.check_options(dims, 1)
|
569
|
+
# 欠損値に最大値を入れて普通に min する
|
570
|
+
# byte,sint,int,sfloat,float の MAX の値を入れるように変更すべき
|
571
|
+
ary0 = @array.dup
|
572
|
+
ary0[@mask.not] = @array.max
|
573
|
+
NArrayMiss.reduction(@mask, min_count, dims, false, typecode) do
|
574
|
+
ary0.min(*dims)
|
575
|
+
end
|
576
|
+
end
|
577
|
+
def max(*dims)
|
578
|
+
min_count = NArrayMiss.check_options(dims, 1)
|
579
|
+
# 欠損値に最小値を入れて普通に max する
|
580
|
+
# byte,sint,int,sfloat,float の MIN の値を入れるように変更すべき
|
581
|
+
ary0 = @array.dup
|
582
|
+
ary0[@mask.not] = @array.min
|
583
|
+
NArrayMiss.reduction(@mask, min_count, dims, false, typecode) do
|
584
|
+
ary0.max(*dims)
|
585
|
+
end
|
586
|
+
end
|
587
|
+
|
588
|
+
def mean(*dims)
|
589
|
+
min_count = NArrayMiss.check_options(dims, 1)
|
590
|
+
# 整数型の場合は浮動小数型へ変換
|
591
|
+
ary0 = self.integer? ? self.to_type(NArray::DFLOAT) : self
|
592
|
+
NArrayMiss.reduction(@mask, min_count, dims, true, typecode) do |count_sum, count_accum|
|
593
|
+
var = ary0.sum(*dims)/count_sum
|
594
|
+
end
|
595
|
+
end
|
596
|
+
def stddev(*dims)
|
597
|
+
min_count = NArrayMiss.check_options(dims, 2)
|
598
|
+
# 整数型の場合は浮動小数型へ変換
|
599
|
+
ary0 = self.integer? ? self.to_type(NArray::DFLOAT) : self
|
600
|
+
NArrayMiss.reduction(@mask, min_count, dims, true, typecode) do |count_sum, count_accum|
|
601
|
+
ary0 = ary0 - ary0.accum(*dims)/count_accum
|
602
|
+
ary0 = ary0.abs if ary0.complex?
|
603
|
+
ary0 = (ary0**2).sum(*dims) / (count_sum-1)
|
604
|
+
NMMath.sqrt(ary0)
|
605
|
+
end
|
606
|
+
end
|
607
|
+
def rms(*dims)
|
608
|
+
min_count = NArrayMiss.check_options(dims, 1)
|
609
|
+
# 整数型の場合は浮動小数型へ変換
|
610
|
+
ary0 = self.integer? ? self.to_type(NArray::DFLOAT) : self
|
611
|
+
NArrayMiss.reduction(@mask, min_count, dims, true, typecode) do |count_sum, count_accum|
|
612
|
+
ary0 = ary0.abs if ary0.complex?
|
613
|
+
ary0 = (ary0**2).sum(*dims) / count_sum
|
614
|
+
NMMath.sqrt(ary0)
|
615
|
+
end
|
616
|
+
end
|
617
|
+
def rmsdev(*dims)
|
618
|
+
min_count = NArrayMiss.check_options(dims, 1)
|
619
|
+
# 整数型の場合は浮動小数型へ変換
|
620
|
+
ary0 = self.integer? ? self.to_type(NArray::DFLOAT) : self
|
621
|
+
NArrayMiss.reduction(@mask, min_count, dims, true, typecode) do |count_sum, count_accum|
|
622
|
+
ary0 = ary0 - ary0.accum(*dims)/count_accum
|
623
|
+
ary0 = ary0.abs if ary0.complex?
|
624
|
+
ary0 = (ary0**2).sum(*dims) / count_sum
|
625
|
+
NMMath.sqrt(ary0)
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
def median(*arg)
|
630
|
+
if arg.length==0 then
|
631
|
+
return @array[@mask].median
|
632
|
+
else
|
633
|
+
nshape = NArray.to_na(@array.shape)
|
634
|
+
nshape[arg]=1
|
635
|
+
nslice = nshape[nshape.ne(1).where]
|
636
|
+
index = NArray.object(@mask.rank)
|
637
|
+
index[nshape.eq(1).where] = true
|
638
|
+
obj = NArrayMiss.new(@array.typecode,*nslice.to_a)
|
639
|
+
total = 1
|
640
|
+
nslice.each{|n| total *= n}
|
641
|
+
for i in 0...total
|
642
|
+
index[nshape.ne(1).where] = pos(i,nslice)
|
643
|
+
mask = NArray.byte(*@array.shape).fill(0)
|
644
|
+
mask[*index] = 1
|
645
|
+
mask = @mask&mask
|
646
|
+
if mask.count_true != 0 then
|
647
|
+
obj[*pos(i,nslice)] = @array[mask].median
|
648
|
+
end
|
649
|
+
end
|
650
|
+
return obj
|
651
|
+
end
|
652
|
+
end
|
653
|
+
|
654
|
+
|
655
|
+
=begin
|
656
|
+
=== Sort
|
657
|
+
--- NArrayMiss#sort(dim)
|
658
|
+
sort in the 0..((|dim|)) (All dimensions if omitted)
|
659
|
+
--- NArrayMiss#sort_index(dim)
|
660
|
+
return index of sort result.
|
661
|
+
=end
|
662
|
+
|
663
|
+
for operator in ["sort","sort_index"]
|
664
|
+
eval(<<-EOL,nil,__FILE__,__LINE__+1)
|
665
|
+
def #{operator}(*arg)
|
666
|
+
obj=NArrayMiss.new(@array.typecode,*@array.shape)
|
667
|
+
if arg.length==0 then
|
668
|
+
obj[@mask] = @array[@mask].#{operator}
|
669
|
+
return obj
|
670
|
+
else
|
671
|
+
nshape = NArray.to_na(@array.shape)
|
672
|
+
nshape[arg]=1
|
673
|
+
nslice = nshape[nshape.ne(1).where]
|
674
|
+
index = NArray.object(@mask.rank)
|
675
|
+
index[nshape.eq(1).where] = true
|
676
|
+
obj = NArrayMiss.new(@array.typecode,*@array.shape)
|
677
|
+
total = 1
|
678
|
+
nslice.each{|n| total *= n}
|
679
|
+
for i in 0...total
|
680
|
+
index[nshape.ne(1).where] = pos(i,nslice)
|
681
|
+
mask = NArray.byte(*@array.shape).fill(0)
|
682
|
+
mask[*index] = 1
|
683
|
+
mask = @mask&mask
|
684
|
+
if mask.count_true != 0 then
|
685
|
+
obj[mask] = @array[mask].#{operator}
|
686
|
+
end
|
687
|
+
end
|
688
|
+
return obj
|
689
|
+
end
|
690
|
+
end
|
691
|
+
EOL
|
692
|
+
end
|
693
|
+
|
694
|
+
|
695
|
+
=begin
|
696
|
+
=== Transpose
|
697
|
+
--- NArrayMiss#transpose(dim0, dim1, ...)
|
698
|
+
transpose array. The 0-th dimension goes to the ((|dim0|))-th dimension of new array.
|
699
|
+
=end
|
700
|
+
|
701
|
+
def transpose(*arg)
|
702
|
+
obj = self.dup
|
703
|
+
shape = arg.collect{|i| obj.shape[i]}
|
704
|
+
obj.reshape!(*shape)
|
705
|
+
obj.set_without_validation( @array.transpose(*arg) )
|
706
|
+
obj.set_mask(@mask.transpose(*arg))
|
707
|
+
obj
|
708
|
+
end
|
709
|
+
|
710
|
+
|
711
|
+
=begin
|
712
|
+
=== Changing Shapes of indices
|
713
|
+
--- NArrayMiss#reshape!(size, ...)
|
714
|
+
change shape of array.
|
715
|
+
--- NArrayMiss#reshape(size, ...)
|
716
|
+
same as (({NArrayMiss#reshape!})) but create new object.
|
717
|
+
--- NArrayMiss#shape=(size, ...)
|
718
|
+
same as (({NArrayMiss#reshape!})).
|
719
|
+
--- NArrayMiss#newdim!(dim)
|
720
|
+
insert new dimension with size=1
|
721
|
+
--- NArrayMiss#newdim(dim)
|
722
|
+
same as (({NArrayMiss#newdim!})) but create new object.
|
723
|
+
--- NArrayMiss#rewrank!(dim)
|
724
|
+
same as (({NArrayMiss#newdim!})).
|
725
|
+
--- NArrayMiss#rewrank=(dim)
|
726
|
+
same as (({NArrayMiss#newdim!})).
|
727
|
+
=end
|
728
|
+
|
729
|
+
def reshape!(*arg)
|
730
|
+
@array = @array.reshape!(*arg)
|
731
|
+
@mask = @mask.reshape!(*arg)
|
732
|
+
self
|
733
|
+
end
|
734
|
+
def reshape(*arg)
|
735
|
+
obj = self.dup
|
736
|
+
obj.reshape!(*arg)
|
737
|
+
end
|
738
|
+
alias :shape= :reshape!
|
739
|
+
def newdim!(*arg)
|
740
|
+
@array = @array.newdim!(*arg)
|
741
|
+
@mask = @mask.newdim!(*arg)
|
742
|
+
self
|
743
|
+
end
|
744
|
+
alias :rewrank! :newdim!
|
745
|
+
alias :rewrank= :newdim!
|
746
|
+
def newdim(*arg)
|
747
|
+
obj = self.dup
|
748
|
+
obj.newdim!(*arg)
|
749
|
+
end
|
750
|
+
alias :rewrank :newdim
|
751
|
+
|
752
|
+
|
753
|
+
=begin
|
754
|
+
=== Type conversion
|
755
|
+
--- NArrayMiss#floor
|
756
|
+
return (({NArrayMiss})) of integer whose elements processed (({floor})).
|
757
|
+
--- NArrayMiss#ceil
|
758
|
+
return (({NArrayMiss})) of integer whose elements processed (({ceil})).
|
759
|
+
--- NArrayMiss#round
|
760
|
+
return (({NArrayMiss})) of integer whose elements processed (({round})).
|
761
|
+
--- NArrayMiss#to_i
|
762
|
+
return (({NArrayMiss})) of integer whose elements processed (({to_i})).
|
763
|
+
--- NArrayMiss#to_f
|
764
|
+
return (({NArrayMiss})) of float whose elements processed (({to_f})).
|
765
|
+
--- NArrayMiss#to_type(typecode)
|
766
|
+
return (({NArrayMiss})) of ((|typecode|)).
|
767
|
+
--- NArrayMiss#to_a
|
768
|
+
convert (({NArrayMiss})) to (({Array})).
|
769
|
+
--- NArrayMiss#to_na!([missing_value])
|
770
|
+
convert (({NArrayMiss})) to (({NArray})).
|
771
|
+
if there is argument, set missing_value for invalid elements.
|
772
|
+
--- NArrayMiss#to_na([missing_value])
|
773
|
+
convert (({NArrayMiss})) to (({NArray})).
|
774
|
+
if there is argument, set missing_value for invalid elements.
|
775
|
+
--- NArrayMiss#to_s
|
776
|
+
convert (({NArrayMiss})) to (({String})) as a binary data.
|
777
|
+
--- NArrayMiss#to_string
|
778
|
+
create (({NArrayMiss})) of object whose elements are processed (({to_s}))
|
779
|
+
=end
|
780
|
+
|
781
|
+
def floor
|
782
|
+
NArrayMiss.to_nam_no_dup(@array.floor, @mask.dup)
|
783
|
+
end
|
784
|
+
def ceil
|
785
|
+
NArrayMiss.to_nam_no_dup(@array.ceil, @mask.dup)
|
786
|
+
end
|
787
|
+
def round
|
788
|
+
NArrayMiss.to_nam_no_dup(@array.round, @mask.dup)
|
789
|
+
end
|
790
|
+
def to_i
|
791
|
+
NArrayMiss.to_nam_no_dup(@array.to_i, @mask.dup)
|
792
|
+
end
|
793
|
+
def to_f
|
794
|
+
NArrayMiss.to_nam_no_dup(@array.to_f, @mask.dup)
|
795
|
+
end
|
796
|
+
|
797
|
+
def to_type(typecode)
|
798
|
+
NArrayMiss.to_nam_no_dup(@array.to_type(typecode), @mask.dup)
|
799
|
+
end
|
800
|
+
def to_a
|
801
|
+
@array.to_a
|
802
|
+
end
|
803
|
+
def to_na!(*arg)
|
804
|
+
if arg.length==0
|
805
|
+
return @array
|
806
|
+
elsif arg.length==1 then
|
807
|
+
self.set_missing_value!(arg[0])
|
808
|
+
return @array
|
809
|
+
else
|
810
|
+
raise(ArgumentError, "Usage: NArray#to_na([missing_value])")
|
811
|
+
end
|
812
|
+
end
|
813
|
+
def to_na(*arg)
|
814
|
+
return self.dup.to_na!(*arg)
|
815
|
+
end
|
816
|
+
def to_s
|
817
|
+
@array.to_s
|
818
|
+
end
|
819
|
+
def to_string
|
820
|
+
obj = NArrayMiss.obj(*@array.shape)
|
821
|
+
obj.set_without_validation( @array.to_string )
|
822
|
+
obh.set_mask(@mask)
|
823
|
+
obj
|
824
|
+
end
|
825
|
+
|
826
|
+
|
827
|
+
=begin
|
828
|
+
=== Iteration
|
829
|
+
--- NArrayMiss#each{|x| ...}
|
830
|
+
--- NArrayMiss#each_valid{|x| ...}
|
831
|
+
--- NArrayMiss#each_valid_with_index{|x,i| ...}
|
832
|
+
--- NArrayMiss#collect{|x| ...}
|
833
|
+
--- NArrayMiss#collect!{|x| ...}
|
834
|
+
=end
|
835
|
+
|
836
|
+
def each
|
837
|
+
for i in 0..self.total-1
|
838
|
+
yield(@array[i])
|
839
|
+
end
|
840
|
+
end
|
841
|
+
def each_valid
|
842
|
+
for i in 0..self.total-1
|
843
|
+
yield(@array[i]) if @mask[i]
|
844
|
+
end
|
845
|
+
end
|
846
|
+
def each_valid_with_index
|
847
|
+
for i in 0..self.total-1
|
848
|
+
yield(@array[i],i) if @mask[i]
|
849
|
+
end
|
850
|
+
end
|
851
|
+
def collect!
|
852
|
+
for i in 0..self.total-1
|
853
|
+
self[i] = yield(self[i])
|
854
|
+
end
|
855
|
+
self
|
856
|
+
end
|
857
|
+
def collect(&blk)
|
858
|
+
self.dup.collect!(&blk)
|
859
|
+
end
|
860
|
+
|
861
|
+
|
862
|
+
=begin
|
863
|
+
=== Boolean and mask related (only for byte, sint and int)
|
864
|
+
--- NArrayMiss#count_false
|
865
|
+
return the number of elements whose value==0 and valid.
|
866
|
+
--- NArrayMiss#count_true
|
867
|
+
return the number of elements whose value!=0 and valid.
|
868
|
+
--- NArrayMiss#mask(mask)
|
869
|
+
return (({NArrayMiss#get_mask!&((|mask|))})).
|
870
|
+
--- NArrayMiss#all?
|
871
|
+
return true if all the valid elements are not 0, else false.
|
872
|
+
--- NArrayMiss#any?
|
873
|
+
return true if any valid element is not 0, else false.
|
874
|
+
--- NArrayMiss#none?
|
875
|
+
return true if none of the valid elements is not 0, else false.
|
876
|
+
--- NArrayMiss#where
|
877
|
+
return (({NArray})) of indices where valid elements are not 0.
|
878
|
+
--- NArrayMiss#where2
|
879
|
+
return (({Array})) including two (({NArray}))s of indices,
|
880
|
+
where valid elements are not 0, and 0, respectively.
|
881
|
+
=end
|
882
|
+
|
883
|
+
def count_false
|
884
|
+
if @array.typecode==BYTE then
|
885
|
+
return @array.count_false-@mask.count_false
|
886
|
+
else
|
887
|
+
raise("cannot count_true NArrayMiss except BYTE type")
|
888
|
+
end
|
889
|
+
end
|
890
|
+
def count_true
|
891
|
+
if @array.typecode==BYTE then
|
892
|
+
return (@array&@mask).count_true
|
893
|
+
else
|
894
|
+
raise("cannot count_true NArrayMiss except BYTE type")
|
895
|
+
end
|
896
|
+
end
|
897
|
+
def mask(arg)
|
898
|
+
obj = self.dup
|
899
|
+
if arg.class==NArrayMiss then
|
900
|
+
arg = arg.get_array!&arg.get_mask!
|
901
|
+
end
|
902
|
+
obj.set_mask(@mask&arg)
|
903
|
+
end
|
904
|
+
|
905
|
+
def all?
|
906
|
+
@array[@mask].all?
|
907
|
+
end
|
908
|
+
def any?
|
909
|
+
@array[@mask].any?
|
910
|
+
end
|
911
|
+
def none?
|
912
|
+
@array[@mask].none?
|
913
|
+
end
|
914
|
+
|
915
|
+
def where
|
916
|
+
(@array&@mask).where
|
917
|
+
end
|
918
|
+
def where2
|
919
|
+
self.where-@mask.where
|
920
|
+
end
|
921
|
+
|
922
|
+
|
923
|
+
|
924
|
+
|
925
|
+
=begin
|
926
|
+
=== Complex compound number (only for scomplex and complex)
|
927
|
+
--- NArrayMiss#real
|
928
|
+
--- NArrayMiss#imag
|
929
|
+
--- NArrayMiss#conj
|
930
|
+
--- NArrayMiss#angle
|
931
|
+
--- NArrayMiss#imag=(other)
|
932
|
+
--- NArrayMiss#im
|
933
|
+
=end
|
934
|
+
|
935
|
+
def real
|
936
|
+
NArrayMiss.to_nam_no_dup(@array.real,@mask)
|
937
|
+
end
|
938
|
+
def imag
|
939
|
+
NArrayMiss.to_nam_no_dup(@array.imag,@mask)
|
940
|
+
end
|
941
|
+
def conj
|
942
|
+
NArrayMiss.to_nam_no_dup(@array.conj,@mask)
|
943
|
+
end
|
944
|
+
def angle
|
945
|
+
NArrayMiss.to_nam_no_dup(@array.angle,@mask)
|
946
|
+
end
|
947
|
+
def imag=(arg)
|
948
|
+
@array.image=(arg)
|
949
|
+
self
|
950
|
+
end
|
951
|
+
def im
|
952
|
+
NArrayMiss.to_nam_no_dup(@array.im,@mask)
|
953
|
+
end
|
954
|
+
|
955
|
+
|
956
|
+
=begin
|
957
|
+
=== Byte swap
|
958
|
+
--- NArrayMiss#swap_byte
|
959
|
+
swap byte order.
|
960
|
+
--- NArrayMiss#hton
|
961
|
+
convert to network byte order.
|
962
|
+
--- NArrayMiss#ntoh
|
963
|
+
convert from network byte order.
|
964
|
+
--- NArrayMiss#htov
|
965
|
+
convert to VAX byte order.
|
966
|
+
--- NArrayMiss#vtoh
|
967
|
+
convert from VAX byte order.
|
968
|
+
=end
|
969
|
+
|
970
|
+
def swap_byte
|
971
|
+
obj = self.dup
|
972
|
+
obj.set_without_validation(@array.swap_byte)
|
973
|
+
obj
|
974
|
+
end
|
975
|
+
def hton
|
976
|
+
NArrayMiss.to_nam(@array.hton,@mask.hton)
|
977
|
+
end
|
978
|
+
alias :ntoh :hton
|
979
|
+
def htov
|
980
|
+
NArrayMiss.to_nam(@array.htov,@mask.htov)
|
981
|
+
end
|
982
|
+
alias :vtoh :htov
|
983
|
+
|
984
|
+
|
985
|
+
=begin
|
986
|
+
=== Mask and missing value
|
987
|
+
--- NArrayMiss#set_valid(index)
|
988
|
+
validate element at ((|index|)).
|
989
|
+
((|index|)) must be (({Integer, Range, Array, or ture})).
|
990
|
+
--- NArrayMiss#validation(index)
|
991
|
+
alias to set_valid
|
992
|
+
--- NArrayMiss#set_invalid(index)
|
993
|
+
invaliadate element at ((|index|)).
|
994
|
+
((|index|)) must be (({Integer, Range, Array, or ture})).
|
995
|
+
--- NArrayMiss#invalidation(index)
|
996
|
+
alias to set_invalid
|
997
|
+
--- NArrayMiss#all_valid
|
998
|
+
set all elements valid
|
999
|
+
--- NArrayMiss#all_invalid
|
1000
|
+
set all elements invalid
|
1001
|
+
--- NArrayMiss#set_mask(mask)
|
1002
|
+
masking by ((|mask|))
|
1003
|
+
--- NArrayMiss#set_missing_value(value)
|
1004
|
+
replace invalid elements by ((|value|)).
|
1005
|
+
--- NArrayMiss#get_mask!
|
1006
|
+
return (({NArray})) of byte as mask.
|
1007
|
+
--- NArrayMiss#get_mask
|
1008
|
+
return (({NArray})) of byte as mask.
|
1009
|
+
--- NArrayMiss#get_array!
|
1010
|
+
return (({NArray})) as data.
|
1011
|
+
--- NArrayMiss#get_array
|
1012
|
+
return (({NArray})) as data.
|
1013
|
+
--- NArrayMiss#valid?
|
1014
|
+
return (({Array})) whose elements are true or false corresponding to valid or invalid of elements, respectively.
|
1015
|
+
--- NArrayMiss#all_valid?
|
1016
|
+
return true if all elements are valid, else false.
|
1017
|
+
--- NArrayMiss#none_valid?
|
1018
|
+
return true if all elements are invalid, else false.
|
1019
|
+
--- NArrayMiss#all_invalid?
|
1020
|
+
alias to none_valid?
|
1021
|
+
--- NArrayMiss#any_valid?
|
1022
|
+
return true if any elements are valid, else false.
|
1023
|
+
|
1024
|
+
--- NArrayMiss#count_valid
|
1025
|
+
return the number of valid elements.
|
1026
|
+
--- NArrayMiss#count_invalid
|
1027
|
+
return the number of invalid elements.
|
1028
|
+
=end
|
1029
|
+
|
1030
|
+
def set_valid(*pos)
|
1031
|
+
@mask[*pos] = 1
|
1032
|
+
self
|
1033
|
+
end
|
1034
|
+
alias validation set_valid
|
1035
|
+
def set_invalid(*pos)
|
1036
|
+
@mask[*pos] = 0
|
1037
|
+
self
|
1038
|
+
end
|
1039
|
+
alias invalidation set_invalid
|
1040
|
+
def all_valid
|
1041
|
+
@mask[true]=1
|
1042
|
+
self
|
1043
|
+
end
|
1044
|
+
def all_invalid
|
1045
|
+
@mask[true]=0
|
1046
|
+
self
|
1047
|
+
end
|
1048
|
+
def set_mask(mask)
|
1049
|
+
if mask.class == Array then
|
1050
|
+
tmp = NArray.byte(*@mask.shape)
|
1051
|
+
tmp[true] = mask
|
1052
|
+
mask = tmp
|
1053
|
+
end
|
1054
|
+
if mask.class == NArrayMiss then
|
1055
|
+
mask = mask.to_na(0)
|
1056
|
+
end
|
1057
|
+
if mask.class == NArray then
|
1058
|
+
if mask.typecode != BYTE then
|
1059
|
+
raise("mask must be NArrayMiss.byte, NArray.byte or Array")
|
1060
|
+
end
|
1061
|
+
if @array.shape != mask.shape then
|
1062
|
+
raise("mask.shape must be same as array")
|
1063
|
+
end
|
1064
|
+
@mask = mask.dup
|
1065
|
+
return self
|
1066
|
+
else
|
1067
|
+
raise("mask must be NArray.byte or Array")
|
1068
|
+
end
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
def set_missing_value!(val)
|
1072
|
+
@array[@mask.not] = val
|
1073
|
+
self
|
1074
|
+
end
|
1075
|
+
def set_missing_value(val)
|
1076
|
+
obj = self.dup
|
1077
|
+
obj.set_missing_value!(val)
|
1078
|
+
end
|
1079
|
+
|
1080
|
+
def get_mask!
|
1081
|
+
@mask
|
1082
|
+
end
|
1083
|
+
def get_mask
|
1084
|
+
@mask.dup
|
1085
|
+
end
|
1086
|
+
def get_array!
|
1087
|
+
@array
|
1088
|
+
end
|
1089
|
+
def get_array
|
1090
|
+
@array.dup
|
1091
|
+
end
|
1092
|
+
|
1093
|
+
def valid?
|
1094
|
+
where = self.get_mask!.where2
|
1095
|
+
tf = Array.new(self.total)
|
1096
|
+
for i in where[0]
|
1097
|
+
tf[i] = true
|
1098
|
+
end
|
1099
|
+
for i in where[1]
|
1100
|
+
tf[i] = false
|
1101
|
+
end
|
1102
|
+
tf
|
1103
|
+
end
|
1104
|
+
def all_valid?
|
1105
|
+
@mask.all?
|
1106
|
+
end
|
1107
|
+
def none_valid?
|
1108
|
+
@mask.none?
|
1109
|
+
end
|
1110
|
+
alias :all_invalid? :none_valid?
|
1111
|
+
def any_valid?
|
1112
|
+
@mask.any?
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
def count_valid(*arg)
|
1116
|
+
if arg.length==0 then
|
1117
|
+
return @mask.count_true
|
1118
|
+
else
|
1119
|
+
return @mask.to_type(NArray::INT).sum(*arg)
|
1120
|
+
end
|
1121
|
+
end
|
1122
|
+
def count_invalid(*arg)
|
1123
|
+
if arg.length==0 then
|
1124
|
+
return @mask.count_false
|
1125
|
+
else
|
1126
|
+
return NArray.int(*@mask.shape).fill(1).sum(*arg)-
|
1127
|
+
@mask.to_type(NArray::INT).sum(*arg)
|
1128
|
+
end
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
|
1132
|
+
=begin
|
1133
|
+
=== Others
|
1134
|
+
--- NArrayMiss#integer?
|
1135
|
+
return true if (({NArrayMiss})) is byte, sint or int, else false.
|
1136
|
+
--- NArrayMiss#complex?
|
1137
|
+
return true if (({NArrayMiss})) is scomplex or complex, else false.
|
1138
|
+
--- NArrayMiss#dup
|
1139
|
+
--- NArrayMiss#coerce(object)
|
1140
|
+
--- NArrayMiss#inspect
|
1141
|
+
|
1142
|
+
go back to ((<Index>))
|
1143
|
+
=end
|
1144
|
+
|
1145
|
+
def integer?
|
1146
|
+
@array.integer?
|
1147
|
+
end
|
1148
|
+
def complex?
|
1149
|
+
@array.complex?
|
1150
|
+
end
|
1151
|
+
|
1152
|
+
|
1153
|
+
def dup
|
1154
|
+
NArrayMiss.to_nam(@array,@mask)
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
alias __clone__ clone
|
1158
|
+
def clone
|
1159
|
+
obj = __clone__
|
1160
|
+
obj.set_array(@array.clone)
|
1161
|
+
obj.set_mask(@mask.clone)
|
1162
|
+
return obj
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
def coerce(x)
|
1166
|
+
if Numeric===x then
|
1167
|
+
return [NArrayMiss.new(NArray[x].typecode,*self.shape).fill(x),self]
|
1168
|
+
elsif x.class==Array || x.class==NArray then
|
1169
|
+
return [NArrayMiss.to_nam(x), self]
|
1170
|
+
else
|
1171
|
+
raise("donnot know how to cange #{x.class} to NArrayMiss")
|
1172
|
+
end
|
1173
|
+
end
|
1174
|
+
|
1175
|
+
|
1176
|
+
def inspect
|
1177
|
+
# "array -> " + @array.inspect + "\nmask -> " + @mask.inspect
|
1178
|
+
count_line = 0
|
1179
|
+
max_line = 10
|
1180
|
+
max_col = 80
|
1181
|
+
sep = ", "
|
1182
|
+
const = Hash.new
|
1183
|
+
NArray.constants.each{|c| const[NArray.const_get(c)] = c}
|
1184
|
+
str_ret = "NArrayMiss."+const[typecode].to_s.downcase+"("+shape.join(",")+"):"
|
1185
|
+
if rank == 0 then
|
1186
|
+
str_ret << " []"
|
1187
|
+
return str_ret
|
1188
|
+
else
|
1189
|
+
str_ret << "\n"
|
1190
|
+
end
|
1191
|
+
str = ""
|
1192
|
+
index = Array.new(rank,0)
|
1193
|
+
index[0] = true
|
1194
|
+
i = 1
|
1195
|
+
(rank-1).times{ str_ret << "[ " }
|
1196
|
+
while(true)
|
1197
|
+
i.times{ str_ret << "[ " }
|
1198
|
+
|
1199
|
+
str = @array[*index].inspect
|
1200
|
+
ary = str[str.index("[")+1..str.index("]")-1].strip.split(/\s*,\s*/)
|
1201
|
+
miss = @mask[*index].where2[1]
|
1202
|
+
miss = miss[miss<ary.length].to_a
|
1203
|
+
if ary[-1]=="..." && miss[-1]==ary.length-1 then miss.pop end
|
1204
|
+
for j in miss
|
1205
|
+
ary[j] = "-"
|
1206
|
+
end
|
1207
|
+
while ( rank*4+ary.join(", ").length > max_col )
|
1208
|
+
ary.pop
|
1209
|
+
ary[-1] = "..."
|
1210
|
+
end
|
1211
|
+
str_ret << ary.join(", ")
|
1212
|
+
i = 1
|
1213
|
+
while (i<rank)
|
1214
|
+
if index[i]<shape[i]-1 then
|
1215
|
+
str_ret << " ]" << sep << "\n"
|
1216
|
+
count_line += 1
|
1217
|
+
index[i] += 1
|
1218
|
+
break
|
1219
|
+
else
|
1220
|
+
str_ret << " ]"
|
1221
|
+
index[i] = 0
|
1222
|
+
i += 1
|
1223
|
+
end
|
1224
|
+
end
|
1225
|
+
|
1226
|
+
if i>=rank then
|
1227
|
+
str_ret << " ]"
|
1228
|
+
return str_ret
|
1229
|
+
elsif count_line>=max_line then
|
1230
|
+
str_ret << " ..."
|
1231
|
+
return str_ret
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
(rank-i).times{ str_ret << " " }
|
1235
|
+
end
|
1236
|
+
return str_ret
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
|
1240
|
+
def _dump(limit)
|
1241
|
+
Marshal::dump([@array._dump(nil),@mask._dump(nil)])
|
1242
|
+
end
|
1243
|
+
def self._load(o)
|
1244
|
+
ary, mask = Marshal::load(o)
|
1245
|
+
ary = NArray._load(ary)
|
1246
|
+
mask = NArray._load(mask)
|
1247
|
+
NArrayMiss.to_nam_no_dup(ary,mask)
|
1248
|
+
end
|
1249
|
+
|
1250
|
+
|
1251
|
+
|
1252
|
+
|
1253
|
+
# private
|
1254
|
+
private
|
1255
|
+
def pos(n,shape)
|
1256
|
+
rank = shape.length
|
1257
|
+
result = NArray.int(rank)
|
1258
|
+
m=n
|
1259
|
+
for i in 0..rank-2
|
1260
|
+
j = rank-1-i
|
1261
|
+
result[j] = m/shape[j-1]
|
1262
|
+
m = m%shape[j-1]
|
1263
|
+
end
|
1264
|
+
result[0] = m
|
1265
|
+
result
|
1266
|
+
end
|
1267
|
+
def binary_operation(arg, dummy)
|
1268
|
+
# arg: 第2項目のオブジェクト
|
1269
|
+
# dummy: 演算を行っても結果に影響を与えない特別な値。(欠損部分に代入する)
|
1270
|
+
flag=true
|
1271
|
+
case arg
|
1272
|
+
when Numeric
|
1273
|
+
term1 = @array
|
1274
|
+
term2 = arg
|
1275
|
+
mask = @mask
|
1276
|
+
when Array, NArray
|
1277
|
+
term1 = @array.dup
|
1278
|
+
term1[@mask.not] = dummy # 欠損部分に dummy を代入
|
1279
|
+
term2 = arg.kind_of?(NArray) ? arg : NArray.to_na(arg) # Array -> NArray
|
1280
|
+
mask = NArray.byte(*term2.shape).fill(1) # 2項目は欠損無し
|
1281
|
+
mask = @mask & mask
|
1282
|
+
when NArrayMiss
|
1283
|
+
term1 = @array.dup
|
1284
|
+
term1[@mask.not] = dummy
|
1285
|
+
mask = arg.get_mask!
|
1286
|
+
term2 = arg.get_array
|
1287
|
+
term2[mask.not] = dummy
|
1288
|
+
mask = @mask & mask
|
1289
|
+
else
|
1290
|
+
term1, term2 = arg.coerce(self)
|
1291
|
+
# 演算を arg のクラスに任せるため、yield の結果をそのまま返す
|
1292
|
+
flag = false
|
1293
|
+
end
|
1294
|
+
result = yield(term1, term2)
|
1295
|
+
result = NArrayMiss.to_nam_no_dup(result, mask) if flag
|
1296
|
+
result
|
1297
|
+
end
|
1298
|
+
|
1299
|
+
|
1300
|
+
def self.reduction(mask, min_count, dims, flag, typecode)
|
1301
|
+
# flag: リダクションを行う次元方向の有効な値の個数で、割り算を行うかどうかのフラグ
|
1302
|
+
count_sum = mask.to_type(NArray::LINT).sum(*dims)
|
1303
|
+
# 返り値が配列か、スカラーかによって分岐
|
1304
|
+
if count_sum.kind_of?(NArray)
|
1305
|
+
mask = count_sum.ge(min_count)
|
1306
|
+
# すべての要素が欠損値にならないかチェック
|
1307
|
+
if mask.any?
|
1308
|
+
count_accum = NArray.ref(count_sum)
|
1309
|
+
dims.collect{|d|d<0 ? d+mask.rank : d}.sort.each do |d|
|
1310
|
+
count_accum.newdim!(d)
|
1311
|
+
end
|
1312
|
+
# 割り算を行う場合は、先に count_sum を NArrayMiss 化
|
1313
|
+
# yield の戻り値は NArrayMiss
|
1314
|
+
# 割り算を行わない場合は、後で NArrayMiss 化
|
1315
|
+
# yield の戻り値は NArray
|
1316
|
+
count_sum = NArrayMiss.to_nam_no_dup(count_sum,mask) if flag
|
1317
|
+
ary = yield(count_sum, count_accum)
|
1318
|
+
ary = NArrayMiss.to_nam_no_dup(ary, mask) unless flag
|
1319
|
+
else
|
1320
|
+
# すべての要素が欠損値の NArrayMiss を返す
|
1321
|
+
na = NArray.new(typecode, *mask.shape)
|
1322
|
+
ary = NArrayMiss.to_nam_no_dup(na, false)
|
1323
|
+
end
|
1324
|
+
else
|
1325
|
+
# 有効な要素数があるかチェック
|
1326
|
+
if count_sum >= min_count
|
1327
|
+
count_accum = NArray.int(*([1]*mask.rank)).fill!(count_sum)
|
1328
|
+
ary = yield(count_sum, count_accum)
|
1329
|
+
else
|
1330
|
+
# 有効な要素数が足りない場合は nil を返す
|
1331
|
+
return nil
|
1332
|
+
end
|
1333
|
+
end
|
1334
|
+
return ary
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
|
1338
|
+
# 引数にオプション (Hash) が指定されているかチェックし、
|
1339
|
+
# されている場合は、オプションを取得し戻り値として返す。
|
1340
|
+
# 現時点では、オプションは "min_count" のみ
|
1341
|
+
def self.check_options(arg, default_mincount)
|
1342
|
+
min_count = default_mincount
|
1343
|
+
options = %w(min_count)
|
1344
|
+
if arg.length!=0 && arg[-1].kind_of?(Hash)
|
1345
|
+
option = arg.pop
|
1346
|
+
option.each_key{|key|
|
1347
|
+
if !options.index(key) then
|
1348
|
+
raise(ArgumentError,key+" option is not exist")
|
1349
|
+
end
|
1350
|
+
}
|
1351
|
+
min_count = option["min_count"] || default_mincount
|
1352
|
+
min_count = min_count.to_i
|
1353
|
+
if min_count < default_mincount
|
1354
|
+
raise(ArgumentError, "min_count must be >= #{default_mincount}")
|
1355
|
+
end
|
1356
|
+
end
|
1357
|
+
return min_count
|
1358
|
+
end
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
|
1362
|
+
|
1363
|
+
module NMMath
|
1364
|
+
|
1365
|
+
|
1366
|
+
func1 = ["sqrt","exp","log","log10","log2",
|
1367
|
+
"sin","cos","tan","sinh","cosh","tanh",
|
1368
|
+
"asin","acos","atan","asinh","acosh","atanh",
|
1369
|
+
"csc", "sec", "cot", "csch", "sech", "coth",
|
1370
|
+
"acsc", "asec", "acot", "acsch", "asech", "acoth",
|
1371
|
+
]
|
1372
|
+
func2 = ["atan2"]
|
1373
|
+
|
1374
|
+
for operator in func1
|
1375
|
+
eval <<-EOL,nil,__FILE__,__LINE__+1
|
1376
|
+
def #{operator}(x)
|
1377
|
+
case x
|
1378
|
+
when Numeric, Array, NArray
|
1379
|
+
NMath::#{operator}(x)
|
1380
|
+
when NArrayMiss
|
1381
|
+
obj = NArrayMiss.new(x.typecode,*x.shape)
|
1382
|
+
mask = x.get_mask!
|
1383
|
+
obj[mask] = NMath::#{operator}(x.get_array![mask])
|
1384
|
+
obj[mask.not] = x[mask.not]
|
1385
|
+
obj.set_mask(mask)
|
1386
|
+
obj
|
1387
|
+
else
|
1388
|
+
raise ArgumentError, "argument is invalid class: \#{x.class}"
|
1389
|
+
end
|
1390
|
+
end
|
1391
|
+
module_function :#{operator}
|
1392
|
+
EOL
|
1393
|
+
end
|
1394
|
+
|
1395
|
+
for operator in func2
|
1396
|
+
eval <<-EOL,nil,__FILE__,__LINE__+1
|
1397
|
+
def #{operator}(x,y)
|
1398
|
+
obj = nil
|
1399
|
+
case x
|
1400
|
+
when Numeric, Array, NArray
|
1401
|
+
mask1 = nil
|
1402
|
+
when NArrayMiss
|
1403
|
+
obj = NArrayMiss.new(x.typecode,*x.shape)
|
1404
|
+
mask1 = x.get_mask!
|
1405
|
+
else
|
1406
|
+
raise ArgumentError, "argument is invalid class"
|
1407
|
+
end
|
1408
|
+
case y
|
1409
|
+
when Numeric, Array, NArray
|
1410
|
+
mask2 = nil
|
1411
|
+
when NArrayMiss
|
1412
|
+
obj ||= NArrayMiss.new(y.typecode,*y.shape)
|
1413
|
+
mask2 = y.get_mask!
|
1414
|
+
else
|
1415
|
+
raise ArgumentError, "argument is invalid class"
|
1416
|
+
end
|
1417
|
+
if mask2.nil? then
|
1418
|
+
if mask1.nil? then
|
1419
|
+
return NMath::#{operator}(x,y)
|
1420
|
+
else
|
1421
|
+
obj[mask1] = NMath::#{operator}(x.get_array![mask1],y)
|
1422
|
+
obj[mask1.not] = x[mask1.not]
|
1423
|
+
obj.set_mask(mask1)
|
1424
|
+
return obj
|
1425
|
+
end
|
1426
|
+
else
|
1427
|
+
if mask1.nil? then
|
1428
|
+
obj[mask2] = NMath::#{operator}(x,y.get_array![mask2])
|
1429
|
+
obj[mask2.not] = y[mask2.not]
|
1430
|
+
obj.set_mask(mask2)
|
1431
|
+
return obj
|
1432
|
+
else
|
1433
|
+
obj[mask1&mask2] = NMath::#{operator}(x.get_array![mask1],y.get_array![mask2])
|
1434
|
+
obj[(mask1&mask2).not] = x[(mask1&mask2).not]
|
1435
|
+
return obj
|
1436
|
+
end
|
1437
|
+
end
|
1438
|
+
end
|
1439
|
+
module_function :#{operator}
|
1440
|
+
EOL
|
1441
|
+
end
|
1442
|
+
|
1443
|
+
methods = Hash.new
|
1444
|
+
methods["covariance"] = {:min_count => 2, :post => <<-EOL}
|
1445
|
+
mean0 = ary0.accum(*dims) / count_accum
|
1446
|
+
mean1 = ary1.accum(*dims) / count_accum
|
1447
|
+
ary = ((ary0-mean0)*(ary1-mean1)).sum(*dims)
|
1448
|
+
ary / (count_sum-1)
|
1449
|
+
EOL
|
1450
|
+
methods.each do |name, hash|
|
1451
|
+
eval <<-EOL,nil,__FILE__,__LINE__+1
|
1452
|
+
def #{name}(ary0,ary1,*dims)
|
1453
|
+
min_count = NArrayMiss.check_options(dims, 2)
|
1454
|
+
case ary0
|
1455
|
+
when Numeric, Array, NArray
|
1456
|
+
mask0 = nil
|
1457
|
+
when NArrayMiss
|
1458
|
+
mask0 = ary0.get_mask!
|
1459
|
+
else
|
1460
|
+
raise ArgumentError, "argument is invalid class"
|
1461
|
+
end
|
1462
|
+
case ary1
|
1463
|
+
when Numeric, Array, NArray
|
1464
|
+
mask1 = nil
|
1465
|
+
when NArrayMiss
|
1466
|
+
mask1 = ary1.get_mask!
|
1467
|
+
else
|
1468
|
+
raise ArgumentError, "argument is invalid class"
|
1469
|
+
end
|
1470
|
+
if mask1.nil? then
|
1471
|
+
if mask0.nil? then
|
1472
|
+
return NMath.#{name}(ary0, ary1, *dims)
|
1473
|
+
else
|
1474
|
+
ary1 = NArrayMiss.to_nam_no_dup(ary1, true)
|
1475
|
+
end
|
1476
|
+
else
|
1477
|
+
if mask0.nil?
|
1478
|
+
ary0 = NArrayMiss.to_nam_no_dup(ary0, true)
|
1479
|
+
end
|
1480
|
+
end
|
1481
|
+
if ary1.shape != ary1.shape
|
1482
|
+
raise "shape is different"
|
1483
|
+
end
|
1484
|
+
ary0 = ary0.to_type(NArray::DFLOAT)
|
1485
|
+
ary1 = ary1.to_type(NArray::DFLOAT)
|
1486
|
+
mask = mask0.nil? ? mask1 : mask1.nil? ? mask0 : mask0&mask1
|
1487
|
+
ary0.set_mask(mask)
|
1488
|
+
ary1.set_mask(mask)
|
1489
|
+
NArrayMiss.reduction(mask, min_count, dims, true, NArray::DFLOAT) do |count_sum, count_accum|
|
1490
|
+
#{hash[:post]}
|
1491
|
+
end
|
1492
|
+
end
|
1493
|
+
module_function :#{name}
|
1494
|
+
EOL
|
1495
|
+
end
|
1496
|
+
|
1497
|
+
for operator in func1+func2+["covariance"]
|
1498
|
+
eval <<-EOL,nil,__FILE__,__LINE__+1
|
1499
|
+
def #{operator}(*x)
|
1500
|
+
x = [self]+x if NArrayMiss===self
|
1501
|
+
NMMath.#{operator}(*x)
|
1502
|
+
end
|
1503
|
+
EOL
|
1504
|
+
end
|
1505
|
+
|
1506
|
+
end
|
1507
|
+
|
1508
|
+
class NArrayMiss
|
1509
|
+
include NMMath
|
1510
|
+
end
|