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,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
+ }