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.
- checksums.yaml +7 -0
- data/Gemfile +14 -0
- data/LICENSE +30 -0
- data/README.md +71 -0
- data/Rakefile +24 -0
- data/ext/numo/narray/SFMT-params.h +97 -0
- data/ext/numo/narray/SFMT-params19937.h +48 -0
- data/ext/numo/narray/SFMT.c +602 -0
- data/ext/numo/narray/SFMT.h +147 -0
- data/ext/numo/narray/array.c +575 -0
- data/ext/numo/narray/data.c +958 -0
- data/ext/numo/narray/extconf.rb +84 -0
- data/ext/numo/narray/index.c +1092 -0
- data/ext/numo/narray/kwargs.c +142 -0
- data/ext/numo/narray/math.c +133 -0
- data/ext/numo/narray/narray.c +1976 -0
- data/ext/numo/narray/narray.def +28 -0
- data/ext/numo/narray/ndloop.c +1840 -0
- data/ext/numo/narray/numo/compat.h +23 -0
- data/ext/numo/narray/numo/intern.h +115 -0
- data/ext/numo/narray/numo/narray.h +480 -0
- data/ext/numo/narray/numo/ndloop.h +93 -0
- data/ext/numo/narray/numo/template.h +149 -0
- data/ext/numo/narray/numo/types/bit.h +38 -0
- data/ext/numo/narray/numo/types/complex.h +404 -0
- data/ext/numo/narray/numo/types/complex_macro.h +384 -0
- data/ext/numo/narray/numo/types/dcomplex.h +42 -0
- data/ext/numo/narray/numo/types/dfloat.h +44 -0
- data/ext/numo/narray/numo/types/float_def.h +34 -0
- data/ext/numo/narray/numo/types/float_macro.h +202 -0
- data/ext/numo/narray/numo/types/int16.h +27 -0
- data/ext/numo/narray/numo/types/int32.h +23 -0
- data/ext/numo/narray/numo/types/int64.h +23 -0
- data/ext/numo/narray/numo/types/int8.h +23 -0
- data/ext/numo/narray/numo/types/int_macro.h +66 -0
- data/ext/numo/narray/numo/types/real_accum.h +481 -0
- data/ext/numo/narray/numo/types/robj_macro.h +78 -0
- data/ext/numo/narray/numo/types/robject.h +25 -0
- data/ext/numo/narray/numo/types/scomplex.h +42 -0
- data/ext/numo/narray/numo/types/sfloat.h +45 -0
- data/ext/numo/narray/numo/types/uint16.h +24 -0
- data/ext/numo/narray/numo/types/uint32.h +20 -0
- data/ext/numo/narray/numo/types/uint64.h +20 -0
- data/ext/numo/narray/numo/types/uint8.h +20 -0
- data/ext/numo/narray/numo/types/uint_macro.h +57 -0
- data/ext/numo/narray/numo/types/xint_macro.h +166 -0
- data/ext/numo/narray/rand.c +40 -0
- data/ext/numo/narray/src/t_bit.c +3236 -0
- data/ext/numo/narray/src/t_dcomplex.c +6776 -0
- data/ext/numo/narray/src/t_dfloat.c +9417 -0
- data/ext/numo/narray/src/t_int16.c +5757 -0
- data/ext/numo/narray/src/t_int32.c +5757 -0
- data/ext/numo/narray/src/t_int64.c +5759 -0
- data/ext/numo/narray/src/t_int8.c +5355 -0
- data/ext/numo/narray/src/t_robject.c +5567 -0
- data/ext/numo/narray/src/t_scomplex.c +6731 -0
- data/ext/numo/narray/src/t_sfloat.c +9374 -0
- data/ext/numo/narray/src/t_uint16.c +5753 -0
- data/ext/numo/narray/src/t_uint32.c +5753 -0
- data/ext/numo/narray/src/t_uint64.c +5755 -0
- data/ext/numo/narray/src/t_uint8.c +5351 -0
- data/ext/numo/narray/step.c +266 -0
- data/ext/numo/narray/struct.c +814 -0
- data/lib/numo/narray/extra.rb +1266 -0
- data/lib/numo/narray.rb +4 -0
- 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
|
+
}
|