cumo 0.2.4 → 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,164 +24,10 @@
24
24
  #define DBL_EPSILON 2.2204460492503131e-16
25
25
  #endif
26
26
 
27
- static ID cumo_id_beg, cumo_id_end, cumo_id_len, cumo_id_step, cumo_id_excl;
27
+ static ID cumo_id_beg, cumo_id_end, cumo_id_len, cumo_id_step;
28
28
 
29
- //#define EXCL(r) RTEST(rb_ivar_get((r), cumo_id_excl))
30
- #define EXCL(r) RTEST(rb_funcall((r), rb_intern("exclude_end?"), 0))
31
-
32
- #define SET_EXCL(r,v) rb_ivar_set((r), cumo_id_excl, (v) ? Qtrue : Qfalse)
33
-
34
- static void
35
- step_init(
36
- VALUE self,
37
- VALUE beg,
38
- VALUE end,
39
- VALUE step,
40
- VALUE len,
41
- VALUE excl
42
- )
43
- {
44
- if (RTEST(len)) {
45
- if (!(FIXNUM_P(len) || TYPE(len)==T_BIGNUM)) {
46
- rb_raise(rb_eArgError, "length must be Integer");
47
- }
48
- if (RTEST(rb_funcall(len,rb_intern("<"),1,INT2FIX(0)))) {
49
- rb_raise(rb_eRangeError,"length must be non negative");
50
- }
51
- }
52
- rb_ivar_set(self, cumo_id_beg, beg);
53
- rb_ivar_set(self, cumo_id_end, end);
54
- rb_ivar_set(self, cumo_id_len, len);
55
- rb_ivar_set(self, cumo_id_step, step);
56
- SET_EXCL(self, excl);
57
- }
58
-
59
- static VALUE
60
- cumo_na_step_new2(
61
- VALUE range,
62
- VALUE step,
63
- VALUE len
64
- )
65
- {
66
- VALUE beg, end, excl;
67
- VALUE self = rb_obj_alloc(cumo_na_cStep);
68
-
69
- //beg = rb_ivar_get(range, cumo_id_beg);
70
- beg = rb_funcall(range, cumo_id_beg, 0);
71
- //end = rb_ivar_get(range, cumo_id_end);
72
- end = rb_funcall(range, cumo_id_end, 0);
73
- excl = rb_funcall(range, rb_intern("exclude_end?"), 0);
74
-
75
- step_init(self, beg, end, step, len, excl);
76
- return self;
77
- }
78
-
79
-
80
- /*
81
- * call-seq:
82
- * Step.new(start, end, step=nil, length=nil) => step
83
- * Step.new(range, step=nil, length=nil) => step
84
- *
85
- * Constructs a step using three parameters among <i>start</i>,
86
- * <i>end</i>, <i>step</i> and <i>length</i>. <i>start</i>,
87
- * <i>end</i> parameters can be replaced with <i>range</i>. If the
88
- * <i>step</i> is omitted (or supplied with nil), then calculated
89
- * from <i>length</i> or definded as 1.
90
- */
91
-
92
- static VALUE
93
- step_initialize( int argc, VALUE *argv, VALUE self )
94
- {
95
- VALUE a, b=Qnil, c=Qnil, d=Qnil, e=Qnil;
96
-
97
- rb_scan_args(argc, argv, "13", &a, &b, &c, &d);
98
- /* Selfs are immutable, so that they should be initialized only once. */
99
- if (rb_ivar_defined(self, cumo_id_beg)) {
100
- rb_name_error(rb_intern("initialize"), "`initialize' called twice");
101
- }
102
- if (rb_obj_is_kind_of(a,rb_cRange)) {
103
- if (argc>3) {
104
- rb_raise(rb_eArgError, "extra argument");
105
- }
106
- d = c;
107
- c = b;
108
- e = rb_funcall(a, rb_intern("exclude_end?"), 0);
109
- //b = rb_ivar_get(a, cumo_id_end);
110
- b = rb_funcall(a, cumo_id_end, 0);
111
- //a = rb_ivar_get(a, cumo_id_beg);
112
- a = rb_funcall(a, cumo_id_beg, 0);
113
- }
114
- step_init(self, a, b, c, d, e);
115
- return Qnil;
116
- }
117
-
118
- /*
119
- * call-seq:
120
- * step.begin => obj
121
- * step.first => obj
122
- *
123
- * Returns the start of <i>step</i>.
124
- */
125
-
126
- static VALUE
127
- step_first( VALUE self )
128
- {
129
- return rb_ivar_get(self, cumo_id_beg);
130
- }
131
-
132
- /*
133
- * call-seq:
134
- * step.end => obj
135
- * step.last => obj
136
- *
137
- * Returns the object that defines the end of <i>step</i>.
138
- */
139
-
140
- static VALUE
141
- step_last( VALUE self )
142
- {
143
- return rb_ivar_get(self, cumo_id_end);
144
- }
145
-
146
- /*
147
- * call-seq:
148
- * step.length => obj
149
- * step.size => obj
150
- *
151
- * Returns the length of <i>step</i>.
152
- */
153
-
154
- static VALUE
155
- step_length( VALUE self )
156
- {
157
- return rb_ivar_get(self, cumo_id_len);
158
- }
159
-
160
- /*
161
- * call-seq:
162
- * step.step => obj
163
- *
164
- * Returns the step of <i>step</i>.
165
- */
166
-
167
- static VALUE
168
- step_step( VALUE self )
169
- {
170
- return rb_ivar_get(self, cumo_id_step);
171
- }
172
-
173
- /*
174
- * call-seq:
175
- * step.exclude_end? => true or false
176
- *
177
- * Returns <code>true</code> if <i>step</i> excludes its end value.
178
- */
179
- static VALUE
180
- step_exclude_end_p(VALUE self)
181
- {
182
- return RTEST(rb_ivar_get(self, cumo_id_excl)) ? Qtrue : Qfalse;
183
- }
184
29
 
30
+ #define EXCL(r) RTEST(rb_funcall((r), rb_intern("exclude_end?"), 0))
185
31
 
186
32
  /*
187
33
  * call-seq:
@@ -192,7 +38,7 @@ step_exclude_end_p(VALUE self)
192
38
  */
193
39
 
194
40
  void
195
- cumo_na_step_array_index(VALUE self, size_t ary_size,
41
+ cumo_na_step_array_index(VALUE obj, size_t ary_size,
196
42
  size_t *plen, ssize_t *pbeg, ssize_t *pstep)
197
43
  {
198
44
  size_t len;
@@ -200,14 +46,28 @@ cumo_na_step_array_index(VALUE self, size_t ary_size,
200
46
  VALUE vbeg, vend, vstep, vlen;
201
47
  ssize_t end=ary_size;
202
48
 
203
- //vbeg = rb_ivar_get(self, cumo_id_beg);
204
- //vend = rb_ivar_get(self, cumo_id_end);
205
- vlen = rb_ivar_get(self, cumo_id_len);
206
- vstep = rb_ivar_get(self, cumo_id_step);
207
- vbeg = rb_funcall(self, cumo_id_beg, 0);
208
- vend = rb_funcall(self, cumo_id_end, 0);
209
- //vlen = rb_funcall(self, cumo_id_len, 0);
210
- //vstep = rb_funcall(self, cumo_id_step, 0);
49
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
50
+ rb_arithmetic_sequence_components_t x;
51
+ rb_arithmetic_sequence_extract(obj, &x);
52
+
53
+ vstep = x.step;
54
+ vbeg = x.begin;
55
+ vend = x.end;
56
+ #else
57
+ cumo_enumerator_t *e;
58
+
59
+ if (rb_obj_is_kind_of(obj, rb_cRange)) {
60
+ vstep = rb_ivar_get(obj, cumo_id_step);
61
+ } else { // Enumerator
62
+ cumo_na_parse_enumerator_step(obj, &vstep);
63
+ e = (cumo_enumerator_t *)DATA_PTR(obj);
64
+ obj = e->obj; // Range
65
+ }
66
+
67
+ vbeg = rb_funcall(obj, cumo_id_beg, 0);
68
+ vend = rb_funcall(obj, cumo_id_end, 0);
69
+ #endif
70
+ vlen = rb_ivar_get(obj, cumo_id_len);
211
71
 
212
72
  if (RTEST(vbeg)) {
213
73
  beg = NUM2SSIZET(vbeg);
@@ -237,7 +97,7 @@ cumo_na_step_array_index(VALUE self, size_t ary_size,
237
97
  }
238
98
  } else {
239
99
  if (RTEST(vend)) {
240
- if (EXCL(self)) {
100
+ if (EXCL(obj)) {
241
101
  if (step>0) end--;
242
102
  if (step<0) end++;
243
103
  }
@@ -251,7 +111,7 @@ cumo_na_step_array_index(VALUE self, size_t ary_size,
251
111
  step = 1;
252
112
  if (RTEST(vbeg)) {
253
113
  if (RTEST(vend)) {
254
- if (EXCL(self)) {
114
+ if (EXCL(obj)) {
255
115
  if (beg<end) end--;
256
116
  if (beg>end) end++;
257
117
  }
@@ -262,7 +122,7 @@ cumo_na_step_array_index(VALUE self, size_t ary_size,
262
122
  }
263
123
  } else {
264
124
  if (RTEST(vend)) {
265
- if (EXCL(self)) {
125
+ if (EXCL(obj)) {
266
126
  end--;
267
127
  }
268
128
  beg = end - (len-1);
@@ -286,7 +146,7 @@ cumo_na_step_array_index(VALUE self, size_t ary_size,
286
146
  if (!RTEST(vend)) {
287
147
  end = ary_size-1;
288
148
  }
289
- else if (EXCL(self)) {
149
+ else if (EXCL(obj)) {
290
150
  end--;
291
151
  }
292
152
  if (beg<=end) {
@@ -301,7 +161,7 @@ cumo_na_step_array_index(VALUE self, size_t ary_size,
301
161
  if (!RTEST(vend)) {
302
162
  end = 0;
303
163
  }
304
- else if (EXCL(self)) {
164
+ else if (EXCL(obj)) {
305
165
  end++;
306
166
  }
307
167
  if (beg>=end) {
@@ -327,25 +187,35 @@ cumo_na_step_array_index(VALUE self, size_t ary_size,
327
187
  if (pstep) *pstep = step;
328
188
  }
329
189
 
330
-
331
190
  void
332
- cumo_na_step_sequence( VALUE self, size_t *plen, double *pbeg, double *pstep )
191
+ cumo_na_step_sequence( VALUE obj, size_t *plen, double *pbeg, double *pstep )
333
192
  {
334
- VALUE vbeg, vend, vstep, vlen;
193
+ VALUE vend, vstep, vlen;
335
194
  double dbeg, dend, dstep=1, dsize, err;
336
195
  size_t size, n;
337
196
 
338
- //vbeg = rb_ivar_get(self, cumo_id_beg);
339
- vbeg = rb_funcall(self, cumo_id_beg, 0);
340
- dbeg = NUM2DBL(vbeg);
341
-
342
- //vend = rb_ivar_get(self, cumo_id_end);
343
- vend = rb_funcall(self, cumo_id_end, 0);
197
+ #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
198
+ rb_arithmetic_sequence_components_t x;
199
+ rb_arithmetic_sequence_extract(obj, &x);
200
+
201
+ vstep = x.step;
202
+ dbeg = NUM2DBL(x.begin);
203
+ vend = x.end;
204
+ #else
205
+ cumo_enumerator_t *e;
206
+
207
+ if (rb_obj_is_kind_of(obj, rb_cRange)) {
208
+ vstep = rb_ivar_get(obj, cumo_id_step);
209
+ } else { // Enumerator
210
+ cumo_na_parse_enumerator_step(obj, &vstep);
211
+ e = (cumo_enumerator_t *)DATA_PTR(obj);
212
+ obj = e->obj; // Range
213
+ }
344
214
 
345
- vlen = rb_ivar_get(self, cumo_id_len);
346
- vstep = rb_ivar_get(self, cumo_id_step);
347
- //vlen = rb_funcall(self, cumo_id_len ,0);
348
- //vstep = rb_funcall(self, cumo_id_step,0);
215
+ dbeg = NUM2DBL(rb_funcall(obj, cumo_id_beg, 0));
216
+ vend = rb_funcall(obj, cumo_id_end, 0);
217
+ #endif
218
+ vlen = rb_ivar_get(obj, cumo_id_len);
349
219
 
350
220
  if (RTEST(vlen)) {
351
221
  size = NUM2SIZET(vlen);
@@ -353,7 +223,7 @@ cumo_na_step_sequence( VALUE self, size_t *plen, double *pbeg, double *pstep )
353
223
  if (!RTEST(vstep)) {
354
224
  if (RTEST(vend)) {
355
225
  dend = NUM2DBL(vend);
356
- if (EXCL(self)) {
226
+ if (EXCL(obj)) {
357
227
  n = size;
358
228
  } else {
359
229
  n = size-1;
@@ -378,7 +248,7 @@ cumo_na_step_sequence( VALUE self, size_t *plen, double *pbeg, double *pstep )
378
248
  err = (fabs(dbeg)+fabs(dend)+fabs(dend-dbeg))/fabs(dstep)*DBL_EPSILON;
379
249
  if (err>0.5) err=0.5;
380
250
  dsize = (dend-dbeg)/dstep;
381
- if (EXCL(self))
251
+ if (EXCL(obj))
382
252
  dsize -= err;
383
253
  else
384
254
  dsize += err;
@@ -398,77 +268,13 @@ cumo_na_step_sequence( VALUE self, size_t *plen, double *pbeg, double *pstep )
398
268
  if (pstep) *pstep = dstep;
399
269
  }
400
270
 
401
- /*
402
- static VALUE
403
- step_each( VALUE self )
404
- {
405
- VALUE a;
406
- double beg, step;
407
- size_t i, size;
408
-
409
- a = cumo_na_step_parameters( self, Qnil );
410
- beg = NUM2DBL(RARRAY_PTR(a)[0]);
411
- step = NUM2DBL(RARRAY_PTR(a)[1]);
412
- size = NUM2SIZET(RARRAY_PTR(a)[2]);
413
-
414
- for (i=0; i<size; i++) {
415
- rb_yield(rb_float_new(beg+i*step));
416
- }
417
- return self;
418
- }
419
- */
420
-
421
- static VALUE
422
- range_with_step( VALUE range, VALUE step )
423
- {
424
- return cumo_na_step_new2( range, step, Qnil );
425
- }
426
-
427
- static VALUE
428
- range_with_length( VALUE range, VALUE len )
429
- {
430
- return cumo_na_step_new2( range, Qnil, len );
431
- }
432
-
433
-
434
- static VALUE
435
- cumo_na_s_step( int argc, VALUE *argv, VALUE mod )
436
- {
437
- VALUE self = rb_obj_alloc(cumo_na_cStep);
438
- step_initialize(argc, argv, self);
439
- return self;
440
- }
441
-
442
-
443
271
  void
444
272
  Init_cumo_na_step()
445
273
  {
446
- cumo_na_cStep = rb_define_class_under(cNArray, "Step", rb_cObject);
447
- rb_include_module(cumo_na_cStep, rb_mEnumerable);
448
- rb_define_method(cumo_na_cStep, "initialize", step_initialize, -1);
449
-
450
- //rb_define_method(cumo_na_cStep, "each", step_each, 0);
451
-
452
- rb_define_method(cumo_na_cStep, "first", step_first, 0);
453
- rb_define_method(cumo_na_cStep, "last", step_last, 0);
454
- rb_define_method(cumo_na_cStep, "begin", step_first, 0);
455
- rb_define_method(cumo_na_cStep, "end", step_last, 0);
456
- rb_define_method(cumo_na_cStep, "step", step_step, 0);
457
- rb_define_method(cumo_na_cStep, "length", step_length, 0);
458
- rb_define_method(cumo_na_cStep, "size", step_length, 0);
459
- rb_define_method(cumo_na_cStep, "exclude_end?", step_exclude_end_p, 0);
460
- //rb_define_method(cumo_na_cStep, "to_s", step_to_s, 0);
461
- //rb_define_method(cumo_na_cStep, "inspect", step_inspect, 0);
462
- //rb_define_method(cumo_na_cStep, "parameters", cumo_na_step_parameters, 1);
463
-
464
- rb_define_method(rb_cRange, "%", range_with_step, 1);
465
- rb_define_method(rb_cRange, "*", range_with_length, 1);
466
-
467
- rb_define_singleton_method(cNArray, "step", cumo_na_s_step, -1);
274
+ rb_define_alias(rb_cRange, "%", "step");
468
275
 
469
276
  cumo_id_beg = rb_intern("begin");
470
277
  cumo_id_end = rb_intern("end");
471
278
  cumo_id_len = rb_intern("length");
472
279
  cumo_id_step = rb_intern("step");
473
- cumo_id_excl = rb_intern("excl");
474
280
  }
@@ -208,6 +208,55 @@ module Cumo
208
208
  end
209
209
  end
210
210
 
211
+
212
+ # Iterate over an axis
213
+ # @ example
214
+ # > a = Cumo::DFloat.new(2,2,2).seq
215
+ # > p a
216
+ # Cumo::DFloat#shape=[2,2,2]
217
+ # [[[0, 1],
218
+ # [2, 3]],
219
+ # [[4, 5],
220
+ # [6, 7]]]
221
+ #
222
+ # > a.each_over_axis{|i| p i}
223
+ # Cumo::DFloat(view)#shape=[2,2]
224
+ # [[0, 1],
225
+ # [2, 3]]
226
+ # Cumo::DFloat(view)#shape=[2,2]
227
+ # [[4, 5],
228
+ # [6, 7]]
229
+ #
230
+ # > a.each_over_axis(1){|i| p i}
231
+ # Cumo::DFloat(view)#shape=[2,2]
232
+ # [[0, 1],
233
+ # [4, 5]]
234
+ # Cumo::DFloat(view)#shape=[2,2]
235
+ # [[2, 3],
236
+ # [6, 7]]
237
+
238
+ def each_over_axis(axis=0)
239
+ unless block_given?
240
+ return to_enum(:each_over_axis,axis)
241
+ end
242
+ if ndim == 0
243
+ if axis != 0
244
+ raise ArgumentError,"axis=#{axis} is invalid"
245
+ end
246
+ niter = 1
247
+ else
248
+ axis = check_axis(axis)
249
+ niter = shape[axis]
250
+ end
251
+ idx = [true]*ndim
252
+ niter.times do |i|
253
+ idx[axis] = i
254
+ yield(self[*idx])
255
+ end
256
+ self
257
+ end
258
+
259
+
211
260
  # Append values to the end of an narray.
212
261
  # @example
213
262
  # a = Cumo::DFloat[1, 2, 3]
@@ -987,7 +1036,7 @@ module Cumo
987
1036
  raise NArray::ShapeError, "must be >= 2-dimensional array"
988
1037
  end
989
1038
  m,n = shape[-2..-1]
990
- NArray.triu_indices(m,n,k=0)
1039
+ NArray.triu_indices(m,n,k)
991
1040
  end
992
1041
 
993
1042
  # Return the indices for the uppler-triangle on and above the k-th diagonal.