narray-bigmem 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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