numo-narray 0.9.0.1-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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,157 @@
1
+ /**
2
+ * @file SFMT.h
3
+ *
4
+ * @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom
5
+ * number generator
6
+ *
7
+ * @author Mutsuo Saito (Hiroshima University)
8
+ * @author Makoto Matsumoto (Hiroshima University)
9
+ *
10
+ * Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
11
+ * University. All rights reserved.
12
+ *
13
+ * The new BSD License is applied to this software.
14
+ * see LICENSE.txt
15
+ *
16
+ * @note We assume that your system has inttypes.h. If your system
17
+ * doesn't have inttypes.h, you have to typedef uint32_t and uint64_t,
18
+ * and you have to define PRIu64 and PRIx64 in this file as follows:
19
+ * @verbatim
20
+ typedef unsigned int uint32_t
21
+ typedef unsigned long long uint64_t
22
+ #define PRIu64 "llu"
23
+ #define PRIx64 "llx"
24
+ @endverbatim
25
+ * uint32_t must be exactly 32-bit unsigned integer type (no more, no
26
+ * less), and uint64_t must be exactly 64-bit unsigned integer type.
27
+ * PRIu64 and PRIx64 are used for printf function to print 64-bit
28
+ * unsigned int and 64-bit unsigned int in hexadecimal format.
29
+ */
30
+
31
+ #ifndef SFMT_H
32
+ #define SFMT_H
33
+
34
+ #include <stdio.h>
35
+
36
+ #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
37
+ #include <inttypes.h>
38
+ #elif defined(_MSC_VER) || defined(__BORLANDC__)
39
+ typedef unsigned int uint32_t;
40
+ typedef unsigned __int64 uint64_t;
41
+ #define inline __inline
42
+ #else
43
+ #include <inttypes.h>
44
+ #if defined(__GNUC__)
45
+ #define inline __inline__
46
+ #endif
47
+ #endif
48
+
49
+ #ifndef PRIu64
50
+ #if defined(_MSC_VER) || defined(__BORLANDC__)
51
+ #define PRIu64 "I64u"
52
+ #define PRIx64 "I64x"
53
+ #else
54
+ #define PRIu64 "llu"
55
+ #define PRIx64 "llx"
56
+ #endif
57
+ #endif
58
+
59
+ #if defined(__GNUC__)
60
+ #define ALWAYSINLINE __attribute__((always_inline))
61
+ #else
62
+ #define ALWAYSINLINE
63
+ #endif
64
+
65
+ #if defined(_MSC_VER)
66
+ #if _MSC_VER >= 1200
67
+ #define PRE_ALWAYS __forceinline
68
+ #else
69
+ #define PRE_ALWAYS inline
70
+ #endif
71
+ #else
72
+ #define PRE_ALWAYS inline
73
+ #endif
74
+
75
+ uint32_t gen_rand32(void);
76
+ uint64_t gen_rand64(void);
77
+ void fill_array32(uint32_t *array, int size);
78
+ void fill_array64(uint64_t *array, int size);
79
+ void init_gen_rand(uint32_t seed);
80
+ void init_by_array(uint32_t *init_key, int key_length);
81
+ const char *get_idstring(void);
82
+ int get_min_array_size32(void);
83
+ int get_min_array_size64(void);
84
+
85
+ /* These real versions are due to Isaku Wada */
86
+ /** generates a random number on [0,1]-real-interval */
87
+ inline static double to_real1(uint32_t v)
88
+ {
89
+ return v * (1.0/4294967295.0);
90
+ /* divided by 2^32-1 */
91
+ }
92
+
93
+ /** generates a random number on [0,1]-real-interval */
94
+ inline static double genrand_real1(void)
95
+ {
96
+ return to_real1(gen_rand32());
97
+ }
98
+
99
+ /** generates a random number on [0,1)-real-interval */
100
+ inline static double to_real2(uint32_t v)
101
+ {
102
+ return v * (1.0/4294967296.0);
103
+ /* divided by 2^32 */
104
+ }
105
+
106
+ /** generates a random number on [0,1)-real-interval */
107
+ inline static double genrand_real2(void)
108
+ {
109
+ return to_real2(gen_rand32());
110
+ }
111
+
112
+ /** generates a random number on (0,1)-real-interval */
113
+ inline static double to_real3(uint32_t v)
114
+ {
115
+ return (((double)v) + 0.5)*(1.0/4294967296.0);
116
+ /* divided by 2^32 */
117
+ }
118
+
119
+ /** generates a random number on (0,1)-real-interval */
120
+ inline static double genrand_real3(void)
121
+ {
122
+ return to_real3(gen_rand32());
123
+ }
124
+ /** These real versions are due to Isaku Wada */
125
+
126
+ /** generates a random number on [0,1) with 53-bit resolution*/
127
+ inline static double to_res53(uint64_t v)
128
+ {
129
+ return v * (1.0/18446744073709551616.0L);
130
+ }
131
+
132
+ /** generates a random number on [0,1) with 53-bit resolution from two
133
+ * 32 bit integers */
134
+ inline static double to_res53_mix(uint32_t x, uint32_t y)
135
+ {
136
+ return to_res53(x | ((uint64_t)y << 32));
137
+ }
138
+
139
+ /** generates a random number on [0,1) with 53-bit resolution
140
+ */
141
+ inline static double genrand_res53(void)
142
+ {
143
+ return to_res53(gen_rand64());
144
+ }
145
+
146
+ /** generates a random number on [0,1) with 53-bit resolution
147
+ using 32bit integer.
148
+ */
149
+ inline static double genrand_res53_mix(void)
150
+ {
151
+ uint32_t x, y;
152
+
153
+ x = gen_rand32();
154
+ y = gen_rand32();
155
+ return to_res53_mix(x, y);
156
+ }
157
+ #endif
@@ -0,0 +1,525 @@
1
+ /*
2
+ array.c
3
+ Numerical Array Extension for Ruby
4
+ (C) Copyright 1999-2011 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 "numo/narray.h"
13
+ //#include "narray_local.h"
14
+
15
+ /* Multi-Dimensional Array Investigation */
16
+ typedef struct {
17
+ size_t shape;
18
+ VALUE val;
19
+ } na_mdai_item_t;
20
+
21
+ typedef struct {
22
+ int capa;
23
+ na_mdai_item_t *item;
24
+ int type; // Ruby numeric type - investigated separately
25
+ VALUE na_type; // NArray type
26
+ VALUE int_max;
27
+ } na_mdai_t;
28
+
29
+ // Order of Ruby object.
30
+ enum { NA_NONE, NA_BIT, NA_INT32, NA_INT64, NA_RATIONAL,
31
+ NA_DFLOAT, NA_DCOMPLEX, NA_ROBJ, NA_NTYPES };
32
+
33
+ static VALUE
34
+ na_object_type(int type, VALUE v)
35
+ {
36
+ static VALUE int32_max = Qnil;
37
+ if (NIL_P(int32_max))
38
+ int32_max = ULONG2NUM(2147483647);
39
+
40
+ switch(TYPE(v)) {
41
+
42
+ case T_TRUE:
43
+ case T_FALSE:
44
+ if (type<NA_BIT)
45
+ return NA_BIT;
46
+ return type;
47
+
48
+ #if SIZEOF_LONG == 4
49
+ case T_FIXNUM:
50
+ if (type<NA_INT32)
51
+ return NA_INT32;
52
+ return type;
53
+ case T_BIGNUM:
54
+ if (type<NA_INT64) {
55
+ v = rb_funcall(v,rb_intern("abs"),0);
56
+ if (RTEST(rb_funcall(v,rb_intern("<="),1,int32_max))) {
57
+ if (type<NA_INT32)
58
+ return NA_INT32;
59
+ } else {
60
+ return NA_INT64;
61
+ }
62
+ }
63
+ return type;
64
+
65
+ #elif SIZEOF_LONG == 8
66
+ case T_FIXNUM:
67
+ if (type<NA_INT64) {
68
+ long x = NUM2LONG(v);
69
+ if (x<0) x=-x;
70
+ if (x<=2147483647) {
71
+ if (type<NA_INT32)
72
+ return NA_INT32;
73
+ } else {
74
+ return NA_INT64;
75
+ }
76
+ }
77
+ return type;
78
+ case T_BIGNUM:
79
+ if (type<NA_INT64)
80
+ return NA_INT64;
81
+ return type;
82
+ #else
83
+ case T_FIXNUM:
84
+ case T_BIGNUM:
85
+ if (type<NA_INT64) {
86
+ v = rb_funcall(v,rb_intern("abs"),0);
87
+ if (RTEST(rb_funcall(v,rb_intern("<="),1,int32_max))) {
88
+ if (type<NA_INT32)
89
+ return NA_INT32;
90
+ } else {
91
+ return NA_INT64;
92
+ }
93
+ }
94
+ return type;
95
+ #endif
96
+
97
+ case T_FLOAT:
98
+ if (type<NA_DFLOAT)
99
+ return NA_DFLOAT;
100
+ return type;
101
+
102
+ case T_NIL:
103
+ return type;
104
+
105
+ default:
106
+ if (CLASS_OF(v) == rb_const_get( rb_cObject, rb_intern("Complex") )) {
107
+ return NA_DCOMPLEX;
108
+ }
109
+ }
110
+ return NA_ROBJ;
111
+ }
112
+
113
+
114
+ #define MDAI_ATTR_TYPE(tp,v,attr) \
115
+ {tp = na_object_type(tp,rb_funcall(v,rb_intern(attr),0));}
116
+
117
+ void na_mdai_object_type(na_mdai_t *mdai, VALUE v)
118
+ {
119
+ if (IsNArray(v)) {
120
+ if (NIL_P(mdai->na_type)) {
121
+ mdai->na_type = CLASS_OF(v);
122
+ } else {
123
+ mdai->na_type = na_upcast(CLASS_OF(v), CLASS_OF(mdai->na_type));
124
+ }
125
+ } else if (rb_obj_is_kind_of(v, rb_cRange)) {
126
+ MDAI_ATTR_TYPE(mdai->type,v,"begin");
127
+ MDAI_ATTR_TYPE(mdai->type,v,"end");
128
+ } else if (rb_obj_is_kind_of(v, na_cStep)) {
129
+ MDAI_ATTR_TYPE(mdai->type,v,"begin");
130
+ MDAI_ATTR_TYPE(mdai->type,v,"end");
131
+ MDAI_ATTR_TYPE(mdai->type,v,"step");
132
+ } else {
133
+ mdai->type = na_object_type(mdai->type,v);
134
+ }
135
+ }
136
+
137
+
138
+ static na_mdai_t *
139
+ na_mdai_alloc(VALUE ary)
140
+ {
141
+ int i, n=4;
142
+ na_mdai_t *mdai;
143
+
144
+ mdai = ALLOC(na_mdai_t);
145
+ mdai->capa = n;
146
+ mdai->item = ALLOC_N( na_mdai_item_t, n );
147
+ for (i=0; i<n; i++) {
148
+ mdai->item[i].shape = 0;
149
+ mdai->item[i].val = Qnil;
150
+ }
151
+ mdai->item[0].val = ary;
152
+ mdai->type = NA_NONE;
153
+ mdai->na_type = Qnil;
154
+
155
+ return mdai;
156
+ }
157
+
158
+ static void
159
+ na_mdai_realloc(na_mdai_t *mdai, int n_extra)
160
+ {
161
+ int i, n;
162
+
163
+ i = mdai->capa;
164
+ mdai->capa += n_extra;
165
+ n = mdai->capa;
166
+ REALLOC_N( mdai->item, na_mdai_item_t, n );
167
+ for (; i<n; i++) {
168
+ mdai->item[i].shape = 0;
169
+ mdai->item[i].val = Qnil;
170
+ }
171
+ }
172
+
173
+ static void
174
+ na_mdai_free(na_mdai_t *mdai)
175
+ {
176
+ xfree(mdai->item);
177
+ xfree(mdai);
178
+ }
179
+
180
+
181
+ /* investigate ndim, shape, type of Array */
182
+ static int
183
+ na_mdai_investigate(na_mdai_t *mdai, int ndim)
184
+ {
185
+ ssize_t i;
186
+ int j;
187
+ size_t len, length;
188
+ double dbeg, dstep;
189
+ VALUE v;
190
+ VALUE val;
191
+
192
+ val = mdai->item[ndim-1].val;
193
+ len = RARRAY_LEN(val);
194
+
195
+ for (i=0; i < RARRAY_LEN(val); i++) {
196
+ v = RARRAY_AREF(val,i);
197
+
198
+ if (TYPE(v) == T_ARRAY) {
199
+ /* check recursive array */
200
+ for (j=0; j<ndim; j++) {
201
+ if (mdai->item[j].val == v)
202
+ rb_raise(rb_eStandardError,
203
+ "cannot convert from a recursive Array to NArray");
204
+ }
205
+ if ( ndim >= mdai->capa ) {
206
+ na_mdai_realloc(mdai,4);
207
+ }
208
+ mdai->item[ndim].val = v;
209
+ if ( na_mdai_investigate(mdai,ndim+1) ) {
210
+ len--; /* Array is empty */
211
+ }
212
+ }
213
+ else
214
+ if (rb_obj_is_kind_of(v, rb_cRange) || rb_obj_is_kind_of(v, na_cStep)) {
215
+ nary_step_sequence(v,&length,&dbeg,&dstep);
216
+ len += length-1;
217
+ na_mdai_object_type(mdai,v);
218
+ }
219
+ else {
220
+ na_mdai_object_type(mdai,v);
221
+
222
+ if (IsNArray(v)) {
223
+ int r;
224
+ narray_t *na;
225
+ GetNArray(v,na);
226
+ if ( na->ndim == 0 ) {
227
+ len--; /* NArray is empty */
228
+ } else {
229
+ if ( ndim+na->ndim > mdai->capa ) {
230
+ na_mdai_realloc(mdai,((na->ndim-1)/4+1)*4);
231
+ }
232
+ for ( j=0,r=ndim; j < na->ndim ; j++,r++ ) {
233
+ if ( mdai->item[r].shape < na->shape[j] )
234
+ mdai->item[r].shape = na->shape[j];
235
+ }
236
+ }
237
+ }
238
+ }
239
+ }
240
+
241
+ if (len==0) return 1; /* this array is empty */
242
+ if (mdai->item[ndim-1].shape < len) {
243
+ mdai->item[ndim-1].shape = len;
244
+ }
245
+ return 0;
246
+ }
247
+
248
+ static void
249
+ na_mdai_result(na_mdai_t *mdai, na_compose_t *nc)
250
+ {
251
+ int i, ndim;
252
+ VALUE tp;
253
+ size_t *shape;
254
+
255
+ // Dimension
256
+ for (i=0; i < mdai->capa && mdai->item[i].shape > 0; i++) ;
257
+ nc->ndim = ndim = i;
258
+ nc->shape = NULL;
259
+ nc->dtype = Qnil;
260
+
261
+ if (ndim>0) {
262
+ // Shape
263
+ //shape = ALLOC_N(size_t,i);
264
+ //for (i=0; i<*ndim; i++) {
265
+ // shape[i] = mdai->item[i].shape;
266
+ //}
267
+ nc->shape = shape = ALLOC_N(size_t,ndim);
268
+ for (i=0; i<ndim; i++) {
269
+ shape[i] = mdai->item[i].shape;
270
+ //printf("shape[%d]=%d\n",i,shape[i]);
271
+ //rb_ary_push( shape, SIZE2NUM(mdai->item[i].shape) );
272
+ }
273
+
274
+ // DataType
275
+ switch(mdai->type) {
276
+ case NA_BIT:
277
+ tp = numo_cBit;
278
+ break;
279
+ case NA_INT32:
280
+ tp = numo_cInt32;
281
+ break;
282
+ case NA_INT64:
283
+ tp = numo_cInt64;
284
+ break;
285
+ case NA_DFLOAT:
286
+ tp = numo_cDFloat;
287
+ break;
288
+ case NA_DCOMPLEX:
289
+ tp = numo_cDComplex;
290
+ break;
291
+ case NA_ROBJ:
292
+ tp = numo_cRObject;
293
+ break;
294
+ default:
295
+ tp = Qnil;
296
+ }
297
+ if (!NIL_P(mdai->na_type)) {
298
+ if (NIL_P(tp)) {
299
+ tp = mdai->na_type;
300
+ } else {
301
+ tp = na_upcast(mdai->na_type,tp);
302
+ }
303
+ }
304
+ nc->dtype = tp;
305
+ }
306
+ }
307
+
308
+
309
+ VALUE
310
+ na_ary_composition(VALUE ary)
311
+ {
312
+ volatile VALUE vmdai, vnc;
313
+ na_mdai_t *mdai;
314
+ na_compose_t *nc;
315
+ int j;
316
+
317
+ nc = ALLOC(na_compose_t);
318
+ vnc = Data_Wrap_Struct(rb_cData, 0, -1, nc);
319
+ if (TYPE(ary) == T_ARRAY) {
320
+ mdai = na_mdai_alloc(ary);
321
+ vmdai = Data_Wrap_Struct(rb_cData, 0, na_mdai_free, mdai);
322
+ na_mdai_investigate(mdai, 1);
323
+ na_mdai_result(mdai, nc);
324
+ rb_gc_force_recycle(vmdai);
325
+ } else if (IsNArray(ary)) {
326
+ narray_t *na;
327
+ GetNArray(ary,na);
328
+ nc->ndim = na->ndim;
329
+ nc->shape = ALLOC_N(size_t, na->ndim);
330
+ for (j=0; j<na->ndim; j++) {
331
+ nc->shape[j] = na->shape[j];
332
+ }
333
+ nc->dtype = CLASS_OF(ary);
334
+ } else {
335
+ rb_bug("invalid type for md-array: %s", rb_class2name(CLASS_OF(ary)));
336
+ }
337
+ return vnc;
338
+ }
339
+
340
+
341
+ static VALUE
342
+ na_s_array_shape(VALUE mod, VALUE ary)
343
+ {
344
+ volatile VALUE vnc;
345
+ VALUE shape;
346
+ na_compose_t *nc;
347
+ int i;
348
+
349
+ if (TYPE(ary)!=T_ARRAY) {
350
+ // 0-dimension
351
+ return rb_ary_new();
352
+ }
353
+ // investigate MD-Array
354
+ vnc = na_ary_composition(ary);
355
+ Data_Get_Struct(vnc, na_compose_t, nc);
356
+ shape = rb_ary_new2(nc->ndim);
357
+ for (i=0; i<nc->ndim; i++) {
358
+ rb_ary_push( shape, SIZE2NUM(nc->shape[i]) );
359
+ }
360
+ return shape;
361
+ }
362
+
363
+
364
+ VALUE
365
+ na_ary_composition_dtype(VALUE ary)
366
+ {
367
+ volatile VALUE vnc;
368
+ na_compose_t *nc;
369
+
370
+ switch(TYPE(ary)) {
371
+ case T_ARRAY:
372
+ vnc = na_ary_composition(ary);
373
+ Data_Get_Struct(vnc, na_compose_t, nc);
374
+ return nc->dtype;
375
+ }
376
+ return CLASS_OF(ary);
377
+ }
378
+
379
+ static VALUE
380
+ na_s_array_type(VALUE mod, VALUE ary)
381
+ {
382
+ return na_ary_composition_dtype(ary);
383
+ }
384
+
385
+
386
+
387
+ /*
388
+ Generate NArray object. NArray datatype is automatically selected.
389
+ @overload [](elements)
390
+ @param [Numeric,Array] elements
391
+ @return [NArray]
392
+ */
393
+ static VALUE
394
+ nary_s_bracket(VALUE klass, VALUE ary)
395
+ {
396
+ VALUE dtype=Qnil;
397
+
398
+ if (TYPE(ary)!=T_ARRAY) {
399
+ rb_bug("Argument is not array");
400
+ }
401
+
402
+ dtype = na_ary_composition_dtype(ary);
403
+
404
+ if (RTEST(rb_obj_is_kind_of(dtype,rb_cClass))) {
405
+ if (RTEST(rb_funcall(dtype,rb_intern("<="),1,cNArray))) {
406
+ return rb_funcall(dtype,rb_intern("cast"),1,ary);
407
+ }
408
+ }
409
+ rb_raise(nary_eCastError, "cannot convert to NArray");
410
+ return Qnil;
411
+ }
412
+
413
+
414
+ VALUE
415
+ nst_check_compatibility(VALUE self, VALUE ary);
416
+
417
+
418
+ /* investigate ndim, shape, type of Array */
419
+ static int
420
+ na_mdai_for_struct(na_mdai_t *mdai, int ndim)
421
+ {
422
+ size_t i;
423
+ int j, r;
424
+ size_t len;
425
+ VALUE v;
426
+ VALUE val;
427
+ narray_t *na;
428
+
429
+ //fprintf(stderr,"ndim=%d\n",ndim); rb_p(mdai->na_type);
430
+ if (ndim>4) { abort(); }
431
+ val = mdai->item[ndim].val;
432
+
433
+ //fpintf(stderr,"val = "); rb_p(val);
434
+
435
+ if (CLASS_OF(val) == mdai->na_type) {
436
+ GetNArray(val,na);
437
+ if ( ndim+na->ndim > mdai->capa ) {
438
+ abort();
439
+ na_mdai_realloc(mdai,((na->ndim-1)/4+1)*4);
440
+ }
441
+ for ( j=0,r=ndim; j < na->ndim; j++,r++ ) {
442
+ if ( mdai->item[r].shape < na->shape[j] )
443
+ mdai->item[r].shape = na->shape[j];
444
+ }
445
+ return 1;
446
+ }
447
+
448
+ if (TYPE(val) == T_ARRAY) {
449
+ /* check recursive array */
450
+ for (j=0; j<ndim-1; j++) {
451
+ if (mdai->item[j].val == val)
452
+ rb_raise(rb_eStandardError,
453
+ "cannot convert from a recursive Array to NArray");
454
+ }
455
+ //fprintf(stderr,"check:"); rb_p(val);
456
+ // val is a Struct recort
457
+ if (RTEST( nst_check_compatibility(mdai->na_type, val) )) {
458
+ //fputs("compati\n",stderr);
459
+ return 1;
460
+ }
461
+ // otherwise, multi-dimention
462
+ if (ndim >= mdai->capa) {
463
+ //fprintf(stderr,"exeed capa\n"); abort();
464
+ na_mdai_realloc(mdai,4);
465
+ }
466
+ // finally, multidimension-check
467
+ len = RARRAY_LEN(val);
468
+ for (i=0; i < len; i++) {
469
+ v = RARRAY_AREF(val,i);
470
+ if (TYPE(v) != T_ARRAY) {
471
+ //abort();
472
+ return 0;
473
+ }
474
+ }
475
+ for (i=0; i < len; i++) {
476
+ v = RARRAY_AREF(val,i);
477
+ //fprintf(stderr,"check:"); rb_p(v);
478
+ mdai->item[ndim+1].val = v;
479
+ if ( na_mdai_for_struct( mdai, ndim+1 ) == 0 ) {
480
+ //fprintf(stderr,"not struct:"); rb_p(v);
481
+ //abort();
482
+ return 0;
483
+ }
484
+ }
485
+ if (mdai->item[ndim].shape < len) {
486
+ mdai->item[ndim].shape = len;
487
+ }
488
+ return 1;
489
+ }
490
+
491
+ //fprintf(stderr,"invalid for struct:"); rb_p(val); abort();
492
+ return 0;
493
+ }
494
+
495
+
496
+ VALUE
497
+ na_ary_composition_for_struct(VALUE nstruct, VALUE ary)
498
+ {
499
+ volatile VALUE vmdai, vnc;
500
+ na_mdai_t *mdai;
501
+ na_compose_t *nc;
502
+
503
+ mdai = na_mdai_alloc(ary);
504
+ mdai->na_type = nstruct;
505
+ vmdai = Data_Wrap_Struct(rb_cData, 0, na_mdai_free, mdai);
506
+ na_mdai_for_struct(mdai, 0);
507
+ nc = ALLOC(na_compose_t);
508
+ vnc = Data_Wrap_Struct(rb_cData, 0, -1, nc);
509
+ na_mdai_result(mdai, nc);
510
+ //fprintf(stderr,"nc->ndim=%d\n",nc->ndim);
511
+ rb_gc_force_recycle(vmdai);
512
+ return vnc;
513
+ }
514
+
515
+
516
+
517
+ void
518
+ Init_nary_array()
519
+ {
520
+ //rb_define_singleton_method(cNArray, "mdai", na_mdai, 1);
521
+ rb_define_singleton_method(cNArray, "array_shape", na_s_array_shape, 1);
522
+ rb_define_singleton_method(cNArray, "array_type", na_s_array_type, 1);
523
+
524
+ rb_define_singleton_method(cNArray, "[]", nary_s_bracket, -2);
525
+ }