narray-bigmem 0.0.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,4 @@
1
+ unless ENV["OMP_NUM_THREADS"]
2
+ ENV["OMP_NUM_THREADS"] = "1"
3
+ end
4
+ require "narray/narray"
@@ -0,0 +1,362 @@
1
+ # Numerical Array Extention for Ruby
2
+ # (C) Copyright 2000-2008 by Masahiro TANAKA
3
+ #
4
+ # This program is free software.
5
+ # You can distribute/modify this program
6
+ # under the same terms as Ruby itself.
7
+ # NO WARRANTY.
8
+ #
9
+ class NArray
10
+
11
+ def self.cast(array,type=nil)
12
+ case array
13
+ when NArray
14
+ when Array
15
+ array = NArray.to_na(array)
16
+ else
17
+ raise ArgumentError, "1st argument must be NArray or Array"
18
+ end
19
+ type = array.typecode if type.nil?
20
+ shape = array.shape
21
+ na = self.new(type,*shape)
22
+ na[] = array
23
+ na
24
+ end
25
+
26
+ def integer?
27
+ self.typecode==NArray::BYTE ||
28
+ self.typecode==NArray::SINT ||
29
+ self.typecode==NArray::LINT
30
+ end
31
+ def complex?
32
+ self.typecode==NArray::DCOMPLEX ||
33
+ self.typecode==NArray::SCOMPLEX
34
+ end
35
+
36
+ def all?
37
+ where.size == size
38
+ end
39
+
40
+ def any?
41
+ where.size > 0
42
+ end
43
+
44
+ def none?
45
+ where.size == 0
46
+ end
47
+
48
+ def ==(other)
49
+ other.kind_of?(NArray) &&
50
+ shape == other.shape &&
51
+ eq(other).all?
52
+ end
53
+
54
+ def eql?(other)
55
+ self.class == other.class &&
56
+ typecode == other.typecode &&
57
+ shape == other.shape &&
58
+ case typecode
59
+ when NArray::OBJECT
60
+ to_a.eql? other.to_a
61
+ else
62
+ to_s.eql? other.to_s
63
+ end
64
+ end
65
+
66
+ def hash
67
+ case typecode
68
+ when NArray::OBJECT
69
+ [self.class, to_a].hash
70
+ else
71
+ [self.class, typecode, shape, to_s].hash
72
+ end
73
+ end
74
+
75
+ def rank_total(*ranks)
76
+ if ranks.size>0
77
+ idx = []
78
+ ranks.each{|i| idx.push(*i)}
79
+ # ranks is expected to be, e.g., [1, 3..5, 7]
80
+ a = self.shape
81
+ n = 1
82
+ idx.each{|i| n *= a[i]}
83
+ n
84
+ else
85
+ self.total
86
+ end
87
+ end
88
+
89
+ # delete rows/columns
90
+ def delete_at(*args)
91
+ if args.size > self.rank
92
+ raise ArgumentError, "too many arguments"
93
+ end
94
+ shp = self.shape
95
+ ind = []
96
+ self.rank.times do |i|
97
+ n = shp[i]
98
+ case a=args[i]
99
+ when Integer
100
+ a = n+a if a<0
101
+ raise IndexError, "index(%d) out of range"%[a] if a<0
102
+ x = [0...a,a+1...n]
103
+ when Range
104
+ b = a.first
105
+ b = n+b if b<0
106
+ raise IndexError, "index(%s) out of range"%[a] if b<0
107
+ e = a.last
108
+ e = n+e if e<0
109
+ e -= 1 if a.exclude_end?
110
+ raise IndexError, "index(%s) out of range"%[a] if e<0
111
+ x = [0...b,e+1...n]
112
+ when Array
113
+ x = (0...n).to_a
114
+ x -= a.map do |j|
115
+ raise IndexError, "contains non-integer" unless Integer===j
116
+ (j<0) ? n+j : j
117
+ end
118
+ else
119
+ if a
120
+ raise ArgumentError, "invalid argument"
121
+ else
122
+ x = true
123
+ end
124
+ end
125
+ ind << x
126
+ end
127
+ self[*ind]
128
+ end
129
+
130
+ # Statistics
131
+ def mean(*ranks)
132
+ if integer?
133
+ a = self.to_type(NArray::DFLOAT)
134
+ else
135
+ a = self
136
+ end
137
+ a = NArray.ref(a)
138
+ a.sum(*ranks) / (rank_total(*ranks))
139
+ end
140
+
141
+ def stddev(*ranks)
142
+ if integer?
143
+ a = self.to_type(NArray::DFLOAT)
144
+ else
145
+ a = self
146
+ end
147
+ a = NArray.ref(a)
148
+ n = rank_total(*ranks)
149
+ if complex?
150
+ NMath::sqrt( (( a-a.accum(*ranks).div!(n) ).abs**2).sum(*ranks)/(n-1) )
151
+ else
152
+ NMath::sqrt( (( a-a.accum(*ranks).div!(n) )**2).sum(*ranks)/(n-1) )
153
+ end
154
+ end
155
+
156
+ def rms(*ranks)
157
+ if integer?
158
+ a = self.to_type(NArray::DFLOAT)
159
+ else
160
+ a = self
161
+ end
162
+ a = NArray.ref(a)
163
+ n = rank_total(*ranks)
164
+ if complex?
165
+ NMath::sqrt( (a.abs**2).sum(*ranks)/n )
166
+ else
167
+ NMath::sqrt( (a**2).sum(*ranks)/n )
168
+ end
169
+ end
170
+
171
+ def rmsdev(*ranks)
172
+ if integer?
173
+ a = self.to_type(NArray::DFLOAT)
174
+ else
175
+ a = self
176
+ end
177
+ a = NArray.ref(a)
178
+ n = rank_total(*ranks)
179
+ if complex?
180
+ NMath::sqrt( (( a-a.accum(*ranks).div!(n) ).abs**2).sum(*ranks)/n )
181
+ else
182
+ NMath::sqrt( (( a-a.accum(*ranks).div!(n) )**2).sum(*ranks)/n )
183
+ end
184
+ end
185
+
186
+ def median(rank=nil)
187
+ shape = self.shape
188
+ rank = shape.size-1 if rank==nil
189
+ s = sort(rank).reshape!(true,*shape[rank+1..-1])
190
+ n = s.shape[0]
191
+ if n%2==1
192
+ s[n/2,false]
193
+ else
194
+ s[n/2-1..n/2,false].sum(0)/2
195
+ end
196
+ end
197
+
198
+
199
+ # Normal distributed random number; valid for floating point types
200
+ def randomn
201
+ size = self.size
202
+ case type = self.typecode
203
+ when COMPLEX; type=FLOAT
204
+ when SCOMPLEX; type=SFLOAT
205
+ when FLOAT
206
+ when SFLOAT
207
+ else
208
+ raise TypeError, "NArray type must be (S)FLOAT or (S)COMPLEX."
209
+ end
210
+ rr = NArray.new(type,size)
211
+ xx = NArray.new(type,size)
212
+ i = 0
213
+ while i < size
214
+ n = size-i
215
+ m = ((n+Math::sqrt(n))*1.27).to_i
216
+ x = NArray.new(type,m).random!(1) * 2 - 1
217
+ y = NArray.new(type,m).random!(1) * 2 - 1
218
+ r = x**2 + y**2
219
+ idx = (r<1).where
220
+ idx = idx[0...n] if idx.size > n
221
+ if idx.size>0
222
+ rr[i] = r[idx]
223
+ xx[i] = x[idx]
224
+ i += idx.size
225
+ end
226
+ end
227
+ # Box-Muller transform
228
+ rr = ( xx * NMath::sqrt( -2 * NMath::log(rr) / rr ) )
229
+ # finish
230
+ rr.reshape!(*self.shape) if self.rank > 1
231
+ rr = rr.to_type(self.typecode) if type!=self.typecode
232
+ if RUBY_VERSION < "1.8.0"
233
+ self.type.refer(rr)
234
+ else
235
+ self.class.refer(rr)
236
+ end
237
+ end
238
+ #alias randomn! randomn
239
+
240
+ def randomn!
241
+ self[]= randomn
242
+ self
243
+ end
244
+
245
+ def reverse(*ranks)
246
+ if self.rank==0
247
+ return self.dup
248
+ elsif ranks.size==0
249
+ idx = (0...self.rank).map{-1..0}
250
+ else
251
+ idx = [true]*self.rank
252
+ ranks.each do |i|
253
+ if !i.kind_of?(Integer)
254
+ raise ArgumentError, "Argument must be Integer"
255
+ end
256
+ if i >= self.rank
257
+ raise ArgumentError, "dimension(%s) out of range"%[i]
258
+ end
259
+ idx[i] = -1..0
260
+ end
261
+ end
262
+ self[*idx]
263
+ end
264
+
265
+ def rot90(n_times=1)
266
+ if self.rank < 2
267
+ raise "must be >= 2 dimensional array"
268
+ end
269
+ case n_times%4
270
+ when 0
271
+ self.dup
272
+ when 1
273
+ self.transpose(1,0).reverse(0)
274
+ when 2
275
+ self.reverse(0,1)
276
+ when 3
277
+ self.transpose(1,0).reverse(1)
278
+ end
279
+ end
280
+
281
+ #SFloatOne = NArray.sfloat(1).fill!(1)
282
+ end
283
+
284
+
285
+ module NMath
286
+ PI = Math::PI
287
+ E = Math::E
288
+
289
+ def recip x
290
+ 1/x.to_f
291
+ end
292
+
293
+ # Trigonometric function
294
+ def csc x
295
+ 1/sin(x)
296
+ end
297
+ def csch x
298
+ 1/sinh(x)
299
+ end
300
+ def acsc x
301
+ asin(1/x.to_f)
302
+ end
303
+ def acsch x
304
+ asinh(1/x.to_f)
305
+ end
306
+
307
+ def sec x
308
+ 1/cos(x)
309
+ end
310
+ def sech x
311
+ 1/cosh(x)
312
+ end
313
+ def asec x
314
+ acos(1/x.to_f)
315
+ end
316
+ def asech x
317
+ acosh(1/x.to_f)
318
+ end
319
+
320
+ def cot x
321
+ 1/tan(x)
322
+ end
323
+ def coth x
324
+ 1/tanh(x)
325
+ end
326
+ def acot x
327
+ atan(1/x.to_f)
328
+ end
329
+ def acoth x
330
+ atanh(1/x.to_f)
331
+ end
332
+
333
+ # Statistics
334
+ def covariance(x,y,*ranks)
335
+ x = NArray.to_na(x) unless x.kind_of?(NArray)
336
+ x = x.to_type(NArray::DFLOAT) if x.integer?
337
+ y = NArray.to_na(y) unless y.kind_of?(NArray)
338
+ y = y.to_type(NArray::DFLOAT) if y.integer?
339
+ n = x.rank_total(*ranks)
340
+ xm = x.accum(*ranks).div!(n)
341
+ ym = y.accum(*ranks).div!(n)
342
+ ((x-xm)*(y-ym)).sum(*ranks) / (n-1)
343
+ end
344
+
345
+ module_function :recip
346
+ module_function :csc,:sec,:cot,:csch,:sech,:coth
347
+ module_function :acsc,:asec,:acot,:acsch,:asech,:acoth
348
+ module_function :covariance
349
+ end
350
+
351
+
352
+ module FFTW
353
+ def convol(a1,a2)
354
+ n1x,n1y = a1.shape
355
+ n2x,n2y = a2.shape
356
+ raise "arrays must have same shape" if n1x!=n2x || n1y!=n2y
357
+ (FFTW.fftw( FFTW.fftw(a1,-1) * FFTW.fftw(a2,-1), 1).real) / (n1x*n1y)
358
+ end
359
+ module_function :convol
360
+ end
361
+
362
+ require 'nmatrix'
@@ -0,0 +1,248 @@
1
+ # Numerical Array Extention for Ruby
2
+ # (C) Copyright 2000-2003 by Masahiro TANAKA
3
+ #
4
+
5
+ #
6
+ # ------ NMatrix ------
7
+ #
8
+ class NMatrix < NArray
9
+ CLASS_DIMENSION = 2
10
+
11
+ def +(other)
12
+ case other
13
+ when NMatrix
14
+ return super(NArray.refer(other))
15
+ when NArray
16
+ unless other.instance_of?(NArray)
17
+ return other.coerce_rev( self, :+ )
18
+ end
19
+ end
20
+ raise TypeError,"Illegal operation: NMatrix + %s" % other.class
21
+ end
22
+
23
+ def -(other)
24
+ case other
25
+ when NMatrix
26
+ return super(NArray.refer(other))
27
+ when NArray
28
+ unless other.instance_of?(NArray)
29
+ return other.coerce_rev( self, :- )
30
+ end
31
+ end
32
+ raise TypeError,"Illegal operation: NMatrix - %s" % other.class
33
+ end
34
+
35
+ def *(other)
36
+ case other
37
+ when NMatrix
38
+ NMatrix.mul_add( NArray.refer(self).newdim!(0),other.newdim(2), 1 )
39
+ #NMatrix.mul_add( NArray.refer(self).newdim!(0),
40
+ # other.transpose(1,0).newdim!(2), 0 )
41
+ when NVector
42
+ NVector.mul_add( NArray.refer(self), other.newdim(1), 0 )
43
+ when NArray
44
+ if other.instance_of?(NArray)
45
+ NMatrix.mul( NArray.refer(self), other.newdim(0,0) )
46
+ else
47
+ other.coerce_rev( self, :* )
48
+ end
49
+ when Numeric
50
+ super
51
+ #NMatrix.mul( NArray.refer(self), other )
52
+ when Array
53
+ NMatrix.mul( self, NArray[*other].newdim!(0,0) )
54
+ else
55
+ raise TypeError,"Illegal operation: NMatrix * %s" % other.class
56
+ end
57
+ end
58
+
59
+ def /(other)
60
+ case other
61
+ when NMatrix
62
+ other.lu.solve(self)
63
+ when NVector
64
+ raise TypeError,"Illegal operation: NMatrix / %s" % other.class
65
+ when NArray
66
+ if other.instance_of?(NArray)
67
+ NMatrix.div( NArray.refer(self), other.newdim(0,0) )
68
+ else
69
+ other.coerce_rev( self, :/ )
70
+ end
71
+ when Numeric
72
+ NMatrix.div( NArray.refer(self), other )
73
+ when Array
74
+ NMatrix.div( self, NArray[*other].newdim!(0,0) )
75
+ else
76
+ raise TypeError,"Illegal operation: NMatrix / %s" % other.class
77
+ end
78
+ end
79
+
80
+ def **(n)
81
+ case n
82
+ when Integer
83
+ if n==0
84
+ return 1.0
85
+ elsif n<0
86
+ m = self.inverse
87
+ n = -n
88
+ else
89
+ m = self
90
+ end
91
+ (2..n).each{ m *= self }
92
+ m
93
+ else
94
+ raise TypeError,"Illegal operation: NMatrix ** %s" % other.class
95
+ end
96
+ end
97
+
98
+ def coerce_rev(other,id)
99
+ case id
100
+ when :*
101
+ if other.instance_of?(NArray)
102
+ return NMatrix.mul( other.newdim(0,0), self )
103
+ end
104
+ if other.instance_of?(NArrayScalar)
105
+ return NMatrix.mul( other.newdim(0), self )
106
+ end
107
+ when :/
108
+ if other.instance_of?(NArray)
109
+ return NMatrix.mul( other.newdim(0,0), self.inverse )
110
+ end
111
+ if other.instance_of?(NArrayScalar)
112
+ return NMatrix.mul( other.newdim(0), self.inverse )
113
+ end
114
+ end
115
+ raise TypeError,"Illegal operation: %s %s NMatrix" %
116
+ [other.class, id.id2name]
117
+ end
118
+
119
+ def inverse
120
+ self.lu.solve( NMatrix.new(self.typecode, *self.shape).fill!(0).unit )
121
+ end
122
+
123
+ def transpose(*arg)
124
+ if arg.size==0
125
+ super(1,0)
126
+ else
127
+ super
128
+ end
129
+ end
130
+
131
+ def diagonal!(val=1)
132
+ shp = self.shape
133
+ idx = NArray.int(shp[0..1].min).indgen! * (shp[0]+1)
134
+ ref = reshape(shp[0]*shp[1],true)
135
+ if val.kind_of?(Numeric)
136
+ ref[idx,true] = val
137
+ else
138
+ val = NArray.to_na(val)
139
+ raise ArgumentError, "must be 1-d array" if val.dim!=1
140
+ ref[idx,true] = val.newdim!(-1)
141
+ end
142
+ self
143
+ end
144
+
145
+ def diagonal(val)
146
+ self.dup.diagonal!(val)
147
+ end
148
+
149
+ def unit
150
+ diagonal!
151
+ end
152
+ alias identity unit
153
+ alias I unit
154
+
155
+ end # class NMatrix
156
+
157
+
158
+ #
159
+ # ------ NVector ------
160
+ #
161
+ class NVector < NArray
162
+ CLASS_DIMENSION = 1
163
+
164
+ def +(other)
165
+ case other
166
+ when NVector
167
+ return super(NArray.refer(other))
168
+ when NArray
169
+ unless other.instance_of?(NArray)
170
+ return other.coerce_rev( self, :+ )
171
+ end
172
+ end
173
+ raise TypeError,"Illegal operation: NVector + %s" % other.class
174
+ end
175
+
176
+ def -(other)
177
+ case other
178
+ when NVector
179
+ return super(NArray.refer(other))
180
+ when NArray
181
+ unless other.instance_of?(NArray)
182
+ return other.coerce_rev( self, :- )
183
+ end
184
+ end
185
+ raise TypeError,"Illegal operation: NVector - %s" % other.class
186
+ end
187
+
188
+ def *(other)
189
+ case other
190
+ when NMatrix
191
+ NVector.mul_add( NArray.refer(self).newdim!(0), other, 1 )
192
+ when NVector
193
+ NArray.mul_add( NArray.refer(self), other, 0 ) # inner product
194
+ when NArray
195
+ if other.instance_of?(NArray)
196
+ NVector.mul( NArray.refer(self), other.newdim(0) )
197
+ else
198
+ other.coerce_rev( self, :* )
199
+ end
200
+ when Numeric
201
+ NVector.mul( NArray.refer(self), other )
202
+ else
203
+ raise TypeError,"Illegal operation: NVector * %s" % other.class
204
+ end
205
+ end
206
+
207
+ def /(other)
208
+ case other
209
+ when NMatrix
210
+ other.lu.solve(self)
211
+ when NVector
212
+ raise TypeError,"Illegal operation: NVector / %s" % other.class
213
+ when NArray
214
+ if other.instance_of?(NArray)
215
+ NVector.div( NArray.refer(self), other.newdim(0) )
216
+ else
217
+ other.coerce_rev( self, :/ )
218
+ end
219
+ when Numeric
220
+ NVector.div( NArray.refer(self), other )
221
+ else
222
+ raise TypeError,"Illegal operation: NVector / %s" % other.class
223
+ end
224
+ end
225
+
226
+ def **(n)
227
+ if n==2
228
+ self*self
229
+ else
230
+ raise ArgumentError,"Only v**2 is implemented"
231
+ end
232
+ end
233
+
234
+ def coerce_rev(other,id)
235
+ case id
236
+ when :*
237
+ if other.instance_of?(NArray)
238
+ return NVector.mul( other.newdim(0), self )
239
+ end
240
+ if other.instance_of?(NArrayScalar)
241
+ return NVector.mul( other, self )
242
+ end
243
+ end
244
+ raise TypeError,"Illegal operation: %s %s NVector" %
245
+ [other.class, id.id2name]
246
+ end
247
+
248
+ end # class NVector