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,872 @@
1
+ /*
2
+ nstrut.c
3
+ Numerical Array Extension for Ruby
4
+ (C) Copyright 1999-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 "numo/narray.h"
13
+ #include "numo/template.h"
14
+
15
+ #define cT numo_cStruct
16
+ VALUE cT;
17
+
18
+ static VALUE
19
+ nst_allocate(VALUE self)
20
+ {
21
+ narray_t *na;
22
+ char *ptr;
23
+ VALUE velmsz;
24
+
25
+ GetNArray(self,na);
26
+
27
+ switch(NA_TYPE(na)) {
28
+ case NARRAY_DATA_T:
29
+ ptr = NA_DATA_PTR(na);
30
+ if (na->size > 0 && ptr == NULL) {
31
+ velmsz = rb_const_get(CLASS_OF(self), rb_intern("element_byte_size"));
32
+ ptr = xmalloc(NUM2SIZE(velmsz) * na->size);
33
+ NA_DATA_PTR(na) = ptr;
34
+ }
35
+ break;
36
+ case NARRAY_VIEW_T:
37
+ rb_funcall(NA_VIEW_DATA(na), rb_intern("allocate"), 0);
38
+ break;
39
+ case NARRAY_FILEMAP_T:
40
+ //ptr = ((narray_filemap_t*)na)->ptr;
41
+ // to be implemented
42
+ default:
43
+ rb_bug("invalid narray type : %d",NA_TYPE(na));
44
+ }
45
+ return self;
46
+ }
47
+
48
+
49
+ static inline VALUE
50
+ nst_definitions(VALUE nst)
51
+ {
52
+ return rb_const_get(nst, rb_intern("DEFINITIONS"));
53
+ }
54
+
55
+ static VALUE
56
+ nst_definition(VALUE nst, VALUE idx)
57
+ {
58
+ long i;
59
+ VALUE def = nst_definitions(CLASS_OF(nst));
60
+ long len = RARRAY_LEN(def);
61
+
62
+ if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {
63
+ ID id = rb_to_id(idx);
64
+ for (i=0; i<len; i++) {
65
+ VALUE key = RARRAY_AREF(RARRAY_AREF(def,i),0);
66
+ if (SYM2ID(key) == id) {
67
+ return RARRAY_AREF(def,i);
68
+ }
69
+ }
70
+ } else if (rb_obj_is_kind_of(idx,rb_cNumeric)) {
71
+ i = NUM2LONG(idx);
72
+ if (i<-len || i>=len) {
73
+ rb_raise(rb_eIndexError,"offset %"SZF"u out of range of struct(size:%ld)", i, len);
74
+ }
75
+ return RARRAY_AREF(def,i);
76
+ }
77
+ return Qnil;
78
+ }
79
+
80
+
81
+
82
+ void na_copy_array_structure(VALUE self, VALUE view);
83
+
84
+ VALUE
85
+ na_make_view_struct(VALUE self, VALUE dtype, VALUE offset)
86
+ {
87
+ size_t i, n;
88
+ int j, k, ndim;
89
+ size_t *shape;
90
+ size_t *idx1, *idx2;
91
+ ssize_t stride;
92
+ stridx_t *stridx;
93
+ narray_t *na, *nt;
94
+ narray_view_t *na1, *na2;
95
+ VALUE klass;
96
+ volatile VALUE view;
97
+
98
+ GetNArray(self,na);
99
+
100
+ // build from Numo::Struct
101
+ if (rb_obj_is_kind_of(dtype,cNArray)) {
102
+ GetNArray(dtype,nt);
103
+ ndim = na->ndim + nt->ndim;
104
+ shape = ALLOCA_N(size_t,ndim);
105
+ // struct dimensions
106
+ for (j=0; j<na->ndim; j++) {
107
+ shape[j] = na->shape[j];
108
+ }
109
+ // member dimension
110
+ for (j=na->ndim,k=0; j<ndim; j++,k++) {
111
+ shape[j] = nt->shape[k];
112
+ }
113
+ klass = CLASS_OF(dtype);
114
+ stridx = ALLOC_N(stridx_t, ndim);
115
+ stride = na_dtype_elmsz(klass);
116
+ for (j=ndim,k=nt->ndim; k; ) {
117
+ SDX_SET_STRIDE(stridx[--j],stride);
118
+ stride *= nt->shape[--k];
119
+ }
120
+ } else {
121
+ ndim = na->ndim;
122
+ shape = ALLOCA_N(size_t,ndim);
123
+ for (j=0; j<ndim; j++) {
124
+ shape[j] = na->shape[j];
125
+ }
126
+ klass = CLASS_OF(self);
127
+ if (TYPE(dtype)==T_CLASS) {
128
+ if (RTEST(rb_class_inherited_p(dtype,cNArray))) {
129
+ klass = dtype;
130
+ }
131
+ }
132
+ stridx = ALLOC_N(stridx_t, ndim);
133
+ }
134
+
135
+ view = na_s_allocate_view(klass);
136
+ na_copy_flags(self, view);
137
+ GetNArrayView(view, na2);
138
+ na_setup_shape((narray_t*)na2, ndim, shape);
139
+ na2->stridx = stridx;
140
+
141
+ switch(na->type) {
142
+ case NARRAY_DATA_T:
143
+ case NARRAY_FILEMAP_T:
144
+ stride = na_get_elmsz(self);
145
+ for (j=na->ndim; j--;) {
146
+ SDX_SET_STRIDE(na2->stridx[j], stride);
147
+ stride *= na->shape[j];
148
+ }
149
+ na2->offset = 0;
150
+ na2->data = self;
151
+ break;
152
+ case NARRAY_VIEW_T:
153
+ GetNArrayView(self, na1);
154
+ for (j=na1->base.ndim; j--; ) {
155
+ if (SDX_IS_INDEX(na1->stridx[j])) {
156
+ n = na1->base.shape[j];
157
+ idx1 = SDX_GET_INDEX(na1->stridx[j]);
158
+ idx2 = ALLOC_N(size_t, na1->base.shape[j]);
159
+ for (i=0; i<n; i++) {
160
+ idx2[i] = idx1[i];
161
+ }
162
+ SDX_SET_INDEX(na2->stridx[j],idx2);
163
+ } else {
164
+ na2->stridx[j] = na1->stridx[j];
165
+ }
166
+ }
167
+ na2->offset = na1->offset;
168
+ na2->data = na1->data;
169
+ break;
170
+ }
171
+
172
+ if (RTEST(offset)) {
173
+ na2->offset += NUM2SIZE(offset);
174
+ }
175
+
176
+ return view;
177
+ }
178
+
179
+
180
+ VALUE
181
+ nst_field_view(VALUE self, VALUE idx)
182
+ {
183
+ VALUE def, type, ofs;
184
+
185
+ def = nst_definition(self, idx);
186
+ if (!RTEST(def)) {
187
+ idx = rb_funcall(idx, rb_intern("to_s"), 0);
188
+ rb_raise(rb_eTypeError, "Invalid field: '%s' for struct %s",
189
+ StringValuePtr(idx), rb_class2name(CLASS_OF(self)));
190
+ }
191
+ type = RARRAY_AREF(def,1);
192
+ ofs = RARRAY_AREF(def,2);
193
+ return na_make_view_struct(self, type, ofs);
194
+ }
195
+
196
+ VALUE
197
+ nst_field(VALUE self, VALUE idx)
198
+ {
199
+ VALUE obj;
200
+ narray_view_t *nv;
201
+
202
+ obj = nst_field_view(self,idx);
203
+ GetNArrayView(obj,nv);
204
+ if (nv->base.ndim==0) {
205
+ obj = rb_funcall(obj,rb_intern("extract"),0);
206
+ }
207
+ return obj;
208
+ }
209
+
210
+ VALUE
211
+ nst_field_set(VALUE self, VALUE idx, VALUE other)
212
+ {
213
+ VALUE obj;
214
+
215
+ obj = nst_field_view(self,idx);
216
+ rb_funcall(obj,rb_intern("store"),1,other);
217
+ return other;
218
+ }
219
+
220
+
221
+ static VALUE
222
+ nst_method_missing(int argc, VALUE *argv, VALUE self)
223
+ {
224
+ VALUE s, tag, obj;
225
+
226
+ if (argc == 2) {
227
+ s = rb_sym_to_s(argv[0]);
228
+ if (RSTRING_PTR(s)[RSTRING_LEN(s)-1] == '=') {
229
+ tag = rb_str_intern(rb_str_new(RSTRING_PTR(s), RSTRING_LEN(s)-1));
230
+ obj = nst_field(self, tag);
231
+ if (RTEST(obj)) {
232
+ rb_funcall(obj, rb_intern("store"), 1, argv[1]);
233
+ return argv[1];
234
+ }
235
+ }
236
+ return rb_call_super(argc,argv);
237
+ }
238
+ if (argc == 1) {
239
+ obj = nst_field(self,argv[0]);
240
+ if (RTEST(obj)) {
241
+ return obj;
242
+ }
243
+ }
244
+ return rb_call_super(argc,argv);
245
+ }
246
+
247
+
248
+ /*
249
+ Foo = Numo::Struct.new {
250
+ int8 :byte
251
+ float64 :float, [2,2]
252
+ dcomplex :compl
253
+ }
254
+ */
255
+ static VALUE
256
+ nst_s_new(int argc, VALUE *argv, VALUE klass)
257
+ {
258
+ VALUE name=Qnil, rest, size;
259
+ VALUE st, members;
260
+ ID id;
261
+
262
+ rb_scan_args(argc, argv, "0*", &rest);
263
+ if (RARRAY_LEN(rest)>0) {
264
+ name = RARRAY_AREF(rest,0);
265
+ if (!NIL_P(name)) {
266
+ VALUE tmp = rb_check_string_type(name);
267
+ if (!NIL_P(tmp)) {
268
+ rb_ary_shift(rest);
269
+ } else {
270
+ name = Qnil;
271
+ }
272
+ }
273
+ }
274
+
275
+ if (NIL_P(name)) {
276
+ st = rb_class_new(klass);
277
+ rb_make_metaclass(st, RBASIC(klass)->klass);
278
+ rb_class_inherited(klass, st);
279
+ }
280
+ else {
281
+ char *cname = StringValuePtr(name);
282
+ id = rb_intern(cname);
283
+ if (!rb_is_const_id(id)) {
284
+ rb_name_error(id, "identifier %s needs to be constant", cname);
285
+ }
286
+ if (rb_const_defined_at(klass, id)) {
287
+ rb_warn("redefining constant Struct::%s", cname);
288
+ rb_mod_remove_const(klass, ID2SYM(id));
289
+ }
290
+ st = rb_define_class_under(klass, rb_id2name(id), klass);
291
+ }
292
+
293
+ rb_iv_set(st, "__members__", rb_ary_new());
294
+ rb_iv_set(st, "__offset__", INT2FIX(0));
295
+
296
+ if (rb_block_given_p()) {
297
+ rb_mod_module_eval(0, 0, st);
298
+ }
299
+
300
+ size = rb_iv_get(st, "__offset__");
301
+ members = rb_iv_get(st, "__members__");
302
+ //printf("size=%d\n",NUM2INT(size));
303
+ rb_define_const(st, CONTIGUOUS_STRIDE, size);
304
+ rb_define_const(st, ELEMENT_BYTE_SIZE, size);
305
+ rb_define_const(st, ELEMENT_BIT_SIZE, rb_funcall(size,'*',1,INT2FIX(8)));
306
+
307
+ OBJ_FREEZE(members);
308
+ rb_define_const(st, "DEFINITIONS", members);
309
+
310
+ rb_define_singleton_method(st, "new", rb_class_new_instance, -1);
311
+ //rb_define_singleton_method(st, "[]", rb_class_new_instance, -1);
312
+ rb_define_method(st, "allocate", nst_allocate, 0);
313
+
314
+ return st;
315
+ }
316
+
317
+
318
+ static VALUE
319
+ nstruct_add_type(VALUE type, int argc, VALUE *argv, VALUE nst)
320
+ {
321
+ VALUE ofs, size;
322
+ ID id;
323
+ int i;
324
+ VALUE name=Qnil;
325
+ size_t *shape=NULL;
326
+ int ndim=0;
327
+ ssize_t stride;
328
+ narray_view_t *nt;
329
+ int j;
330
+
331
+ for (i=0; i<argc; i++) {
332
+ switch(TYPE(argv[i])) {
333
+ case T_STRING:
334
+ case T_SYMBOL:
335
+ if (NIL_P(name)) {
336
+ name = argv[i];
337
+ break;
338
+ }
339
+ rb_raise(rb_eArgError,"multiple name in struct definition");
340
+ case T_ARRAY:
341
+ if (shape) {
342
+ rb_raise(rb_eArgError,"multiple shape in struct definition");
343
+ }
344
+ ndim = RARRAY_LEN(argv[i]);
345
+ if (ndim > NA_MAX_DIMENSION) {
346
+ rb_raise(rb_eArgError,"too large number of dimensions");
347
+ }
348
+ if (ndim == 0) {
349
+ rb_raise(rb_eArgError,"array is empty");
350
+ }
351
+ shape = ALLOCA_N(size_t, ndim);
352
+ na_array_to_internal_shape(Qnil, argv[i], shape);
353
+ break;
354
+ }
355
+ }
356
+
357
+ id = rb_to_id(name);
358
+ name = ID2SYM(id);
359
+ if (rb_obj_is_kind_of(type,cNArray)) {
360
+ narray_t *na;
361
+ GetNArray(type,na);
362
+ type = CLASS_OF(type);
363
+ ndim = na->ndim;
364
+ shape = na->shape;
365
+ }
366
+ type = rb_narray_view_new(type,ndim,shape);
367
+ GetNArrayView(type,nt);
368
+
369
+ nt->stridx = ALLOC_N(stridx_t,ndim);
370
+ stride = na_dtype_elmsz(CLASS_OF(type));
371
+ for (j=ndim; j--; ) {
372
+ SDX_SET_STRIDE(nt->stridx[j], stride);
373
+ stride *= shape[j];
374
+ }
375
+
376
+ ofs = rb_iv_get(nst, "__offset__");
377
+ nt->offset = NUM2SIZE(ofs);
378
+
379
+ size = rb_funcall(type, rb_intern("byte_size"), 0);
380
+ rb_iv_set(nst, "__offset__", rb_funcall(ofs,'+',1,size));
381
+ rb_ary_push(rb_iv_get(nst,"__members__"),
382
+ rb_ary_new3(4,name,type,ofs,size)); // <- field definition
383
+ return Qnil;
384
+ }
385
+
386
+
387
+ static VALUE
388
+ nst_extract(VALUE self)
389
+ {
390
+ return self;
391
+ }
392
+
393
+
394
+ static void
395
+ iter_nstruct_to_a(na_loop_t *const lp)
396
+ {
397
+ long i, len;
398
+ VALUE opt, types, defs, def;
399
+ VALUE elmt, velm, vary;
400
+ size_t ofs, pos;
401
+ narray_view_t *ne;
402
+
403
+ opt = lp->option;
404
+ types = RARRAY_AREF(opt,0);
405
+ defs = RARRAY_AREF(opt,1);
406
+ pos = lp->args[0].iter[0].pos;
407
+
408
+ len = RARRAY_LEN(types);
409
+ vary = rb_ary_new2(len);
410
+
411
+ for (i=0; i<len; i++) {
412
+ def = RARRAY_AREF(defs,i);
413
+ ofs = NUM2SIZE(RARRAY_AREF(def,2));
414
+ //ofs = NUM2SIZE(RARRAY_AREF(ofsts,i));
415
+ elmt = RARRAY_AREF(types,i);
416
+ GetNArrayView(elmt,ne);
417
+ ne->offset = pos + ofs;
418
+ if (ne->base.ndim==0) {
419
+ velm = rb_funcall(elmt,rb_intern("extract"),0);
420
+ } else {
421
+ velm = rb_funcall(elmt,rb_intern("to_a"),0);
422
+ }
423
+ rb_ary_push(vary, velm);
424
+ }
425
+ rb_ary_push(lp->args[1].value, vary);
426
+ }
427
+
428
+ static VALUE
429
+ nst_create_member_views(VALUE self)
430
+ {
431
+ VALUE defs, def, types, type, elmt;
432
+ long i, len;
433
+ narray_view_t *ne;
434
+
435
+ defs = nst_definitions(CLASS_OF(self));
436
+ len = RARRAY_LEN(defs);
437
+ types = rb_ary_new2(len);
438
+ //ofsts = rb_ary_new2(len);
439
+ for (i=0; i<len; i++) {
440
+ def = RARRAY_AREF(defs,i);
441
+ type = RARRAY_AREF(def,1);
442
+ //ofst = RARRAY_AREF(def,2);
443
+ elmt = na_make_view(type);
444
+ rb_ary_push(types, elmt);
445
+ //rb_ary_push(ofsts, ofst);
446
+ GetNArrayView(elmt,ne);
447
+ ne->data = na_original_data(self);
448
+ }
449
+ return rb_assoc_new(types,defs);
450
+ }
451
+
452
+ static VALUE
453
+ nary_struct_to_a(VALUE self)
454
+ {
455
+ volatile VALUE opt;
456
+ ndfunc_arg_in_t ain[3] = {{Qnil,0},{sym_loop_opt},{sym_option}};
457
+ ndfunc_arg_out_t aout[1] = {{rb_cArray,0}}; // dummy?
458
+ ndfunc_t ndf = { iter_nstruct_to_a, NO_LOOP, 3, 1, ain, aout };
459
+
460
+ opt = nst_create_member_views(self);
461
+ return na_ndloop_cast_narray_to_rarray(&ndf, self, opt);
462
+ }
463
+
464
+
465
+
466
+ // ---
467
+ static size_t
468
+ check_array(VALUE item) {
469
+ narray_t *na;
470
+
471
+ if (TYPE(item) == T_ARRAY) {
472
+ return 1;
473
+ }
474
+ if (RTEST(rb_obj_is_kind_of(item, cNArray))) {
475
+ GetNArray(item,na);
476
+ if (na->ndim == 1) {
477
+ return 1;
478
+ } else {
479
+ return 0;
480
+ }
481
+ }
482
+ return 0;
483
+ }
484
+
485
+ static size_t
486
+ check_array_1d(VALUE item, size_t size) {
487
+ narray_t *na;
488
+ size_t i, len;
489
+
490
+ if (TYPE(item) == T_ARRAY) {
491
+ len = RARRAY_LEN(item);
492
+ if (size != len) {
493
+ return 0;
494
+ }
495
+ for (i=0; i<len; i++) {
496
+ if (!check_array(RARRAY_AREF(item,i))) {
497
+ return 0;
498
+ }
499
+ }
500
+ return 1;
501
+ }
502
+ if (RTEST(rb_obj_is_kind_of(item, cNArray))) {
503
+ GetNArray(item,na);
504
+ if (na->ndim == 1 && na->size == size) {
505
+ return 1;
506
+ } else {
507
+ return 0;
508
+ }
509
+ }
510
+ return 0;
511
+ }
512
+
513
+ VALUE
514
+ nst_check_compatibility(VALUE nst, VALUE ary)
515
+ {
516
+ VALUE defs, def, type, item;
517
+ long len, i;
518
+ narray_t *nt;
519
+
520
+ if (TYPE(ary) != T_ARRAY) {
521
+ if (nst==CLASS_OF(ary)) { // same Struct
522
+ return Qtrue;
523
+ }
524
+ return Qfalse;
525
+ }
526
+ defs = nst_definitions(nst);
527
+ len = RARRAY_LEN(defs);
528
+
529
+ if (len != RARRAY_LEN(ary)) {
530
+ //puts("pass2");
531
+ return Qfalse;
532
+ }
533
+ for (i=0; i<len; i++) {
534
+ def = RARRAY_AREF(defs,i);
535
+ type = RARRAY_AREF(def,1);
536
+ GetNArray(type,nt);
537
+ item = RARRAY_AREF(ary,i);
538
+ if (nt->ndim == 0) {
539
+ if (check_array(item)) {
540
+ //puts("pass3");
541
+ return Qfalse;
542
+ }
543
+ } else if (nt->ndim == 1) {
544
+ if (!check_array_1d(item, nt->size)) {
545
+ //puts("pass4");
546
+ return Qfalse;
547
+ }
548
+ } else {
549
+ // multi-dimension member
550
+ volatile VALUE vnc;
551
+ na_compose_t *nc;
552
+ int j;
553
+
554
+ //rb_p(item);
555
+ vnc = na_ary_composition(item);
556
+ //puts("pass2");
557
+ Data_Get_Struct(vnc, na_compose_t, nc);
558
+ if (nt->ndim != nc->ndim) {
559
+ return Qfalse;
560
+ }
561
+ for (j=0; j<nc->ndim; j++) {
562
+ if (nc->shape[j] != nt->shape[j]) {
563
+ return Qfalse;
564
+ }
565
+ }
566
+ return Qtrue;
567
+ }
568
+ }
569
+ return Qtrue;
570
+ }
571
+
572
+
573
+
574
+ VALUE na_ary_composition_for_struct(VALUE nstruct, VALUE ary);
575
+
576
+ // ------
577
+ static void
578
+ iter_nstruct_from_a(na_loop_t *const lp)
579
+ {
580
+ long i, len;
581
+ VALUE ary;
582
+ VALUE types, defs, def;
583
+ VALUE elmt, item;
584
+ size_t ofs;
585
+ narray_view_t *ne;
586
+
587
+ types = RARRAY_AREF(lp->option,0);
588
+ defs = RARRAY_AREF(lp->option,1);
589
+
590
+ len = RARRAY_LEN(types);
591
+ ary = lp->args[0].value;
592
+ //rb_p(CLASS_OF(ary));rb_p(ary);
593
+
594
+ for (i=0; i<len; i++) {
595
+ def = RARRAY_AREF(defs,i);
596
+ ofs = NUM2SIZE(RARRAY_AREF(def,2));
597
+ elmt = RARRAY_AREF(types,i);
598
+ GetNArrayView(elmt,ne);
599
+ ne->offset = lp->args[1].iter[0].pos + ofs;
600
+ item = RARRAY_AREF(ary,i);
601
+ //rb_p(ary);
602
+ //rb_p(item);
603
+ //rb_p(elmt);
604
+ //abort();
605
+ rb_funcall(elmt, rb_intern("store"), 1, item);
606
+ }
607
+ }
608
+
609
+ static VALUE
610
+ nary_struct_cast_array(VALUE klass, VALUE rary)
611
+ {
612
+ volatile VALUE vnc, nary;
613
+ narray_t *na;
614
+ na_compose_t *nc;
615
+ VALUE opt;
616
+ ndfunc_arg_in_t ain[3] = {{rb_cArray,0},{Qnil,0},{sym_option}};
617
+ ndfunc_t ndf = { iter_nstruct_from_a, NO_LOOP, 3, 0, ain, 0 };
618
+
619
+ //fprintf(stderr,"rary:");rb_p(rary);
620
+ //fprintf(stderr,"class_of(rary):");rb_p(CLASS_OF(rary));
621
+
622
+ vnc = na_ary_composition_for_struct(klass, rary);
623
+ Data_Get_Struct(vnc, na_compose_t, nc);
624
+ nary = rb_narray_new(klass, nc->ndim, nc->shape);
625
+ GetNArray(nary,na);
626
+ //fprintf(stderr,"na->size=%lu\n",na->size);
627
+ //fprintf(stderr,"na->ndim=%d\n",na->ndim);
628
+ if (na->size>0) {
629
+ opt = nst_create_member_views(nary);
630
+ rb_funcall(nary, rb_intern("allocate"), 0);
631
+ na_ndloop_cast_rarray_to_narray2(&ndf, rary, nary, opt);
632
+ }
633
+ return nary;
634
+ }
635
+
636
+ static inline VALUE
637
+ nary_struct_s_cast(VALUE klass, VALUE rary)
638
+ {
639
+ return nary_struct_cast_array(klass, rary);
640
+ }
641
+
642
+
643
+
644
+ static void
645
+ iter_struct_store_struct(na_loop_t *const lp)
646
+ {
647
+ size_t i, s1, s2;
648
+ char *p1, *p2;
649
+ size_t *idx1, *idx2;
650
+ size_t elmsz;
651
+ char *x, *y;
652
+
653
+ INIT_COUNTER(lp, i);
654
+ INIT_PTR_IDX(lp, 0, p1, s1, idx1);
655
+ INIT_PTR_IDX(lp, 1, p2, s2, idx2);
656
+ INIT_ELMSIZE(lp, 0, elmsz);
657
+ if (idx2) {
658
+ if (idx1) {
659
+ for (; i--;) {
660
+ x = (char*)(p1+*idx1); idx1++;
661
+ y = (char*)(p2+*idx2); idx2++;
662
+ memcpy(x,y,elmsz);
663
+ }
664
+ } else {
665
+ for (; i--;) {
666
+ x = (char*)p1; p1+=s1;
667
+ y = (char*)(p2+*idx2); idx2++;
668
+ memcpy(x,y,elmsz);
669
+ }
670
+ }
671
+ } else {
672
+ if (idx1) {
673
+ for (; i--;) {
674
+ x = (char*)(p1+*idx1); idx1++;
675
+ y = (char*)p2; p2+=s2;
676
+ memcpy(x,y,elmsz);
677
+ }
678
+ } else {
679
+ for (; i--;) {
680
+ x = (char*)p1; p1+=s1;
681
+ y = (char*)p2; p2+=s2;
682
+ memcpy(x,y,elmsz);
683
+ }
684
+ }
685
+ }
686
+ }
687
+
688
+
689
+ static VALUE
690
+ nary_struct_store_struct(VALUE self, VALUE obj)
691
+ {
692
+ ndfunc_arg_in_t ain[2] = {{OVERWRITE,0},{Qnil,0}};
693
+ ndfunc_t ndf = { iter_struct_store_struct, FULL_LOOP, 2, 0, ain, 0 };
694
+
695
+ na_ndloop(&ndf, 2, self, obj);
696
+ return self;
697
+ }
698
+
699
+
700
+
701
+
702
+ static inline VALUE
703
+ nary_struct_store_array(VALUE self, VALUE obj)
704
+ {
705
+ return nary_struct_store_struct(self, nary_struct_cast_array(CLASS_OF(self),obj));
706
+ }
707
+
708
+ /*
709
+ Store elements to Numo::Struct from other.
710
+ @overload store(other)
711
+ @param [Object] other
712
+ @return [Numo::Struct] self
713
+ */
714
+ static VALUE
715
+ nary_struct_store(VALUE self, VALUE obj)
716
+ {
717
+ if (TYPE(obj)==T_ARRAY) {
718
+ nary_struct_store_array(self,obj);
719
+ return self;
720
+ }
721
+ if (CLASS_OF(self) == CLASS_OF(obj)) {
722
+ nary_struct_store_struct(self,obj);
723
+ return self;
724
+ }
725
+ rb_raise(nary_eCastError, "unknown conversion from %s to %s",
726
+ rb_class2name(CLASS_OF(obj)),
727
+ rb_class2name(CLASS_OF(self)));
728
+ return self;
729
+ }
730
+
731
+
732
+
733
+ static VALUE
734
+ //iter_struct_inspect(na_loop_t *const lp)
735
+ iter_struct_inspect(char *ptr, size_t pos, VALUE opt)
736
+ {
737
+ VALUE types, defs, def, name, elmt, vary, v, x;
738
+ size_t ofs;
739
+ long i, len;
740
+ narray_view_t *ne;
741
+
742
+ types = RARRAY_AREF(opt,0);
743
+ defs = RARRAY_AREF(opt,1);
744
+
745
+ len = RARRAY_LEN(types);
746
+ vary = rb_ary_new2(len);
747
+
748
+ for (i=0; i<len; i++) {
749
+ def = RARRAY_AREF(defs,i);
750
+ name = RARRAY_AREF(def,0);
751
+ ofs = NUM2SIZE(RARRAY_AREF(def,2));
752
+ elmt = RARRAY_AREF(types,i);
753
+ GetNArrayView(elmt,ne);
754
+ ne->offset = pos + ofs;
755
+ v = rb_str_concat(rb_sym_to_s(name), rb_str_new2(": "));
756
+ x = rb_funcall(elmt, rb_intern("format_to_a"), 0); // <-- fix me
757
+ if (ne->base.ndim==0) {
758
+ x = rb_funcall(x, rb_intern("first"), 0);
759
+ }
760
+ x = rb_funcall(x, rb_intern("to_s"), 0);
761
+ v = rb_str_concat(v, x);
762
+ rb_ary_push(vary, v);
763
+ }
764
+ v = rb_ary_join(vary, rb_str_new2(", "));
765
+ v = rb_str_concat(rb_str_new2("["), v);
766
+ v = rb_str_concat(v, rb_str_new2("]"));
767
+ return v;
768
+ }
769
+
770
+ /*
771
+ Returns a string containing a human-readable representation of NArray.
772
+ @overload inspect
773
+ @return [String]
774
+ */
775
+ VALUE
776
+ nary_struct_inspect(VALUE ary)
777
+ {
778
+ VALUE opt;
779
+ opt = nst_create_member_views(ary);
780
+ return na_ndloop_inspect(ary, iter_struct_inspect, opt);
781
+ }
782
+
783
+
784
+ static VALUE
785
+ nst_s_add_type(int argc, VALUE *argv, VALUE mod)
786
+ {
787
+ if (argc==0)
788
+ rb_raise(rb_eArgError,
789
+ "wrong number of arguments (%d for 1)", argc);
790
+ nstruct_add_type(argv[0],argc-1,argv+1,mod);
791
+ return Qnil;
792
+ }
793
+
794
+
795
+
796
+
797
+ #define NST_TYPEDEF(tpname,tpclass) \
798
+ static VALUE \
799
+ nst_s_##tpname(VALUE argc, VALUE *argv, VALUE mod) \
800
+ { nstruct_add_type(tpclass,argc,argv,mod); \
801
+ return Qnil; \
802
+ }
803
+
804
+ NST_TYPEDEF(int8,numo_cInt8)
805
+ NST_TYPEDEF(int16,numo_cInt16)
806
+ NST_TYPEDEF(int32,numo_cInt32)
807
+ NST_TYPEDEF(int64,numo_cInt64)
808
+ NST_TYPEDEF(uint8,numo_cUInt8)
809
+ NST_TYPEDEF(uint16,numo_cUInt16)
810
+ NST_TYPEDEF(uint32,numo_cUInt32)
811
+ NST_TYPEDEF(uint64,numo_cUInt64)
812
+ NST_TYPEDEF(dfloat,numo_cDFloat)
813
+ NST_TYPEDEF(dcomplex,numo_cDComplex)
814
+ NST_TYPEDEF(sfloat,numo_cSFloat)
815
+ NST_TYPEDEF(scomplex,numo_cSComplex)
816
+
817
+
818
+ #define rb_define_singleton_alias(klass,name1,name2) \
819
+ rb_define_alias(rb_singleton_class(klass),name1,name2)
820
+
821
+ void
822
+ Init_nary_struct()
823
+ {
824
+ cT = rb_define_class_under(mNumo, "Struct", numo_cNArray);
825
+ //cNStMember = rb_define_class_under(cT, "Member", rb_cObject);
826
+
827
+ //rb_define_alloc_func(cNStMember, nst_member_s_allocate);
828
+ //rb_define_method(cNStMember, "initialize", nst_member_initialize, -1);
829
+
830
+ //rb_undef_alloc_func(cT);
831
+ rb_define_singleton_method(cT, "new", nst_s_new, -1);
832
+ rb_define_singleton_method(cT, "add_type", nst_s_add_type, -1);
833
+ rb_define_singleton_method(cT, "int8", nst_s_int8, -1);
834
+ rb_define_singleton_method(cT, "int16", nst_s_int16, -1);
835
+ rb_define_singleton_method(cT, "int32", nst_s_int32, -1);
836
+ rb_define_singleton_method(cT, "int64", nst_s_int64, -1);
837
+ rb_define_singleton_method(cT, "uint8", nst_s_uint8, -1);
838
+ rb_define_singleton_method(cT, "uint16", nst_s_uint16, -1);
839
+ rb_define_singleton_method(cT, "uint32", nst_s_uint32, -1);
840
+ rb_define_singleton_method(cT, "uint64", nst_s_uint64, -1);
841
+ rb_define_singleton_method(cT, "sfloat", nst_s_sfloat, -1);
842
+ rb_define_singleton_alias (cT, "float32", "sfloat");
843
+ rb_define_singleton_method(cT, "scomplex", nst_s_scomplex, -1);
844
+ rb_define_singleton_alias (cT, "complex64", "scomplex");
845
+ rb_define_singleton_method(cT, "dfloat", nst_s_dfloat, -1);
846
+ rb_define_singleton_alias (cT, "float64", "dfloat");
847
+ rb_define_singleton_method(cT, "dcomplex", nst_s_dcomplex, -1);
848
+ rb_define_singleton_alias (cT, "complex128", "dcomplex");
849
+
850
+ rb_define_method(cT, "definition", nst_definition, 1);
851
+ rb_define_method(cT, "definitions", nst_definitions, 0);
852
+ rb_define_method(cT, "field", nst_field, 1);
853
+ rb_define_method(cT, "field_set", nst_field_set, 2);
854
+ rb_define_method(cT, "extract", nst_extract, 0);
855
+ rb_define_method(cT, "method_missing", nst_method_missing, -1);
856
+
857
+ //rb_define_method(cT, "fill", nary_nstruct_fill, 1);
858
+
859
+ //rb_define_method(cT, "debug_print", nary_nstruct_debug_print, 0);
860
+
861
+ rb_define_method(cT, "to_a", nary_struct_to_a, 0);
862
+
863
+ rb_define_method(cT, "store", nary_struct_store, 1);
864
+
865
+ rb_define_method(cT, "inspect", nary_struct_inspect, 0);
866
+
867
+ rb_define_singleton_method(cT, "cast", nary_struct_s_cast, 1);
868
+ rb_define_singleton_method(cT, "[]", nary_struct_s_cast, -2);
869
+
870
+ //rb_define_method(cT, "initialize", rb_struct_initialize, -2);
871
+ //rb_define_method(cT, "initialize_copy", rb_struct_init_copy, 1);
872
+ }