narray_miss 0.1.0

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