narray 0.5.9.9 → 0.6.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.
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);