narray-bigmem 0.0.0
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/ChangeLog +602 -0
- data/MANIFEST +54 -0
- data/README +41 -0
- data/README_NARRAY.en +49 -0
- data/README_NARRAY.ja +52 -0
- data/SPEC.en +327 -0
- data/SPEC.ja +307 -0
- data/ext/narray/depend +14 -0
- data/ext/narray/extconf.rb +123 -0
- data/ext/narray/mkmath.rb +792 -0
- data/ext/narray/mknafunc.rb +212 -0
- data/ext/narray/mkop.rb +734 -0
- data/ext/narray/na_array.c +659 -0
- data/ext/narray/na_func.c +1709 -0
- data/ext/narray/na_index.c +1021 -0
- data/ext/narray/na_linalg.c +635 -0
- data/ext/narray/na_random.c +444 -0
- data/ext/narray/narray.c +1341 -0
- data/ext/narray/narray.def +29 -0
- data/ext/narray/narray.h +231 -0
- data/ext/narray/narray_local.h +218 -0
- data/lib/narray.rb +4 -0
- data/lib/narray_ext.rb +362 -0
- data/lib/nmatrix.rb +248 -0
- metadata +94 -0
@@ -0,0 +1,659 @@
|
|
1
|
+
/*
|
2
|
+
na_array.c
|
3
|
+
Numerical Array Extention for Ruby
|
4
|
+
(C) Copyright 1999-2008 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 "narray.h"
|
13
|
+
#include "narray_local.h"
|
14
|
+
|
15
|
+
/* Multi-Dimensional Array Investigation */
|
16
|
+
typedef struct {
|
17
|
+
na_shape_t shape;
|
18
|
+
VALUE val;
|
19
|
+
} na_mdai_item_t;
|
20
|
+
|
21
|
+
typedef struct {
|
22
|
+
na_shape_t n;
|
23
|
+
na_mdai_item_t *item;
|
24
|
+
int *type;
|
25
|
+
} na_mdai_t;
|
26
|
+
|
27
|
+
|
28
|
+
int na_object_type(VALUE v)
|
29
|
+
{
|
30
|
+
switch(TYPE(v)) {
|
31
|
+
|
32
|
+
case T_TRUE:
|
33
|
+
case T_FALSE:
|
34
|
+
return NA_BYTE;
|
35
|
+
|
36
|
+
case T_FIXNUM:
|
37
|
+
case T_BIGNUM:
|
38
|
+
return NA_LINT;
|
39
|
+
|
40
|
+
case T_FLOAT:
|
41
|
+
return NA_DFLOAT;
|
42
|
+
|
43
|
+
case T_NIL:
|
44
|
+
return NA_NONE;
|
45
|
+
|
46
|
+
default:
|
47
|
+
if (IsNArray(v))
|
48
|
+
return ((struct NARRAY *)(RDATA(v)->data))->type ;
|
49
|
+
|
50
|
+
if (CLASS_OF(v) == cComplex)
|
51
|
+
return NA_DCOMPLEX;
|
52
|
+
}
|
53
|
+
return NA_ROBJ;
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
static na_mdai_t *
|
58
|
+
na_alloc_mdai(VALUE ary)
|
59
|
+
{
|
60
|
+
int i;
|
61
|
+
na_shape_t n=2;
|
62
|
+
na_mdai_t *mdai;
|
63
|
+
|
64
|
+
mdai = ALLOC(na_mdai_t);
|
65
|
+
mdai->n = n;
|
66
|
+
mdai->item = ALLOC_N( na_mdai_item_t, n );
|
67
|
+
for (i=0; i<n; ++i) {
|
68
|
+
mdai->item[i].shape = 0;
|
69
|
+
mdai->item[i].val = Qnil;
|
70
|
+
}
|
71
|
+
mdai->item[0].val = ary;
|
72
|
+
mdai->type = ALLOC_N( int, NA_NTYPES );
|
73
|
+
for (i=0; i<NA_NTYPES; ++i)
|
74
|
+
mdai->type[i]=0;
|
75
|
+
|
76
|
+
return mdai;
|
77
|
+
}
|
78
|
+
|
79
|
+
static void
|
80
|
+
na_realloc_mdai(na_mdai_t *mdai, na_shape_t n_extra)
|
81
|
+
{
|
82
|
+
na_shape_t i, n;
|
83
|
+
|
84
|
+
i = mdai->n;
|
85
|
+
mdai->n += n_extra;
|
86
|
+
n = mdai->n;
|
87
|
+
REALLOC_N( mdai->item, na_mdai_item_t, n );
|
88
|
+
for (; i<n; ++i) {
|
89
|
+
mdai->item[i].shape = 0;
|
90
|
+
mdai->item[i].val = Qnil;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
static na_shape_t *
|
95
|
+
na_free_mdai(na_mdai_t *mdai, int *rank, int *type)
|
96
|
+
{
|
97
|
+
na_shape_t i;
|
98
|
+
int t, r;
|
99
|
+
na_shape_t *shape;
|
100
|
+
|
101
|
+
for (t=i=NA_BYTE; i<NA_NTYPES; ++i) {
|
102
|
+
if ( mdai->type[i] > 0 )
|
103
|
+
t = na_upcast[t][i];
|
104
|
+
}
|
105
|
+
*type = t;
|
106
|
+
for (i=0; i < mdai->n && mdai->item[i].shape > 0; ++i) ;
|
107
|
+
*rank = r = i;
|
108
|
+
shape = ALLOC_N(na_shape_t,r);
|
109
|
+
for (i=0; r-->0; ++i) {
|
110
|
+
shape[i] = mdai->item[r].shape;
|
111
|
+
}
|
112
|
+
xfree(mdai->type);
|
113
|
+
xfree(mdai->item);
|
114
|
+
xfree(mdai);
|
115
|
+
return shape;
|
116
|
+
}
|
117
|
+
|
118
|
+
|
119
|
+
#define EXCL(r) (RTEST(rb_funcall((r),na_id_exclude_end,0)))
|
120
|
+
|
121
|
+
/* Range as a Sequence of numbers */
|
122
|
+
static void
|
123
|
+
na_range_to_sequence(VALUE obj, na_shape_t *n, na_shape_t *beg, int *step)
|
124
|
+
{
|
125
|
+
na_shape_t end, len;
|
126
|
+
|
127
|
+
*beg = NUM2SHAPE(rb_funcall(obj, na_id_beg, 0));
|
128
|
+
end = NUM2SHAPE(rb_funcall(obj, na_id_end, 0));
|
129
|
+
len = end - *beg;
|
130
|
+
|
131
|
+
/* direction */
|
132
|
+
if (len>0) {
|
133
|
+
*step = 1;
|
134
|
+
if (EXCL(obj)) --end; else ++len;
|
135
|
+
}
|
136
|
+
else if (len<0) {
|
137
|
+
len = -len;
|
138
|
+
*step = -1;
|
139
|
+
if (EXCL(obj)) ++end; else ++len;
|
140
|
+
}
|
141
|
+
else /*if(len==0)*/ {
|
142
|
+
*step = 0;
|
143
|
+
if (!EXCL(obj)) {
|
144
|
+
++len;
|
145
|
+
}
|
146
|
+
}
|
147
|
+
*n = len;
|
148
|
+
}
|
149
|
+
|
150
|
+
|
151
|
+
/* investigate rank, shape, type of Array */
|
152
|
+
static int
|
153
|
+
na_do_mdai(na_mdai_t *mdai, int rank)
|
154
|
+
{
|
155
|
+
na_shape_t i, start, len, length;
|
156
|
+
int j, dir;
|
157
|
+
VALUE v;
|
158
|
+
VALUE ary;
|
159
|
+
|
160
|
+
ary = mdai->item[rank-1].val;
|
161
|
+
len = RARRAY_LEN(ary);
|
162
|
+
|
163
|
+
for (i=0; i < RARRAY_LEN(ary); ++i) {
|
164
|
+
|
165
|
+
v = RARRAY_PTR(ary)[i];
|
166
|
+
|
167
|
+
if (TYPE(v) == T_ARRAY) {
|
168
|
+
/* check recursive array */
|
169
|
+
for (j=0; j<rank; ++j) {
|
170
|
+
if (mdai->item[j].val == v)
|
171
|
+
rb_raise(rb_eStandardError,"converting recursive Array to NArray");
|
172
|
+
}
|
173
|
+
if ( rank >= mdai->n ) {
|
174
|
+
na_realloc_mdai(mdai,2);
|
175
|
+
}
|
176
|
+
mdai->item[rank].val = v;
|
177
|
+
if ( na_do_mdai(mdai,rank+1) ) {
|
178
|
+
--len; /* Array is empty */
|
179
|
+
}
|
180
|
+
}
|
181
|
+
else
|
182
|
+
if ( rb_obj_is_kind_of(v, rb_cRange) ) {
|
183
|
+
na_range_to_sequence(v,&length,&start,&dir);
|
184
|
+
len += length-1;
|
185
|
+
mdai->type[ na_object_type(rb_funcall(v, na_id_beg, 0)) ] = 1;
|
186
|
+
mdai->type[ na_object_type(rb_funcall(v, na_id_end, 0)) ] = 1;
|
187
|
+
}
|
188
|
+
else {
|
189
|
+
|
190
|
+
mdai->type[ na_object_type(v) ] = 1;
|
191
|
+
|
192
|
+
if (IsNArray(v)) {
|
193
|
+
int r;
|
194
|
+
struct NARRAY *na; GetNArray(v,na);
|
195
|
+
|
196
|
+
if ( na->rank == 0 ) {
|
197
|
+
--len; /* NArray is empty */
|
198
|
+
} else {
|
199
|
+
if ( rank+na->rank > mdai->n ) {
|
200
|
+
na_realloc_mdai(mdai,((na->rank-1)/4+1)*4);
|
201
|
+
}
|
202
|
+
for ( j=na->rank, r=rank; j-- > 0 ; ++r ) {
|
203
|
+
if ( mdai->item[r].shape < na->shape[j] )
|
204
|
+
mdai->item[r].shape = na->shape[j];
|
205
|
+
}
|
206
|
+
}
|
207
|
+
}
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
if (len==0) return 1; /* this array is empty */
|
212
|
+
if (mdai->item[rank-1].shape < len) {
|
213
|
+
mdai->item[rank-1].shape = len;
|
214
|
+
}
|
215
|
+
return 0;
|
216
|
+
}
|
217
|
+
|
218
|
+
|
219
|
+
/* get index from multiple-index */
|
220
|
+
static na_shape_t
|
221
|
+
na_index_pos(struct NARRAY *ary, na_shape_t *idxs)
|
222
|
+
{
|
223
|
+
int i;
|
224
|
+
na_shape_t idx, pos = 0;
|
225
|
+
|
226
|
+
for ( i = ary->rank; (i--)>0; ) {
|
227
|
+
idx = idxs[i];
|
228
|
+
if (idx < 0 || ary->shape[i] <= idx) {
|
229
|
+
abort();
|
230
|
+
rb_raise(rb_eRuntimeError,
|
231
|
+
"Subsctipt out of range: accessing shape[%i]=%zd with %zd",
|
232
|
+
i, ary->shape[i], idx );
|
233
|
+
}
|
234
|
+
pos = pos * ary->shape[i] + idx;
|
235
|
+
}
|
236
|
+
return pos;
|
237
|
+
}
|
238
|
+
|
239
|
+
|
240
|
+
static void
|
241
|
+
na_copy_nary_to_nary(VALUE obj, struct NARRAY *dst,
|
242
|
+
int thisrank, na_shape_t *idx)
|
243
|
+
{
|
244
|
+
struct NARRAY *src;
|
245
|
+
struct slice *s;
|
246
|
+
int i, n;
|
247
|
+
|
248
|
+
GetNArray(obj,src);
|
249
|
+
n = thisrank - src->rank + 1;
|
250
|
+
|
251
|
+
s = ALLOCA_N(struct slice, dst->rank+1);
|
252
|
+
for (i=0; i < n; ++i) {
|
253
|
+
s[i].n = 1;
|
254
|
+
s[i].beg = 0;
|
255
|
+
s[i].step = 0;
|
256
|
+
s[i].idx = NULL;
|
257
|
+
}
|
258
|
+
for ( ; i <= thisrank; ++i) {
|
259
|
+
s[i].n = src->shape[i-n];
|
260
|
+
s[i].beg = 0;
|
261
|
+
s[i].step = 1;
|
262
|
+
s[i].idx = NULL;
|
263
|
+
}
|
264
|
+
for ( ; i < dst->rank; ++i) {
|
265
|
+
s[i].n = 1;
|
266
|
+
s[i].beg = idx[i];
|
267
|
+
s[i].step = 0;
|
268
|
+
s[i].idx = NULL;
|
269
|
+
}
|
270
|
+
na_aset_slice(dst,src,s);
|
271
|
+
}
|
272
|
+
|
273
|
+
|
274
|
+
/* copy Array to NArray */
|
275
|
+
static void
|
276
|
+
na_copy_ary_to_nary( VALUE ary, struct NARRAY *na,
|
277
|
+
int thisrank, na_shape_t *idx, int type )
|
278
|
+
{
|
279
|
+
na_shape_t i, len, pos, start, step;
|
280
|
+
int j, dir;
|
281
|
+
VALUE v;
|
282
|
+
|
283
|
+
if (thisrank==0) {
|
284
|
+
for (i = idx[0] = 0; i < RARRAY_LEN(ary); ++i) {
|
285
|
+
v = RARRAY_PTR(ary)[i];
|
286
|
+
if (rb_obj_is_kind_of(v, rb_cRange)) {
|
287
|
+
na_range_to_sequence(v,&len,&start,&dir);
|
288
|
+
if (len>0) {
|
289
|
+
pos = na_index_pos(na,idx);
|
290
|
+
IndGenFuncs[type](len, NA_PTR(na,pos),na_sizeof[type], start, (na_shape_t)dir);
|
291
|
+
idx[0] += len;
|
292
|
+
}
|
293
|
+
}
|
294
|
+
else if (TYPE(v) != T_ARRAY) {
|
295
|
+
/* NIL if empty */
|
296
|
+
if (v != Qnil) {
|
297
|
+
pos = na_index_pos(na,idx);
|
298
|
+
SetFuncs[type][NA_ROBJ]( 1, NA_PTR(na,pos), 0, &v, 0 );
|
299
|
+
/* copy here */
|
300
|
+
}
|
301
|
+
idx[0] ++;
|
302
|
+
}
|
303
|
+
}
|
304
|
+
}
|
305
|
+
else /* thisrank > 0 */
|
306
|
+
{
|
307
|
+
for (i = idx[thisrank] = 0; i < RARRAY_LEN(ary); ++i) {
|
308
|
+
v = RARRAY_PTR(ary)[i];
|
309
|
+
if (TYPE(v) == T_ARRAY) {
|
310
|
+
na_copy_ary_to_nary(v,na,thisrank-1,idx,type);
|
311
|
+
if (idx[thisrank-1]>0) ++idx[thisrank];
|
312
|
+
}
|
313
|
+
else if (IsNArray(v)) {
|
314
|
+
na_copy_nary_to_nary(v,na,thisrank-1,idx);
|
315
|
+
++idx[thisrank];
|
316
|
+
}
|
317
|
+
else {
|
318
|
+
for (j=thisrank; j; ) idx[--j] = 0;
|
319
|
+
|
320
|
+
if (rb_obj_is_kind_of(v, rb_cRange)) {
|
321
|
+
na_range_to_sequence(v,&len,&start,&dir);
|
322
|
+
if (len>0) {
|
323
|
+
pos = na_index_pos(na,idx);
|
324
|
+
++idx[thisrank];
|
325
|
+
step = na_index_pos(na,idx)-pos;
|
326
|
+
IndGenFuncs[type]( len, NA_PTR(na,pos), na_sizeof[type]*step,
|
327
|
+
start, (na_shape_t)dir );
|
328
|
+
idx[thisrank] += len-1;
|
329
|
+
}
|
330
|
+
}
|
331
|
+
else {
|
332
|
+
pos = na_index_pos(na,idx);
|
333
|
+
SetFuncs[type][NA_ROBJ]( 1, NA_PTR(na,pos), 0, &(RARRAY_PTR(ary)[i]), 0 );
|
334
|
+
++idx[thisrank];
|
335
|
+
}
|
336
|
+
/* copy here */
|
337
|
+
}
|
338
|
+
}
|
339
|
+
}
|
340
|
+
}
|
341
|
+
|
342
|
+
|
343
|
+
static VALUE
|
344
|
+
na_ary_to_nary_w_type(VALUE ary, int type_spec, VALUE klass)
|
345
|
+
{
|
346
|
+
int i, rank;
|
347
|
+
int type = NA_BYTE;
|
348
|
+
na_shape_t *shape;
|
349
|
+
na_shape_t *idx;
|
350
|
+
na_mdai_t *mdai;
|
351
|
+
struct NARRAY *na;
|
352
|
+
VALUE v;
|
353
|
+
|
354
|
+
/* empty array */
|
355
|
+
if (RARRAY_LEN(ary) < 1) {
|
356
|
+
return na_make_empty( type, klass );
|
357
|
+
}
|
358
|
+
|
359
|
+
mdai = na_alloc_mdai(ary);
|
360
|
+
na_do_mdai(mdai,1);
|
361
|
+
shape = na_free_mdai(mdai,&rank,&type);
|
362
|
+
|
363
|
+
|
364
|
+
/*
|
365
|
+
printf("rank=%i\n", rank);
|
366
|
+
printf("type=%i\n", type);
|
367
|
+
for (i=0; i<rank; ++i) {
|
368
|
+
printf("shape[%i]=%zi\n", i, shape[i]);
|
369
|
+
}
|
370
|
+
*/
|
371
|
+
|
372
|
+
/* type specification */
|
373
|
+
if (type_spec!=NA_NONE)
|
374
|
+
type = type_spec;
|
375
|
+
|
376
|
+
/* empty array */
|
377
|
+
if (rank==0)
|
378
|
+
return na_make_empty( type, klass );
|
379
|
+
|
380
|
+
/* Create NArray */
|
381
|
+
v = na_make_object(type,rank,shape,klass);
|
382
|
+
xfree(shape);
|
383
|
+
|
384
|
+
GetNArray(v,na);
|
385
|
+
na_clear_data(na);
|
386
|
+
|
387
|
+
idx = ALLOCA_N(na_shape_t,rank);
|
388
|
+
for (i=0; i<rank; ++i) idx[i]=0;
|
389
|
+
|
390
|
+
na_copy_ary_to_nary( ary, na, rank-1, idx, type );
|
391
|
+
|
392
|
+
return v;
|
393
|
+
}
|
394
|
+
|
395
|
+
|
396
|
+
VALUE
|
397
|
+
na_ary_to_nary(VALUE ary, VALUE klass)
|
398
|
+
{
|
399
|
+
return na_ary_to_nary_w_type( ary, NA_NONE, klass );
|
400
|
+
}
|
401
|
+
|
402
|
+
|
403
|
+
/* obj.kind_of?(NArray) == true */
|
404
|
+
|
405
|
+
VALUE
|
406
|
+
na_dup_w_type(VALUE v2, int type)
|
407
|
+
{
|
408
|
+
VALUE v1;
|
409
|
+
struct NARRAY *a1, *a2;
|
410
|
+
|
411
|
+
GetNArray(v2,a2);
|
412
|
+
v1 = na_make_object(type, a2->rank, a2->shape, CLASS_OF(v2));
|
413
|
+
GetNArray(v1,a1);
|
414
|
+
na_copy_nary(a1,a2);
|
415
|
+
return v1;
|
416
|
+
}
|
417
|
+
|
418
|
+
|
419
|
+
VALUE
|
420
|
+
na_change_type(VALUE obj, int type)
|
421
|
+
{
|
422
|
+
struct NARRAY *a2;
|
423
|
+
|
424
|
+
GetNArray(obj,a2);
|
425
|
+
|
426
|
+
if (a2->type == type)
|
427
|
+
return obj;
|
428
|
+
|
429
|
+
return na_dup_w_type(obj, type);
|
430
|
+
}
|
431
|
+
|
432
|
+
|
433
|
+
VALUE
|
434
|
+
na_upcast_type(VALUE obj, int type) /* na_upcast_narray */
|
435
|
+
{
|
436
|
+
int newtype;
|
437
|
+
struct NARRAY *a2;
|
438
|
+
|
439
|
+
GetNArray(obj,a2);
|
440
|
+
newtype = na_upcast[a2->type][type];
|
441
|
+
|
442
|
+
if (newtype == a2->type)
|
443
|
+
return obj;
|
444
|
+
|
445
|
+
return na_dup_w_type(obj, newtype);
|
446
|
+
}
|
447
|
+
|
448
|
+
|
449
|
+
/* obj.kind_of?(Object) == true */
|
450
|
+
|
451
|
+
VALUE
|
452
|
+
na_cast_object(VALUE obj, int type) /* na_cast_certain */
|
453
|
+
{
|
454
|
+
if (IsNArray(obj)) {
|
455
|
+
return na_change_type(obj,type);
|
456
|
+
}
|
457
|
+
if (TYPE(obj) == T_ARRAY) {
|
458
|
+
return na_ary_to_nary_w_type(obj,type,cNArray);
|
459
|
+
}
|
460
|
+
return na_make_scalar(obj,type);
|
461
|
+
}
|
462
|
+
|
463
|
+
|
464
|
+
VALUE
|
465
|
+
na_cast_unless_narray(VALUE obj, int type)
|
466
|
+
{
|
467
|
+
if (IsNArray(obj)) {
|
468
|
+
return obj;
|
469
|
+
}
|
470
|
+
if (TYPE(obj) == T_ARRAY) {
|
471
|
+
return na_ary_to_nary_w_type(obj,type,cNArray);
|
472
|
+
}
|
473
|
+
return na_make_scalar(obj,type);
|
474
|
+
}
|
475
|
+
|
476
|
+
|
477
|
+
VALUE
|
478
|
+
na_cast_unless_array(VALUE obj, int type)
|
479
|
+
{
|
480
|
+
if (IsNArray(obj)) {
|
481
|
+
return obj;
|
482
|
+
}
|
483
|
+
if (TYPE(obj) == T_ARRAY) {
|
484
|
+
return na_ary_to_nary(obj,cNArray);
|
485
|
+
}
|
486
|
+
return na_make_scalar(obj,type);
|
487
|
+
}
|
488
|
+
|
489
|
+
|
490
|
+
VALUE
|
491
|
+
na_upcast_object(VALUE obj, int type)
|
492
|
+
{
|
493
|
+
if (IsNArray(obj)) {
|
494
|
+
return na_upcast_type(obj,type);
|
495
|
+
}
|
496
|
+
if (TYPE(obj) == T_ARRAY) {
|
497
|
+
return na_ary_to_nary_w_type(obj,type,cNArray);
|
498
|
+
}
|
499
|
+
return na_make_scalar(obj,type);
|
500
|
+
}
|
501
|
+
|
502
|
+
|
503
|
+
/* :nodoc: */
|
504
|
+
VALUE
|
505
|
+
na_to_narray(VALUE obj)
|
506
|
+
{
|
507
|
+
if (IsNArray(obj)) {
|
508
|
+
return obj;
|
509
|
+
}
|
510
|
+
if (TYPE(obj) == T_ARRAY) {
|
511
|
+
return na_ary_to_nary(obj,cNArray);
|
512
|
+
}
|
513
|
+
return na_make_scalar(obj,na_object_type(obj));
|
514
|
+
}
|
515
|
+
|
516
|
+
|
517
|
+
/* convert NArray to Array */
|
518
|
+
static VALUE
|
519
|
+
na_to_array0(struct NARRAY* na, na_shape_t *idx, int thisrank, void (*func)())
|
520
|
+
{
|
521
|
+
na_shape_t i;
|
522
|
+
int elmsz;
|
523
|
+
char *ptr;
|
524
|
+
VALUE ary, val;
|
525
|
+
|
526
|
+
/* Create New Array */
|
527
|
+
ary = rb_ary_new2(na->shape[thisrank]);
|
528
|
+
|
529
|
+
if (thisrank == 0) {
|
530
|
+
ptr = NA_PTR( na, na_index_pos(na,idx) );
|
531
|
+
elmsz = na_sizeof[na->type];
|
532
|
+
for (i = na->shape[0]; i; --i) {
|
533
|
+
(*func)( 1, &val, 0, ptr, 0 );
|
534
|
+
ptr += elmsz;
|
535
|
+
rb_ary_push( ary, val );
|
536
|
+
}
|
537
|
+
}
|
538
|
+
else {
|
539
|
+
for (i = 0; i < na->shape[thisrank]; ++i) {
|
540
|
+
idx[thisrank] = i;
|
541
|
+
rb_ary_push( ary, na_to_array0(na,idx,thisrank-1,func) );
|
542
|
+
}
|
543
|
+
}
|
544
|
+
return ary;
|
545
|
+
}
|
546
|
+
|
547
|
+
|
548
|
+
/* method: to_a -- convert itself to Array */
|
549
|
+
VALUE
|
550
|
+
na_to_array(VALUE obj)
|
551
|
+
{
|
552
|
+
struct NARRAY *na;
|
553
|
+
na_shape_t *idx;
|
554
|
+
int i;
|
555
|
+
|
556
|
+
GetNArray(obj,na);
|
557
|
+
|
558
|
+
if (na->rank<1)
|
559
|
+
return rb_ary_new();
|
560
|
+
|
561
|
+
idx = ALLOCA_N(na_shape_t,na->rank);
|
562
|
+
for (i = 0; i<na->rank; ++i) idx[i] = 0;
|
563
|
+
return na_to_array0(na,idx,na->rank-1,SetFuncs[NA_ROBJ][na->type]);
|
564
|
+
}
|
565
|
+
|
566
|
+
|
567
|
+
static VALUE
|
568
|
+
na_inspect_col( na_shape_t n, char *p2, int p2step, void (*tostr)(),
|
569
|
+
VALUE sep, int rank )
|
570
|
+
{
|
571
|
+
VALUE str=Qnil, tmp;
|
572
|
+
na_shape_t max_col = 77;
|
573
|
+
na_shape_t sep_len = RSTRING_LEN(sep);
|
574
|
+
|
575
|
+
if (n>0)
|
576
|
+
(*tostr)(&str,p2);
|
577
|
+
|
578
|
+
for (n--; n>0; --n) {
|
579
|
+
p2 += p2step;
|
580
|
+
(*tostr)(&tmp,p2);
|
581
|
+
|
582
|
+
if (!NIL_P(sep)) rb_str_concat(str, sep);
|
583
|
+
|
584
|
+
if (RSTRING_LEN(str) + RSTRING_LEN(tmp) + rank*4 + sep_len < max_col) {
|
585
|
+
rb_str_concat(str, tmp);
|
586
|
+
} else {
|
587
|
+
rb_str_cat(str,"...",3);
|
588
|
+
return str;
|
589
|
+
}
|
590
|
+
}
|
591
|
+
return str;
|
592
|
+
}
|
593
|
+
|
594
|
+
|
595
|
+
/*
|
596
|
+
* Create inspect string ... under construction
|
597
|
+
*/
|
598
|
+
|
599
|
+
VALUE
|
600
|
+
na_make_inspect(VALUE val)
|
601
|
+
{
|
602
|
+
int i, ii, rank, count_line=0, max_line=10;
|
603
|
+
na_shape_t *si;
|
604
|
+
struct NARRAY *ary;
|
605
|
+
struct slice *s1;
|
606
|
+
|
607
|
+
VALUE fs = rb_str_new(", ",2);
|
608
|
+
|
609
|
+
GetNArray(val,ary);
|
610
|
+
if (ary->total < 1) return rb_str_new(0, 0);
|
611
|
+
|
612
|
+
/* Allocate Structure */
|
613
|
+
rank = ary->rank;
|
614
|
+
s1 = ALLOCA_N(struct slice, rank+1);
|
615
|
+
si = ALLOCA_N(na_shape_t,rank);
|
616
|
+
na_set_slice_1obj(rank,s1,ary->shape);
|
617
|
+
|
618
|
+
/* Iteration */
|
619
|
+
na_init_slice(s1, rank, ary->shape, na_sizeof[ary->type]);
|
620
|
+
i = rank;
|
621
|
+
s1[i].p = ary->ptr;
|
622
|
+
val = rb_str_new(0,0);
|
623
|
+
for(;;) {
|
624
|
+
/* set pointers */
|
625
|
+
while (i > 0) {
|
626
|
+
--i;
|
627
|
+
rb_str_cat(val, "[ ", 2);
|
628
|
+
s1[i].p = s1[i].pbeg + s1[i+1].p;
|
629
|
+
si[i] = s1[i].n;
|
630
|
+
}
|
631
|
+
|
632
|
+
rb_str_concat(val, na_inspect_col( s1[0].n, s1[0].p, s1[0].pstep,
|
633
|
+
InspFuncs[ary->type], fs, rank ));
|
634
|
+
|
635
|
+
/* rank up */
|
636
|
+
do {
|
637
|
+
rb_str_cat(val, " ]", 2);
|
638
|
+
if ( ++i == rank ) return val;
|
639
|
+
} while ( --si[i] == 0 );
|
640
|
+
s1[i].p += s1[i].pstep;
|
641
|
+
|
642
|
+
rb_str_concat(val, fs);
|
643
|
+
rb_str_cat(val, "\n", 1);
|
644
|
+
|
645
|
+
/* count check */
|
646
|
+
if (++count_line>=max_line) {
|
647
|
+
rb_str_cat(val, " ...", 4);
|
648
|
+
return val;
|
649
|
+
}
|
650
|
+
/* indent */
|
651
|
+
for (ii=i; ii<rank; ++ii)
|
652
|
+
rb_str_cat(val, " ", 2);
|
653
|
+
}
|
654
|
+
}
|
655
|
+
|
656
|
+
|
657
|
+
void Init_na_array() {
|
658
|
+
rb_define_method(cNArray, "to_a", na_to_array,0); //
|
659
|
+
}
|