narray 0.5.9.9 → 0.6.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/src/ChangeLog CHANGED
@@ -1,3 +1,39 @@
1
+ 2011-08-27 Masahiro TANAKA <masa16.tanaka@gmail.com>
2
+
3
+ * narray.c (na_alloc_struct): check array size.
4
+ * extconf.rb (#install_rb): --export-all option for mingw.
5
+ * ver 0.6.0.0
6
+
7
+ 2011-02-04 Masahiro TANAKA <masa16.tanaka@gmail.com>
8
+
9
+ * na_func.c (na_prod, na_prod_body, na_cumprod, na_cumprod_bang):
10
+ New method.
11
+
12
+ 2010-01-04 David MacMahon <davidm at astro.berkeley...>
13
+
14
+ * mkop.rb, na_func.c, na_linalg.c, narray_local.h:
15
+ Add NArray#mod! method
16
+ Also adds NArray#mod as an alias for NArray#%.
17
+
18
+ 2010-01-04 David MacMahon <davidm at astro.berkeley...>
19
+
20
+ * mkop.rb: Fix divide-by-zero bug in % operator
21
+ Prior to this fix, the following would crash Ruby with a floating point
22
+ exception (at least on Mac OS X 10.6)...
23
+ 1 % NArray[0]
24
+ Now that code raises ZeroDivisionError which can be rescued.
25
+
26
+ 2010-01-04 David MacMahon <davidm at astro.berkeley...>
27
+
28
+ * Rakefile: Add Rakefile for easy gem creation
29
+ Just run "rake gem" to create the gem file in the pkg/ subdirectory.
30
+ Added .gitignore file to ignore pkg/ subdirectory.
31
+
32
+ 2011-01-04 sgwong
33
+
34
+ * extconf.rb: failure due to the change of
35
+ $DLDFLAGS in ruby1.9
36
+
1
37
  2010-12-14 Masahiro TANAKA <masa16.tanaka@gmail.com>
2
38
 
3
39
  * lib/nmatrix.rb (NMatrix#diagonal!):
data/src/README.en CHANGED
@@ -1,4 +1,4 @@
1
- Ruby/NArray ver 0.5.9 (2006-08-09) by Masahiro TANAKA
1
+ Ruby/NArray ver 0.6.0.0 (2011-08-27) by Masahiro TANAKA
2
2
 
3
3
  * NArray properties:
4
4
 
@@ -15,7 +15,7 @@
15
15
 
16
16
  * NArray is similar to:
17
17
 
18
- + Python/NumPy, Perl/PDL, Yorick, IDL
18
+ + Python/NumPy, Perl/PDL, Yorick, IDL
19
19
 
20
20
  * NArray is far from completed!
21
21
 
@@ -30,13 +30,12 @@
30
30
 
31
31
  ruby extconf.rb
32
32
  make
33
- make site-install
34
- (or, make install)
33
+ make install
35
34
 
36
35
  * Tested Platform
37
36
 
38
- ruby 1.8.4 (2005-12-24) [i686-linux]
39
- gcc version 4.1.1 20060525 (Red Hat 4.1.1-1)
37
+ ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux]
38
+ gcc version 4.5.1 20100924 (Red Hat 4.5.1-4) (GCC)
40
39
 
41
40
  * License
42
41
 
data/src/README.ja CHANGED
@@ -1,4 +1,4 @@
1
- Ruby/NArray ver 0.5.9 (2006-08-09) by Masahiro TANAKA
1
+ Ruby/NArray ver 0.6.0.0 (2011-08-27) by Masahiro TANAKA
2
2
 
3
3
  * Ruby/NArrayの特徴。
4
4
 
@@ -33,15 +33,14 @@
33
33
 
34
34
  ruby extconf.rb
35
35
  make
36
- make site-install
37
- (または make install)
36
+ make install
38
37
 
39
38
  と実行します。
40
39
 
41
40
  * 動作確認
42
41
 
43
- ruby 1.8.4 (2005-12-24) [i686-linux]
44
- gcc version 4.1.1 20060525 (Red Hat 4.1.1-1)
42
+ ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-linux]
43
+ gcc version 4.5.1 20100924 (Red Hat 4.5.1-4) (GCC)
45
44
 
46
45
  * 配布条件
47
46
 
data/src/SPEC.en CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- Ruby/NArray ver 0.5.9p8 (2010-12-06) by Masahiro TANAKA
2
+ Ruby/NArray ver 0.6.0.0 (2011-08-27) by Masahiro TANAKA
3
3
 
4
4
 
5
5
  Class method:
@@ -56,7 +56,7 @@ Slicing Array
56
56
  value of each element of mask, the corresponding
57
57
  element in "a" is eliminated (when 0) or
58
58
  retained (when not 0).
59
- Example:
59
+ Example:
60
60
  a=NArray.float(2,2).indgen!
61
61
  p a[ a.lt 3 ]
62
62
  --> [ 0.0, 1.0, 2.0 ]
@@ -68,8 +68,8 @@ Slicing Array
68
68
  e.g.: a[3] is same as a[0,1] if a is 3x3 array.
69
69
 
70
70
  - self.slice(...) Same as self[...] but keeps the rank of
71
- original array by not elimiting dimensions
72
- whose length became equal to 1 (which self[]
71
+ original array by not elimiting dimensions
72
+ whose length became equal to 1 (which self[]
73
73
  does). This is not the case with the
74
74
  1-dimensional indexing and masking (same as []).
75
75
 
@@ -79,7 +79,7 @@ Replacing Elements -- Same rule as slicing
79
79
  a[ 0..3, 1..4, 2..5 ] = 2
80
80
  a[ [1,3,2,4], true ] = 3
81
81
  a[] = 4 Same as a.fill!(4)
82
-
82
+
83
83
  a[0..2] = b[1..5] --> Error! due to different num of elements.
84
84
  a[1,2] = b[0..2,1..3] Storing elements from index [1,2]
85
85
  ( a[1,2]=b[0,1],a[2,2]=b[1,1],... )
@@ -138,9 +138,9 @@ Comparison
138
138
  self.ge other
139
139
  self >= other
140
140
  self.lt other
141
- self < other
141
+ self < other
142
142
  self.le other
143
- self <= other
143
+ self <= other
144
144
 
145
145
  self.and other element-wise condition.
146
146
  self.or other
@@ -158,6 +158,9 @@ Comparison
158
158
 
159
159
  Statistics
160
160
  self.sum(dim,..) Summation
161
+ self.cumsum Cumulative Summation (for 1-d array)
162
+ self.prod(dim,..) Product (Multiply elements)
163
+ self.cumprod Cumulative Produce (for 1-d array)
161
164
  self.mean(dim,..) Mean
162
165
  self.stddev(dim,..) Standard deviation
163
166
  self.rms(dim,..) Root mean square
@@ -212,9 +215,9 @@ Iteration
212
215
  Byte swap
213
216
  self.swap_byte swap byte order
214
217
  self.hton convert to network byte order
215
- self.ntoh
218
+ self.ntoh
216
219
  self.htov convert to VAX byte order
217
- self.vtoh
220
+ self.vtoh
218
221
 
219
222
  Boolean / mask related
220
223
  self.count_false count # of elements whose value == 0 (only for
data/src/SPEC.ja CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- Ruby/NArray ver 0.5.9p8 (2010-12-06) by Masahiro TANAKA
2
+ Ruby/NArray ver 0.6.0.0 (2011-08-27) by Masahiro TANAKA
3
3
 
4
4
 
5
5
  クラスメソッド:
@@ -48,10 +48,10 @@
48
48
  a[ 0, true ] a[0, 0..-1] と同じ。
49
49
  a[ 0, false ] aが3次元のとき、a[0,true,true] と同じ。
50
50
  省略された次元すべてにtrueを指定したのと同じ。
51
- a[ mask ] マスキング. mask は長さが a と等しい byte 型
51
+ a[ mask ] マスキング. mask は長さが a と等しい byte 型
52
52
  NArray. mask の各要素の値に応じて、a のそれぞ
53
53
  れは落される(0の場合)か、保持される(0以外の場合)。
54
- 例:
54
+ 例:
55
55
  a=NArray.float(2,2).indgen!
56
56
  p a[ a.lt 3 ]
57
57
  --> [ 0.0, 1.0, 2.0 ]
@@ -69,7 +69,7 @@
69
69
  a[ 0..3, 1..4, 2..5 ] = 2
70
70
  a[ [1,3,2,4], true ] = 3
71
71
  a[] = 4 a.fill!(4) と同じ。
72
-
72
+
73
73
  a[0..2] = b[1..5] --> 要素数が異なるのでエラー。
74
74
  a[1,2] = b[0..2,1..3] [1,2]を始点として代入。
75
75
  a[0..2,0..3] = b[0..2,1] 繰り返し代入。
@@ -129,7 +129,7 @@
129
129
  self.ge other
130
130
  self >= other
131
131
  self.lt other
132
- self < other
132
+ self < other
133
133
  self.le other
134
134
  self <= other
135
135
 
@@ -147,7 +147,10 @@
147
147
  例: idx_t,idx_f = (a>12).where2
148
148
 
149
149
  統計
150
- self.sum(dim,..) 指定した次元の和。
150
+ self.sum(dim,..) 指定した次元の和
151
+ self.cumsum 累積和(1次元配列のみ)
152
+ self.prod(dim,..) 指定した次元の積
153
+ self.cumprod 累積積(1次元配列のみ)
151
154
  self.mean(dim,..) 指定した次元の平均。
152
155
  self.stddev(dim,..) 指定した次元の標準偏差(標本標準偏差)。
153
156
  self.rms(dim,..) 指定した次元のroot mean square。
@@ -183,7 +186,7 @@
183
186
  self.ceil selfより大きい最小の整数を返す。
184
187
  self.round selfにもっとも近い整数を返す。
185
188
  self.to_f 値を浮動小数点数に変換する。
186
- self.to_i 値を整数に変換する。
189
+ self.to_i 値を整数に変換する。
187
190
  self.to_a 値をRubyの配列に変換する。
188
191
  self.to_s バイナリデータをそのままRubyの文字列データに変換する。
189
192
  self.to_string 各要素を文字列に変換する。
@@ -196,9 +199,9 @@
196
199
  バイトスワップ
197
200
  self.swap_byte バイトスワップ
198
201
  self.hton ネットワークバイトオーダーに変換
199
- self.ntoh
202
+ self.ntoh
200
203
  self.htov VAXバイトオーダーに変換
201
- self.vtoh
204
+ self.vtoh
202
205
 
203
206
  Boolean / マスク関係
204
207
  self.count_false 値 == 0 の要素数 (byte型のみ)
data/src/depend CHANGED
@@ -11,4 +11,4 @@ na_math.o: na_math.c narray.h $(hdrdir)/ruby.h
11
11
 
12
12
 
13
13
  cleanall: clean
14
- @$(RM) na_op.c na_math.c
14
+ @$(RM) -r na_op.c na_math.c src pkg
data/src/extconf.rb CHANGED
@@ -46,14 +46,16 @@ if RUBY_VERSION < '1.8'
46
46
  end
47
47
  end
48
48
  else
49
- $INSTALLFILES = [['narray.h', '$(archdir)'], ['narray_config.h', '$(archdir)']]
49
+ $INSTALLFILES = [['narray.h', '$(archdir)'], ['narray_config.h', '$(archdir)']]
50
50
  if /cygwin|mingw/ =~ RUBY_PLATFORM
51
51
  $INSTALLFILES << ['libnarray.a', '$(archdir)']
52
52
  end
53
53
  end
54
54
 
55
55
  if /cygwin|mingw/ =~ RUBY_PLATFORM
56
- if RUBY_VERSION > '1.8.0'
56
+ if RUBY_VERSION >= '1.9.0'
57
+ $DLDFLAGS << " -Wl,--export-all,--out-implib=libnarray.a"
58
+ elsif RUBY_VERSION > '1.8.0'
57
59
  $DLDFLAGS << ",--out-implib=libnarray.a"
58
60
  elsif RUBY_VERSION > '1.8'
59
61
  CONFIG["DLDFLAGS"] << ",--out-implib=libnarray.a"
@@ -66,12 +68,6 @@ end
66
68
  #$DEBUG = true
67
69
  #$CFLAGS = ["-Wall",$CFLAGS].join(" ")
68
70
 
69
- # configure options:
70
- # --with-fftw-dir=path
71
- # --with-fftw-include=path
72
- # --with-fftw-lib=path
73
- #dir_config("fftw")
74
-
75
71
  srcs = %w(
76
72
  narray
77
73
  na_array
@@ -97,17 +93,6 @@ have_type("int16_t", header)
97
93
  have_type("int32_t", header)
98
94
  have_type("u_int32_t", header)
99
95
  have_type("uint32_t", header)
100
- #have_library("m")
101
- #have_func("sincos")
102
- #have_func("asinh")
103
-
104
- #if have_header("fftw.h")
105
- # if have_library("fftw", "fftwnd_create_plan")
106
- # srcs.push "na_fftw"
107
- # else
108
- # $defs.delete "-DHAVE_FFTW_H"
109
- # end
110
- #end
111
96
 
112
97
  $objs = srcs.collect{|i| i+".o"}
113
98
 
@@ -52,6 +52,47 @@ class NArray
52
52
  end
53
53
  end
54
54
 
55
+ # delete rows/columns
56
+ def delete_at(*args)
57
+ if args.size > self.rank
58
+ raise ArgumentError, "too many arguments"
59
+ end
60
+ shp = self.shape
61
+ ind = []
62
+ self.rank.times do |i|
63
+ n = shp[i]
64
+ case a=args[i]
65
+ when Integer
66
+ a = n+a if a<0
67
+ raise IndexError, "index(%d) out of range"%[a] if a<0
68
+ x = [0...a,a+1...n]
69
+ when Range
70
+ b = a.first
71
+ b = n+b if b<0
72
+ raise IndexError, "index(%s) out of range"%[a] if b<0
73
+ e = a.last
74
+ e = n+e if e<0
75
+ e -= 1 if a.exclude_end?
76
+ raise IndexError, "index(%s) out of range"%[a] if e<0
77
+ x = [0...b,e+1...n]
78
+ when Array
79
+ x = (0...n).to_a
80
+ x -= a.map do |j|
81
+ raise IndexError, "contains non-integer" unless Interger===j
82
+ (j<0) ? n+j : j
83
+ end
84
+ else
85
+ if a
86
+ raise ArgumentError, "invalid argument"
87
+ else
88
+ x = true
89
+ end
90
+ end
91
+ ind << x
92
+ end
93
+ self[*ind]
94
+ end
95
+
55
96
  # Statistics
56
97
  def mean(*ranks)
57
98
  if integer?
@@ -163,7 +204,7 @@ class NArray
163
204
  #alias randomn! randomn
164
205
 
165
206
  def randomn!
166
- self[]= random
207
+ self[]= randomn
167
208
  self
168
209
  end
169
210
 
@@ -241,7 +282,7 @@ module FFTW
241
282
  def convol(a1,a2)
242
283
  n1x,n1y = a1.shape
243
284
  n2x,n2y = a2.shape
244
- raise "arrays must have same shape" if n1x!=n2x || n1y!=n2y
285
+ raise "arrays must have same shape" if n1x!=n2x || n1y!=n2y
245
286
  (FFTW.fftw( FFTW.fftw(a1,-1) * FFTW.fftw(a2,-1), 1).real) / (n1x*n1y)
246
287
  end
247
288
  module_function :convol
data/src/mkop.rb CHANGED
@@ -186,6 +186,15 @@ mkfuncs('DivU', $data_types, $data_types,
186
186
  ["*p1 = rb_funcall(*p1,'/',1,*p2);"]
187
187
  )
188
188
 
189
+ mkfuncs('ModU', $data_types, $data_types,
190
+ [nil] +
191
+ ["if (*p2==0) {na_zerodiv();}
192
+ *p1 %= *p2;"]*3 +
193
+ ["*p1 = fmod(*p1, *p2);"]*2 +
194
+ [nil]*2 +
195
+ ["*p1 = rb_funcall(*p1,'%',1,*p2);"]
196
+ )
197
+
189
198
 
190
199
  # method: imag=
191
200
  mkfuncs('ImgSet',$data_types,$real_types,
@@ -506,7 +515,8 @@ mkfuncs('DivB', $data_types, $data_types,
506
515
 
507
516
  mkfuncs('ModB', $data_types, $data_types,
508
517
  [nil] +
509
- ["*p1 = *p2 % *p3;"]*3 +
518
+ ["if (*p3==0) {na_zerodiv();};
519
+ *p1 = *p2 % *p3;"]*3 +
510
520
  ["*p1 = fmod(*p2, *p3);"]*2 +
511
521
  [nil]*2 +
512
522
  ["*p1 = rb_funcall(*p2,'%',1,*p3);"]
data/src/na_func.c CHANGED
@@ -41,7 +41,7 @@ void
41
41
  /* initialize slice structure */
42
42
  void na_init_slice( struct slice *s, int rank, int *shape, int elmsz )
43
43
  {
44
- int r, i, b;
44
+ int r, i, b;
45
45
  na_index_t *idx;
46
46
 
47
47
  /*
@@ -79,7 +79,7 @@ void na_init_slice( struct slice *s, int rank, int *shape, int elmsz )
79
79
  /* set beginning pointers */
80
80
  if ( s[r].idx == NULL )
81
81
  s[r].pbeg = s[r].stride * s[r].beg * elmsz;
82
- else
82
+ else
83
83
  s[r].pbeg = s[r].idx[0];
84
84
  }
85
85
  }
@@ -169,7 +169,7 @@ void na_loop_index_ref( struct NARRAY *a1, struct NARRAY *a2,
169
169
  int ps2 = s2[0].pstep;
170
170
  int *si;
171
171
  na_index_t *idx;
172
-
172
+
173
173
  /*
174
174
  int copy;
175
175
  if (a1->type==a2->type && s1[0].step==1 && s2[0].step==1)
@@ -220,7 +220,7 @@ void na_loop_index_ref( struct NARRAY *a1, struct NARRAY *a2,
220
220
  /* array2 may have index */
221
221
  if ( s2[i].idx == NULL )
222
222
  s2[i].p += s2[i].pstep;
223
- else
223
+ else
224
224
  s2[i].p = s2[i+1].p + s2[i].idx[si[i]]; /* * s2[i].pstep; */
225
225
  }
226
226
  }
@@ -292,12 +292,12 @@ void na_loop_general( struct NARRAY *a1, struct NARRAY *a2,
292
292
  /* next point for a1 */
293
293
  if ( s1[i].idx == NULL )
294
294
  s1[i].p += s1[i].pstep;
295
- else
295
+ else
296
296
  s1[i].p = s1[i+1].p + s1[i].idx[si[i]];
297
297
  /* next point for a2 */
298
298
  if ( s2[i].idx == NULL )
299
299
  s2[i].p += s2[i].pstep;
300
- else
300
+ else
301
301
  s2[i].p = s2[i+1].p + s2[i].idx[si[i]];
302
302
  }
303
303
  }
@@ -392,7 +392,7 @@ static int
392
392
  return 1;
393
393
  else if ( ary_sz == 1 )
394
394
  return 0;
395
- else
395
+ else
396
396
  rb_raise(rb_eRuntimeError, "Array size mismatch: %i != %i at %i-th dim",
397
397
  ary_sz, itr_sz, i);
398
398
  }
@@ -435,7 +435,7 @@ int
435
435
  }
436
436
 
437
437
  s1[j].n =
438
- s2[j].n =
438
+ s2[j].n =
439
439
  s3[j].n = shape[i];
440
440
 
441
441
  s1[j].beg =
@@ -641,7 +641,7 @@ static VALUE
641
641
  if (a2->type==NA_ROBJ && a1->type!=NA_ROBJ) {
642
642
  obj1 = na_change_type(obj1,NA_ROBJ);
643
643
  GetNArray(obj1,a1);
644
- } else
644
+ } else
645
645
  if (!NA_IsCOMPLEX(a1) && NA_IsCOMPLEX(a2)) {
646
646
  obj1 = na_upcast_type(obj1,a2->type);
647
647
  GetNArray(obj1,a1);
@@ -819,6 +819,10 @@ static VALUE na_div_bang(VALUE obj1, VALUE obj2)
819
819
  static VALUE na_mul_bang(VALUE obj1, VALUE obj2)
820
820
  { return na_set_func( obj1, obj2, MulUFuncs ); }
821
821
 
822
+ /* method: self.mod!(other) */
823
+ static VALUE na_mod_bang(VALUE obj1, VALUE obj2)
824
+ { return na_set_func( obj1, obj2, ModUFuncs ); }
825
+
822
826
  /* method: self.conj! */
823
827
  static VALUE na_conj_bang(VALUE self)
824
828
  { return na_set_func( self, self, ConjFuncs ); }
@@ -1230,12 +1234,54 @@ static VALUE
1230
1234
  na_sum(int argc, VALUE *argv, VALUE self)
1231
1235
  { return na_sum_body(argc,argv,self,0); }
1232
1236
 
1233
- /* method: sum( rank, ... ) */
1237
+ /* method: accum( rank, ... ) */
1234
1238
  static VALUE
1235
1239
  na_accum(int argc, VALUE *argv, VALUE self)
1236
1240
  { return na_sum_body(argc,argv,self,1); }
1237
1241
 
1238
1242
 
1243
+
1244
+ static VALUE
1245
+ na_prod_body(int argc, VALUE *argv, VALUE self, int flag)
1246
+ {
1247
+ int *shape, rankc, *rankv, cl_dim;
1248
+ struct NARRAY *a1, *a2;
1249
+ VALUE obj, klass;
1250
+ int32_t one = 1;
1251
+
1252
+ GetNArray(self,a1);
1253
+
1254
+ rankv = ALLOC_N(int,a1->rank*2);
1255
+ rankc = na_arg_to_rank( argc, argv, a1->rank, rankv, 0 );
1256
+
1257
+ shape = &rankv[a1->rank];
1258
+ na_accum_set_shape( shape, a1->rank, a1->shape, rankc, rankv );
1259
+
1260
+ klass = CLASS_OF(self);
1261
+ cl_dim = na_class_dim(klass);
1262
+ if (flag==0 && cl_dim>0 && na_shrink_class(cl_dim,rankv))
1263
+ klass = cNArray;
1264
+
1265
+ obj = na_make_object(a1->type,a1->rank,shape,klass);
1266
+ GetNArray(obj,a2);
1267
+
1268
+ SetFuncs[a2->type][NA_LINT](a2->total, a2->ptr, na_sizeof[a2->type], &one, 0);
1269
+
1270
+ na_exec_unary( a2, a1, MulUFuncs[a1->type] );
1271
+
1272
+ if (flag==0)
1273
+ obj = na_shrink_rank(obj,cl_dim,rankv);
1274
+
1275
+ xfree(rankv);
1276
+ return obj;
1277
+ }
1278
+
1279
+ /* method: prod( rank, ... ) */
1280
+ static VALUE
1281
+ na_prod(int argc, VALUE *argv, VALUE self)
1282
+ { return na_prod_body(argc,argv,self,0); }
1283
+
1284
+
1239
1285
  static VALUE
1240
1286
  na_mul_add_body(int argc, VALUE *argv, volatile VALUE self, volatile VALUE other,
1241
1287
  VALUE wrap_klass, int flag)
@@ -1290,7 +1336,7 @@ static VALUE
1290
1336
  /* method: mul_add( other, rank, ... ) */
1291
1337
  static VALUE
1292
1338
  na_mul_add(int argc, VALUE *argv, VALUE self)
1293
- {
1339
+ {
1294
1340
  if (argc<2)
1295
1341
  rb_raise(rb_eArgError, "wrong # of arguments (%d for >=2)", argc);
1296
1342
  return na_mul_add_body(argc-1,argv+1,self,argv[0],Qnil,0);
@@ -1345,6 +1391,36 @@ static VALUE
1345
1391
  }
1346
1392
 
1347
1393
 
1394
+ /* cumprod!
1395
+ [1 2 3 4 5] -> [1 3 6 10 15]
1396
+ */
1397
+ static VALUE
1398
+ na_cumprod_bang(VALUE self)
1399
+ {
1400
+ struct NARRAY *a;
1401
+ int step;
1402
+
1403
+ GetNArray(self,a);
1404
+
1405
+ if ( a->rank != 1 )
1406
+ rb_raise( rb_eTypeError, "only for 1-dimensional array" );
1407
+ if ( a->total < 2 )
1408
+ return self; /* do nothing */
1409
+
1410
+ step = na_sizeof[a->type];
1411
+ MulUFuncs[a->type](a->total-1, a->ptr+step,step, a->ptr,step);
1412
+
1413
+ return self;
1414
+ }
1415
+
1416
+ /* cumprod */
1417
+ static VALUE
1418
+ na_cumprod(VALUE self)
1419
+ {
1420
+ return na_cumprod_bang(na_clone(self));
1421
+ }
1422
+
1423
+
1348
1424
  /* Copy element of idx=0 from a2 to a1, as start of accumulation */
1349
1425
  /* a1->rank <= a2->rank is assumed */
1350
1426
  static void
@@ -1552,6 +1628,7 @@ void Init_na_funcs(void)
1552
1628
  rb_define_method(cNArray, "*", na_mul, 1);
1553
1629
  rb_define_method(cNArray, "/", na_div, 1);
1554
1630
  rb_define_method(cNArray, "%", na_mod, 1);
1631
+ rb_define_alias (cNArray, "mod", "%");
1555
1632
  rb_define_method(cNArray, "&", na_bit_and, 1);
1556
1633
  rb_define_method(cNArray, "|", na_bit_or, 1);
1557
1634
  rb_define_method(cNArray, "^", na_bit_xor, 1);
@@ -1561,6 +1638,7 @@ void Init_na_funcs(void)
1561
1638
  rb_define_method(cNArray, "sbt!", na_sbt_bang, 1);
1562
1639
  rb_define_method(cNArray, "mul!", na_mul_bang, 1);
1563
1640
  rb_define_method(cNArray, "div!", na_div_bang, 1);
1641
+ rb_define_method(cNArray, "mod!", na_mod_bang, 1);
1564
1642
  rb_define_method(cNArray, "imag=",na_imag_set, 1);
1565
1643
 
1566
1644
  rb_define_method(cNArray, "swap_byte", na_swap_byte, 0);
@@ -1607,10 +1685,13 @@ void Init_na_funcs(void)
1607
1685
 
1608
1686
  rb_define_method(cNArray, "sum", na_sum, -1);
1609
1687
  rb_define_method(cNArray, "accum", na_accum, -1);
1688
+ rb_define_method(cNArray, "prod", na_prod, -1);
1610
1689
  rb_define_method(cNArray, "min", na_min, -1);
1611
1690
  rb_define_method(cNArray, "max", na_max, -1);
1612
1691
  rb_define_method(cNArray, "cumsum!", na_cumsum_bang, 0);
1613
1692
  rb_define_method(cNArray, "cumsum", na_cumsum, 0);
1693
+ rb_define_method(cNArray, "cumprod!", na_cumprod_bang, 0);
1694
+ rb_define_method(cNArray, "cumprod", na_cumprod, 0);
1614
1695
  rb_define_method(cNArray, "sort", na_sort, -1);
1615
1696
  rb_define_method(cNArray, "sort!", na_sort_bang, -1);
1616
1697
  rb_define_method(cNArray, "sort_index", na_sort_index, -1);