narray 0.5.9.4

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.
Files changed (81) hide show
  1. data/src/ChangeLog +614 -0
  2. data/src/MANIFEST +82 -0
  3. data/src/README.en +54 -0
  4. data/src/README.ja +63 -0
  5. data/src/SPEC.en +300 -0
  6. data/src/SPEC.ja +284 -0
  7. data/src/depend +14 -0
  8. data/src/extconf.rb +111 -0
  9. data/src/lib/narray_ext.rb +211 -0
  10. data/src/lib/nmatrix.rb +244 -0
  11. data/src/mkmath.rb +780 -0
  12. data/src/mknafunc.rb +190 -0
  13. data/src/mkop.rb +638 -0
  14. data/src/na_array.c +644 -0
  15. data/src/na_func.c +1624 -0
  16. data/src/na_index.c +988 -0
  17. data/src/na_linalg.c +616 -0
  18. data/src/na_random.c +409 -0
  19. data/src/narray.c +1308 -0
  20. data/src/narray.def +29 -0
  21. data/src/narray.h +170 -0
  22. data/src/narray_local.h +210 -0
  23. data/src/nimage/README.en +38 -0
  24. data/src/nimage/demo/fits.rb +97 -0
  25. data/src/nimage/demo/fits_convol.rb +28 -0
  26. data/src/nimage/demo/fits_fftdemo.rb +27 -0
  27. data/src/nimage/demo/fitsdemo1.rb +13 -0
  28. data/src/nimage/demo/fitsdemo2.rb +30 -0
  29. data/src/nimage/demo/fitsdemo3.rb +26 -0
  30. data/src/nimage/demo/fitsmorph.rb +39 -0
  31. data/src/nimage/demo/life_na.rb +57 -0
  32. data/src/nimage/demo/mandel.rb +41 -0
  33. data/src/nimage/extconf.rb +12 -0
  34. data/src/nimage/lib/nimage.rb +51 -0
  35. data/src/nimage/nimage.c +328 -0
  36. data/src/speed/add.py +12 -0
  37. data/src/speed/add.rb +8 -0
  38. data/src/speed/add_int.py +12 -0
  39. data/src/speed/add_int.rb +9 -0
  40. data/src/speed/lu.m +14 -0
  41. data/src/speed/lu.rb +22 -0
  42. data/src/speed/mat.m +23 -0
  43. data/src/speed/mat.rb +28 -0
  44. data/src/speed/mul.py +12 -0
  45. data/src/speed/mul.rb +9 -0
  46. data/src/speed/mul2.py +15 -0
  47. data/src/speed/mul2.rb +13 -0
  48. data/src/speed/mul_comp.py +12 -0
  49. data/src/speed/mul_comp.rb +9 -0
  50. data/src/speed/mul_int.py +12 -0
  51. data/src/speed/mul_int.rb +9 -0
  52. data/src/speed/mybench.py +15 -0
  53. data/src/speed/mybench.rb +31 -0
  54. data/src/speed/solve.m +18 -0
  55. data/src/speed/solve.py +16 -0
  56. data/src/speed/solve.rb +21 -0
  57. data/src/test/statistics.rb +22 -0
  58. data/src/test/testarray.rb +20 -0
  59. data/src/test/testbit.rb +27 -0
  60. data/src/test/testcast.rb +14 -0
  61. data/src/test/testcomplex.rb +35 -0
  62. data/src/test/testfftw.rb +16 -0
  63. data/src/test/testindex.rb +11 -0
  64. data/src/test/testindexary.rb +26 -0
  65. data/src/test/testindexset.rb +55 -0
  66. data/src/test/testmask.rb +40 -0
  67. data/src/test/testmath.rb +48 -0
  68. data/src/test/testmath2.rb +46 -0
  69. data/src/test/testmatrix.rb +13 -0
  70. data/src/test/testmatrix2.rb +33 -0
  71. data/src/test/testmatrix3.rb +19 -0
  72. data/src/test/testminmax.rb +46 -0
  73. data/src/test/testobject.rb +29 -0
  74. data/src/test/testpow.rb +19 -0
  75. data/src/test/testrandom.rb +23 -0
  76. data/src/test/testround.rb +11 -0
  77. data/src/test/testsort.rb +37 -0
  78. data/src/test/teststr.rb +13 -0
  79. data/src/test/testtrans.rb +18 -0
  80. data/src/test/testwhere.rb +27 -0
  81. metadata +127 -0
data/src/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) na_op.c na_math.c
data/src/extconf.rb ADDED
@@ -0,0 +1,111 @@
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.8.0'
57
+ $DLDFLAGS << ",--out-implib=libnarray.a"
58
+ elsif RUBY_VERSION > '1.8'
59
+ CONFIG["DLDFLAGS"] << ",--out-implib=libnarray.a"
60
+ system("touch libnarray.a")
61
+ else
62
+ CONFIG["DLDFLAGS"] << " --output-lib libnarray.a"
63
+ end
64
+ end
65
+
66
+ #$DEBUG = true
67
+ #$CFLAGS = ["-Wall",$CFLAGS].join(" ")
68
+
69
+ # configure options:
70
+ # --with-fftw-dir=path
71
+ # --with-fftw-include=path
72
+ # --with-fftw-lib=path
73
+ #dir_config("fftw")
74
+
75
+ srcs = %w(
76
+ narray
77
+ na_array
78
+ na_func
79
+ na_index
80
+ na_random
81
+ na_op
82
+ na_math
83
+ na_linalg
84
+ )
85
+
86
+ if have_header("sys/types.h")
87
+ header = "sys/types.h"
88
+ else
89
+ header = nil
90
+ end
91
+
92
+ have_type("u_int8_t", header)
93
+ have_type("int16_t", header)
94
+ have_type("int32_t", header)
95
+ have_type("u_int32_t", header)
96
+ #have_library("m")
97
+ #have_func("sincos")
98
+ #have_func("asinh")
99
+
100
+ #if have_header("fftw.h")
101
+ # if have_library("fftw", "fftwnd_create_plan")
102
+ # srcs.push "na_fftw"
103
+ # else
104
+ # $defs.delete "-DHAVE_FFTW_H"
105
+ # end
106
+ #end
107
+
108
+ $objs = srcs.collect{|i| i+".o"}
109
+
110
+ create_conf_h("narray_config.h")
111
+ create_makefile("narray")
@@ -0,0 +1,211 @@
1
+ # Numerical Array Extention for Ruby
2
+ # (C) Copyright 2000-2003 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 integer?
12
+ self.typecode==NArray::BYTE ||
13
+ self.typecode==NArray::SINT ||
14
+ self.typecode==NArray::LINT
15
+ end
16
+ def complex?
17
+ self.typecode==NArray::DCOMPLEX ||
18
+ self.typecode==NArray::SCOMPLEX
19
+ end
20
+
21
+ def all?
22
+ where.size == size
23
+ end
24
+
25
+ def any?
26
+ where.size > 0
27
+ end
28
+
29
+ def none?
30
+ where.size == 0
31
+ end
32
+
33
+ def ==(other)
34
+ if other.kind_of?(NArray)
35
+ (shape == other.shape) && eq(other).all?
36
+ else
37
+ false
38
+ end
39
+ end
40
+
41
+ def rank_total(*ranks)
42
+ if ranks.size>0
43
+ idx = []
44
+ ranks.each{|i| idx.push(*i)}
45
+ # ranks is expected to be, e.g., [1, 3..5, 7]
46
+ a = self.shape
47
+ n = 1
48
+ idx.each{|i| n *= a[i]}
49
+ n
50
+ else
51
+ self.total
52
+ end
53
+ end
54
+
55
+ # Statistics
56
+ def mean(*ranks)
57
+ if integer?
58
+ a = self.to_f
59
+ else
60
+ a = self
61
+ end
62
+ a = NArray.ref(a)
63
+ a.sum(*ranks) / (rank_total(*ranks))
64
+ end
65
+
66
+ def stddev(*ranks)
67
+ if integer?
68
+ a = self.to_f
69
+ else
70
+ a = self
71
+ end
72
+ a = NArray.ref(a)
73
+ n = rank_total(*ranks)
74
+ NMath::sqrt( (( a-a.accum(*ranks).div!(n) )**2).sum(*ranks)/(n-1) )
75
+ end
76
+
77
+ def median(rank=nil)
78
+ shape = self.shape
79
+ rank = shape.size-1 if rank==nil
80
+ s = sort(rank).reshape!(true,*shape[rank+1..-1])
81
+ n = s.shape[0]
82
+ if n%2==1
83
+ s[n/2,false]
84
+ else
85
+ s[n/2-1..n/2,false].sum(0)/2
86
+ end
87
+ end
88
+
89
+
90
+ # Normal distributed random number; valid for floating point types
91
+ def randomn
92
+ size = self.size
93
+ case type = self.typecode
94
+ when COMPLEX; type=FLOAT
95
+ when SCOMPLEX; type=SFLOAT
96
+ when FLOAT
97
+ when SFLOAT
98
+ else
99
+ raise TypeError, "NArray type must be (S)FLOAT or (S)COMPLEX."
100
+ end
101
+ rr = NArray.new(type,size)
102
+ xx = NArray.new(type,size)
103
+ i = 0
104
+ while i < size
105
+ n = size-i
106
+ m = ((n+Math::sqrt(n))*1.27).to_i
107
+ x = NArray.new(type,m).random!(1) * 2 - 1
108
+ y = NArray.new(type,m).random!(1) * 2 - 1
109
+ r = x**2 + y**2
110
+ idx = (r<1).where
111
+ idx = idx[0...n] if idx.size > n
112
+ if idx.size>0
113
+ rr[i] = r[idx]
114
+ xx[i] = x[idx]
115
+ i += idx.size
116
+ end
117
+ end
118
+ # Box-Muller transform
119
+ rr = ( xx * NMath::sqrt( -2 * NMath::log(rr) / rr ) )
120
+ # finish
121
+ rr.reshape!(*self.shape) if self.rank > 1
122
+ rr = rr.to_type(self.typecode) if type!=self.typecode
123
+ if RUBY_VERSION < "1.8.0"
124
+ self.type.refer(rr)
125
+ else
126
+ self.class.refer(rr)
127
+ end
128
+ end
129
+ alias randomn! randomn
130
+
131
+ #SFloatOne = NArray.sfloat(1).fill!(1)
132
+ end
133
+
134
+
135
+ module NMath
136
+ PI = Math::PI
137
+ E = Math::E
138
+
139
+ def recip x
140
+ 1/x.to_f
141
+ end
142
+
143
+ # Trigonometric function
144
+ def csc x
145
+ 1/sin(x)
146
+ end
147
+ def csch x
148
+ 1/sinh(x)
149
+ end
150
+ def acsc x
151
+ asin(1/x.to_f)
152
+ end
153
+ def acsch x
154
+ asinh(1/x.to_f)
155
+ end
156
+
157
+ def sec x
158
+ 1/cos(x)
159
+ end
160
+ def sech x
161
+ 1/cosh(x)
162
+ end
163
+ def asec x
164
+ acos(1/x.to_f)
165
+ end
166
+ def asech x
167
+ acosh(1/x.to_f)
168
+ end
169
+
170
+ def cot x
171
+ 1/tan(x)
172
+ end
173
+ def coth x
174
+ 1/atanh(x)
175
+ end
176
+ def acot x
177
+ atan(1/x.to_f)
178
+ end
179
+ def acoth x
180
+ atanh(1/x.to_f)
181
+ end
182
+
183
+ # Statistics
184
+ def covariance(x,y,*ranks)
185
+ x = NArray.to_na(x) unless x.kind_of?(NArray)
186
+ x = x.to_f if x.integer?
187
+ y = NArray.to_na(y) unless y.kind_of?(NArray)
188
+ y = y.to_f if y.integer?
189
+ n = x.rank_total(*ranks)
190
+ xm = x.accum(*ranks).div!(n)
191
+ ym = y.accum(*ranks).div!(n)
192
+ ((x-xm)*(y-ym)).sum(*ranks) / (n-1)
193
+ end
194
+
195
+ module_function :csc,:sec,:cot,:csch,:sech,:coth
196
+ module_function :acsc,:asec,:acot,:acsch,:asech,:acoth
197
+ module_function :covariance
198
+ end
199
+
200
+
201
+ module FFTW
202
+ def convol(a1,a2)
203
+ n1x,n1y = a1.shape
204
+ n2x,n2y = a2.shape
205
+ raise "arrays must have same shape" if n1x!=n2x || n1y!=n2y
206
+ (FFTW.fftw( FFTW.fftw(a1,-1) * FFTW.fftw(a2,-1), 1).real) / (n1x*n1y)
207
+ end
208
+ module_function :convol
209
+ end
210
+
211
+ require 'nmatrix'
@@ -0,0 +1,244 @@
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, :+.to_i )
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, :-.to_i )
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, :*.to_i )
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, :/.to_i )
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 :*.to_i
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 :/.to_i
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
+ val = NArray.to_na(val)
136
+ raise ArgumentError, "must be 1-d array" if val.dim!=1
137
+ ref[idx,true] = val.newdim!(-1)
138
+ self
139
+ end
140
+
141
+ def diagonal(val)
142
+ self.dup.diagonal!(val)
143
+ end
144
+
145
+ def unit
146
+ diagonal!
147
+ end
148
+ alias identity unit
149
+ alias I unit
150
+
151
+ end # class NMatrix
152
+
153
+
154
+ #
155
+ # ------ NVector ------
156
+ #
157
+ class NVector < NArray
158
+ CLASS_DIMENSION = 1
159
+
160
+ def +(other)
161
+ case other
162
+ when NVector
163
+ return super(NArray.refer(other))
164
+ when NArray
165
+ unless other.instance_of?(NArray)
166
+ return other.coerce_rev( self, :+.to_i )
167
+ end
168
+ end
169
+ raise TypeError,"Illegal operation: NVector + %s" % other.class
170
+ end
171
+
172
+ def -(other)
173
+ case other
174
+ when NVector
175
+ return super(NArray.refer(other))
176
+ when NArray
177
+ unless other.instance_of?(NArray)
178
+ return other.coerce_rev( self, :-.to_i )
179
+ end
180
+ end
181
+ raise TypeError,"Illegal operation: NVector - %s" % other.class
182
+ end
183
+
184
+ def *(other)
185
+ case other
186
+ when NMatrix
187
+ NVector.mul_add( NArray.refer(self).newdim!(0), other, 1 )
188
+ when NVector
189
+ NArray.mul_add( NArray.refer(self), other, 0 ) # inner product
190
+ when NArray
191
+ if other.instance_of?(NArray)
192
+ NVector.mul( NArray.refer(self), other.newdim(0) )
193
+ else
194
+ other.coerce_rev( self, :*.to_i )
195
+ end
196
+ when Numeric
197
+ NVector.mul( NArray.refer(self), other )
198
+ else
199
+ raise TypeError,"Illegal operation: NVector * %s" % other.class
200
+ end
201
+ end
202
+
203
+ def /(other)
204
+ case other
205
+ when NMatrix
206
+ other.lu.solve(self)
207
+ when NVector
208
+ raise TypeError,"Illegal operation: NVector / %s" % other.class
209
+ when NArray
210
+ if other.instance_of?(NArray)
211
+ NVector.div( NArray.refer(self), other.newdim(0) )
212
+ else
213
+ other.coerce_rev( self, :/.to_i )
214
+ end
215
+ when Numeric
216
+ NVector.div( NArray.refer(self), other )
217
+ else
218
+ raise TypeError,"Illegal operation: NVector / %s" % other.class
219
+ end
220
+ end
221
+
222
+ def **(n)
223
+ if n==2
224
+ self*self
225
+ else
226
+ raise ArgumentError,"Only v**2 is implemented"
227
+ end
228
+ end
229
+
230
+ def coerce_rev(other,id)
231
+ case id
232
+ when :*.to_i
233
+ if other.instance_of?(NArray)
234
+ return NVector.mul( other.newdim(0), self )
235
+ end
236
+ if other.instance_of?(NArrayScalar)
237
+ return NVector.mul( other, self )
238
+ end
239
+ end
240
+ raise TypeError,"Illegal operation: %s %s NVector" %
241
+ [other.class, id.id2name]
242
+ end
243
+
244
+ end # class NVector