numo-narray-alt 0.9.3

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