numru-narray 1.0.0

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