narray-nmatrix 0.6.1.0.pre

Sign up to get free protection for your applications and to get access to all the features.
data/SPEC.ja ADDED
@@ -0,0 +1,307 @@
1
+
2
+ Ruby/NArray ver 0.6.0.7 (2013-02-01) by Masahiro TANAKA
3
+
4
+
5
+ クラスメソッド:
6
+ NArray.new(typecode, size, ...) 配列を生成する。要素は0で初期化。
7
+
8
+ NArray.byte(size,...) 1 byte unsigned integer
9
+ NArray.sint(size,...) 2 byte signed integer
10
+ NArray.int(size,...) 4 byte signed integer
11
+ NArray.sfloat(size,...) single precision float
12
+ NArray.float(size,...) double precision float
13
+ NArray.scomplex(size,...) single precision complex
14
+ NArray.complex(size,...) double precision complex
15
+ NArray.object(size,...) Ruby object
16
+ 以上要素は0またはnilで初期化。
17
+
18
+ NArray.to_na(array) NArrayに変換
19
+ NArray.to_na(string,type[,size,..])
20
+ NArray[...]
21
+ NArray[1,5,10.0] #=> NArray.float(3):[1.0, 5.0, 10.0]
22
+ NArray[1..10] #=> NArray.int(10):[1,2,3,4,5,6,7,8,9,10]
23
+
24
+
25
+ クラス変数:
26
+ CLASS_DIMENSION データとして扱われる次元。
27
+ NArrayは0。NVectorは1。NMatrixは2。
28
+
29
+ 配列情報参照
30
+ self.dim 次元(インデックスの数)を返す。
31
+ self.rank 次元(インデックスの数)を返す。
32
+ self.shape 次元ごとのサイズを返す。
33
+ self.total 全要素数を返す。
34
+
35
+ インデックス参照
36
+ self[ dim0, dim1, ... ]
37
+
38
+ -- インデックス引数に指定できるもの: 数値、範囲、配列、true, false
39
+ -- インデックスの順序: FORTRAN 型
40
+ -- 添字引数が1つの場合、多次元配列はflattenされた1次元配列とみなされる。
41
+ 例: a が 3x3 配列のとき、a[3] は a[0,1] の要素を指す。
42
+
43
+ a[ 1, 2, -1 ] 要素の取り出し。負数は最後から数える(-1が最後)
44
+ 要素指定の次元は縮約される。
45
+ a[ 0..3, 4..1 ] 範囲取り出し。範囲の最後が最初より前ならば逆順になる。
46
+ a[ [1,4,2] ] インデックス配列。要素が[a[1],a[4],a[2]]のNArrayが返る。
47
+ a[] a.dup と同じ。
48
+ a[ 0, true ] a[0, 0..-1] と同じ。
49
+ a[ 0, false ] aが3次元のとき、a[0,true,true] と同じ。
50
+ 省略された次元すべてにtrueを指定したのと同じ。
51
+ a[ mask ] マスキング. mask は長さが a と等しい byte 型
52
+ NArray. mask の各要素の値に応じて、a のそれぞ
53
+ れは落される(0の場合)か、保持される(0以外の場合)。
54
+ 例:
55
+ a=NArray.float(2,2).indgen!
56
+ p a[ a.lt 3 ]
57
+ --> [ 0.0, 1.0, 2.0 ]
58
+ (a.lt 3 は byte 型 NArray を返す)
59
+ (同じことは a[ (a.lt 3).where ] でも出来る)
60
+
61
+ -- self.slice(...) self[...] と同じだが、長さが1になった次元を落
62
+ さず(self[]は落す)、もとのランクを保つ。但し、
63
+ 1次元インデックス付けとマスキングは例外([]と同
64
+ じ)。
65
+
66
+ インデックス代入。-- 取出しとほぼ同じルール。
67
+
68
+ a[ 1, 2, 3 ] = 1
69
+ a[ 0..3, 1..4, 2..5 ] = 2
70
+ a[ [1,3,2,4], true ] = 3
71
+ a[] = 4 a.fill!(4) と同じ。
72
+
73
+ a[0..2] = b[1..5] --> 要素数が異なるのでエラー。
74
+ a[1,2] = b[0..2,1..3] [1,2]を始点として代入。
75
+ a[0..2,0..3] = b[0..2,1] 繰り返し代入。
76
+ ( a[0,0]=b[0,1],..,a[0,3]=b[0,1] )
77
+
78
+ 行・列の削除 -- インデックス取り出しの逆
79
+
80
+ self.delete_at(...) 引数はインデクス参照と同じ。
81
+ 参照: https://github.com/masa16/narray/issues/5
82
+
83
+ 値のセット。
84
+ self.indgen!([start[,step]]) startからstepづつ増加した値をセット。
85
+ self.fill!(value) すべての要素にvalueをセット。
86
+ self.random!(max) 0<=x<max の一様なランダム値を生成。
87
+ using MT19337
88
+ self.randomn 平均0、分散1の正規分布のランダム値を生成。
89
+ (Box-Muller)
90
+ NArray.srand([seed]) 乱数のシードを設定。
91
+ 省略時は時刻から自動生成。
92
+
93
+ 演算: 要素ごとにおこなう。
94
+ a = NArray.float(3,3).indgen
95
+ b = NArray.float(3,3).fill(10)
96
+ c = a*b # --> NArray.float(3,3)
97
+
98
+ a = NArray.float(3,1).indgen
99
+ b = NArray.float(1,3).fill(10)
100
+ c = a*b # --> NArray.float(3,3) -- size=1の次元は拡張する。
101
+
102
+ 算術演算子
103
+ -self
104
+ self + other
105
+ self - other
106
+ self * other
107
+ self / other
108
+ self % other
109
+ self ** other
110
+ self.abs
111
+
112
+ self.add! other
113
+ self.sbt! other
114
+ self.mul! other
115
+ self.div! other
116
+ self.mod! other
117
+
118
+ self.mul_add(other,dim,...) (self * other).sum(dim,...)とほぼ同じ。
119
+ ただし途中で配列を作らない。
120
+
121
+ ビット演算子(整数のみ可能)
122
+ ~self
123
+ self & other
124
+ self | other
125
+ self ^ other
126
+
127
+ 比較
128
+ -- 要素ごとに値を比較し、結果をBYTE型 NArrayを返す。
129
+ true/falseでないことに注意。
130
+ self.eq other ( == とは異なることに注意)
131
+ self.ne other
132
+ self.gt other
133
+ self > other
134
+ self.ge other
135
+ self >= other
136
+ self.lt other
137
+ self < other
138
+ self.le other
139
+ self <= other
140
+
141
+ self.and other 要素ごとの条件比較。
142
+ self.or other
143
+ self.xor other
144
+ self.not other
145
+
146
+ self.all? 要素がすべて真ならば真。
147
+ self.any? 要素のどれかが真ならば真。
148
+ self.none? 要素のどれかが真ならば真。
149
+ self.where 要素が真のインデックス配列を返す。
150
+ self.where2 要素が真と偽のインデックス配列を含む(Ruby)配列を返す。
151
+
152
+ 例: idx_t,idx_f = (a>12).where2
153
+
154
+ 同値性
155
+ NArray[1] == NArray[1] #=> true
156
+ NArray[1] == NArray[1.0] #=> true
157
+ NArray[1].eql? NArray[1] #=> true
158
+ NArray[1].eql? NArray[1.0] #=> false
159
+ NArray[1].equal? NArray[1] #=> false
160
+ a=b=NArray[1]; a.equal? b #=> true
161
+
162
+ 統計
163
+ self.sum(dim,..) 指定した次元の和
164
+ self.cumsum 累積和(1次元配列のみ)
165
+ self.prod(dim,..) 指定した次元の積
166
+ self.cumprod 累積積(1次元配列のみ)
167
+ self.mean(dim,..) 指定した次元の平均。
168
+ self.stddev(dim,..) 指定した次元の標準偏差(標本標準偏差)。
169
+ self.rms(dim,..) 指定した次元のroot mean square。
170
+ self.rmsdev(dim,..) 指定した次元のroot mean square deviation。
171
+ self.min(dim,..) 指定した次元の最小。
172
+ self.max(dim,..) 指定した次元の最大。
173
+ (省略時は全ての次元。Range指定可。)
174
+ self.median(dim) 0..dimの次元の中央値。省略時はすべての次元。
175
+
176
+ ソート
177
+ self.sort(dim) 0..dimの次元でソート。省略時はすべての次元。
178
+ self.sort_index(dim) ソートしたインデックスを返す。
179
+ self[self.sort_index] は self.sort と同等。
180
+
181
+ 転置
182
+ self.transpose( dim0, dim1, .. )
183
+ 配列の転置。selfの第(dim0)次元が新しい配列の第0次元になる。
184
+ 負数は後からの順番。
185
+ transpose(-1,1..-2,0) で最初と最後を入れ換え。
186
+
187
+ インデックスの変更 (要素数は不変)
188
+ self.reshape!(size,...)
189
+ self.shape= size,...
190
+ self.newdim!(dim,...) 指定位置にサイズ1の次元を挿入する。
191
+
192
+ データの参照
193
+ self.refer selfのデータを参照する別のオブジェクトを作成。
194
+ self.reshape(size,...) self.refer.reshape! と同様。
195
+ self.newdim(dim,...) self.refer.newdim! と同様。
196
+
197
+ 反転・回転
198
+ self.reverse([dim,...]) 指定した次元を逆順にする
199
+ self.rot90([k]) 2次元配列の90度の回転をk回行う
200
+
201
+ 型変換
202
+ self.floor selfより小さい最大の整数を返す。
203
+ self.ceil selfより大きい最小の整数を返す。
204
+ self.round selfにもっとも近い整数を返す。
205
+ self.to_f 値を浮動小数点数に変換する。
206
+ self.to_i 値を整数に変換する。
207
+ self.to_a 値をRubyの配列に変換する。
208
+ self.to_s バイナリデータをそのままRubyの文字列データに変換する。
209
+ self.to_string 各要素を文字列に変換する。
210
+
211
+ イテレータ
212
+ self.each {|i| ...}
213
+ self.collect {|i| ...}
214
+ self.collect! {|i| ...}
215
+
216
+ バイトスワップ
217
+ self.swap_byte バイトスワップ
218
+ self.hton ネットワークバイトオーダーに変換
219
+ self.ntoh
220
+ self.htov VAXバイトオーダーに変換
221
+ self.vtoh
222
+
223
+ Boolean / マスク関係
224
+ self.count_false 値 == 0 の要素数 (byte型のみ)
225
+ self.count_true 値 == 1 の要素数 (byte型のみ)
226
+ self.mask( mask ) self[ mask ] と同じだかマスキング専用.
227
+ [] と違い int, sint のマスクも使える.
228
+
229
+ 複素数
230
+ self.real
231
+ self.imag
232
+ self.conj
233
+ self.conj!
234
+ self.angle atan2(self.imag, self.real)
235
+ self.imag= other 虚数部分にotherをセット。
236
+ self.im 虚数倍。
237
+
238
+ NMath モジュール
239
+ sqrt(x)
240
+ exp(x)
241
+ log(x)
242
+ log10(x)
243
+ log2(x)
244
+ atan2(x,y)
245
+ sin,cos,tan
246
+ sinh,cosh,tanh
247
+ asin,acos,atan
248
+ asinh,acosh,atanh
249
+ csc,sec,cot
250
+ csch,sech,coth
251
+ acsc,asec,acot
252
+ acsch,asech,acoth
253
+ covariance
254
+
255
+
256
+ FFTW モジュール (fftw-2.1.3をshared libでコンパイルしたもので確認)
257
+ (別モジュール)
258
+ fftw(x,[1|-1])
259
+ convol(a,b) FFTWを用いた畳み込み。
260
+
261
+
262
+ NMatrix
263
+
264
+ NArrayのサブクラス。最初の2次元をMatrixとして用いる。
265
+ 残りの次元は多次元配列として扱われる。
266
+ 次元の順序は、数学での表記とは逆: a_ij => a[j,i]
267
+
268
+ メソッド:
269
+ +,- 相手が NMatrix のときに演算可。
270
+ * 相手が NMatrix または NVector のときは Matrix積。
271
+ 相手が Numeric または NArray のときは Scalar積。
272
+ 例: NMatrix[[1,2],[3,4]] * [1,10]
273
+ == NMatrix[ [[1,2],[3,4]], [[10,20],[30,40]] ]
274
+ / 相手が Numeric または NArray のときはScalar除算。
275
+ 相手が square NMatrix のときはLUにより線形方程式を解く。
276
+ a/b == b.lu.solve(a)
277
+
278
+ transpose 引数を省略した場合は、最初のMatrix次元を交換。
279
+ diagonal(other)
280
+ diagonal!(other) 対角要素に値をセット。引数省略時は1をセット。
281
+ I 対角要素に値に1をセット。
282
+ inverse 逆行列
283
+ lu LU分解を計算。NMatrixLU クラスのインスタンスを返す。
284
+
285
+
286
+ NVector
287
+
288
+ NArrayのサブクラス。最初の1次元をVectorとして用いる。
289
+ 残りの次元は多次元配列として扱われる。
290
+
291
+ メソッド:
292
+ +,- 相手が NVector のときに演算可。
293
+ * 相手が NMatrix のときは Matrix積。
294
+ 相手が NVector のときは 内積。
295
+ 相手が Numeric または NArray のときは Scalar積。
296
+ / 相手が Numeric または NArray のときは Scalar除算。
297
+ 相手が square NMatrix のときはLUにより線形方程式を解く。
298
+ v/m == m.lu.solve(v)
299
+
300
+ NMatrixLU
301
+
302
+ NMatrix#lu メソッドにより作られる。
303
+ LU (NMatrix) と pivot (NVector) を含む。
304
+
305
+ メソッド:
306
+ solve(other) LU分解の結果を使って other を解く。
307
+ other は NMatrix または NVector のインスタンス。
data/depend ADDED
@@ -0,0 +1,14 @@
1
+ na_op.c: mknafunc.rb mkop.rb
2
+ $(RUBY) -I$(srcdir) $(srcdir)/mkop.rb
3
+
4
+ na_op.o: na_op.c narray.h $(hdrdir)/ruby.h
5
+
6
+
7
+ na_math.c: mknafunc.rb mkmath.rb
8
+ $(RUBY) -I$(srcdir) $(srcdir)/mkmath.rb
9
+
10
+ na_math.o: na_math.c narray.h $(hdrdir)/ruby.h
11
+
12
+
13
+ cleanall: clean
14
+ @$(RM) -r Makefile narray_config.h na_op.c na_math.c src pkg
@@ -0,0 +1,100 @@
1
+ require "mkmf"
2
+
3
+ def have_type(type, header=nil)
4
+ printf "checking for %s... ", type
5
+ STDOUT.flush
6
+ src = <<"SRC"
7
+ #include <ruby.h>
8
+ SRC
9
+ unless header.nil?
10
+ src << <<"SRC"
11
+ #include <#{header}>
12
+ SRC
13
+ end
14
+ r = try_link(src + <<"SRC")
15
+ int main() { return 0; }
16
+ int t() { #{type} a; return 0; }
17
+ SRC
18
+ unless r
19
+ print "no\n"
20
+ return false
21
+ end
22
+ $defs.push(format("-DHAVE_%s", type.upcase))
23
+ print "yes\n"
24
+ return true
25
+ end
26
+
27
+ def create_conf_h(file)
28
+ print "creating #{file}\n"
29
+ hfile = open(file, "w")
30
+ for line in $defs
31
+ line =~ /^-D(.*)/
32
+ hfile.printf "#define %s 1\n", $1
33
+ end
34
+ hfile.close
35
+ end
36
+
37
+ if RUBY_VERSION < '1.8'
38
+ alias __install_rb :install_rb
39
+ def install_rb(mfile, dest, srcdir = nil)
40
+ __install_rb(mfile, dest, srcdir)
41
+ archdir = dest.sub(/sitelibdir/,"sitearchdir").sub(/rubylibdir/,"archdir")
42
+ path = ['$(srcdir)/narray.h','narray_config.h']
43
+ path << ['libnarray.a'] if /cygwin|mingw/ =~ RUBY_PLATFORM
44
+ for f in path
45
+ mfile.printf "\t@$(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0644, true)' %s %s\n", f, archdir
46
+ end
47
+ end
48
+ else
49
+ $INSTALLFILES = [['narray.h', '$(archdir)'], ['narray_config.h', '$(archdir)']]
50
+ if /cygwin|mingw/ =~ RUBY_PLATFORM
51
+ $INSTALLFILES << ['libnarray.a', '$(archdir)']
52
+ end
53
+ end
54
+
55
+ if /cygwin|mingw/ =~ RUBY_PLATFORM
56
+ if RUBY_VERSION >= '1.9.0'
57
+ $DLDFLAGS << " -Wl,--export-all,--out-implib=libnarray.a"
58
+ elsif RUBY_VERSION > '1.8.0'
59
+ $DLDFLAGS << ",--out-implib=libnarray.a"
60
+ elsif RUBY_VERSION > '1.8'
61
+ CONFIG["DLDFLAGS"] << ",--out-implib=libnarray.a"
62
+ system("touch libnarray.a")
63
+ else
64
+ CONFIG["DLDFLAGS"] << " --output-lib libnarray.a"
65
+ end
66
+ end
67
+
68
+ #$DEBUG = true
69
+ #$CFLAGS = ["-Wall",$CFLAGS].join(" ")
70
+
71
+ srcs = %w(
72
+ narray
73
+ na_array
74
+ na_func
75
+ na_index
76
+ na_random
77
+ na_op
78
+ na_math
79
+ na_linalg
80
+ )
81
+
82
+ header = "stdint.h"
83
+ unless have_header(header)
84
+ header = "sys/types.h"
85
+ unless have_header(header)
86
+ header = nil
87
+ end
88
+ end
89
+
90
+ have_type("u_int8_t", header)
91
+ have_type("uint8_t", header)
92
+ have_type("int16_t", header)
93
+ have_type("int32_t", header)
94
+ have_type("u_int32_t", header)
95
+ have_type("uint32_t", header)
96
+
97
+ $objs = srcs.collect{|i| i+".o"}
98
+
99
+ create_conf_h("narray_config.h")
100
+ create_makefile("narray")
@@ -0,0 +1,18 @@
1
+ # This file exists for backwards compatibility with earlier versions of NArray
2
+ # that defined all of its classes and modules in the top level namespace rather
3
+ # than just the NArray class at the top level and all other related classes and
4
+ # modules nested within the NArray class.
5
+ #
6
+ # After requiring the 'narray/narray' package to load the top level NArray class
7
+ # and the nested classes and modules it contains, top level aliases are created
8
+ # for the nested classes to provide backwards compatibility.
9
+
10
+ require 'narray/narray'
11
+
12
+ # Create top level aliases
13
+
14
+ NMath = NArray::NMath
15
+ NVector = NArray::NVector
16
+ NMatrix = NArray::NMatrix
17
+ NMatrixLU = NArray::NMatrixLU
18
+ NArrayScalar = NArray::NArrayScalar
@@ -0,0 +1,5 @@
1
+ # Require the NArray shared library that defines the top level "NA" module and
2
+ # all of its contents. Requiring "narray.so" will load the narray shared
3
+ # library even on systems that use an extension other than ".so" for shared
4
+ # libraries (e.g. ".bundle" or ".dylib" on Mac OS X or ".dll" on Windows).
5
+ require 'narray.so'
@@ -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
+
283
+ module NMath
284
+ PI = Math::PI
285
+ E = Math::E
286
+
287
+ def recip x
288
+ 1/x.to_f
289
+ end
290
+
291
+ # Trigonometric function
292
+ def csc x
293
+ 1/sin(x)
294
+ end
295
+ def csch x
296
+ 1/sinh(x)
297
+ end
298
+ def acsc x
299
+ asin(1/x.to_f)
300
+ end
301
+ def acsch x
302
+ asinh(1/x.to_f)
303
+ end
304
+
305
+ def sec x
306
+ 1/cos(x)
307
+ end
308
+ def sech x
309
+ 1/cosh(x)
310
+ end
311
+ def asec x
312
+ acos(1/x.to_f)
313
+ end
314
+ def asech x
315
+ acosh(1/x.to_f)
316
+ end
317
+
318
+ def cot x
319
+ 1/tan(x)
320
+ end
321
+ def coth x
322
+ 1/tanh(x)
323
+ end
324
+ def acot x
325
+ atan(1/x.to_f)
326
+ end
327
+ def acoth x
328
+ atanh(1/x.to_f)
329
+ end
330
+
331
+ # Statistics
332
+ def covariance(x,y,*ranks)
333
+ x = NArray.to_na(x) unless x.kind_of?(NArray)
334
+ x = x.to_type(NArray::DFLOAT) if x.integer?
335
+ y = NArray.to_na(y) unless y.kind_of?(NArray)
336
+ y = y.to_type(NArray::DFLOAT) if y.integer?
337
+ n = x.rank_total(*ranks)
338
+ xm = x.accum(*ranks).div!(n)
339
+ ym = y.accum(*ranks).div!(n)
340
+ ((x-xm)*(y-ym)).sum(*ranks) / (n-1)
341
+ end
342
+
343
+ module_function :recip
344
+ module_function :csc,:sec,:cot,:csch,:sech,:coth
345
+ module_function :acsc,:asec,:acot,:acsch,:asech,:acoth
346
+ module_function :covariance
347
+ end
348
+
349
+ end # class NArray
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'