numo-narray 0.9.0.1-x64-mingw32

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 (124) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/README.md +47 -0
  4. data/Rakefile +41 -0
  5. data/ext/numo/narray/SFMT-params.h +97 -0
  6. data/ext/numo/narray/SFMT-params19937.h +46 -0
  7. data/ext/numo/narray/SFMT.c +620 -0
  8. data/ext/numo/narray/SFMT.h +157 -0
  9. data/ext/numo/narray/array.c +525 -0
  10. data/ext/numo/narray/data.c +901 -0
  11. data/ext/numo/narray/depend.erb +33 -0
  12. data/ext/numo/narray/extconf.rb +117 -0
  13. data/ext/numo/narray/gen/bit.erb.c +811 -0
  14. data/ext/numo/narray/gen/cogen.rb +18 -0
  15. data/ext/numo/narray/gen/def/dcomplex.rb +32 -0
  16. data/ext/numo/narray/gen/def/dfloat.rb +30 -0
  17. data/ext/numo/narray/gen/def/int16.rb +29 -0
  18. data/ext/numo/narray/gen/def/int32.rb +29 -0
  19. data/ext/numo/narray/gen/def/int64.rb +29 -0
  20. data/ext/numo/narray/gen/def/int8.rb +29 -0
  21. data/ext/numo/narray/gen/def/robject.rb +30 -0
  22. data/ext/numo/narray/gen/def/scomplex.rb +32 -0
  23. data/ext/numo/narray/gen/def/sfloat.rb +30 -0
  24. data/ext/numo/narray/gen/def/uint16.rb +29 -0
  25. data/ext/numo/narray/gen/def/uint32.rb +29 -0
  26. data/ext/numo/narray/gen/def/uint64.rb +29 -0
  27. data/ext/numo/narray/gen/def/uint8.rb +29 -0
  28. data/ext/numo/narray/gen/dtype.erb.c +328 -0
  29. data/ext/numo/narray/gen/tmpl/accum.c +36 -0
  30. data/ext/numo/narray/gen/tmpl/accum_binary.c +75 -0
  31. data/ext/numo/narray/gen/tmpl/accum_index.c +58 -0
  32. data/ext/numo/narray/gen/tmpl/allocate.c +35 -0
  33. data/ext/numo/narray/gen/tmpl/aref.c +51 -0
  34. data/ext/numo/narray/gen/tmpl/aset.c +61 -0
  35. data/ext/numo/narray/gen/tmpl/binary.c +53 -0
  36. data/ext/numo/narray/gen/tmpl/binary2.c +55 -0
  37. data/ext/numo/narray/gen/tmpl/binary_s.c +34 -0
  38. data/ext/numo/narray/gen/tmpl/bit_binary.c +94 -0
  39. data/ext/numo/narray/gen/tmpl/bit_count.c +82 -0
  40. data/ext/numo/narray/gen/tmpl/bit_unary.c +77 -0
  41. data/ext/numo/narray/gen/tmpl/cast.c +37 -0
  42. data/ext/numo/narray/gen/tmpl/cast_array.c +79 -0
  43. data/ext/numo/narray/gen/tmpl/cast_numeric.c +22 -0
  44. data/ext/numo/narray/gen/tmpl/coerce_cast.c +8 -0
  45. data/ext/numo/narray/gen/tmpl/cond_binary.c +51 -0
  46. data/ext/numo/narray/gen/tmpl/cond_unary.c +45 -0
  47. data/ext/numo/narray/gen/tmpl/cum.c +42 -0
  48. data/ext/numo/narray/gen/tmpl/each.c +43 -0
  49. data/ext/numo/narray/gen/tmpl/each_with_index.c +64 -0
  50. data/ext/numo/narray/gen/tmpl/extract.c +23 -0
  51. data/ext/numo/narray/gen/tmpl/eye.c +91 -0
  52. data/ext/numo/narray/gen/tmpl/fill.c +38 -0
  53. data/ext/numo/narray/gen/tmpl/format.c +60 -0
  54. data/ext/numo/narray/gen/tmpl/format_to_a.c +47 -0
  55. data/ext/numo/narray/gen/tmpl/head.c +25 -0
  56. data/ext/numo/narray/gen/tmpl/inspect.c +16 -0
  57. data/ext/numo/narray/gen/tmpl/map_with_index.c +94 -0
  58. data/ext/numo/narray/gen/tmpl/median.c +44 -0
  59. data/ext/numo/narray/gen/tmpl/minmax.c +47 -0
  60. data/ext/numo/narray/gen/tmpl/poly.c +49 -0
  61. data/ext/numo/narray/gen/tmpl/pow.c +74 -0
  62. data/ext/numo/narray/gen/tmpl/powint.c +17 -0
  63. data/ext/numo/narray/gen/tmpl/qsort.c +149 -0
  64. data/ext/numo/narray/gen/tmpl/rand.c +33 -0
  65. data/ext/numo/narray/gen/tmpl/rand_norm.c +46 -0
  66. data/ext/numo/narray/gen/tmpl/robj_allocate.c +32 -0
  67. data/ext/numo/narray/gen/tmpl/seq.c +61 -0
  68. data/ext/numo/narray/gen/tmpl/set2.c +56 -0
  69. data/ext/numo/narray/gen/tmpl/sort.c +36 -0
  70. data/ext/numo/narray/gen/tmpl/sort_index.c +86 -0
  71. data/ext/numo/narray/gen/tmpl/store.c +31 -0
  72. data/ext/numo/narray/gen/tmpl/store_array.c +5 -0
  73. data/ext/numo/narray/gen/tmpl/store_from.c +53 -0
  74. data/ext/numo/narray/gen/tmpl/store_numeric.c +22 -0
  75. data/ext/numo/narray/gen/tmpl/to_a.c +41 -0
  76. data/ext/numo/narray/gen/tmpl/unary.c +58 -0
  77. data/ext/numo/narray/gen/tmpl/unary2.c +58 -0
  78. data/ext/numo/narray/gen/tmpl/unary_s.c +57 -0
  79. data/ext/numo/narray/index.c +822 -0
  80. data/ext/numo/narray/kwarg.c +79 -0
  81. data/ext/numo/narray/math.c +140 -0
  82. data/ext/numo/narray/narray.c +1539 -0
  83. data/ext/numo/narray/ndloop.c +1928 -0
  84. data/ext/numo/narray/numo/compat.h +23 -0
  85. data/ext/numo/narray/numo/intern.h +112 -0
  86. data/ext/numo/narray/numo/narray.h +411 -0
  87. data/ext/numo/narray/numo/ndloop.h +99 -0
  88. data/ext/numo/narray/numo/template.h +140 -0
  89. data/ext/numo/narray/numo/types/bit.h +19 -0
  90. data/ext/numo/narray/numo/types/complex.h +410 -0
  91. data/ext/numo/narray/numo/types/complex_macro.h +205 -0
  92. data/ext/numo/narray/numo/types/dcomplex.h +11 -0
  93. data/ext/numo/narray/numo/types/dfloat.h +12 -0
  94. data/ext/numo/narray/numo/types/float_def.h +34 -0
  95. data/ext/numo/narray/numo/types/float_macro.h +277 -0
  96. data/ext/numo/narray/numo/types/int16.h +12 -0
  97. data/ext/numo/narray/numo/types/int32.h +12 -0
  98. data/ext/numo/narray/numo/types/int64.h +12 -0
  99. data/ext/numo/narray/numo/types/int8.h +12 -0
  100. data/ext/numo/narray/numo/types/int_macro.h +34 -0
  101. data/ext/numo/narray/numo/types/robj_macro.h +218 -0
  102. data/ext/numo/narray/numo/types/robject.h +21 -0
  103. data/ext/numo/narray/numo/types/scomplex.h +11 -0
  104. data/ext/numo/narray/numo/types/sfloat.h +13 -0
  105. data/ext/numo/narray/numo/types/uint16.h +12 -0
  106. data/ext/numo/narray/numo/types/uint32.h +12 -0
  107. data/ext/numo/narray/numo/types/uint64.h +12 -0
  108. data/ext/numo/narray/numo/types/uint8.h +12 -0
  109. data/ext/numo/narray/numo/types/uint_macro.h +31 -0
  110. data/ext/numo/narray/numo/types/xint_macro.h +133 -0
  111. data/ext/numo/narray/rand.c +87 -0
  112. data/ext/numo/narray/step.c +506 -0
  113. data/ext/numo/narray/struct.c +872 -0
  114. data/lib/2.1/numo/narray.so +0 -0
  115. data/lib/2.2/numo/narray.so +0 -0
  116. data/lib/2.3/numo/narray.so +0 -0
  117. data/lib/erbpp.rb +286 -0
  118. data/lib/erbpp/line_number.rb +126 -0
  119. data/lib/erbpp/narray_def.rb +338 -0
  120. data/lib/numo/narray.rb +6 -0
  121. data/numo-narray.gemspec +35 -0
  122. data/spec/bit_spec.rb +93 -0
  123. data/spec/narray_spec.rb +249 -0
  124. metadata +238 -0
@@ -0,0 +1,133 @@
1
+ #define m_zero 0
2
+ #define m_one 1
3
+
4
+ #define m_from_double(x) (x)
5
+ #define m_from_real(x) (x)
6
+
7
+ #define m_add(x,y) ((x)+(y))
8
+ #define m_sub(x,y) ((x)-(y))
9
+ #define m_mul(x,y) ((x)*(y))
10
+ #define m_div(x,y) ((x)/(y))
11
+ #define m_mod(x,y) ((x)%(y))
12
+ #define m_divmod(x,y,a,b) {a=(x)/(y); b=m_mod(x,y);}
13
+ #define m_pow(x,y) pow_int(x,y)
14
+ #define m_pow_int(x,y) pow_int(x,y)
15
+
16
+ #define m_bit_and(x,y) ((x)&(y))
17
+ #define m_bit_or(x,y) ((x)|(y))
18
+ #define m_bit_xor(x,y) ((x)^(y))
19
+ #define m_bit_not(x) (~(x))
20
+
21
+ #define m_minus(x) (-(x))
22
+ #define m_inverse(x) int_inverse(x)
23
+ #define m_square(x) ((x)*(x))
24
+
25
+ #define m_eq(x,y) ((x)==(y))
26
+ #define m_ne(x,y) ((x)!=(y))
27
+ #define m_gt(x,y) ((x)>(y))
28
+ #define m_ge(x,y) ((x)>=(y))
29
+ #define m_lt(x,y) ((x)<(y))
30
+ #define m_le(x,y) ((x)<=(y))
31
+ #define m_isnan(x) 0
32
+
33
+ #define m_mulsum(x,y,z) {z += x*y;}
34
+ #define m_mulsum_init INT2FIX(0)
35
+
36
+ #define cmp(a,b) \
37
+ ((qsort_cast(a)==qsort_cast(b)) ? 0 : \
38
+ (qsort_cast(a) > qsort_cast(b)) ? 1 : -1)
39
+ #define cmpgt(a,b) \
40
+ (qsort_cast(a) > qsort_cast(b))
41
+
42
+
43
+ static inline dtype f_sum(size_t n, char *p, ssize_t stride)
44
+ {
45
+ dtype x,y=0;
46
+ size_t i=n;
47
+ for (; i--;) {
48
+ x = *(dtype*)p;
49
+ y += x;
50
+ p += stride;
51
+ }
52
+ return y;
53
+ }
54
+
55
+ static inline dtype f_prod(size_t n, char *p, ssize_t stride)
56
+ {
57
+ dtype x,y=1;
58
+ size_t i=n;
59
+ for (; i--;) {
60
+ x = *(dtype*)p;
61
+ y *= x;
62
+ p += stride;
63
+ }
64
+ return y;
65
+ }
66
+
67
+ static inline dtype f_min(size_t n, char *p, ssize_t stride)
68
+ {
69
+ dtype x,y;
70
+ size_t i=n;
71
+
72
+ y = *(dtype*)p;
73
+ p += stride;
74
+ i--;
75
+ for (; i--;) {
76
+ x = *(dtype*)p;
77
+ if (x < y) {
78
+ y = x;
79
+ }
80
+ p += stride;
81
+ }
82
+ return y;
83
+ }
84
+
85
+ static inline dtype f_max(size_t n, char *p, ssize_t stride)
86
+ {
87
+ dtype x,y;
88
+ size_t i=n;
89
+
90
+ y = *(dtype*)p;
91
+ p += stride;
92
+ i--;
93
+ for (; i--;) {
94
+ x = *(dtype*)p;
95
+ if (x > y) {
96
+ y = x;
97
+ }
98
+ p += stride;
99
+ }
100
+ return y;
101
+ }
102
+
103
+ static inline size_t f_min_index(size_t n, char *p, ssize_t stride)
104
+ {
105
+ dtype x, y;
106
+ size_t i, j=0;
107
+
108
+ y = *(dtype*)p;
109
+ for (i=1; i<n; i++) {
110
+ x = *(dtype*)(p+i*stride);
111
+ if (x < y) {
112
+ y = x;
113
+ j = i;
114
+ }
115
+ }
116
+ return j;
117
+ }
118
+
119
+ static inline size_t f_max_index(size_t n, char *p, ssize_t stride)
120
+ {
121
+ dtype x, y;
122
+ size_t i, j=0;
123
+
124
+ y = *(dtype*)p;
125
+ for (i=1; i<n; i++) {
126
+ x = *(dtype*)(p+i*stride);
127
+ if (x > y) {
128
+ y = x;
129
+ j = i;
130
+ }
131
+ }
132
+ return j;
133
+ }
@@ -0,0 +1,87 @@
1
+ #include "ruby.h"
2
+ #include "numo/narray.h"
3
+ #include "SFMT.h"
4
+
5
+ #ifdef HAVE_UNISTD_H
6
+ #include <unistd.h>
7
+ #endif
8
+ #include <time.h>
9
+ #ifdef HAVE_SYS_TIME_H
10
+ #include <sys/time.h>
11
+ #endif
12
+
13
+ int n_bits(u_int64_t a)
14
+ {
15
+ int i, x, /*xu,*/ xl, n=5;
16
+ u_int64_t m;
17
+
18
+ if (a==0) return 0;
19
+ //if (a<0) a=-a;
20
+
21
+ x = 1<<n;
22
+ //xu = 1<<(n+1);
23
+ xl = 0;
24
+ //printf("%3i, [%3i, %3i], %i\n", i, xu, xl, x);
25
+
26
+ for (i=n; i>=0; i--) {
27
+ m = ~((1<<(x-1))-1);
28
+ if (m & a) {
29
+ xl = x;
30
+ x += 1<<(i-1);
31
+ } else {
32
+ //xu = x;
33
+ x -= 1<<(i-1);
34
+ }
35
+ //printf("%3i, [%3i, %3i], %i, 0x%lx, 0x%lx\n", i, xu, xl, x, m, m&a);
36
+ }
37
+ return xl;
38
+ }
39
+
40
+ void rand_norm(double *a)
41
+ {
42
+ double x1, x2, w;
43
+ do {
44
+ x1 = to_res53(gen_rand64());
45
+ x1 = x1*2-1;
46
+ x2 = to_res53(gen_rand64());
47
+ x2 = x2*2-1;
48
+ w = x1 * x1 + x2 * x2;
49
+ } while (w>=1);
50
+ w = sqrt( (-2*log(w)) / w );
51
+ a[0] = x1*w;
52
+ a[1] = x2*w;
53
+ }
54
+
55
+ static u_int64_t
56
+ random_seed()
57
+ {
58
+ static int n = 0;
59
+ struct timeval tv;
60
+
61
+ gettimeofday(&tv, 0);
62
+ return tv.tv_sec ^ tv.tv_usec ^ getpid() ^ n++;
63
+ }
64
+
65
+ static VALUE
66
+ nary_s_srand(int argc, VALUE *argv, VALUE obj)
67
+ {
68
+ VALUE vseed;
69
+ u_int64_t seed;
70
+
71
+ //rb_secure(4);
72
+ if (rb_scan_args(argc, argv, "01", &vseed) == 0) {
73
+ seed = random_seed();
74
+ }
75
+ else {
76
+ seed = NUM2UINT64(vseed);
77
+ }
78
+ init_gen_rand(seed);
79
+
80
+ return Qnil;
81
+ }
82
+
83
+ void
84
+ Init_nary_rand() {
85
+ rb_define_singleton_method(cNArray, "srand", nary_s_srand, -1);
86
+ init_gen_rand(0);
87
+ }
@@ -0,0 +1,506 @@
1
+ /*
2
+ step.c
3
+ Numerical Array Extension for Ruby
4
+ (C) Copyright 2007,2013 by Masahiro TANAKA
5
+
6
+ This program is free software.
7
+ You can distribute/modify this program
8
+ under the same terms as Ruby itself.
9
+ NO WARRANTY.
10
+ */
11
+ #include <ruby.h>
12
+ #include <math.h>
13
+
14
+ #include "numo/narray.h"
15
+
16
+ #if defined(__FreeBSD__) && __FreeBSD__ < 4
17
+ #include <floatingpoint.h>
18
+ #endif
19
+
20
+ #ifdef HAVE_FLOAT_H
21
+ #include <float.h>
22
+ #endif
23
+
24
+ #ifdef HAVE_IEEEFP_H
25
+ #include <ieeefp.h>
26
+ #endif
27
+
28
+ #ifndef DBL_EPSILON
29
+ #define DBL_EPSILON 2.2204460492503131e-16
30
+ #endif
31
+
32
+ static ID id_beg, id_end, id_len, id_step, id_excl;
33
+
34
+ //#define EXCL(r) RTEST(rb_ivar_get((r), id_excl))
35
+ #define EXCL(r) RTEST(rb_funcall((r), rb_intern("exclude_end?"), 0))
36
+
37
+ #define SET_EXCL(r,v) rb_ivar_set((r), id_excl, (v) ? Qtrue : Qfalse)
38
+
39
+ static void
40
+ step_init(
41
+ VALUE self,
42
+ VALUE beg,
43
+ VALUE end,
44
+ VALUE step,
45
+ VALUE len,
46
+ VALUE excl
47
+ )
48
+ {
49
+ if (RTEST(len)) {
50
+ if (!(FIXNUM_P(len) || TYPE(len)==T_BIGNUM)) {
51
+ rb_raise(rb_eArgError, "length must be Integer");
52
+ }
53
+ if (RTEST(rb_funcall(len,rb_intern("<"),1,INT2FIX(0)))) {
54
+ rb_raise(rb_eRangeError,"length must be non negative");
55
+ }
56
+ }
57
+ rb_ivar_set(self, id_beg, beg);
58
+ rb_ivar_set(self, id_end, end);
59
+ rb_ivar_set(self, id_len, len);
60
+ rb_ivar_set(self, id_step, step);
61
+ SET_EXCL(self, excl);
62
+ }
63
+
64
+ VALUE
65
+ nary_step_new(
66
+ VALUE beg,
67
+ VALUE end,
68
+ VALUE step,
69
+ VALUE len,
70
+ VALUE excl
71
+ )
72
+ {
73
+ VALUE self = rb_obj_alloc(na_cStep);
74
+
75
+ step_init(self, beg, end, step, len, excl);
76
+ return self;
77
+ }
78
+
79
+ VALUE
80
+ nary_step_new2(
81
+ VALUE range,
82
+ VALUE step,
83
+ VALUE len
84
+ )
85
+ {
86
+ VALUE beg, end, excl;
87
+ VALUE self = rb_obj_alloc(na_cStep);
88
+
89
+ //beg = rb_ivar_get(range, id_beg);
90
+ beg = rb_funcall(range, id_beg, 0);
91
+ //end = rb_ivar_get(range, id_end);
92
+ end = rb_funcall(range, id_end, 0);
93
+ excl = rb_funcall(range, rb_intern("exclude_end?"), 0);
94
+
95
+ step_init(self, beg, end, step, len, excl);
96
+ return self;
97
+ }
98
+
99
+
100
+ /*
101
+ * call-seq:
102
+ * Step.new(start, end, step=nil, length=nil) => step
103
+ * Step.new(range, step=nil, length=nil) => step
104
+ *
105
+ * Constructs a step using three parameters among <i>start</i>,
106
+ * <i>end</i>, <i>step</i> and <i>length</i>. <i>start</i>,
107
+ * <i>end</i> parameters can be replaced with <i>range</i>. If the
108
+ * <i>step</i> is omitted (or supplied with nil), then calculated
109
+ * from <i>length</i> or definded as 1.
110
+ */
111
+
112
+ static VALUE
113
+ step_initialize( int argc, VALUE *argv, VALUE self )
114
+ {
115
+ VALUE a, b=Qnil, c=Qnil, d=Qnil, e=Qnil;
116
+
117
+ rb_scan_args(argc, argv, "13", &a, &b, &c, &d);
118
+ /* Selfs are immutable, so that they should be initialized only once. */
119
+ if (rb_ivar_defined(self, id_beg)) {
120
+ rb_name_error(rb_intern("initialize"), "`initialize' called twice");
121
+ }
122
+ if (rb_obj_is_kind_of(a,rb_cRange)) {
123
+ if (argc>3) {
124
+ rb_raise(rb_eArgError, "extra argument");
125
+ }
126
+ d = c;
127
+ c = b;
128
+ e = rb_funcall(a, rb_intern("exclude_end?"), 0);
129
+ //b = rb_ivar_get(a, id_end);
130
+ b = rb_funcall(a, id_end, 0);
131
+ //a = rb_ivar_get(a, id_beg);
132
+ a = rb_funcall(a, id_beg, 0);
133
+ }
134
+ step_init(self, a, b, c, d, e);
135
+ return Qnil;
136
+ }
137
+
138
+ /*
139
+ * call-seq:
140
+ * step.begin => obj
141
+ * step.first => obj
142
+ *
143
+ * Returns the start of <i>step</i>.
144
+ */
145
+
146
+ static VALUE
147
+ step_first( VALUE self )
148
+ {
149
+ return rb_ivar_get(self, id_beg);
150
+ }
151
+
152
+ /*
153
+ * call-seq:
154
+ * step.end => obj
155
+ * step.last => obj
156
+ *
157
+ * Returns the object that defines the end of <i>step</i>.
158
+ */
159
+
160
+ static VALUE
161
+ step_last( VALUE self )
162
+ {
163
+ return rb_ivar_get(self, id_end);
164
+ }
165
+
166
+ /*
167
+ * call-seq:
168
+ * step.length => obj
169
+ * step.size => obj
170
+ *
171
+ * Returns the length of <i>step</i>.
172
+ */
173
+
174
+ static VALUE
175
+ step_length( VALUE self )
176
+ {
177
+ return rb_ivar_get(self, id_len);
178
+ }
179
+
180
+ /*
181
+ * call-seq:
182
+ * step.step => obj
183
+ *
184
+ * Returns the step of <i>step</i>.
185
+ */
186
+
187
+ static VALUE
188
+ step_step( VALUE self )
189
+ {
190
+ return rb_ivar_get(self, id_step);
191
+ }
192
+
193
+ /*
194
+ * call-seq:
195
+ * step.exclude_end? => true or false
196
+ *
197
+ * Returns <code>true</code> if <i>step</i> excludes its end value.
198
+ */
199
+ static VALUE
200
+ step_exclude_end_p(VALUE self)
201
+ {
202
+ return RTEST(rb_ivar_get(self, id_excl)) ? Qtrue : Qfalse;
203
+ }
204
+
205
+
206
+ /*
207
+ * call-seq:
208
+ * step.parameters([array_size]) => [start,step,length]
209
+ *
210
+ * Returns the iteration parameters of <i>step</i>. If
211
+ * <i>array_sizse</i> is given, negative array index is considered.
212
+ */
213
+
214
+ void
215
+ nary_step_array_index(VALUE self, size_t ary_size,
216
+ size_t *plen, ssize_t *pbeg, ssize_t *pstep)
217
+ {
218
+ size_t len;
219
+ ssize_t beg=0, step=1;
220
+ VALUE vbeg, vend, vstep, vlen;
221
+ ssize_t end=ary_size;
222
+
223
+ //vbeg = rb_ivar_get(self, id_beg);
224
+ //vend = rb_ivar_get(self, id_end);
225
+ vlen = rb_ivar_get(self, id_len);
226
+ vstep = rb_ivar_get(self, id_step);
227
+ vbeg = rb_funcall(self, id_beg, 0);
228
+ vend = rb_funcall(self, id_end, 0);
229
+ //vlen = rb_funcall(self, id_len, 0);
230
+ //vstep = rb_funcall(self, id_step, 0);
231
+
232
+ if (RTEST(vbeg)) {
233
+ beg = NUM2SSIZE(vbeg);
234
+ if (beg<0) {
235
+ beg += ary_size;
236
+ }
237
+ }
238
+ if (RTEST(vend)) {
239
+ end = NUM2SSIZE(vend);
240
+ if (end<0) {
241
+ end += ary_size;
242
+ }
243
+ }
244
+
245
+ //puts("pass 1");
246
+
247
+ if (RTEST(vlen)) {
248
+ len = NUM2SIZE(vlen);
249
+ if (len>0) {
250
+ if (RTEST(vstep)) {
251
+ step = NUM2SSIZE(step);
252
+ if (RTEST(vbeg)) {
253
+ if (RTEST(vend)) {
254
+ rb_raise( rb_eStandardError, "verbose Step object" );
255
+ } else {
256
+ end = beg + step*(len-1);
257
+ }
258
+ } else {
259
+ if (RTEST(vend)) {
260
+ if (EXCL(self)) {
261
+ if (step>0) end--;
262
+ if (step<0) end++;
263
+ }
264
+ beg = end - step*(len-1);
265
+ } else {
266
+ beg = 0;
267
+ end = step*(len-1);
268
+ }
269
+ }
270
+ } else { // no step
271
+ step = 1;
272
+ if (RTEST(vbeg)) {
273
+ if (RTEST(vend)) {
274
+ if (EXCL(self)) {
275
+ if (beg<end) end--;
276
+ if (beg>end) end++;
277
+ }
278
+ if (len>1)
279
+ step = (end-beg)/(len-1);
280
+ } else {
281
+ end = beg + (len-1);
282
+ }
283
+ } else {
284
+ if (RTEST(vend)) {
285
+ if (EXCL(self)) {
286
+ end--;
287
+ }
288
+ beg = end - (len-1);
289
+ } else {
290
+ beg = 0;
291
+ end = len-1;
292
+ }
293
+ }
294
+ }
295
+ }
296
+ } else { // no len
297
+ if (RTEST(vstep)) {
298
+ step = NUM2SSIZE(vstep);
299
+ } else {
300
+ step = 1;
301
+ }
302
+ if (step>0) {
303
+ if (!RTEST(vbeg)) {
304
+ beg = 0;
305
+ }
306
+ if (!RTEST(vend)) {
307
+ end = ary_size-1;
308
+ }
309
+ else if (EXCL(self)) {
310
+ end--;
311
+ }
312
+ if (beg<=end) {
313
+ len = (end-beg)/step+1;
314
+ } else {
315
+ len = 0;
316
+ }
317
+ } else if (step<0) {
318
+ if (!RTEST(vbeg)) {
319
+ beg = ary_size-1;
320
+ }
321
+ if (!RTEST(vend)) {
322
+ end = 0;
323
+ }
324
+ else if (EXCL(self)) {
325
+ end++;
326
+ }
327
+ if (beg>=end) {
328
+ len = (beg-end)/(-step)+1;
329
+ } else {
330
+ len = 0;
331
+ }
332
+ } else {
333
+ rb_raise( rb_eStandardError, "step must be non-zero" );
334
+ }
335
+ }
336
+
337
+ //puts("pass 2");
338
+
339
+ if (beg<0 || beg>=(ssize_t)ary_size ||
340
+ end<0 || end>=(ssize_t)ary_size) {
341
+ rb_raise( rb_eRangeError,
342
+ "beg=%"SZF"d,end=%"SZF"d is out of array size (%"SZF"u)",
343
+ beg, end, ary_size );
344
+ }
345
+ if (plen) *plen = len;
346
+ if (pbeg) *pbeg = beg;
347
+ if (pstep) *pstep = step;
348
+ }
349
+
350
+
351
+ void
352
+ nary_step_sequence( VALUE self, size_t *plen, double *pbeg, double *pstep )
353
+ {
354
+ VALUE vbeg, vend, vstep, vlen;
355
+ double dbeg, dend, dstep=1, dsize, err;
356
+ size_t size, n;
357
+
358
+ //vbeg = rb_ivar_get(self, id_beg);
359
+ vbeg = rb_funcall(self, id_beg, 0);
360
+ dbeg = NUM2DBL(vbeg);
361
+
362
+ //vend = rb_ivar_get(self, id_end);
363
+ vend = rb_funcall(self, id_end, 0);
364
+
365
+ vlen = rb_ivar_get(self, id_len);
366
+ vstep = rb_ivar_get(self, id_step);
367
+ //vlen = rb_funcall(self, id_len ,0);
368
+ //vstep = rb_funcall(self, id_step,0);
369
+
370
+ if (RTEST(vlen)) {
371
+ size = NUM2SIZE(vlen);
372
+
373
+ if (!RTEST(vstep)) {
374
+ if (RTEST(vend)) {
375
+ dend = NUM2DBL(vend);
376
+ if (EXCL(self)) {
377
+ n = size;
378
+ } else {
379
+ n = size-1;
380
+ }
381
+ if (n>0) {
382
+ dstep = (dend-dbeg)/n;
383
+ } else {
384
+ dstep = 1;
385
+ }
386
+ } else {
387
+ dstep = 1;
388
+ }
389
+ }
390
+ } else {
391
+ if (!RTEST(vstep)) {
392
+ dstep = 1;
393
+ } else {
394
+ dstep = NUM2DBL(vstep);
395
+ }
396
+ if (RTEST(vend)) {
397
+ dend = NUM2DBL(vend);
398
+ err = (fabs(dbeg)+fabs(dend)+fabs(dend-dbeg))/fabs(dstep)*DBL_EPSILON;
399
+ if (err>0.5) err=0.5;
400
+ dsize = (dend-dbeg)/dstep;
401
+ if (EXCL(self))
402
+ dsize -= err;
403
+ else
404
+ dsize += err;
405
+ dsize = floor(dsize) + 1;
406
+ if (dsize<0) dsize=0;
407
+ if (isinf(dsize) || isnan(dsize)) {
408
+ rb_raise(rb_eArgError, "not finite size");
409
+ }
410
+ size = dsize;
411
+ } else {
412
+ rb_raise(rb_eArgError, "cannot determine length argument");
413
+ }
414
+ }
415
+
416
+ if (plen) *plen = size;
417
+ if (pbeg) *pbeg = dbeg;
418
+ if (pstep) *pstep = dstep;
419
+ }
420
+
421
+ /*
422
+ static VALUE
423
+ step_each( VALUE self )
424
+ {
425
+ VALUE a;
426
+ double beg, step;
427
+ size_t i, size;
428
+
429
+ a = nary_step_parameters( self, Qnil );
430
+ beg = NUM2DBL(RARRAY_PTR(a)[0]);
431
+ step = NUM2DBL(RARRAY_PTR(a)[1]);
432
+ size = NUM2SIZE(RARRAY_PTR(a)[2]);
433
+
434
+ for (i=0; i<size; i++) {
435
+ rb_yield(rb_float_new(beg+i*step));
436
+ }
437
+ return self;
438
+ }
439
+ */
440
+
441
+ static VALUE
442
+ range_with_step( VALUE range, VALUE step )
443
+ {
444
+ return nary_step_new2( range, step, Qnil );
445
+ }
446
+
447
+ static VALUE
448
+ range_with_length( VALUE range, VALUE len )
449
+ {
450
+ return nary_step_new2( range, Qnil, len );
451
+ }
452
+
453
+
454
+ static VALUE
455
+ nary_s_step( int argc, VALUE *argv, VALUE mod )
456
+ {
457
+ VALUE self = rb_obj_alloc(na_cStep);
458
+ step_initialize(argc, argv, self);
459
+ return self;
460
+ }
461
+
462
+
463
+ VALUE
464
+ nary_is_sequence( VALUE arg )
465
+ {
466
+ if ( rb_obj_is_kind_of(arg, rb_cRange) )
467
+ return Qtrue;
468
+ if ( rb_obj_is_kind_of(arg, na_cStep) )
469
+ return Qtrue;
470
+ return Qfalse;
471
+ }
472
+
473
+
474
+
475
+ void
476
+ Init_nary_step()
477
+ {
478
+ na_cStep = rb_define_class_under(cNArray, "Step", rb_cObject);
479
+ rb_include_module(na_cStep, rb_mEnumerable);
480
+ rb_define_method(na_cStep, "initialize", step_initialize, -1);
481
+
482
+ //rb_define_method(na_cStep, "each", step_each, 0);
483
+
484
+ rb_define_method(na_cStep, "first", step_first, 0);
485
+ rb_define_method(na_cStep, "last", step_last, 0);
486
+ rb_define_method(na_cStep, "begin", step_first, 0);
487
+ rb_define_method(na_cStep, "end", step_last, 0);
488
+ rb_define_method(na_cStep, "step", step_step, 0);
489
+ rb_define_method(na_cStep, "length", step_length, 0);
490
+ rb_define_method(na_cStep, "size", step_length, 0);
491
+ rb_define_method(na_cStep, "exclude_end?", step_exclude_end_p, 0);
492
+ //rb_define_method(na_cStep, "to_s", step_to_s, 0);
493
+ //rb_define_method(na_cStep, "inspect", step_inspect, 0);
494
+ //rb_define_method(na_cStep, "parameters", nary_step_parameters, 1);
495
+
496
+ rb_define_method(rb_cRange, "%", range_with_step, 1);
497
+ rb_define_method(rb_cRange, "*", range_with_length, 1);
498
+
499
+ rb_define_singleton_method(cNArray, "step", nary_s_step, -1);
500
+
501
+ id_beg = rb_intern("begin");
502
+ id_end = rb_intern("end");
503
+ id_len = rb_intern("length");
504
+ id_step = rb_intern("step");
505
+ id_excl = rb_intern("excl");
506
+ }