narray 0.5.9.4
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.
- data/src/ChangeLog +614 -0
- data/src/MANIFEST +82 -0
- data/src/README.en +54 -0
- data/src/README.ja +63 -0
- data/src/SPEC.en +300 -0
- data/src/SPEC.ja +284 -0
- data/src/depend +14 -0
- data/src/extconf.rb +111 -0
- data/src/lib/narray_ext.rb +211 -0
- data/src/lib/nmatrix.rb +244 -0
- data/src/mkmath.rb +780 -0
- data/src/mknafunc.rb +190 -0
- data/src/mkop.rb +638 -0
- data/src/na_array.c +644 -0
- data/src/na_func.c +1624 -0
- data/src/na_index.c +988 -0
- data/src/na_linalg.c +616 -0
- data/src/na_random.c +409 -0
- data/src/narray.c +1308 -0
- data/src/narray.def +29 -0
- data/src/narray.h +170 -0
- data/src/narray_local.h +210 -0
- data/src/nimage/README.en +38 -0
- data/src/nimage/demo/fits.rb +97 -0
- data/src/nimage/demo/fits_convol.rb +28 -0
- data/src/nimage/demo/fits_fftdemo.rb +27 -0
- data/src/nimage/demo/fitsdemo1.rb +13 -0
- data/src/nimage/demo/fitsdemo2.rb +30 -0
- data/src/nimage/demo/fitsdemo3.rb +26 -0
- data/src/nimage/demo/fitsmorph.rb +39 -0
- data/src/nimage/demo/life_na.rb +57 -0
- data/src/nimage/demo/mandel.rb +41 -0
- data/src/nimage/extconf.rb +12 -0
- data/src/nimage/lib/nimage.rb +51 -0
- data/src/nimage/nimage.c +328 -0
- data/src/speed/add.py +12 -0
- data/src/speed/add.rb +8 -0
- data/src/speed/add_int.py +12 -0
- data/src/speed/add_int.rb +9 -0
- data/src/speed/lu.m +14 -0
- data/src/speed/lu.rb +22 -0
- data/src/speed/mat.m +23 -0
- data/src/speed/mat.rb +28 -0
- data/src/speed/mul.py +12 -0
- data/src/speed/mul.rb +9 -0
- data/src/speed/mul2.py +15 -0
- data/src/speed/mul2.rb +13 -0
- data/src/speed/mul_comp.py +12 -0
- data/src/speed/mul_comp.rb +9 -0
- data/src/speed/mul_int.py +12 -0
- data/src/speed/mul_int.rb +9 -0
- data/src/speed/mybench.py +15 -0
- data/src/speed/mybench.rb +31 -0
- data/src/speed/solve.m +18 -0
- data/src/speed/solve.py +16 -0
- data/src/speed/solve.rb +21 -0
- data/src/test/statistics.rb +22 -0
- data/src/test/testarray.rb +20 -0
- data/src/test/testbit.rb +27 -0
- data/src/test/testcast.rb +14 -0
- data/src/test/testcomplex.rb +35 -0
- data/src/test/testfftw.rb +16 -0
- data/src/test/testindex.rb +11 -0
- data/src/test/testindexary.rb +26 -0
- data/src/test/testindexset.rb +55 -0
- data/src/test/testmask.rb +40 -0
- data/src/test/testmath.rb +48 -0
- data/src/test/testmath2.rb +46 -0
- data/src/test/testmatrix.rb +13 -0
- data/src/test/testmatrix2.rb +33 -0
- data/src/test/testmatrix3.rb +19 -0
- data/src/test/testminmax.rb +46 -0
- data/src/test/testobject.rb +29 -0
- data/src/test/testpow.rb +19 -0
- data/src/test/testrandom.rb +23 -0
- data/src/test/testround.rb +11 -0
- data/src/test/testsort.rb +37 -0
- data/src/test/teststr.rb +13 -0
- data/src/test/testtrans.rb +18 -0
- data/src/test/testwhere.rb +27 -0
- metadata +127 -0
data/src/narray.c
ADDED
@@ -0,0 +1,1308 @@
|
|
1
|
+
/*
|
2
|
+
narray.c
|
3
|
+
Numerical Array Extention for Ruby
|
4
|
+
(C) Copyright 1999-2003 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
|
+
#define NARRAY_C
|
12
|
+
#include <ruby.h>
|
13
|
+
#include "narray.h"
|
14
|
+
#include "narray_local.h"
|
15
|
+
|
16
|
+
/* global variables within this module */
|
17
|
+
VALUE cNArray, cNArrayScalar, cComplex;
|
18
|
+
|
19
|
+
ID na_id_beg, na_id_end, na_id_exclude_end;
|
20
|
+
ID na_id_minus, na_id_abs, na_id_power;
|
21
|
+
ID na_id_compare, na_id_and, na_id_or;
|
22
|
+
ID na_id_class_dim;
|
23
|
+
ID na_id_add, na_id_sbt, na_id_mul, na_id_div, na_id_mod;
|
24
|
+
ID na_id_real, na_id_imag;
|
25
|
+
ID na_id_coerce_rev;
|
26
|
+
ID na_id_new;
|
27
|
+
static ID na_id_to_i, na_id_usec, na_id_now;
|
28
|
+
|
29
|
+
const int na_sizeof[NA_NTYPES+1] = {
|
30
|
+
0,
|
31
|
+
sizeof(u_int8_t),
|
32
|
+
sizeof(int16_t),
|
33
|
+
sizeof(int32_t),
|
34
|
+
sizeof(float),
|
35
|
+
sizeof(double),
|
36
|
+
sizeof(scomplex),
|
37
|
+
sizeof(dcomplex),
|
38
|
+
sizeof(VALUE),
|
39
|
+
0
|
40
|
+
};
|
41
|
+
|
42
|
+
const char *na_typestring[] = {
|
43
|
+
"none",
|
44
|
+
"byte", /* 1 */
|
45
|
+
"sint", /* 2 */
|
46
|
+
"int", /* 3 */
|
47
|
+
"sfloat", /* 4 */
|
48
|
+
"float", /* 5 */
|
49
|
+
"scomplex", /* 6 */
|
50
|
+
"complex", /* 7 */
|
51
|
+
"object", /* 8 */
|
52
|
+
"ntypes" /* 9 */
|
53
|
+
};
|
54
|
+
|
55
|
+
#ifdef NARRAY_GC
|
56
|
+
static int mem_count = 0;
|
57
|
+
static int na_gc_freq = 2500000; /* Frequency of Garbage Collection */
|
58
|
+
#endif
|
59
|
+
|
60
|
+
void Init_nmath(void);
|
61
|
+
void Init_na_funcs(void);
|
62
|
+
void Init_na_linalg(void);
|
63
|
+
void Init_na_random(void);
|
64
|
+
|
65
|
+
|
66
|
+
#ifdef DEBUG
|
67
|
+
void na_xfree(void *ptr)
|
68
|
+
{
|
69
|
+
if (!ptr) abort();
|
70
|
+
free(ptr);
|
71
|
+
}
|
72
|
+
#endif
|
73
|
+
|
74
|
+
/* mark items */
|
75
|
+
static void
|
76
|
+
na_mark_obj(struct NARRAY *ary)
|
77
|
+
{
|
78
|
+
int i;
|
79
|
+
VALUE *ptr;
|
80
|
+
|
81
|
+
ptr = (VALUE*) ary->ptr;
|
82
|
+
for (i=ary->total; i>0; i--)
|
83
|
+
rb_gc_mark(*ptr++);
|
84
|
+
}
|
85
|
+
|
86
|
+
static void
|
87
|
+
na_mark_ref(struct NARRAY *ary)
|
88
|
+
{
|
89
|
+
struct NARRAY *a2;
|
90
|
+
|
91
|
+
rb_gc_mark( ary->ref );
|
92
|
+
|
93
|
+
GetNArray(ary->ref,a2);
|
94
|
+
if (a2->type == NA_ROBJ) na_mark_obj(a2);
|
95
|
+
}
|
96
|
+
|
97
|
+
|
98
|
+
static void
|
99
|
+
na_free(struct NARRAY* ary)
|
100
|
+
{
|
101
|
+
if ( ary->total > 0 ) {
|
102
|
+
if (ary->ref == Qnil || ary->ref == Qtrue) { /* non reference */
|
103
|
+
xfree(ary->ptr);
|
104
|
+
}
|
105
|
+
xfree(ary->shape);
|
106
|
+
#ifdef DEBUG
|
107
|
+
ary->shape = NULL;
|
108
|
+
ary->ptr = NULL;
|
109
|
+
#endif
|
110
|
+
}
|
111
|
+
xfree(ary);
|
112
|
+
}
|
113
|
+
|
114
|
+
|
115
|
+
/* allocation of NARRAY */
|
116
|
+
struct NARRAY*
|
117
|
+
na_alloc_struct(int type, int rank, int *shape)
|
118
|
+
{
|
119
|
+
int total=1;
|
120
|
+
int i, memsz;
|
121
|
+
struct NARRAY *ary;
|
122
|
+
|
123
|
+
for (i=0; i<rank; i++)
|
124
|
+
total *= shape[i];
|
125
|
+
|
126
|
+
if (rank<=0 || total<=0) {
|
127
|
+
/* empty array */
|
128
|
+
ary = ALLOC(struct NARRAY);
|
129
|
+
ary->rank =
|
130
|
+
ary->total = 0;
|
131
|
+
ary->shape = NULL;
|
132
|
+
ary->ptr = NULL;
|
133
|
+
ary->type = type;
|
134
|
+
}
|
135
|
+
else {
|
136
|
+
memsz = na_sizeof[type] * total;
|
137
|
+
|
138
|
+
/* Garbage Collection */
|
139
|
+
#ifdef NARRAY_GC
|
140
|
+
mem_count += memsz;
|
141
|
+
if ( mem_count > na_gc_freq ) { rb_gc(); mem_count=0; }
|
142
|
+
#endif
|
143
|
+
|
144
|
+
ary = ALLOC(struct NARRAY);
|
145
|
+
ary->shape = ALLOC_N(int, rank);
|
146
|
+
ary->ptr = ALLOC_N(char, memsz);
|
147
|
+
|
148
|
+
ary->rank = rank;
|
149
|
+
ary->total = total;
|
150
|
+
ary->type = type;
|
151
|
+
for (i=0; i<rank; i++)
|
152
|
+
ary->shape[i] = shape[i];
|
153
|
+
}
|
154
|
+
ary->ref = Qtrue;
|
155
|
+
return ary;
|
156
|
+
}
|
157
|
+
|
158
|
+
#if !defined RCLASS_SUPER
|
159
|
+
#define RCLASS_SUPER(v) (RCLASS(v)->super)
|
160
|
+
#endif
|
161
|
+
|
162
|
+
static void
|
163
|
+
na_check_class_narray(VALUE v)
|
164
|
+
{
|
165
|
+
if (TYPE(v) != T_CLASS) {
|
166
|
+
rb_raise(rb_eRuntimeError, "class required");
|
167
|
+
}
|
168
|
+
while (v) {
|
169
|
+
if (v == cNArray || RCLASS(v)->m_tbl == RCLASS(cNArray)->m_tbl)
|
170
|
+
return;
|
171
|
+
v = RCLASS_SUPER(v);
|
172
|
+
}
|
173
|
+
rb_raise(rb_eRuntimeError, "need NArray or its subclass");
|
174
|
+
}
|
175
|
+
|
176
|
+
|
177
|
+
static VALUE
|
178
|
+
na_wrap_struct_class(struct NARRAY *ary, VALUE klass)
|
179
|
+
{
|
180
|
+
VALUE v;
|
181
|
+
int class_dim;
|
182
|
+
|
183
|
+
/* Extract element */
|
184
|
+
if (ary->rank==0 && ary->total==1) {
|
185
|
+
SetFuncs[NA_ROBJ][ary->type](1,&v,0,ary->ptr,0);
|
186
|
+
na_free(ary);
|
187
|
+
return v;
|
188
|
+
}
|
189
|
+
|
190
|
+
/* check NArray >= klass */
|
191
|
+
na_check_class_narray(klass);
|
192
|
+
|
193
|
+
/* Check dimension */
|
194
|
+
class_dim = NUM2INT(rb_const_get(klass, na_id_class_dim));
|
195
|
+
if (ary->rank < class_dim)
|
196
|
+
rb_raise(rb_eTypeError, "array.dim(=%i) < CLASS_DIMENSION(=%i)",
|
197
|
+
ary->rank, class_dim);
|
198
|
+
|
199
|
+
if (ary->ref == Qnil)
|
200
|
+
rb_raise(rb_eRuntimeError, "already wrapped object");
|
201
|
+
|
202
|
+
/* Turn on WRAPPED flag */
|
203
|
+
if (ary->ref == Qtrue) {
|
204
|
+
ary->ref = Qnil;
|
205
|
+
if (NA_IsROBJ(ary))
|
206
|
+
return Data_Wrap_Struct(klass, na_mark_obj, na_free, ary);
|
207
|
+
else
|
208
|
+
return Data_Wrap_Struct(klass, 0, na_free, ary);
|
209
|
+
}
|
210
|
+
|
211
|
+
/* reference to another NArray*/
|
212
|
+
return Data_Wrap_Struct(klass, na_mark_ref, na_free, ary);
|
213
|
+
}
|
214
|
+
|
215
|
+
|
216
|
+
static VALUE
|
217
|
+
na_wrap_struct(struct NARRAY *ary, VALUE obj)
|
218
|
+
{
|
219
|
+
return na_wrap_struct_class(ary,CLASS_OF(obj));
|
220
|
+
}
|
221
|
+
|
222
|
+
|
223
|
+
VALUE
|
224
|
+
na_make_object(int type, int rank, int *shape, VALUE klass)
|
225
|
+
{
|
226
|
+
struct NARRAY *na;
|
227
|
+
|
228
|
+
na = na_alloc_struct(type, rank, shape);
|
229
|
+
|
230
|
+
if (type==NA_ROBJ) {
|
231
|
+
rb_mem_clear((VALUE*)(na->ptr), na->total);
|
232
|
+
}
|
233
|
+
return na_wrap_struct_class(na, klass);
|
234
|
+
}
|
235
|
+
|
236
|
+
|
237
|
+
/* restriction: Integer, Float, Complex === obj */
|
238
|
+
VALUE
|
239
|
+
na_make_scalar(VALUE obj, int type)
|
240
|
+
{
|
241
|
+
static int shape=1;
|
242
|
+
VALUE v;
|
243
|
+
struct NARRAY *ary;
|
244
|
+
|
245
|
+
v = na_make_object(type,1,&shape,cNArrayScalar);
|
246
|
+
GetNArray(v,ary);
|
247
|
+
SetFuncs[ary->type][NA_ROBJ](1, ary->ptr,0, &obj,0);
|
248
|
+
|
249
|
+
return v;
|
250
|
+
}
|
251
|
+
|
252
|
+
|
253
|
+
VALUE
|
254
|
+
na_make_empty(int type, VALUE klass)
|
255
|
+
{
|
256
|
+
struct NARRAY *na;
|
257
|
+
|
258
|
+
na = na_alloc_struct(type, 0, NULL);
|
259
|
+
return na_wrap_struct_class(na, klass);
|
260
|
+
}
|
261
|
+
|
262
|
+
|
263
|
+
/* allocate reference to NArray */
|
264
|
+
struct NARRAY*
|
265
|
+
na_ref_alloc_struct(VALUE obj)
|
266
|
+
{
|
267
|
+
int i;
|
268
|
+
struct NARRAY *orig, *ary;
|
269
|
+
|
270
|
+
GetNArray(obj,orig);
|
271
|
+
|
272
|
+
if (orig->rank<=0)
|
273
|
+
rb_raise(rb_eRuntimeError, "cannot create NArrayRefer of Empty NArray");
|
274
|
+
|
275
|
+
ary = ALLOC(struct NARRAY);
|
276
|
+
ary->shape = ALLOC_N(int, orig->rank);
|
277
|
+
ary->ptr = orig->ptr;
|
278
|
+
ary->rank = orig->rank;
|
279
|
+
ary->total = orig->total;
|
280
|
+
ary->type = orig->type;
|
281
|
+
for (i=0; i<orig->rank; i++)
|
282
|
+
ary->shape[i] = orig->shape[i];
|
283
|
+
ary->ref = obj;
|
284
|
+
|
285
|
+
return ary;
|
286
|
+
}
|
287
|
+
|
288
|
+
/* method: self.refer */
|
289
|
+
static VALUE
|
290
|
+
na_refer(VALUE self)
|
291
|
+
{
|
292
|
+
return na_wrap_struct(na_ref_alloc_struct(self), self);
|
293
|
+
}
|
294
|
+
|
295
|
+
/* singleton method: NArray.refer( other ) */
|
296
|
+
static VALUE
|
297
|
+
na_s_refer(VALUE klass, VALUE self)
|
298
|
+
{
|
299
|
+
return na_wrap_struct_class(na_ref_alloc_struct(self), klass);
|
300
|
+
}
|
301
|
+
|
302
|
+
/* method: self.original */
|
303
|
+
static VALUE
|
304
|
+
na_original(VALUE self)
|
305
|
+
{
|
306
|
+
struct NARRAY *ary;
|
307
|
+
|
308
|
+
GetNArray(self,ary);
|
309
|
+
return ary->ref;
|
310
|
+
}
|
311
|
+
|
312
|
+
|
313
|
+
/*
|
314
|
+
void
|
315
|
+
na_touch_object(VALUE val, ...)
|
316
|
+
{
|
317
|
+
return;
|
318
|
+
}
|
319
|
+
*/
|
320
|
+
|
321
|
+
void
|
322
|
+
na_clear_data(struct NARRAY *ary)
|
323
|
+
{
|
324
|
+
if (NA_IsROBJ(ary))
|
325
|
+
rb_mem_clear((VALUE*)(ary->ptr), ary->total);
|
326
|
+
else
|
327
|
+
MEMZERO(ary->ptr, char, na_sizeof[ary->type]*ary->total);
|
328
|
+
}
|
329
|
+
|
330
|
+
|
331
|
+
/* local function for new array creation */
|
332
|
+
static VALUE
|
333
|
+
na_new2(int argc, VALUE *argv, int type, VALUE klass)
|
334
|
+
{
|
335
|
+
int i, *shape;
|
336
|
+
struct NARRAY *ary;
|
337
|
+
VALUE v;
|
338
|
+
|
339
|
+
if (argc == 0)
|
340
|
+
rb_raise(rb_eArgError, "Argument required");
|
341
|
+
|
342
|
+
shape = ALLOCA_N(int,argc);
|
343
|
+
for (i=0; i<argc; i++) shape[i]=NUM2INT(argv[i]);
|
344
|
+
|
345
|
+
v = na_make_object(type,argc,shape,klass);
|
346
|
+
GetNArray(v,ary);
|
347
|
+
|
348
|
+
if (ary->type != NA_ROBJ)
|
349
|
+
na_clear_data(ary);
|
350
|
+
|
351
|
+
/* rb_obj_call_init(v, 0, 0); */
|
352
|
+
return v;
|
353
|
+
}
|
354
|
+
|
355
|
+
|
356
|
+
/* Convert type arguments -> typecode */
|
357
|
+
int
|
358
|
+
na_get_typecode(VALUE v)
|
359
|
+
{
|
360
|
+
struct NARRAY *na;
|
361
|
+
int i;
|
362
|
+
|
363
|
+
if (v==rb_cFloat) return NA_DFLOAT;
|
364
|
+
if (v==rb_cInteger) return NA_LINT;
|
365
|
+
if (v==cComplex) return NA_DCOMPLEX;
|
366
|
+
if (v==rb_cObject) return NA_ROBJ;
|
367
|
+
if (FIXNUM_P(v)) {
|
368
|
+
i = NUM2INT(v);
|
369
|
+
if (i<=NA_NONE || i>=NA_NTYPES)
|
370
|
+
rb_raise(rb_eArgError, "Wrong type code");
|
371
|
+
return i;
|
372
|
+
}
|
373
|
+
if (NA_IsNArray(v)) {
|
374
|
+
GetNArray(v,na);
|
375
|
+
return na->type;
|
376
|
+
}
|
377
|
+
if (TYPE(v)==T_STRING) {
|
378
|
+
for (i=1; i<NA_NTYPES; i++) {
|
379
|
+
if ( !strncmp( RSTRING_PTR(v), na_typestring[i], RSTRING_LEN(v)) )
|
380
|
+
return i;
|
381
|
+
}
|
382
|
+
}
|
383
|
+
rb_raise(rb_eArgError, "Unrecognized NArray type");
|
384
|
+
return 0;
|
385
|
+
}
|
386
|
+
|
387
|
+
|
388
|
+
/* class method: new(type, size1,size2,...,sizeN) */
|
389
|
+
static VALUE
|
390
|
+
na_s_new(int argc, VALUE *argv, VALUE klass)
|
391
|
+
{
|
392
|
+
if (argc == 0)
|
393
|
+
rb_raise(rb_eArgError, "Argument required");
|
394
|
+
return na_new2(argc-1, argv+1, na_get_typecode(argv[0]), klass);
|
395
|
+
}
|
396
|
+
|
397
|
+
/* class method: byte(size1,size2,...,sizeN) */
|
398
|
+
static VALUE
|
399
|
+
na_s_new_byte(int argc, VALUE *argv, VALUE klass)
|
400
|
+
{ return na_new2(argc, argv, NA_BYTE, klass); }
|
401
|
+
|
402
|
+
/* class method: sint(size1,size2,...,sizeN) */
|
403
|
+
static VALUE
|
404
|
+
na_s_new_sint(int argc, VALUE *argv, VALUE klass)
|
405
|
+
{ return na_new2(argc, argv, NA_SINT, klass); }
|
406
|
+
|
407
|
+
/* class method: int(size1,size2,...,sizeN) */
|
408
|
+
static VALUE
|
409
|
+
na_s_new_int(int argc, VALUE *argv, VALUE klass)
|
410
|
+
{ return na_new2(argc, argv, NA_LINT, klass); }
|
411
|
+
|
412
|
+
/* class method: sfloat(size1,size2,...,sizeN) */
|
413
|
+
static VALUE
|
414
|
+
na_s_new_sfloat(int argc, VALUE *argv, VALUE klass)
|
415
|
+
{ return na_new2(argc, argv, NA_SFLOAT, klass); }
|
416
|
+
|
417
|
+
/* class method: float(size1,size2,...,sizeN) */
|
418
|
+
static VALUE
|
419
|
+
na_s_new_float(int argc, VALUE *argv, VALUE klass)
|
420
|
+
{ return na_new2(argc, argv, NA_DFLOAT, klass); }
|
421
|
+
|
422
|
+
/* class method: scomplex(size1,size2,...,sizeN) */
|
423
|
+
static VALUE
|
424
|
+
na_s_new_scomplex(int argc, VALUE *argv, VALUE klass)
|
425
|
+
{ return na_new2(argc, argv, NA_SCOMPLEX, klass); }
|
426
|
+
|
427
|
+
/* class method: complex(size1,size2,...,sizeN) */
|
428
|
+
static VALUE
|
429
|
+
na_s_new_complex(int argc, VALUE *argv, VALUE klass)
|
430
|
+
{ return na_new2(argc, argv, NA_DCOMPLEX, klass); }
|
431
|
+
|
432
|
+
/* class method: object(size1,size2,...,sizeN) */
|
433
|
+
static VALUE
|
434
|
+
na_s_new_object(int argc, VALUE *argv, VALUE klass)
|
435
|
+
{ return na_new2(argc, argv, NA_ROBJ, klass); }
|
436
|
+
|
437
|
+
|
438
|
+
|
439
|
+
/* method: dup() */
|
440
|
+
VALUE
|
441
|
+
na_clone(VALUE self)
|
442
|
+
{
|
443
|
+
struct NARRAY *org, *cpy;
|
444
|
+
|
445
|
+
GetNArray(self,org);
|
446
|
+
cpy = na_alloc_struct(org->type,org->rank,org->shape);
|
447
|
+
memcpy(cpy->ptr, org->ptr, na_sizeof[org->type] * org->total);
|
448
|
+
return na_wrap_struct(cpy,self);
|
449
|
+
}
|
450
|
+
|
451
|
+
|
452
|
+
/* local function */
|
453
|
+
void
|
454
|
+
na_copy_nary(struct NARRAY *dst, struct NARRAY *src)
|
455
|
+
{
|
456
|
+
if (dst->total != src->total)
|
457
|
+
rb_raise(rb_eRuntimeError, "src and dst array sizes mismatch");
|
458
|
+
|
459
|
+
if (dst->type == src->type)
|
460
|
+
memcpy(dst->ptr, src->ptr, src->total*na_sizeof[src->type]);
|
461
|
+
else {
|
462
|
+
SetFuncs[dst->type][src->type]( src->total,
|
463
|
+
dst->ptr, na_sizeof[dst->type],
|
464
|
+
src->ptr, na_sizeof[src->type] );
|
465
|
+
}
|
466
|
+
}
|
467
|
+
|
468
|
+
|
469
|
+
/* method: to_type(type) */
|
470
|
+
static VALUE
|
471
|
+
na_to_type(VALUE self, VALUE vtype)
|
472
|
+
{
|
473
|
+
struct NARRAY *a1, *a2;
|
474
|
+
VALUE v;
|
475
|
+
|
476
|
+
GetNArray(self,a1);
|
477
|
+
|
478
|
+
v = na_make_object(na_get_typecode(vtype), a1->rank, a1->shape,
|
479
|
+
CLASS_OF(self));
|
480
|
+
GetNArray(v,a2);
|
481
|
+
na_copy_nary(a2,a1);
|
482
|
+
return v;
|
483
|
+
}
|
484
|
+
|
485
|
+
|
486
|
+
/* method: to_f() */
|
487
|
+
static VALUE
|
488
|
+
na_to_float(VALUE self)
|
489
|
+
{
|
490
|
+
struct NARRAY *a1, *a2;
|
491
|
+
VALUE v;
|
492
|
+
|
493
|
+
GetNArray(self,a1);
|
494
|
+
|
495
|
+
v = na_make_object(na_upcast[NA_SFLOAT][a1->type], a1->rank, a1->shape,
|
496
|
+
CLASS_OF(self));
|
497
|
+
GetNArray(v,a2);
|
498
|
+
na_copy_nary(a2,a1);
|
499
|
+
return v;
|
500
|
+
}
|
501
|
+
|
502
|
+
|
503
|
+
/* method: to_i() */
|
504
|
+
static VALUE
|
505
|
+
na_to_integer(VALUE self)
|
506
|
+
{
|
507
|
+
int type;
|
508
|
+
struct NARRAY *a1, *a2;
|
509
|
+
VALUE v;
|
510
|
+
|
511
|
+
GetNArray(self,a1);
|
512
|
+
if (!NA_IsINTEGER(a1))
|
513
|
+
type = NA_LINT;
|
514
|
+
else
|
515
|
+
type = a1->type;
|
516
|
+
v = na_make_object(type, a1->rank, a1->shape, CLASS_OF(self));
|
517
|
+
GetNArray(v,a2);
|
518
|
+
na_copy_nary(a2,a1);
|
519
|
+
return v;
|
520
|
+
}
|
521
|
+
|
522
|
+
|
523
|
+
/* method: shape() -- returns an array of shape of each rank */
|
524
|
+
static VALUE
|
525
|
+
na_shape(VALUE self)
|
526
|
+
{
|
527
|
+
struct NARRAY *ary;
|
528
|
+
VALUE *shape;
|
529
|
+
int i;
|
530
|
+
|
531
|
+
GetNArray(self,ary);
|
532
|
+
shape = ALLOCA_N(VALUE,ary->rank);
|
533
|
+
for (i = 0; i < ary->rank; i++)
|
534
|
+
shape[i] = INT2FIX(ary->shape[i]);
|
535
|
+
return rb_ary_new4(ary->rank,shape);
|
536
|
+
}
|
537
|
+
|
538
|
+
|
539
|
+
/* method: rank() -- returns the rank of the array */
|
540
|
+
static VALUE
|
541
|
+
na_rank(VALUE self)
|
542
|
+
{
|
543
|
+
struct NARRAY *ary;
|
544
|
+
GetNArray(self,ary);
|
545
|
+
return INT2FIX(ary->rank);
|
546
|
+
}
|
547
|
+
|
548
|
+
|
549
|
+
/* method: size() -- returns the total number of elements */
|
550
|
+
static VALUE
|
551
|
+
na_size(VALUE self)
|
552
|
+
{
|
553
|
+
struct NARRAY *ary;
|
554
|
+
GetNArray(self,ary);
|
555
|
+
return INT2FIX(ary->total);
|
556
|
+
}
|
557
|
+
|
558
|
+
|
559
|
+
/* method: typecode -- returns the type of the array */
|
560
|
+
static VALUE
|
561
|
+
na_typecode(VALUE self)
|
562
|
+
{
|
563
|
+
struct NARRAY *ary;
|
564
|
+
GetNArray(self,ary);
|
565
|
+
return INT2FIX(ary->type);
|
566
|
+
}
|
567
|
+
|
568
|
+
|
569
|
+
/* method: element_size -- returns the element size of the array type */
|
570
|
+
static VALUE
|
571
|
+
na_element_size(VALUE self)
|
572
|
+
{
|
573
|
+
struct NARRAY *ary;
|
574
|
+
GetNArray(self,ary);
|
575
|
+
return INT2FIX(na_sizeof[ary->type]);
|
576
|
+
}
|
577
|
+
|
578
|
+
|
579
|
+
/* method: empty? -- returns true if empty array */
|
580
|
+
static VALUE
|
581
|
+
na_is_empty(VALUE self)
|
582
|
+
{
|
583
|
+
struct NARRAY *ary;
|
584
|
+
GetNArray(self,ary);
|
585
|
+
if (ary->total==0) return Qtrue;
|
586
|
+
return Qfalse;
|
587
|
+
}
|
588
|
+
|
589
|
+
|
590
|
+
/* Binary copy of String => NArray */
|
591
|
+
static VALUE
|
592
|
+
na_str_to_na(int argc, VALUE *argv, VALUE str)
|
593
|
+
{
|
594
|
+
struct NARRAY *ary;
|
595
|
+
VALUE v;
|
596
|
+
int i, type, len=1, str_len, *shape, rank=argc-1;
|
597
|
+
|
598
|
+
if (argc < 1)
|
599
|
+
rb_raise(rb_eArgError, "Type and Size Arguments required");
|
600
|
+
|
601
|
+
type = na_get_typecode(argv[0]);
|
602
|
+
|
603
|
+
str_len = RSTRING_LEN(str);
|
604
|
+
|
605
|
+
if (argc == 1) {
|
606
|
+
rank = 1;
|
607
|
+
shape = ALLOCA_N(int,rank);
|
608
|
+
if ( str_len % na_sizeof[type] != 0 )
|
609
|
+
rb_raise(rb_eArgError, "string size mismatch");
|
610
|
+
shape[0] = str_len / na_sizeof[type];
|
611
|
+
}
|
612
|
+
else {
|
613
|
+
shape = ALLOCA_N(int,rank);
|
614
|
+
for (i=0; i<rank; i++)
|
615
|
+
len *= shape[i] = NUM2INT(argv[i+1]);
|
616
|
+
len *= na_sizeof[type];
|
617
|
+
if ( len != str_len )
|
618
|
+
rb_raise(rb_eArgError, "size mismatch");
|
619
|
+
}
|
620
|
+
|
621
|
+
v = na_make_object( type, rank, shape, cNArray );
|
622
|
+
GetNArray(v,ary);
|
623
|
+
memcpy( ary->ptr, RSTRING_PTR(str), ary->total*na_sizeof[type] );
|
624
|
+
|
625
|
+
return v;
|
626
|
+
}
|
627
|
+
|
628
|
+
|
629
|
+
/* method: to_s -- convert the data contents to a binary string */
|
630
|
+
static VALUE
|
631
|
+
na_to_s(VALUE self)
|
632
|
+
{
|
633
|
+
struct NARRAY *ary;
|
634
|
+
GetNArray(self,ary);
|
635
|
+
if (NA_IsROBJ(ary))
|
636
|
+
rb_raise(rb_eTypeError,"cannot convert object-type NArray");
|
637
|
+
return rb_str_new(ary->ptr,ary->total*na_sizeof[ary->type]);
|
638
|
+
}
|
639
|
+
|
640
|
+
|
641
|
+
/* method: to_binary -- convert the data contents to a BYTE type NArray */
|
642
|
+
static VALUE
|
643
|
+
na_to_binary(VALUE self)
|
644
|
+
{
|
645
|
+
struct NARRAY *a1, *a2;
|
646
|
+
int i, *shape, rank;
|
647
|
+
VALUE v;
|
648
|
+
|
649
|
+
GetNArray(self,a1);
|
650
|
+
|
651
|
+
rank = a1->rank+1;
|
652
|
+
shape = ALLOCA_N(int,rank);
|
653
|
+
shape[0] = na_sizeof[a1->type];
|
654
|
+
for (i=1; i<rank; i++)
|
655
|
+
shape[i] = a1->shape[i-1];
|
656
|
+
|
657
|
+
v = na_make_object( NA_BYTE, rank, shape, cNArray );
|
658
|
+
GetNArray(v,a2);
|
659
|
+
MEMCPY(a2->ptr,a1->ptr,char,a2->total);
|
660
|
+
|
661
|
+
return v;
|
662
|
+
}
|
663
|
+
|
664
|
+
|
665
|
+
/* method: to_type_as_binary(type) */
|
666
|
+
static VALUE
|
667
|
+
na_to_type_as_binary(VALUE self, VALUE vtype)
|
668
|
+
{
|
669
|
+
struct NARRAY *a1, *a2;
|
670
|
+
int size, total, type;
|
671
|
+
VALUE v;
|
672
|
+
|
673
|
+
type = na_get_typecode(vtype);
|
674
|
+
GetNArray(self,a1);
|
675
|
+
|
676
|
+
size = a1->total * na_sizeof[a1->type];
|
677
|
+
if ( size % na_sizeof[type] != 0 )
|
678
|
+
rb_raise(rb_eRuntimeError, "bina1 size mismatch");
|
679
|
+
total = size / na_sizeof[type];
|
680
|
+
|
681
|
+
v = na_make_object( type, 1, &total, cNArray );
|
682
|
+
GetNArray(v,a2);
|
683
|
+
MEMCPY(a2->ptr,a1->ptr,char,size);
|
684
|
+
|
685
|
+
return v;
|
686
|
+
}
|
687
|
+
|
688
|
+
|
689
|
+
static void
|
690
|
+
na_to_string_binary(int n, char *p1, int i1, char *p2, int i2)
|
691
|
+
{
|
692
|
+
for (; n>0; n--) {
|
693
|
+
*(VALUE*)p1 = rb_str_new(p2,i2);
|
694
|
+
p1+=i1; p2+=i2;
|
695
|
+
}
|
696
|
+
}
|
697
|
+
|
698
|
+
|
699
|
+
/* method: to_string */
|
700
|
+
static VALUE
|
701
|
+
na_to_string(VALUE self)
|
702
|
+
{
|
703
|
+
VALUE v;
|
704
|
+
struct NARRAY *a1, *a2;
|
705
|
+
|
706
|
+
GetNArray(self,a1);
|
707
|
+
|
708
|
+
if (a1->total==0)
|
709
|
+
v = na_make_empty(NA_ROBJ, CLASS_OF(self));
|
710
|
+
else
|
711
|
+
if (a1->type==NA_BYTE) {
|
712
|
+
if (a1->rank==1)
|
713
|
+
return rb_str_new(a1->ptr,a1->shape[0]);
|
714
|
+
v = na_make_object(NA_ROBJ, a1->rank-1, a1->shape+1, cNArray);
|
715
|
+
GetNArray(v,a2);
|
716
|
+
na_to_string_binary( a2->total,
|
717
|
+
a2->ptr, sizeof(VALUE),
|
718
|
+
a1->ptr, a1->shape[0] );
|
719
|
+
} else {
|
720
|
+
v = na_make_object(NA_ROBJ, a1->rank, a1->shape, CLASS_OF(self));
|
721
|
+
GetNArray(v,a2);
|
722
|
+
ToStrFuncs[a1->type]( a2->total,
|
723
|
+
a2->ptr, sizeof(VALUE),
|
724
|
+
a1->ptr, na_sizeof[a1->type] );
|
725
|
+
}
|
726
|
+
return v;
|
727
|
+
}
|
728
|
+
|
729
|
+
|
730
|
+
/* singleton method:
|
731
|
+
NArray.to_na( string, type, size1,size2,...,sizeN )
|
732
|
+
NArray.to_na( object )
|
733
|
+
*/
|
734
|
+
static VALUE
|
735
|
+
na_s_to_na(int argc, VALUE *argv, VALUE klass)
|
736
|
+
{
|
737
|
+
static int shape=1;
|
738
|
+
VALUE v;
|
739
|
+
struct NARRAY *ary;
|
740
|
+
|
741
|
+
switch(TYPE(argv[0])) {
|
742
|
+
case T_STRING:
|
743
|
+
return na_str_to_na(argc-1,argv+1,argv[0]);
|
744
|
+
case T_ARRAY:
|
745
|
+
if (argc>1)
|
746
|
+
rb_raise(rb_eArgError,"extra arguments");
|
747
|
+
return na_ary_to_nary( argv[0], klass );
|
748
|
+
default:
|
749
|
+
v = na_make_object(na_object_type(argv[0]),1,&shape,klass);
|
750
|
+
GetNArray(v,ary);
|
751
|
+
SetFuncs[ary->type][NA_ROBJ](1, ary->ptr,0, argv,0);
|
752
|
+
return v;
|
753
|
+
}
|
754
|
+
}
|
755
|
+
|
756
|
+
|
757
|
+
/* singleton method:
|
758
|
+
NArray[object]
|
759
|
+
*/
|
760
|
+
static VALUE
|
761
|
+
na_s_bracket(int argc, VALUE *argv, VALUE klass)
|
762
|
+
{
|
763
|
+
VALUE v = rb_ary_new4(argc, argv);
|
764
|
+
return na_ary_to_nary( v, klass );
|
765
|
+
}
|
766
|
+
|
767
|
+
|
768
|
+
/* method: coerce(other) */
|
769
|
+
static VALUE na_coerce(VALUE self, VALUE other)
|
770
|
+
{
|
771
|
+
struct NARRAY *a1;
|
772
|
+
|
773
|
+
GetNArray(self,a1);
|
774
|
+
return rb_assoc_new( na_cast_object(other,a1->type), self );
|
775
|
+
}
|
776
|
+
|
777
|
+
|
778
|
+
/* method: inspect() -- returns the inspect of the array */
|
779
|
+
static VALUE
|
780
|
+
na_inspect(VALUE self)
|
781
|
+
{
|
782
|
+
VALUE str;
|
783
|
+
struct NARRAY *ary;
|
784
|
+
int i;
|
785
|
+
char buf[256];
|
786
|
+
char *classname;
|
787
|
+
char *ref = "%s(ref).%s(%i";
|
788
|
+
char *org = "%s.%s(%i";
|
789
|
+
|
790
|
+
GetNArray(self,ary);
|
791
|
+
classname = rb_class2name(CLASS_OF(self));
|
792
|
+
|
793
|
+
str = rb_str_new(0,0);
|
794
|
+
if (ary->rank < 1) {
|
795
|
+
sprintf(buf, "%s.%s(): []", classname, na_typestring[ary->type]);
|
796
|
+
rb_str_cat(str,buf,strlen(buf));
|
797
|
+
}
|
798
|
+
else {
|
799
|
+
sprintf(buf, (ary->ref==Qnil) ? org:ref,
|
800
|
+
classname, na_typestring[ary->type], ary->shape[0]);
|
801
|
+
rb_str_cat(str,buf,strlen(buf));
|
802
|
+
for (i=1; i<ary->rank; i++) {
|
803
|
+
sprintf(buf,",%i",ary->shape[i]);
|
804
|
+
rb_str_cat(str,buf,strlen(buf));
|
805
|
+
}
|
806
|
+
rb_str_cat(str,")",1);
|
807
|
+
rb_str_cat(str,": \n",3);
|
808
|
+
rb_str_concat(str, na_make_inspect(self));
|
809
|
+
}
|
810
|
+
return str;
|
811
|
+
}
|
812
|
+
|
813
|
+
|
814
|
+
/* private function for reshape */
|
815
|
+
static void
|
816
|
+
na_reshape(int argc, VALUE *argv, struct NARRAY *ary, VALUE self)
|
817
|
+
{
|
818
|
+
int *shape, class_dim;
|
819
|
+
int i, total=1, unfixed=-1;
|
820
|
+
VALUE klass;
|
821
|
+
|
822
|
+
if (ary->total==0)
|
823
|
+
rb_raise(rb_eRuntimeError, "cannot reshape empty array");
|
824
|
+
|
825
|
+
klass = CLASS_OF(self);
|
826
|
+
class_dim = NUM2INT(rb_const_get(klass, na_id_class_dim));
|
827
|
+
|
828
|
+
if (argc == 0) { /* trim ranks of size=1 */
|
829
|
+
shape = ALLOCA_N(int,ary->rank+1);
|
830
|
+
for (i=0; i<class_dim; i++) shape[i]=0;
|
831
|
+
for ( ; i<ary->rank; i++) shape[i]=1;
|
832
|
+
na_shrink_rank( self, class_dim, shape );
|
833
|
+
if (ary->rank==0) ary->rank=1;
|
834
|
+
return;
|
835
|
+
}
|
836
|
+
|
837
|
+
/* get shape from argument */
|
838
|
+
shape = ALLOC_N(int,argc);
|
839
|
+
for (i=0; i<argc; i++)
|
840
|
+
switch(TYPE(argv[i])) {
|
841
|
+
case T_FIXNUM:
|
842
|
+
total *= shape[i] = NUM2INT(argv[i]);
|
843
|
+
break;
|
844
|
+
case T_TRUE:
|
845
|
+
unfixed = i;
|
846
|
+
break;
|
847
|
+
default:
|
848
|
+
rb_raise(rb_eArgError,"illegal type");
|
849
|
+
}
|
850
|
+
|
851
|
+
if (unfixed>=0) {
|
852
|
+
if (ary->total % total != 0)
|
853
|
+
rb_raise(rb_eArgError, "Total size size must be divisor");
|
854
|
+
shape[unfixed] = ary->total / total;
|
855
|
+
}
|
856
|
+
else if (total != ary->total)
|
857
|
+
rb_raise(rb_eArgError, "Total size must be same");
|
858
|
+
|
859
|
+
/* exchange */
|
860
|
+
xfree(ary->shape);
|
861
|
+
ary->shape = shape;
|
862
|
+
ary->rank = argc;
|
863
|
+
}
|
864
|
+
|
865
|
+
|
866
|
+
/* method: reshape!(size1,size2,...,sizeN) */
|
867
|
+
static VALUE
|
868
|
+
na_reshape_bang(int argc, VALUE *argv, VALUE self)
|
869
|
+
{
|
870
|
+
struct NARRAY *ary;
|
871
|
+
|
872
|
+
GetNArray(self,ary);
|
873
|
+
na_reshape(argc, argv, ary, self);
|
874
|
+
return self;
|
875
|
+
}
|
876
|
+
|
877
|
+
|
878
|
+
/* method: reshape(size1,size2,...,sizeN) */
|
879
|
+
static VALUE
|
880
|
+
na_reshape_ref(int argc, VALUE *argv, VALUE self)
|
881
|
+
{
|
882
|
+
struct NARRAY *ary;
|
883
|
+
|
884
|
+
GetNArray(self,ary);
|
885
|
+
ary = na_ref_alloc_struct(self);
|
886
|
+
na_reshape(argc, argv, ary, self);
|
887
|
+
return na_wrap_struct(ary,self);
|
888
|
+
}
|
889
|
+
|
890
|
+
|
891
|
+
/* method: flatten! */
|
892
|
+
static VALUE
|
893
|
+
na_flatten_bang(VALUE self)
|
894
|
+
{
|
895
|
+
struct NARRAY *ary;
|
896
|
+
|
897
|
+
GetNArray(self,ary);
|
898
|
+
if (ary->total==0 || ary->rank==0)
|
899
|
+
rb_raise(rb_eRuntimeError, "cannot reshape empty array");
|
900
|
+
ary->shape[0] = ary->total;
|
901
|
+
ary->rank = 1;
|
902
|
+
return self;
|
903
|
+
}
|
904
|
+
|
905
|
+
|
906
|
+
/* method: flatten */
|
907
|
+
static VALUE
|
908
|
+
na_flatten_ref(VALUE self)
|
909
|
+
{
|
910
|
+
return na_flatten_bang( na_wrap_struct( na_ref_alloc_struct(self), self ));
|
911
|
+
}
|
912
|
+
|
913
|
+
|
914
|
+
/* private function for newdim */
|
915
|
+
static void
|
916
|
+
na_newdim(int argc, VALUE *argv, struct NARRAY *ary)
|
917
|
+
{
|
918
|
+
int *shape, *count;
|
919
|
+
int i, j;
|
920
|
+
|
921
|
+
if (argc==0)
|
922
|
+
rb_raise(rb_eArgError, "Argument required");
|
923
|
+
if (ary->rank + argc > NA_MAX_RANK-1)
|
924
|
+
rb_raise(rb_eArgError, "Exceed maximum ranks");
|
925
|
+
if (ary->total==0)
|
926
|
+
rb_raise(rb_eRuntimeError, "cannot extend empty array");
|
927
|
+
|
928
|
+
/* count new rank */
|
929
|
+
count = ALLOCA_N(int,ary->rank+1);
|
930
|
+
for (i=0; i<=ary->rank; i++)
|
931
|
+
count[i]=0;
|
932
|
+
for (i=0; i<argc; i++) {
|
933
|
+
j = NUM2INT(argv[i]);
|
934
|
+
if (j<0) /* negative rank : -1=>append after last rank */
|
935
|
+
j += ary->rank+1;
|
936
|
+
if (j<0 || j>ary->rank) /* range check */
|
937
|
+
rb_raise(rb_eArgError, "rank out of range");
|
938
|
+
count[j]++;
|
939
|
+
}
|
940
|
+
/* extend shape shape */
|
941
|
+
shape = ALLOC_N(int,ary->rank+argc);
|
942
|
+
for (j=i=0; i<ary->rank; i++) {
|
943
|
+
while (count[i]-->0) shape[j++] = 1;
|
944
|
+
shape[j++] = ary->shape[i];
|
945
|
+
}
|
946
|
+
while (count[i]-->0) shape[j++] = 1;
|
947
|
+
|
948
|
+
/* exchange shape */
|
949
|
+
xfree(ary->shape);
|
950
|
+
ary->shape = shape;
|
951
|
+
ary->rank += argc;
|
952
|
+
}
|
953
|
+
|
954
|
+
|
955
|
+
/* method: newdim!(size1,size2,...,sizeN) */
|
956
|
+
static VALUE
|
957
|
+
na_newdim_bang(int argc, VALUE *argv, VALUE self)
|
958
|
+
{
|
959
|
+
struct NARRAY *ary;
|
960
|
+
|
961
|
+
GetNArray(self,ary);
|
962
|
+
na_newdim(argc, argv, ary);
|
963
|
+
return self;
|
964
|
+
}
|
965
|
+
|
966
|
+
|
967
|
+
/* method: newdim(size1,size2,...,sizeN) */
|
968
|
+
VALUE
|
969
|
+
na_newdim_ref(int argc, VALUE *argv, VALUE self)
|
970
|
+
{
|
971
|
+
struct NARRAY *ary;
|
972
|
+
|
973
|
+
GetNArray(self,ary);
|
974
|
+
ary = na_ref_alloc_struct(self);
|
975
|
+
na_newdim(argc, argv, ary);
|
976
|
+
return na_wrap_struct(ary,self);
|
977
|
+
}
|
978
|
+
|
979
|
+
|
980
|
+
/* method: fill!(val) */
|
981
|
+
VALUE na_fill(VALUE self, volatile VALUE val)
|
982
|
+
{
|
983
|
+
struct NARRAY *a1, *a2;
|
984
|
+
|
985
|
+
GetNArray(self,a1);
|
986
|
+
val = na_cast_unless_narray(val,a1->type);
|
987
|
+
GetNArray(val,a2);
|
988
|
+
|
989
|
+
if (a2->total != 1)
|
990
|
+
rb_raise(rb_eArgError, "single-element argument required");
|
991
|
+
|
992
|
+
SetFuncs[a1->type][a2->type]( a1->total,
|
993
|
+
a1->ptr, na_sizeof[a1->type],
|
994
|
+
a2->ptr, 0 );
|
995
|
+
//na_touch_object(val);
|
996
|
+
return self;
|
997
|
+
}
|
998
|
+
|
999
|
+
|
1000
|
+
/* method: indgen!([start,[step]]) */
|
1001
|
+
VALUE
|
1002
|
+
na_indgen(int argc, VALUE *argv, VALUE self)
|
1003
|
+
{
|
1004
|
+
int start=0, step=1;
|
1005
|
+
struct NARRAY *ary;
|
1006
|
+
|
1007
|
+
if (argc>0) {
|
1008
|
+
start = NUM2INT(argv[0]);
|
1009
|
+
if (argc==2)
|
1010
|
+
step = NUM2INT(argv[1]);
|
1011
|
+
else
|
1012
|
+
if (argc>2)
|
1013
|
+
rb_raise(rb_eArgError, "wrong # of arguments (%d for <= 2)", argc);
|
1014
|
+
}
|
1015
|
+
|
1016
|
+
GetNArray(self,ary);
|
1017
|
+
IndGenFuncs[ary->type]( ary->total,
|
1018
|
+
ary->ptr, na_sizeof[ary->type],
|
1019
|
+
start, step );
|
1020
|
+
return self;
|
1021
|
+
}
|
1022
|
+
|
1023
|
+
|
1024
|
+
/* method: where2
|
1025
|
+
idx_true, idx_false = narray.where2 */
|
1026
|
+
static VALUE
|
1027
|
+
na_where2(volatile VALUE obj)
|
1028
|
+
{
|
1029
|
+
VALUE v1, v0;
|
1030
|
+
int n, i, n1, n0;
|
1031
|
+
char *c;
|
1032
|
+
int32_t *idx1, *idx0;
|
1033
|
+
struct NARRAY *ary, *a1, *a0; /* a1=true, a0=false */
|
1034
|
+
|
1035
|
+
obj = na_cast_object(obj,NA_BYTE);
|
1036
|
+
GetNArray(obj,ary);
|
1037
|
+
n = ary->total;
|
1038
|
+
|
1039
|
+
/* Count true */
|
1040
|
+
c = ary->ptr;
|
1041
|
+
n1 = 0;
|
1042
|
+
for (i=0; i<n; i++)
|
1043
|
+
if (*(c++)) n1++;
|
1044
|
+
|
1045
|
+
n0 = n-n1;
|
1046
|
+
|
1047
|
+
/* partially true and false */
|
1048
|
+
v1 = na_make_object( NA_LINT, 1, &n1, cNArray );
|
1049
|
+
GetNArray(v1,a1);
|
1050
|
+
idx1 = (int32_t*) a1->ptr;
|
1051
|
+
v0 = na_make_object( NA_LINT, 1, &n0, cNArray );
|
1052
|
+
GetNArray(v0,a0);
|
1053
|
+
idx0 = (int32_t*) a0->ptr;
|
1054
|
+
|
1055
|
+
/* Get Indices */
|
1056
|
+
c = ary->ptr;
|
1057
|
+
for ( i=0; i<n; i++ ) {
|
1058
|
+
if (*(c++))
|
1059
|
+
*(idx1++) = i;
|
1060
|
+
else
|
1061
|
+
*(idx0++) = i;
|
1062
|
+
}
|
1063
|
+
|
1064
|
+
//na_touch_object(obj);
|
1065
|
+
return rb_assoc_new( v1, v0 );
|
1066
|
+
}
|
1067
|
+
|
1068
|
+
|
1069
|
+
/* method: where
|
1070
|
+
idx_true = narray.where */
|
1071
|
+
static VALUE
|
1072
|
+
na_where(VALUE self)
|
1073
|
+
{
|
1074
|
+
return RARRAY( na_where2(self) )->ptr[0];
|
1075
|
+
}
|
1076
|
+
|
1077
|
+
|
1078
|
+
/* iterator: each() */
|
1079
|
+
static VALUE
|
1080
|
+
na_each(VALUE obj)
|
1081
|
+
{
|
1082
|
+
int i, sz;
|
1083
|
+
VALUE v;
|
1084
|
+
struct NARRAY *ary;
|
1085
|
+
char *p;
|
1086
|
+
void (*func)();
|
1087
|
+
|
1088
|
+
GetNArray(obj,ary);
|
1089
|
+
|
1090
|
+
p = ary->ptr;
|
1091
|
+
sz = na_sizeof[ary->type];
|
1092
|
+
func = SetFuncs[NA_ROBJ][ary->type];
|
1093
|
+
|
1094
|
+
for ( i=ary->total; i-->0; ) {
|
1095
|
+
(*func)( 1, &v, 0, p, 0 );
|
1096
|
+
rb_yield(v);
|
1097
|
+
p += sz;
|
1098
|
+
}
|
1099
|
+
return Qnil;
|
1100
|
+
}
|
1101
|
+
|
1102
|
+
|
1103
|
+
/* iterator: collect() */
|
1104
|
+
static VALUE
|
1105
|
+
na_collect(VALUE obj1)
|
1106
|
+
{
|
1107
|
+
int i, sz;
|
1108
|
+
VALUE v, obj2;
|
1109
|
+
struct NARRAY *a1, *a2;
|
1110
|
+
char *p1, *p2;
|
1111
|
+
void (*get)(), (*set)();
|
1112
|
+
|
1113
|
+
GetNArray(obj1,a1);
|
1114
|
+
obj2 = na_make_object(a1->type, a1->rank, a1->shape, CLASS_OF(obj1));
|
1115
|
+
GetNArray(obj2,a2);
|
1116
|
+
|
1117
|
+
p1 = a1->ptr;
|
1118
|
+
p2 = a2->ptr;
|
1119
|
+
sz = na_sizeof[a1->type];
|
1120
|
+
get = SetFuncs[NA_ROBJ][a1->type];
|
1121
|
+
set = SetFuncs[a1->type][NA_ROBJ];
|
1122
|
+
|
1123
|
+
for ( i=a1->total; i-->0; ) {
|
1124
|
+
(*get)( 1, &v, 0, p1, 0 );
|
1125
|
+
v = rb_yield(v);
|
1126
|
+
(*set)( 1, p2, 0, &v, 0 );
|
1127
|
+
p1 += sz;
|
1128
|
+
p2 += sz;
|
1129
|
+
}
|
1130
|
+
return obj2;
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
|
1134
|
+
/* iterator: collect!() */
|
1135
|
+
static VALUE
|
1136
|
+
na_collect_bang(VALUE self)
|
1137
|
+
{
|
1138
|
+
int i, sz;
|
1139
|
+
VALUE v;
|
1140
|
+
struct NARRAY *a1;
|
1141
|
+
char *p1;
|
1142
|
+
void (*get)(), (*set)();
|
1143
|
+
|
1144
|
+
GetNArray(self,a1);
|
1145
|
+
|
1146
|
+
p1 = a1->ptr;
|
1147
|
+
sz = na_sizeof[a1->type];
|
1148
|
+
get = SetFuncs[NA_ROBJ][a1->type];
|
1149
|
+
set = SetFuncs[a1->type][NA_ROBJ];
|
1150
|
+
|
1151
|
+
for ( i=a1->total; i-->0; ) {
|
1152
|
+
(*get)( 1, &v, 0, p1, 0 );
|
1153
|
+
v = rb_yield(v);
|
1154
|
+
(*set)( 1, p1, 0, &v, 0 );
|
1155
|
+
p1 += sz;
|
1156
|
+
}
|
1157
|
+
return self;
|
1158
|
+
}
|
1159
|
+
|
1160
|
+
|
1161
|
+
/* initialization of NArray Class */
|
1162
|
+
void
|
1163
|
+
Init_narray()
|
1164
|
+
{
|
1165
|
+
/* require Complex class */
|
1166
|
+
rb_require("complex");
|
1167
|
+
cComplex = rb_const_get( rb_cObject, rb_intern("Complex") );
|
1168
|
+
|
1169
|
+
/* define NArray class */
|
1170
|
+
cNArray = rb_define_class("NArray",rb_cObject);
|
1171
|
+
|
1172
|
+
/* class methods */
|
1173
|
+
/* rb_define_global_function("NArray",na_to_narray,-1); */
|
1174
|
+
rb_define_singleton_method(cNArray,"new",na_s_new,-1);
|
1175
|
+
rb_define_singleton_method(cNArray,"byte",na_s_new_byte,-1);
|
1176
|
+
rb_define_singleton_method(cNArray,"sint",na_s_new_sint,-1);
|
1177
|
+
rb_define_singleton_method(cNArray,"lint",na_s_new_int,-1);
|
1178
|
+
rb_define_singleton_method(cNArray,"int", na_s_new_int,-1);
|
1179
|
+
rb_define_singleton_method(cNArray,"sfloat",na_s_new_sfloat,-1);
|
1180
|
+
rb_define_singleton_method(cNArray,"dfloat",na_s_new_float,-1);
|
1181
|
+
rb_define_singleton_method(cNArray,"float", na_s_new_float,-1);
|
1182
|
+
rb_define_singleton_method(cNArray,"scomplex",na_s_new_scomplex,-1);
|
1183
|
+
rb_define_singleton_method(cNArray,"dcomplex",na_s_new_complex,-1);
|
1184
|
+
rb_define_singleton_method(cNArray,"complex", na_s_new_complex,-1);
|
1185
|
+
rb_define_singleton_method(cNArray,"object",na_s_new_object,-1);
|
1186
|
+
|
1187
|
+
rb_define_singleton_method(cNArray,"to_na",na_s_to_na,-1);
|
1188
|
+
rb_define_singleton_method(cNArray,"to_narray",na_s_to_na,-1);
|
1189
|
+
rb_define_singleton_method(cNArray,"[]",na_s_bracket,-1);
|
1190
|
+
|
1191
|
+
/* methods */
|
1192
|
+
rb_define_method(cNArray, "[]", na_aref,-1);
|
1193
|
+
rb_define_method(cNArray, "[]=", na_aset,-1);
|
1194
|
+
rb_define_method(cNArray, "slice", na_slice,-1);
|
1195
|
+
rb_define_method(cNArray, "shape", na_shape,0);
|
1196
|
+
rb_define_alias(cNArray, "sizes","shape");
|
1197
|
+
rb_define_method(cNArray, "size", na_size,0);
|
1198
|
+
rb_define_alias(cNArray, "total","size");
|
1199
|
+
rb_define_alias(cNArray, "length","size");
|
1200
|
+
rb_define_method(cNArray, "rank", na_rank,0);
|
1201
|
+
rb_define_alias(cNArray, "dim","rank");
|
1202
|
+
rb_define_alias(cNArray, "dimension","rank");
|
1203
|
+
rb_define_method(cNArray, "typecode", na_typecode,0);
|
1204
|
+
rb_define_method(cNArray, "element_size", na_element_size,0);
|
1205
|
+
rb_define_method(cNArray, "empty?", na_is_empty,0);
|
1206
|
+
rb_define_method(cNArray, "clone", na_clone,0);
|
1207
|
+
rb_define_alias(cNArray, "dup","clone");
|
1208
|
+
rb_define_method(cNArray, "inspect", na_inspect,0);
|
1209
|
+
rb_define_method(cNArray, "coerce", na_coerce,1);
|
1210
|
+
rb_define_method(cNArray, "reshape", na_reshape_ref,-1);
|
1211
|
+
rb_define_method(cNArray, "reshape!", na_reshape_bang,-1);
|
1212
|
+
rb_define_alias(cNArray, "shape=","reshape!");
|
1213
|
+
rb_define_method(cNArray, "newdim", na_newdim_ref,-1);
|
1214
|
+
rb_define_alias(cNArray, "newrank","newdim");
|
1215
|
+
rb_define_method(cNArray, "newdim!", na_newdim_bang,-1);
|
1216
|
+
rb_define_alias(cNArray, "newdim=","newdim!");
|
1217
|
+
rb_define_alias(cNArray, "newrank!","newdim!");
|
1218
|
+
rb_define_alias(cNArray, "newrank=","newdim!");
|
1219
|
+
rb_define_method(cNArray, "flatten", na_flatten_ref,0);
|
1220
|
+
rb_define_method(cNArray, "flatten!", na_flatten_bang,0);
|
1221
|
+
rb_define_method(cNArray, "fill!", na_fill,1);
|
1222
|
+
rb_define_alias(cNArray, "fill","fill!");
|
1223
|
+
rb_define_method(cNArray, "indgen!", na_indgen,-1);
|
1224
|
+
rb_define_alias(cNArray, "indgen","indgen!");
|
1225
|
+
rb_define_method(cNArray, "where", na_where, 0);
|
1226
|
+
rb_define_method(cNArray, "where2", na_where2, 0);
|
1227
|
+
rb_define_method(cNArray, "each", na_each,0);
|
1228
|
+
rb_define_method(cNArray, "collect", na_collect,0);
|
1229
|
+
rb_define_method(cNArray, "collect!", na_collect_bang,0);
|
1230
|
+
/* rb_define_method(cNArray, "each_index", na_each_index,0); */
|
1231
|
+
rb_define_method(cNArray, "to_a", na_to_array,0);
|
1232
|
+
rb_define_method(cNArray, "to_s", na_to_s, 0);
|
1233
|
+
rb_define_method(cNArray, "to_f", na_to_float, 0);
|
1234
|
+
rb_define_method(cNArray, "to_i", na_to_integer, 0);
|
1235
|
+
rb_define_method(cNArray, "to_type", na_to_type, 1);
|
1236
|
+
rb_define_method(cNArray, "to_binary", na_to_binary, 0);
|
1237
|
+
rb_define_method(cNArray, "to_type_as_binary", na_to_type_as_binary, 1);
|
1238
|
+
rb_define_method(cNArray, "to_string", na_to_string, 0);
|
1239
|
+
/*mask*/
|
1240
|
+
rb_define_method(cNArray, "count_false", na_count_false, 0);
|
1241
|
+
rb_define_method(cNArray, "count_true", na_count_true, 0);
|
1242
|
+
rb_define_method(cNArray, "mask", na_aref_mask, 1);
|
1243
|
+
|
1244
|
+
rb_define_const(cNArray, "NARRAY_VERSION", rb_str_new2(NARRAY_VERSION));
|
1245
|
+
rb_define_const(cNArray, "BYTE", INT2FIX(NA_BYTE));
|
1246
|
+
rb_define_const(cNArray, "SINT", INT2FIX(NA_SINT));
|
1247
|
+
rb_define_const(cNArray, "LINT", INT2FIX(NA_LINT));
|
1248
|
+
rb_define_const(cNArray, "INT", INT2FIX(NA_LINT));
|
1249
|
+
rb_define_const(cNArray, "SFLOAT", INT2FIX(NA_SFLOAT));
|
1250
|
+
rb_define_const(cNArray, "DFLOAT", INT2FIX(NA_DFLOAT));
|
1251
|
+
rb_define_const(cNArray, "FLOAT", INT2FIX(NA_DFLOAT));
|
1252
|
+
rb_define_const(cNArray, "SCOMPLEX", INT2FIX(NA_SCOMPLEX));
|
1253
|
+
rb_define_const(cNArray, "DCOMPLEX", INT2FIX(NA_DCOMPLEX));
|
1254
|
+
rb_define_const(cNArray, "COMPLEX", INT2FIX(NA_DCOMPLEX));
|
1255
|
+
rb_define_const(cNArray, "ROBJ", INT2FIX(NA_ROBJ));
|
1256
|
+
rb_define_const(cNArray, "OBJECT", INT2FIX(NA_ROBJ));
|
1257
|
+
rb_define_const(cNArray, "NONE", INT2FIX(NA_NONE));
|
1258
|
+
rb_define_const(cNArray, "CLASS_DIMENSION", INT2FIX(0));
|
1259
|
+
#ifdef WORDS_BIGENDIAN
|
1260
|
+
rb_define_const(cNArray, "ENDIAN", INT2FIX(1));
|
1261
|
+
#else
|
1262
|
+
#ifdef DYNAMIC_ENDIAN /* not supported yet */
|
1263
|
+
rb_define_const(cNArray, "ENDIAN", INT2FIX(-1));
|
1264
|
+
#else /* LITTLE_ENDIAN */
|
1265
|
+
rb_define_const(cNArray, "ENDIAN", INT2FIX(0));
|
1266
|
+
#endif
|
1267
|
+
#endif
|
1268
|
+
/* Reference */
|
1269
|
+
rb_define_singleton_method(cNArray, "refer", na_s_refer,1);
|
1270
|
+
rb_define_singleton_method(cNArray, "ref", na_s_refer,1);
|
1271
|
+
rb_define_method(cNArray, "refer", na_refer,0);
|
1272
|
+
rb_define_method(cNArray, "original", na_original,0);
|
1273
|
+
|
1274
|
+
Init_nmath();
|
1275
|
+
Init_na_funcs();
|
1276
|
+
Init_na_random();
|
1277
|
+
|
1278
|
+
cNArrayScalar = rb_define_class("NArrayScalar", cNArray);
|
1279
|
+
|
1280
|
+
na_id_beg = rb_intern("begin");
|
1281
|
+
na_id_end = rb_intern("end");
|
1282
|
+
na_id_exclude_end = rb_intern("exclude_end?");
|
1283
|
+
na_id_real = rb_intern("real");
|
1284
|
+
na_id_imag = rb_intern("image");
|
1285
|
+
na_id_new = rb_intern("new");
|
1286
|
+
na_id_to_i = rb_intern("to_i");
|
1287
|
+
na_id_usec = rb_intern("usec");
|
1288
|
+
na_id_now = rb_intern("now");
|
1289
|
+
na_id_compare = rb_intern("<=>");
|
1290
|
+
na_id_and = rb_intern("&&");
|
1291
|
+
na_id_or = rb_intern("||");
|
1292
|
+
na_id_minus = rb_intern("-@");
|
1293
|
+
na_id_abs = rb_intern("abs");
|
1294
|
+
na_id_power = rb_intern("**");
|
1295
|
+
na_id_add = rb_intern("+");
|
1296
|
+
na_id_sbt = rb_intern("-");
|
1297
|
+
na_id_mul = rb_intern("*");
|
1298
|
+
na_id_div = rb_intern("/");
|
1299
|
+
na_id_mod = rb_intern("%");
|
1300
|
+
na_id_coerce_rev = rb_intern("coerce_rev");
|
1301
|
+
|
1302
|
+
na_id_class_dim = rb_intern("CLASS_DIMENSION");
|
1303
|
+
|
1304
|
+
Init_na_linalg();
|
1305
|
+
|
1306
|
+
/* NArray extention script */
|
1307
|
+
rb_require("narray_ext.rb");
|
1308
|
+
}
|