numo-narray 0.9.0.1-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/README.md +47 -0
- data/Rakefile +41 -0
- data/ext/numo/narray/SFMT-params.h +97 -0
- data/ext/numo/narray/SFMT-params19937.h +46 -0
- data/ext/numo/narray/SFMT.c +620 -0
- data/ext/numo/narray/SFMT.h +157 -0
- data/ext/numo/narray/array.c +525 -0
- data/ext/numo/narray/data.c +901 -0
- data/ext/numo/narray/depend.erb +33 -0
- data/ext/numo/narray/extconf.rb +117 -0
- data/ext/numo/narray/gen/bit.erb.c +811 -0
- data/ext/numo/narray/gen/cogen.rb +18 -0
- data/ext/numo/narray/gen/def/dcomplex.rb +32 -0
- data/ext/numo/narray/gen/def/dfloat.rb +30 -0
- data/ext/numo/narray/gen/def/int16.rb +29 -0
- data/ext/numo/narray/gen/def/int32.rb +29 -0
- data/ext/numo/narray/gen/def/int64.rb +29 -0
- data/ext/numo/narray/gen/def/int8.rb +29 -0
- data/ext/numo/narray/gen/def/robject.rb +30 -0
- data/ext/numo/narray/gen/def/scomplex.rb +32 -0
- data/ext/numo/narray/gen/def/sfloat.rb +30 -0
- data/ext/numo/narray/gen/def/uint16.rb +29 -0
- data/ext/numo/narray/gen/def/uint32.rb +29 -0
- data/ext/numo/narray/gen/def/uint64.rb +29 -0
- data/ext/numo/narray/gen/def/uint8.rb +29 -0
- data/ext/numo/narray/gen/dtype.erb.c +328 -0
- data/ext/numo/narray/gen/tmpl/accum.c +36 -0
- data/ext/numo/narray/gen/tmpl/accum_binary.c +75 -0
- data/ext/numo/narray/gen/tmpl/accum_index.c +58 -0
- data/ext/numo/narray/gen/tmpl/allocate.c +35 -0
- data/ext/numo/narray/gen/tmpl/aref.c +51 -0
- data/ext/numo/narray/gen/tmpl/aset.c +61 -0
- data/ext/numo/narray/gen/tmpl/binary.c +53 -0
- data/ext/numo/narray/gen/tmpl/binary2.c +55 -0
- data/ext/numo/narray/gen/tmpl/binary_s.c +34 -0
- data/ext/numo/narray/gen/tmpl/bit_binary.c +94 -0
- data/ext/numo/narray/gen/tmpl/bit_count.c +82 -0
- data/ext/numo/narray/gen/tmpl/bit_unary.c +77 -0
- data/ext/numo/narray/gen/tmpl/cast.c +37 -0
- data/ext/numo/narray/gen/tmpl/cast_array.c +79 -0
- data/ext/numo/narray/gen/tmpl/cast_numeric.c +22 -0
- data/ext/numo/narray/gen/tmpl/coerce_cast.c +8 -0
- data/ext/numo/narray/gen/tmpl/cond_binary.c +51 -0
- data/ext/numo/narray/gen/tmpl/cond_unary.c +45 -0
- data/ext/numo/narray/gen/tmpl/cum.c +42 -0
- data/ext/numo/narray/gen/tmpl/each.c +43 -0
- data/ext/numo/narray/gen/tmpl/each_with_index.c +64 -0
- data/ext/numo/narray/gen/tmpl/extract.c +23 -0
- data/ext/numo/narray/gen/tmpl/eye.c +91 -0
- data/ext/numo/narray/gen/tmpl/fill.c +38 -0
- data/ext/numo/narray/gen/tmpl/format.c +60 -0
- data/ext/numo/narray/gen/tmpl/format_to_a.c +47 -0
- data/ext/numo/narray/gen/tmpl/head.c +25 -0
- data/ext/numo/narray/gen/tmpl/inspect.c +16 -0
- data/ext/numo/narray/gen/tmpl/map_with_index.c +94 -0
- data/ext/numo/narray/gen/tmpl/median.c +44 -0
- data/ext/numo/narray/gen/tmpl/minmax.c +47 -0
- data/ext/numo/narray/gen/tmpl/poly.c +49 -0
- data/ext/numo/narray/gen/tmpl/pow.c +74 -0
- data/ext/numo/narray/gen/tmpl/powint.c +17 -0
- data/ext/numo/narray/gen/tmpl/qsort.c +149 -0
- data/ext/numo/narray/gen/tmpl/rand.c +33 -0
- data/ext/numo/narray/gen/tmpl/rand_norm.c +46 -0
- data/ext/numo/narray/gen/tmpl/robj_allocate.c +32 -0
- data/ext/numo/narray/gen/tmpl/seq.c +61 -0
- data/ext/numo/narray/gen/tmpl/set2.c +56 -0
- data/ext/numo/narray/gen/tmpl/sort.c +36 -0
- data/ext/numo/narray/gen/tmpl/sort_index.c +86 -0
- data/ext/numo/narray/gen/tmpl/store.c +31 -0
- data/ext/numo/narray/gen/tmpl/store_array.c +5 -0
- data/ext/numo/narray/gen/tmpl/store_from.c +53 -0
- data/ext/numo/narray/gen/tmpl/store_numeric.c +22 -0
- data/ext/numo/narray/gen/tmpl/to_a.c +41 -0
- data/ext/numo/narray/gen/tmpl/unary.c +58 -0
- data/ext/numo/narray/gen/tmpl/unary2.c +58 -0
- data/ext/numo/narray/gen/tmpl/unary_s.c +57 -0
- data/ext/numo/narray/index.c +822 -0
- data/ext/numo/narray/kwarg.c +79 -0
- data/ext/numo/narray/math.c +140 -0
- data/ext/numo/narray/narray.c +1539 -0
- data/ext/numo/narray/ndloop.c +1928 -0
- data/ext/numo/narray/numo/compat.h +23 -0
- data/ext/numo/narray/numo/intern.h +112 -0
- data/ext/numo/narray/numo/narray.h +411 -0
- data/ext/numo/narray/numo/ndloop.h +99 -0
- data/ext/numo/narray/numo/template.h +140 -0
- data/ext/numo/narray/numo/types/bit.h +19 -0
- data/ext/numo/narray/numo/types/complex.h +410 -0
- data/ext/numo/narray/numo/types/complex_macro.h +205 -0
- data/ext/numo/narray/numo/types/dcomplex.h +11 -0
- data/ext/numo/narray/numo/types/dfloat.h +12 -0
- data/ext/numo/narray/numo/types/float_def.h +34 -0
- data/ext/numo/narray/numo/types/float_macro.h +277 -0
- data/ext/numo/narray/numo/types/int16.h +12 -0
- data/ext/numo/narray/numo/types/int32.h +12 -0
- data/ext/numo/narray/numo/types/int64.h +12 -0
- data/ext/numo/narray/numo/types/int8.h +12 -0
- data/ext/numo/narray/numo/types/int_macro.h +34 -0
- data/ext/numo/narray/numo/types/robj_macro.h +218 -0
- data/ext/numo/narray/numo/types/robject.h +21 -0
- data/ext/numo/narray/numo/types/scomplex.h +11 -0
- data/ext/numo/narray/numo/types/sfloat.h +13 -0
- data/ext/numo/narray/numo/types/uint16.h +12 -0
- data/ext/numo/narray/numo/types/uint32.h +12 -0
- data/ext/numo/narray/numo/types/uint64.h +12 -0
- data/ext/numo/narray/numo/types/uint8.h +12 -0
- data/ext/numo/narray/numo/types/uint_macro.h +31 -0
- data/ext/numo/narray/numo/types/xint_macro.h +133 -0
- data/ext/numo/narray/rand.c +87 -0
- data/ext/numo/narray/step.c +506 -0
- data/ext/numo/narray/struct.c +872 -0
- data/lib/2.1/numo/narray.so +0 -0
- data/lib/2.2/numo/narray.so +0 -0
- data/lib/2.3/numo/narray.so +0 -0
- data/lib/erbpp.rb +286 -0
- data/lib/erbpp/line_number.rb +126 -0
- data/lib/erbpp/narray_def.rb +338 -0
- data/lib/numo/narray.rb +6 -0
- data/numo-narray.gemspec +35 -0
- data/spec/bit_spec.rb +93 -0
- data/spec/narray_spec.rb +249 -0
- metadata +238 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
/*
|
2
|
+
kwarg.c : Process keyword arguments for Ruby
|
3
|
+
|
4
|
+
Copyright (c) 2001 Masahiro TANAKA <masa@ir.isas.ac.jp>
|
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 "numo/compat.h"
|
13
|
+
|
14
|
+
/* void rb_scan_kw_args __((VALUE, ...)); */
|
15
|
+
|
16
|
+
static VALUE
|
17
|
+
kw_hash_i(i, tmp)
|
18
|
+
VALUE i, tmp;
|
19
|
+
{
|
20
|
+
VALUE key;
|
21
|
+
|
22
|
+
key = RARRAY_AREF(i,0);
|
23
|
+
if (TYPE(key)==T_SYMBOL) {
|
24
|
+
key = rb_funcall(key, rb_intern("id2name"), 0);
|
25
|
+
} else
|
26
|
+
if (TYPE(key)!=T_STRING) {
|
27
|
+
rb_raise(rb_eArgError, "keywords must be String or Symbol");
|
28
|
+
}
|
29
|
+
|
30
|
+
rb_hash_aset(tmp, key, RARRAY_AREF(i,1));
|
31
|
+
return Qnil;
|
32
|
+
}
|
33
|
+
|
34
|
+
#ifdef HAVE_STDARG_PROTOTYPES
|
35
|
+
#include <stdarg.h>
|
36
|
+
#define va_init_list(a,b) va_start(a,b)
|
37
|
+
#else
|
38
|
+
#include <varargs.h>
|
39
|
+
#define va_init_list(a,b) va_start(a)
|
40
|
+
#endif
|
41
|
+
|
42
|
+
void
|
43
|
+
#ifdef HAVE_STDARG_PROTOTYPES
|
44
|
+
rb_scan_kw_args(VALUE hash, ...)
|
45
|
+
#else
|
46
|
+
rb_scan_kw_args(hash, va_alist)
|
47
|
+
VALUE hash;
|
48
|
+
va_dcl
|
49
|
+
#endif
|
50
|
+
{
|
51
|
+
va_list vargs;
|
52
|
+
va_init_list(vargs, hash);
|
53
|
+
|
54
|
+
char *key;
|
55
|
+
VALUE *var, val, str, tmp;
|
56
|
+
|
57
|
+
tmp = rb_hash_new();
|
58
|
+
if (TYPE(hash) == T_HASH)
|
59
|
+
rb_iterate(rb_each, hash, kw_hash_i, tmp);
|
60
|
+
else if (hash != Qnil)
|
61
|
+
rb_fatal("rb_san_kw_args: non-hash arg passed");
|
62
|
+
|
63
|
+
for (;;) {
|
64
|
+
key = va_arg(vargs, char*);
|
65
|
+
if (!key) break;
|
66
|
+
var = va_arg(vargs, VALUE*);
|
67
|
+
//printf("i=%d key=%x, val=%x\n",i,key,val);
|
68
|
+
str = rb_str_new2(key);
|
69
|
+
val = rb_funcall(tmp, rb_intern("delete"), 1, str);
|
70
|
+
if (var) *var = val;
|
71
|
+
}
|
72
|
+
va_end(vargs);
|
73
|
+
|
74
|
+
if (rb_funcall(tmp, rb_intern("empty?"), 0)==Qfalse) {
|
75
|
+
val = rb_funcall(tmp, rb_intern("keys"), 0);
|
76
|
+
val = rb_funcall(val, rb_intern("join"), 1, rb_str_new2(","));
|
77
|
+
rb_raise(rb_eArgError, "unknown keywords: %s",StringValueCStr(val));
|
78
|
+
}
|
79
|
+
}
|
@@ -0,0 +1,140 @@
|
|
1
|
+
/*
|
2
|
+
math.c
|
3
|
+
Numerical Array Extension for Ruby
|
4
|
+
(C) Copyright 1999-2011 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 "numo/narray.h"
|
13
|
+
|
14
|
+
VALUE numo_mNMath;
|
15
|
+
EXTERN VALUE numo_mDFloatMath, numo_mDComplexMath;
|
16
|
+
static ID id_send;
|
17
|
+
|
18
|
+
VALUE
|
19
|
+
nary_type_s_upcast(VALUE type1, VALUE type2)
|
20
|
+
{
|
21
|
+
VALUE upcast_hash;
|
22
|
+
VALUE result_type;
|
23
|
+
|
24
|
+
if (type1==type2) return type1;
|
25
|
+
upcast_hash = rb_const_get(type1, rb_intern("UPCAST"));
|
26
|
+
result_type = rb_hash_aref(upcast_hash, type2);
|
27
|
+
if (NIL_P(result_type)) {
|
28
|
+
if (TYPE(type2)==T_CLASS) {
|
29
|
+
if ( RTEST(rb_class_inherited_p(type2,cNArray)) ) {
|
30
|
+
upcast_hash = rb_const_get(type2, rb_intern("UPCAST"));
|
31
|
+
result_type = rb_hash_aref(upcast_hash, type1);
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
return result_type;
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
VALUE nary_math_cast2(VALUE type1, VALUE type2)
|
40
|
+
{
|
41
|
+
if ( RTEST(rb_class_inherited_p( type1, cNArray )) ){
|
42
|
+
return nary_type_s_upcast( type1, type2 );
|
43
|
+
}
|
44
|
+
if ( RTEST(rb_class_inherited_p( type2, cNArray )) ){
|
45
|
+
return nary_type_s_upcast( type2, type1 );
|
46
|
+
}
|
47
|
+
if ( RTEST(rb_class_inherited_p( type1, rb_cNumeric )) &&
|
48
|
+
RTEST(rb_class_inherited_p( type2, rb_cNumeric )) ){
|
49
|
+
if ( RTEST(rb_class_inherited_p( type1, rb_cComplex)) ||
|
50
|
+
RTEST(rb_class_inherited_p( type2, rb_cComplex )) ){
|
51
|
+
return rb_cComplex;
|
52
|
+
}
|
53
|
+
return rb_cFloat;
|
54
|
+
}
|
55
|
+
return type2;
|
56
|
+
}
|
57
|
+
|
58
|
+
|
59
|
+
VALUE na_ary_composition_dtype(VALUE);
|
60
|
+
|
61
|
+
VALUE nary_mathcast(int argc, VALUE *argv)
|
62
|
+
{
|
63
|
+
VALUE type, type2;
|
64
|
+
int i;
|
65
|
+
type = na_ary_composition_dtype(argv[0]);
|
66
|
+
for (i=1; i<argc; i++) {
|
67
|
+
type2 = na_ary_composition_dtype(argv[i]);
|
68
|
+
type = nary_math_cast2(type, type2);
|
69
|
+
if (NIL_P(type)) {
|
70
|
+
rb_raise(rb_eTypeError,"%s is unknown for Numo::NMath",
|
71
|
+
rb_class2name(argv[i]));
|
72
|
+
}
|
73
|
+
}
|
74
|
+
return type;
|
75
|
+
}
|
76
|
+
|
77
|
+
|
78
|
+
/*
|
79
|
+
Dispatches method to Math module of upcasted type,
|
80
|
+
eg, Numo::DFloat::Math.
|
81
|
+
@overload method_missing(name,x,...)
|
82
|
+
@param [Symbol] name method name.
|
83
|
+
@param [NArray,Numeric] x input array.
|
84
|
+
@return [NArray] result.
|
85
|
+
*/
|
86
|
+
VALUE nary_math_method_missing(int argc, VALUE *argv, VALUE mod)
|
87
|
+
{
|
88
|
+
VALUE type, ans, typemod, hash;
|
89
|
+
if (argc>1) {
|
90
|
+
type = nary_mathcast(argc-1,argv+1);
|
91
|
+
|
92
|
+
hash = rb_const_get(mod, rb_intern("DISPATCH"));
|
93
|
+
typemod = rb_hash_aref( hash, type );
|
94
|
+
if (NIL_P(typemod)) {
|
95
|
+
rb_raise(rb_eTypeError,"%s is unknown for Numo::NMath",
|
96
|
+
rb_class2name(type));
|
97
|
+
}
|
98
|
+
|
99
|
+
ans = rb_funcall2(typemod,id_send,argc,argv);
|
100
|
+
|
101
|
+
if (!RTEST(rb_class_inherited_p(type,cNArray)) &&
|
102
|
+
IsNArray(ans) ) {
|
103
|
+
ans = rb_funcall(ans,rb_intern("extract"),0);
|
104
|
+
}
|
105
|
+
return ans;
|
106
|
+
}
|
107
|
+
rb_raise(rb_eArgError,"argument or method missing");
|
108
|
+
return Qnil;
|
109
|
+
}
|
110
|
+
|
111
|
+
|
112
|
+
void
|
113
|
+
Init_nary_math()
|
114
|
+
{
|
115
|
+
VALUE hCast;
|
116
|
+
|
117
|
+
numo_mNMath = rb_define_module_under(mNumo, "NMath");
|
118
|
+
rb_define_singleton_method(numo_mNMath, "method_missing", nary_math_method_missing, -1);
|
119
|
+
|
120
|
+
hCast = rb_hash_new();
|
121
|
+
rb_define_const(numo_mNMath, "DISPATCH", hCast);
|
122
|
+
rb_hash_aset(hCast, numo_cInt64, numo_mDFloatMath);
|
123
|
+
rb_hash_aset(hCast, numo_cInt32, numo_mDFloatMath);
|
124
|
+
rb_hash_aset(hCast, numo_cInt16, numo_mDFloatMath);
|
125
|
+
rb_hash_aset(hCast, numo_cInt8, numo_mDFloatMath);
|
126
|
+
rb_hash_aset(hCast, numo_cUInt64, numo_mDFloatMath);
|
127
|
+
rb_hash_aset(hCast, numo_cUInt32, numo_mDFloatMath);
|
128
|
+
rb_hash_aset(hCast, numo_cUInt16, numo_mDFloatMath);
|
129
|
+
rb_hash_aset(hCast, numo_cUInt8, numo_mDFloatMath);
|
130
|
+
rb_hash_aset(hCast, numo_cDFloat, numo_mDFloatMath);
|
131
|
+
rb_hash_aset(hCast, numo_cDFloat, numo_mDFloatMath);
|
132
|
+
rb_hash_aset(hCast, numo_cDComplex, numo_mDComplexMath);
|
133
|
+
rb_hash_aset(hCast, rb_cFixnum, rb_mMath);
|
134
|
+
rb_hash_aset(hCast, rb_cBignum, rb_mMath);
|
135
|
+
rb_hash_aset(hCast, rb_cInteger, rb_mMath);
|
136
|
+
rb_hash_aset(hCast, rb_cFloat, rb_mMath);
|
137
|
+
rb_hash_aset(hCast, rb_cComplex, numo_mDComplexMath);
|
138
|
+
|
139
|
+
id_send = rb_intern("send");
|
140
|
+
}
|
@@ -0,0 +1,1539 @@
|
|
1
|
+
/*
|
2
|
+
narray.c
|
3
|
+
Numerical Array Extension for Ruby
|
4
|
+
(C) Copyright 1999-2016 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 "numo/narray.h"
|
14
|
+
#include "extconf.h"
|
15
|
+
#include <assert.h>
|
16
|
+
|
17
|
+
/* global variables within this module */
|
18
|
+
VALUE numo_cNArray;
|
19
|
+
VALUE rb_mNumo;
|
20
|
+
VALUE nary_eCastError;
|
21
|
+
VALUE nary_eShapeError;
|
22
|
+
VALUE nary_eOperationError;
|
23
|
+
VALUE nary_eDimensionError;
|
24
|
+
|
25
|
+
static ID id_contiguous_stride;
|
26
|
+
//static ID id_element_bit_size;
|
27
|
+
//static ID id_element_byte_size;
|
28
|
+
|
29
|
+
VALUE cPointer;
|
30
|
+
|
31
|
+
static ID id_allocate;
|
32
|
+
|
33
|
+
VALUE sym_reduce;
|
34
|
+
VALUE sym_option;
|
35
|
+
VALUE sym_loop_opt;
|
36
|
+
VALUE sym_init;
|
37
|
+
|
38
|
+
VALUE na_cStep;
|
39
|
+
#ifndef HAVE_RB_CCOMPLEX
|
40
|
+
VALUE rb_cComplex;
|
41
|
+
#endif
|
42
|
+
|
43
|
+
void Init_nary_data();
|
44
|
+
void Init_nary_step();
|
45
|
+
void Init_nary_index();
|
46
|
+
void Init_nary_bit();
|
47
|
+
void Init_nary_int8();
|
48
|
+
void Init_nary_int16();
|
49
|
+
void Init_nary_int32();
|
50
|
+
void Init_nary_int64();
|
51
|
+
void Init_nary_uint8();
|
52
|
+
void Init_nary_uint16();
|
53
|
+
void Init_nary_uint32();
|
54
|
+
void Init_nary_uint64();
|
55
|
+
void Init_nary_sfloat();
|
56
|
+
void Init_nary_scomplex();
|
57
|
+
void Init_nary_dfloat();
|
58
|
+
void Init_nary_dcomplex();
|
59
|
+
void Init_nary_math();
|
60
|
+
void Init_nary_rand();
|
61
|
+
void Init_nary_array();
|
62
|
+
void Init_nary_struct();
|
63
|
+
void Init_nary_robject();
|
64
|
+
|
65
|
+
|
66
|
+
static void
|
67
|
+
rb_narray_debug_info_nadata(VALUE self)
|
68
|
+
{
|
69
|
+
narray_data_t *na;
|
70
|
+
GetNArrayData(self,na);
|
71
|
+
|
72
|
+
printf(" ptr = 0x%"SZF"x\n", (size_t)(na->ptr));
|
73
|
+
}
|
74
|
+
|
75
|
+
|
76
|
+
static VALUE
|
77
|
+
rb_narray_debug_info_naview(VALUE self)
|
78
|
+
{
|
79
|
+
int i;
|
80
|
+
narray_view_t *na;
|
81
|
+
size_t *idx;
|
82
|
+
size_t j;
|
83
|
+
GetNArrayView(self,na);
|
84
|
+
|
85
|
+
printf(" data = 0x%"SZF"x\n", (size_t)na->data);
|
86
|
+
printf(" offset = %"SZF"d\n", (size_t)na->offset);
|
87
|
+
printf(" stridx = 0x%"SZF"x\n", (size_t)na->stridx);
|
88
|
+
|
89
|
+
if (na->stridx) {
|
90
|
+
printf(" stridx = [");
|
91
|
+
for (i=0; i<na->base.ndim; i++) {
|
92
|
+
if (SDX_IS_INDEX(na->stridx[i])) {
|
93
|
+
|
94
|
+
idx = SDX_GET_INDEX(na->stridx[i]);
|
95
|
+
printf(" index[%d]=[", i);
|
96
|
+
for (j=0; j<na->base.shape[i]; j++) {
|
97
|
+
printf(" %"SZF"d", idx[j]);
|
98
|
+
}
|
99
|
+
printf(" ] ");
|
100
|
+
|
101
|
+
} else {
|
102
|
+
printf(" %"SZF"d", SDX_GET_STRIDE(na->stridx[i]));
|
103
|
+
}
|
104
|
+
}
|
105
|
+
printf(" ]\n");
|
106
|
+
}
|
107
|
+
return Qnil;
|
108
|
+
}
|
109
|
+
|
110
|
+
|
111
|
+
VALUE
|
112
|
+
rb_narray_debug_info(VALUE self)
|
113
|
+
{
|
114
|
+
int i;
|
115
|
+
narray_t *na;
|
116
|
+
GetNArray(self,na);
|
117
|
+
|
118
|
+
printf("%s:\n",rb_class2name(CLASS_OF(self)));
|
119
|
+
printf(" id = 0x%"SZF"x\n", self);
|
120
|
+
printf(" type = %d\n", na->type);
|
121
|
+
printf(" flag = [%d,%d]\n", na->flag[0], na->flag[1]);
|
122
|
+
printf(" size = %"SZF"d\n", na->size);
|
123
|
+
printf(" ndim = %d\n", na->ndim);
|
124
|
+
printf(" shape = 0x%"SZF"x\n", (size_t)na->shape);
|
125
|
+
if (na->shape) {
|
126
|
+
printf(" shape = [");
|
127
|
+
for (i=0;i<na->ndim;i++)
|
128
|
+
printf(" %"SZF"d", na->shape[i]);
|
129
|
+
printf(" ]\n");
|
130
|
+
}
|
131
|
+
|
132
|
+
switch(na->type) {
|
133
|
+
case NARRAY_DATA_T:
|
134
|
+
case NARRAY_FILEMAP_T:
|
135
|
+
rb_narray_debug_info_nadata(self);
|
136
|
+
break;
|
137
|
+
case NARRAY_VIEW_T:
|
138
|
+
rb_narray_debug_info_naview(self);
|
139
|
+
break;
|
140
|
+
}
|
141
|
+
return Qnil;
|
142
|
+
}
|
143
|
+
|
144
|
+
|
145
|
+
void
|
146
|
+
na_free(narray_data_t* na)
|
147
|
+
{
|
148
|
+
assert(na->base.type==NARRAY_DATA_T);
|
149
|
+
|
150
|
+
if (na->ptr != NULL) {
|
151
|
+
xfree(na->ptr);
|
152
|
+
na->ptr = NULL;
|
153
|
+
}
|
154
|
+
if (na->base.size > 0) {
|
155
|
+
if (na->base.shape != NULL && na->base.shape != &(na->base.size)) {
|
156
|
+
xfree(na->base.shape);
|
157
|
+
na->base.shape = NULL;
|
158
|
+
}
|
159
|
+
}
|
160
|
+
xfree(na);
|
161
|
+
}
|
162
|
+
|
163
|
+
static void
|
164
|
+
na_free_view(narray_view_t* na)
|
165
|
+
{
|
166
|
+
assert(na->base.type==NARRAY_VIEW_T);
|
167
|
+
|
168
|
+
if (na->stridx != NULL) {
|
169
|
+
xfree(na->stridx);
|
170
|
+
na->stridx = NULL;
|
171
|
+
}
|
172
|
+
if (na->base.size > 0) {
|
173
|
+
if (na->base.shape != NULL && na->base.shape != &(na->base.size)) {
|
174
|
+
xfree(na->base.shape);
|
175
|
+
na->base.shape = NULL;
|
176
|
+
}
|
177
|
+
}
|
178
|
+
xfree(na);
|
179
|
+
}
|
180
|
+
|
181
|
+
static void
|
182
|
+
na_gc_mark_view(narray_view_t* na)
|
183
|
+
{
|
184
|
+
rb_gc_mark(na->data);
|
185
|
+
}
|
186
|
+
|
187
|
+
VALUE
|
188
|
+
na_s_allocate(VALUE klass)
|
189
|
+
{
|
190
|
+
narray_data_t *na = ALLOC(narray_data_t);
|
191
|
+
|
192
|
+
na->base.ndim = 0;
|
193
|
+
na->base.type = NARRAY_DATA_T;
|
194
|
+
na->base.flag[0] = 0;
|
195
|
+
na->base.flag[1] = 0;
|
196
|
+
na->base.size = 0;
|
197
|
+
na->base.shape = NULL;
|
198
|
+
na->base.reduce = INT2FIX(0);
|
199
|
+
na->ptr = NULL;
|
200
|
+
return Data_Wrap_Struct(klass, 0, na_free, na);
|
201
|
+
}
|
202
|
+
|
203
|
+
|
204
|
+
VALUE
|
205
|
+
na_s_allocate_view(VALUE klass)
|
206
|
+
{
|
207
|
+
narray_view_t *na = ALLOC(narray_view_t);
|
208
|
+
|
209
|
+
na->base.ndim = 0;
|
210
|
+
na->base.type = NARRAY_VIEW_T;
|
211
|
+
na->base.flag[0] = 0;
|
212
|
+
na->base.flag[1] = 0;
|
213
|
+
na->base.size = 0;
|
214
|
+
na->base.shape = NULL;
|
215
|
+
na->base.reduce = INT2FIX(0);
|
216
|
+
na->data = Qnil;
|
217
|
+
na->offset = 0;
|
218
|
+
na->stridx = NULL;
|
219
|
+
return Data_Wrap_Struct(klass, na_gc_mark_view, na_free_view, na);
|
220
|
+
}
|
221
|
+
|
222
|
+
|
223
|
+
//static const size_t zero=0;
|
224
|
+
|
225
|
+
void
|
226
|
+
na_array_to_internal_shape(VALUE self, VALUE ary, size_t *shape)
|
227
|
+
{
|
228
|
+
size_t i, n, c, s;
|
229
|
+
VALUE v;
|
230
|
+
narray_t *na;
|
231
|
+
int flag = 0;
|
232
|
+
|
233
|
+
n = RARRAY_LEN(ary);
|
234
|
+
|
235
|
+
if (RTEST(self)) {
|
236
|
+
GetNArray(self, na);
|
237
|
+
flag = TEST_COLUMN_MAJOR(na);
|
238
|
+
}
|
239
|
+
if (flag) {
|
240
|
+
c = n-1;
|
241
|
+
s = -1;
|
242
|
+
} else {
|
243
|
+
c = 0;
|
244
|
+
s = 1;
|
245
|
+
}
|
246
|
+
for (i=0; i<n; i++) {
|
247
|
+
v = RARRAY_AREF(ary,i);
|
248
|
+
if (!FIXNUM_P(v) && !rb_obj_is_kind_of(v, rb_cInteger)) {
|
249
|
+
rb_raise(rb_eTypeError, "array size must be Integer");
|
250
|
+
}
|
251
|
+
if (RTEST(rb_funcall(v, rb_intern("<"), 1, INT2FIX(0)))) {
|
252
|
+
rb_raise(rb_eArgError,"size must be non-negative");
|
253
|
+
}
|
254
|
+
shape[c] = NUM2SIZE(v);
|
255
|
+
c += s;
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
|
260
|
+
|
261
|
+
void
|
262
|
+
na_alloc_shape(narray_t *na, int ndim)
|
263
|
+
{
|
264
|
+
na->ndim = ndim;
|
265
|
+
na->size = 0;
|
266
|
+
if (ndim == 0) {
|
267
|
+
na->shape = NULL;
|
268
|
+
}
|
269
|
+
else if (ndim == 1) {
|
270
|
+
na->shape = &(na->size);
|
271
|
+
}
|
272
|
+
else if (ndim < 0) {
|
273
|
+
rb_raise(nary_eDimensionError,"ndim=%d is negative", ndim);
|
274
|
+
}
|
275
|
+
else if (ndim > NA_MAX_DIMENSION) {
|
276
|
+
rb_raise(nary_eDimensionError,"ndim=%d is too many", ndim);
|
277
|
+
} else {
|
278
|
+
na->shape = ALLOC_N(size_t, ndim);
|
279
|
+
}
|
280
|
+
}
|
281
|
+
|
282
|
+
void
|
283
|
+
na_setup_shape(narray_t *na, int ndim, size_t *shape)
|
284
|
+
{
|
285
|
+
int i;
|
286
|
+
size_t size;
|
287
|
+
|
288
|
+
na_alloc_shape(na, ndim);
|
289
|
+
|
290
|
+
if (ndim==0) {
|
291
|
+
na->size = 1;
|
292
|
+
}
|
293
|
+
else if (ndim==1) {
|
294
|
+
na->size = shape[0];
|
295
|
+
}
|
296
|
+
else {
|
297
|
+
for (i=0, size=1; i<ndim; i++) {
|
298
|
+
na->shape[i] = shape[i];
|
299
|
+
size *= shape[i];
|
300
|
+
}
|
301
|
+
na->size = size;
|
302
|
+
}
|
303
|
+
}
|
304
|
+
|
305
|
+
void
|
306
|
+
na_setup(VALUE self, int ndim, size_t *shape)
|
307
|
+
{
|
308
|
+
narray_t *na;
|
309
|
+
GetNArray(self,na);
|
310
|
+
na_setup_shape(na, ndim, shape);
|
311
|
+
}
|
312
|
+
|
313
|
+
|
314
|
+
/*
|
315
|
+
* call-seq:
|
316
|
+
* Numo::DataType.new(shape) => narray
|
317
|
+
* Numo::DataType.new(size1, size2, ...) => narray
|
318
|
+
*
|
319
|
+
* Constructs a narray using the given <i>DataType</i> and <i>shape</i> or
|
320
|
+
* <i>sizes</i>.
|
321
|
+
*/
|
322
|
+
static VALUE
|
323
|
+
na_initialize(VALUE self, VALUE args)
|
324
|
+
{
|
325
|
+
VALUE v;
|
326
|
+
size_t *shape=NULL;
|
327
|
+
int ndim;
|
328
|
+
|
329
|
+
if (RARRAY_LEN(args) == 1) {
|
330
|
+
v = RARRAY_AREF(args,0);
|
331
|
+
if (TYPE(v) != T_ARRAY) {
|
332
|
+
v = args;
|
333
|
+
}
|
334
|
+
} else {
|
335
|
+
v = args;
|
336
|
+
}
|
337
|
+
ndim = RARRAY_LEN(v);
|
338
|
+
if (ndim > NA_MAX_DIMENSION) {
|
339
|
+
rb_raise(rb_eArgError,"ndim=%d exceeds maximum dimension",ndim);
|
340
|
+
}
|
341
|
+
shape = ALLOCA_N(size_t, ndim);
|
342
|
+
// setup size_t shape[] from VALUE shape argument
|
343
|
+
na_array_to_internal_shape(self, v, shape);
|
344
|
+
na_setup(self, ndim, shape);
|
345
|
+
|
346
|
+
return self;
|
347
|
+
}
|
348
|
+
|
349
|
+
|
350
|
+
VALUE
|
351
|
+
rb_narray_new(VALUE klass, int ndim, size_t *shape)
|
352
|
+
{
|
353
|
+
volatile VALUE obj;
|
354
|
+
|
355
|
+
obj = rb_funcall(klass, id_allocate, 0);
|
356
|
+
na_setup(obj, ndim, shape);
|
357
|
+
return obj;
|
358
|
+
}
|
359
|
+
|
360
|
+
|
361
|
+
VALUE
|
362
|
+
rb_narray_view_new(VALUE klass, int ndim, size_t *shape)
|
363
|
+
{
|
364
|
+
volatile VALUE obj;
|
365
|
+
|
366
|
+
obj = na_s_allocate_view(klass);
|
367
|
+
na_setup(obj, ndim, shape);
|
368
|
+
return obj;
|
369
|
+
}
|
370
|
+
|
371
|
+
|
372
|
+
/*
|
373
|
+
Replaces the contents of self with the contents of other narray.
|
374
|
+
Used in dup and clone method.
|
375
|
+
@overload initialize_copy(other)
|
376
|
+
@param [Numo::NArray] other
|
377
|
+
@return [Numo::NArray] self
|
378
|
+
*/
|
379
|
+
static VALUE
|
380
|
+
na_initialize_copy(VALUE self, VALUE orig)
|
381
|
+
{
|
382
|
+
narray_t *na;
|
383
|
+
GetNArray(orig,na);
|
384
|
+
|
385
|
+
na_setup(self,NA_NDIM(na),NA_SHAPE(na));
|
386
|
+
na_store(self,orig);
|
387
|
+
na_copy_flags(orig,self);
|
388
|
+
return self;
|
389
|
+
}
|
390
|
+
|
391
|
+
|
392
|
+
/*
|
393
|
+
* call-seq:
|
394
|
+
* zeros(shape) => narray
|
395
|
+
* zeros(size1,size2,...) => narray
|
396
|
+
*
|
397
|
+
* Returns a zero-filled narray with <i>shape</i>.
|
398
|
+
* This singleton method is valid not for NArray class itself
|
399
|
+
* but for typed NArray subclasses, e.g., DFloat, Int64.
|
400
|
+
* @example
|
401
|
+
* a = Numo::DFloat.zeros(3,5)
|
402
|
+
* => Numo::DFloat#shape=[3,5]
|
403
|
+
* [[0, 0, 0, 0, 0],
|
404
|
+
* [0, 0, 0, 0, 0],
|
405
|
+
* [0, 0, 0, 0, 0]]
|
406
|
+
*/
|
407
|
+
static VALUE
|
408
|
+
na_s_zeros(int argc, const VALUE *argv, VALUE klass)
|
409
|
+
{
|
410
|
+
VALUE obj;
|
411
|
+
obj = rb_class_new_instance(argc, argv, klass);
|
412
|
+
return rb_funcall(obj, rb_intern("fill"), 1, INT2FIX(0));
|
413
|
+
}
|
414
|
+
|
415
|
+
|
416
|
+
/*
|
417
|
+
* call-seq:
|
418
|
+
* ones(shape) => narray
|
419
|
+
* ones(size1,size2,...) => narray
|
420
|
+
*
|
421
|
+
* Returns a one-filled narray with <i>shape</i>.
|
422
|
+
* This singleton method is valid not for NArray class itself
|
423
|
+
* but for typed NArray subclasses, e.g., DFloat, Int64.
|
424
|
+
* @example
|
425
|
+
* a = Numo::DFloat.ones(3,5)
|
426
|
+
* => Numo::DFloat#shape=[3,5]
|
427
|
+
* [[1, 1, 1, 1, 1],
|
428
|
+
* [1, 1, 1, 1, 1],
|
429
|
+
* [1, 1, 1, 1, 1]]
|
430
|
+
*/
|
431
|
+
static VALUE
|
432
|
+
na_s_ones(int argc, const VALUE *argv, VALUE klass)
|
433
|
+
{
|
434
|
+
VALUE obj;
|
435
|
+
obj = rb_class_new_instance(argc, argv, klass);
|
436
|
+
return rb_funcall(obj, rb_intern("fill"), 1, INT2FIX(1));
|
437
|
+
}
|
438
|
+
|
439
|
+
|
440
|
+
/*
|
441
|
+
Returns a NArray with shape=(n,n) whose diagonal elements are 1, otherwise 0.
|
442
|
+
@overload eye(n)
|
443
|
+
@param [Integer] n Size of NArray. Creates 2-D NArray with shape=(n,n)
|
444
|
+
@return [Numo::NArray] created NArray.
|
445
|
+
@example
|
446
|
+
a = Numo::DFloat.eye(3)
|
447
|
+
=> Numo::DFloat#shape=[3,3]
|
448
|
+
[[1, 0, 0],
|
449
|
+
[0, 1, 0],
|
450
|
+
[0, 0, 1]]
|
451
|
+
*/
|
452
|
+
static VALUE
|
453
|
+
na_s_eye(int argc, const VALUE *argv, VALUE klass)
|
454
|
+
{
|
455
|
+
VALUE obj;
|
456
|
+
VALUE tmp[2];
|
457
|
+
|
458
|
+
if (argc==0) {
|
459
|
+
rb_raise(rb_eArgError,"No argument");
|
460
|
+
}
|
461
|
+
else if (argc==1) {
|
462
|
+
tmp[0] = tmp[1] = argv[0];
|
463
|
+
argv = tmp;
|
464
|
+
argc = 2;
|
465
|
+
}
|
466
|
+
obj = rb_class_new_instance(argc, argv, klass);
|
467
|
+
return rb_funcall(obj, rb_intern("eye"), 0);
|
468
|
+
}
|
469
|
+
|
470
|
+
|
471
|
+
char *
|
472
|
+
na_get_pointer(VALUE self)
|
473
|
+
{
|
474
|
+
narray_t *na;
|
475
|
+
GetNArray(self,na);
|
476
|
+
|
477
|
+
switch(NA_TYPE(na)) {
|
478
|
+
case NARRAY_DATA_T:
|
479
|
+
return NA_DATA_PTR(na);
|
480
|
+
case NARRAY_FILEMAP_T:
|
481
|
+
return ((narray_filemap_t*)na)->ptr;
|
482
|
+
case NARRAY_VIEW_T:
|
483
|
+
return na_get_pointer(NA_VIEW_DATA(na));
|
484
|
+
//puts("pass NARRAY_VIEW_T in na_get_pointer_for_write");
|
485
|
+
//ptr += ((narray_view_t*)na)->offset;
|
486
|
+
//ptr += NA_VIEW_OFFSET(na);
|
487
|
+
break;
|
488
|
+
default:
|
489
|
+
rb_raise(rb_eRuntimeError,"invalid NA_TYPE");
|
490
|
+
}
|
491
|
+
return NULL;
|
492
|
+
}
|
493
|
+
|
494
|
+
char *
|
495
|
+
na_get_pointer_for_write(VALUE self)
|
496
|
+
{
|
497
|
+
char *ptr;
|
498
|
+
narray_t *na;
|
499
|
+
GetNArray(self,na);
|
500
|
+
|
501
|
+
if (OBJ_FROZEN(self)) {
|
502
|
+
rb_raise(rb_eRuntimeError, "cannot write to frozen NArray.");
|
503
|
+
}
|
504
|
+
|
505
|
+
if (NA_TYPE(na) == NARRAY_DATA_T) {
|
506
|
+
ptr = NA_DATA_PTR(na);
|
507
|
+
if (na->size > 0 && ptr == NULL) {
|
508
|
+
rb_funcall(self, id_allocate, 0);
|
509
|
+
ptr = NA_DATA_PTR(na);
|
510
|
+
}
|
511
|
+
} else {
|
512
|
+
ptr = na_get_pointer(self);
|
513
|
+
if (NA_SIZE(na) > 0 && ptr == NULL) {
|
514
|
+
rb_raise(rb_eRuntimeError,"cannot write to unallocated NArray");
|
515
|
+
}
|
516
|
+
}
|
517
|
+
|
518
|
+
//NA_SET_LOCK(na);
|
519
|
+
|
520
|
+
return ptr;
|
521
|
+
}
|
522
|
+
|
523
|
+
char *
|
524
|
+
na_get_pointer_for_read(VALUE self)
|
525
|
+
{
|
526
|
+
char *ptr;
|
527
|
+
narray_t *na;
|
528
|
+
GetNArray(self,na);
|
529
|
+
|
530
|
+
//if (NA_TEST_LOCK(na)) {
|
531
|
+
// rb_raise(rb_eRuntimeError, "cannot read locked NArray.");
|
532
|
+
//}
|
533
|
+
|
534
|
+
if (NA_TYPE(na) == NARRAY_DATA_T) {
|
535
|
+
ptr = NA_DATA_PTR(na);
|
536
|
+
} else {
|
537
|
+
ptr = na_get_pointer(self);
|
538
|
+
}
|
539
|
+
|
540
|
+
if (NA_SIZE(na) > 0 && ptr == NULL) {
|
541
|
+
rb_raise(rb_eRuntimeError,"cannot read unallocated NArray");
|
542
|
+
}
|
543
|
+
|
544
|
+
//NA_SET_LOCK(na);
|
545
|
+
|
546
|
+
return ptr;
|
547
|
+
}
|
548
|
+
|
549
|
+
|
550
|
+
void
|
551
|
+
na_release_lock(VALUE self)
|
552
|
+
{
|
553
|
+
narray_t *na;
|
554
|
+
GetNArray(self,na);
|
555
|
+
|
556
|
+
NA_UNSET_LOCK(na);
|
557
|
+
|
558
|
+
switch(NA_TYPE(na)) {
|
559
|
+
case NARRAY_VIEW_T:
|
560
|
+
na_release_lock(NA_VIEW_DATA(na));
|
561
|
+
break;
|
562
|
+
}
|
563
|
+
}
|
564
|
+
|
565
|
+
// fix name, ex, allow_stride_for_flatten_view
|
566
|
+
VALUE
|
567
|
+
na_check_ladder(VALUE self, int start_dim)
|
568
|
+
{
|
569
|
+
int i;
|
570
|
+
ssize_t st0, st1;
|
571
|
+
narray_t *na1;
|
572
|
+
narray_view_t *na;
|
573
|
+
GetNArray(self,na1);
|
574
|
+
|
575
|
+
//puts("pass ladder");
|
576
|
+
|
577
|
+
if (start_dim < -na1->ndim || start_dim >= na1->ndim) {
|
578
|
+
rb_bug("start_dim (%d) out of range",start_dim);
|
579
|
+
}
|
580
|
+
|
581
|
+
switch(na1->type) {
|
582
|
+
case NARRAY_DATA_T:
|
583
|
+
case NARRAY_FILEMAP_T:
|
584
|
+
return Qtrue;
|
585
|
+
case NARRAY_VIEW_T:
|
586
|
+
GetNArrayView(self,na);
|
587
|
+
// negative dim -> position from last dim
|
588
|
+
if (start_dim < 0) {
|
589
|
+
start_dim += na->base.ndim;
|
590
|
+
}
|
591
|
+
// not ladder if it has index
|
592
|
+
for (i=start_dim; i<na->base.ndim; i++) {
|
593
|
+
if (SDX_IS_INDEX(na->stridx[i]))
|
594
|
+
return Qfalse;
|
595
|
+
}
|
596
|
+
// check stride
|
597
|
+
i = start_dim;
|
598
|
+
st0 = SDX_GET_STRIDE(na->stridx[i]);
|
599
|
+
for (i++; i<na->base.ndim; i++) {
|
600
|
+
st1 = SDX_GET_STRIDE(na->stridx[i]);
|
601
|
+
if (st0 != (ssize_t)(st1*na->base.shape[i])) {
|
602
|
+
return Qfalse;
|
603
|
+
}
|
604
|
+
st0 = st1;
|
605
|
+
}
|
606
|
+
return Qtrue;
|
607
|
+
}
|
608
|
+
return Qtrue;
|
609
|
+
}
|
610
|
+
|
611
|
+
|
612
|
+
/*
|
613
|
+
stridx_t *
|
614
|
+
na_get_stride(VALUE v)
|
615
|
+
{
|
616
|
+
int i;
|
617
|
+
size_t st;
|
618
|
+
stridx_t *stridx=NULL;
|
619
|
+
narray_t *na;
|
620
|
+
GetNArray(v,na);
|
621
|
+
|
622
|
+
switch(NA_TYPE(na)) {
|
623
|
+
case NARRAY_DATA_T:
|
624
|
+
if (NA_DATA_PTR(na)==NULL) {
|
625
|
+
rb_raise(rb_eRuntimeError,"cannot read no-data NArray");
|
626
|
+
}
|
627
|
+
break;
|
628
|
+
case NARRAY_FILEMAP_T:
|
629
|
+
break;
|
630
|
+
case NARRAY_VIEW_T:
|
631
|
+
stridx = NA_STRIDX(na);
|
632
|
+
break;
|
633
|
+
default:
|
634
|
+
rb_raise(rb_eRuntimeError,"invalid narray internal type");
|
635
|
+
}
|
636
|
+
|
637
|
+
if (!stridx) {
|
638
|
+
stridx = ALLOC_N(stridx_t, na->ndim);
|
639
|
+
st = NUM2SIZE(rb_const_get(CLASS_OF(v), id_contiguous_stride));
|
640
|
+
//printf("step_unit=%ld, CLASS_OF(v)=%lx\n",st, CLASS_OF(v));
|
641
|
+
for (i=na->ndim; i>0;) {
|
642
|
+
SDX_SET_STRIDE(stridx[--i],st);
|
643
|
+
st *= na->shape[i];
|
644
|
+
}
|
645
|
+
}
|
646
|
+
|
647
|
+
return stridx;
|
648
|
+
}
|
649
|
+
*/
|
650
|
+
|
651
|
+
|
652
|
+
/* method: size() -- returns the total number of typeents */
|
653
|
+
static VALUE
|
654
|
+
na_size(VALUE self)
|
655
|
+
{
|
656
|
+
narray_t *na;
|
657
|
+
GetNArray(self,na);
|
658
|
+
return SIZE2NUM(na->size);
|
659
|
+
}
|
660
|
+
|
661
|
+
|
662
|
+
/* method: size() -- returns the total number of typeents */
|
663
|
+
static VALUE
|
664
|
+
na_ndim(VALUE self)
|
665
|
+
{
|
666
|
+
narray_t *na;
|
667
|
+
GetNArray(self,na);
|
668
|
+
return INT2NUM(na->ndim);
|
669
|
+
}
|
670
|
+
|
671
|
+
|
672
|
+
/* method: shape() -- returns shape, array of the size of dimensions */
|
673
|
+
static VALUE
|
674
|
+
na_shape(VALUE self)
|
675
|
+
{
|
676
|
+
volatile VALUE v;
|
677
|
+
narray_t *na;
|
678
|
+
size_t i, n, c, s;
|
679
|
+
|
680
|
+
GetNArray(self,na);
|
681
|
+
n = NA_NDIM(na);
|
682
|
+
if (TEST_COLUMN_MAJOR(na)) {
|
683
|
+
c = n-1;
|
684
|
+
s = -1;
|
685
|
+
} else {
|
686
|
+
c = 0;
|
687
|
+
s = 1;
|
688
|
+
}
|
689
|
+
v = rb_ary_new2(n);
|
690
|
+
for (i=0; i<n; i++) {
|
691
|
+
rb_ary_push(v, SIZE2NUM(na->shape[c]));
|
692
|
+
c += s;
|
693
|
+
}
|
694
|
+
return v;
|
695
|
+
}
|
696
|
+
|
697
|
+
|
698
|
+
size_t
|
699
|
+
na_get_elmsz(VALUE vna)
|
700
|
+
{
|
701
|
+
return NUM2SIZE(rb_const_get(CLASS_OF(vna), id_contiguous_stride));
|
702
|
+
}
|
703
|
+
|
704
|
+
size_t
|
705
|
+
na_dtype_elmsz(VALUE klass)
|
706
|
+
{
|
707
|
+
return NUM2SIZE(rb_const_get(klass, id_contiguous_stride));
|
708
|
+
}
|
709
|
+
|
710
|
+
size_t
|
711
|
+
na_get_offset(VALUE self)
|
712
|
+
{
|
713
|
+
narray_t *na;
|
714
|
+
GetNArray(self,na);
|
715
|
+
|
716
|
+
switch(na->type) {
|
717
|
+
case NARRAY_DATA_T:
|
718
|
+
case NARRAY_FILEMAP_T:
|
719
|
+
return 0;
|
720
|
+
case NARRAY_VIEW_T:
|
721
|
+
return NA_VIEW_OFFSET(na);
|
722
|
+
}
|
723
|
+
return 0;
|
724
|
+
}
|
725
|
+
|
726
|
+
|
727
|
+
void
|
728
|
+
na_index_arg_to_internal_order(int argc, VALUE *argv, VALUE self)
|
729
|
+
{
|
730
|
+
int i,j;
|
731
|
+
VALUE tmp;
|
732
|
+
|
733
|
+
if (TEST_COLUMN_MAJOR(self)) {
|
734
|
+
for (i=0,j=argc-1; i<argc/2; i++,j--) {
|
735
|
+
tmp = argv[i];
|
736
|
+
argv[i] = argv[j];
|
737
|
+
argv[j] = tmp;
|
738
|
+
}
|
739
|
+
}
|
740
|
+
}
|
741
|
+
|
742
|
+
void
|
743
|
+
na_copy_flags(VALUE src, VALUE dst)
|
744
|
+
{
|
745
|
+
narray_t *na1, *na2;
|
746
|
+
|
747
|
+
GetNArray(src,na1);
|
748
|
+
GetNArray(dst,na2);
|
749
|
+
|
750
|
+
na2->flag[0] = na1->flag[0];
|
751
|
+
na2->flag[1] = na1->flag[1];
|
752
|
+
|
753
|
+
RBASIC(dst)->flags |= (RBASIC(src)->flags) &
|
754
|
+
(FL_USER1|FL_USER2|FL_USER3|FL_USER4|FL_USER5|FL_USER6|FL_USER7);
|
755
|
+
}
|
756
|
+
|
757
|
+
|
758
|
+
VALUE
|
759
|
+
na_original_data(VALUE self)
|
760
|
+
{
|
761
|
+
narray_t *na;
|
762
|
+
narray_view_t *nv;
|
763
|
+
|
764
|
+
GetNArray(self,na);
|
765
|
+
switch(na->type) {
|
766
|
+
case NARRAY_VIEW_T:
|
767
|
+
GetNArrayView(self, nv);
|
768
|
+
return nv->data;
|
769
|
+
}
|
770
|
+
return self;
|
771
|
+
}
|
772
|
+
|
773
|
+
|
774
|
+
//----------------------------------------------------------------------
|
775
|
+
|
776
|
+
/*
|
777
|
+
* call-seq:
|
778
|
+
* narray.view => narray
|
779
|
+
*
|
780
|
+
* Return view of NArray
|
781
|
+
*/
|
782
|
+
VALUE
|
783
|
+
na_make_view(VALUE self)
|
784
|
+
{
|
785
|
+
int i, nd;
|
786
|
+
size_t j;
|
787
|
+
size_t *idx1, *idx2;
|
788
|
+
ssize_t stride;
|
789
|
+
narray_t *na;
|
790
|
+
narray_view_t *na1, *na2;
|
791
|
+
volatile VALUE view;
|
792
|
+
|
793
|
+
GetNArray(self,na);
|
794
|
+
nd = na->ndim;
|
795
|
+
|
796
|
+
view = na_s_allocate_view(CLASS_OF(self));
|
797
|
+
|
798
|
+
na_copy_flags(self, view);
|
799
|
+
GetNArrayView(view, na2);
|
800
|
+
|
801
|
+
na_setup_shape((narray_t*)na2, nd, na->shape);
|
802
|
+
na2->stridx = ALLOC_N(stridx_t,nd);
|
803
|
+
|
804
|
+
switch(na->type) {
|
805
|
+
case NARRAY_DATA_T:
|
806
|
+
case NARRAY_FILEMAP_T:
|
807
|
+
stride = na_get_elmsz(self);
|
808
|
+
for (i=nd; i--;) {
|
809
|
+
SDX_SET_STRIDE(na2->stridx[i],stride);
|
810
|
+
stride *= na->shape[i];
|
811
|
+
}
|
812
|
+
na2->offset = 0;
|
813
|
+
na2->data = self;
|
814
|
+
break;
|
815
|
+
case NARRAY_VIEW_T:
|
816
|
+
GetNArrayView(self, na1);
|
817
|
+
for (i=0; i<nd; i++) {
|
818
|
+
if (SDX_IS_INDEX(na1->stridx[i])) {
|
819
|
+
idx1 = SDX_GET_INDEX(na1->stridx[i]);
|
820
|
+
idx2 = ALLOC_N(size_t,na1->base.shape[i]);
|
821
|
+
for (j=0; j<na1->base.shape[i]; j++) {
|
822
|
+
idx2[j] = idx1[j];
|
823
|
+
}
|
824
|
+
SDX_SET_INDEX(na2->stridx[i],idx2);
|
825
|
+
} else {
|
826
|
+
na2->stridx[i] = na1->stridx[i];
|
827
|
+
}
|
828
|
+
}
|
829
|
+
na2->offset = na1->offset;
|
830
|
+
na2->data = na1->data;
|
831
|
+
break;
|
832
|
+
}
|
833
|
+
|
834
|
+
return view;
|
835
|
+
}
|
836
|
+
|
837
|
+
|
838
|
+
//----------------------------------------------------------------------
|
839
|
+
|
840
|
+
/*
|
841
|
+
* call-seq:
|
842
|
+
* narray.expand_dims(dim) => narray view
|
843
|
+
*
|
844
|
+
* Expand the shape of an array. Insert a new axis with size=1
|
845
|
+
* at a given dimension.
|
846
|
+
* @param [Integer] dim dimension at which new axis is inserted.
|
847
|
+
* @return [Numo::NArray] result narray view.
|
848
|
+
*/
|
849
|
+
VALUE
|
850
|
+
na_expand_dims(VALUE self, VALUE vdim)
|
851
|
+
{
|
852
|
+
int i, j, nd, dim;
|
853
|
+
size_t *shape, *na_shape;
|
854
|
+
stridx_t *stridx, *na_stridx;
|
855
|
+
narray_t *na;
|
856
|
+
narray_view_t *na2;
|
857
|
+
VALUE view;
|
858
|
+
|
859
|
+
GetNArray(self,na);
|
860
|
+
nd = na->ndim;
|
861
|
+
|
862
|
+
dim = NUM2INT(vdim);
|
863
|
+
if (dim < -nd-1 || dim > nd) {
|
864
|
+
rb_raise(nary_eDimensionError,"invalid axis (%d for %dD NArray)",
|
865
|
+
dim,nd);
|
866
|
+
}
|
867
|
+
if (dim < 0) {
|
868
|
+
dim += nd+1;
|
869
|
+
}
|
870
|
+
|
871
|
+
view = na_make_view(self);
|
872
|
+
GetNArrayView(view, na2);
|
873
|
+
|
874
|
+
shape = ALLOC_N(size_t,nd+1);
|
875
|
+
stridx = ALLOC_N(stridx_t,nd+1);
|
876
|
+
na_shape = na2->base.shape;
|
877
|
+
na_stridx = na2->stridx;
|
878
|
+
|
879
|
+
for (i=j=0; i<=nd; i++) {
|
880
|
+
if (i==dim) {
|
881
|
+
shape[i] = 1;
|
882
|
+
SDX_SET_STRIDE(stridx[i],0);
|
883
|
+
} else {
|
884
|
+
shape[i] = na_shape[j];
|
885
|
+
stridx[i] = na_stridx[j];
|
886
|
+
j++;
|
887
|
+
}
|
888
|
+
}
|
889
|
+
|
890
|
+
na2->stridx = stridx;
|
891
|
+
xfree(na_stridx);
|
892
|
+
na2->base.shape = shape;
|
893
|
+
xfree(na_shape);
|
894
|
+
na2->base.ndim++;
|
895
|
+
return view;
|
896
|
+
}
|
897
|
+
|
898
|
+
//----------------------------------------------------------------------
|
899
|
+
|
900
|
+
/*
|
901
|
+
* call-seq:
|
902
|
+
* narray.reverse([dim0,dim1,..]) => narray
|
903
|
+
*
|
904
|
+
* Return reversed view along specified dimeinsion
|
905
|
+
*/
|
906
|
+
VALUE
|
907
|
+
nary_reverse(int argc, VALUE *argv, VALUE self)
|
908
|
+
{
|
909
|
+
int i, nd;
|
910
|
+
size_t j, n;
|
911
|
+
size_t offset;
|
912
|
+
size_t *idx1, *idx2;
|
913
|
+
ssize_t stride;
|
914
|
+
ssize_t sign;
|
915
|
+
narray_t *na;
|
916
|
+
narray_view_t *na1, *na2;
|
917
|
+
VALUE view;
|
918
|
+
VALUE reduce;
|
919
|
+
|
920
|
+
reduce = na_reduce_dimension(argc, argv, 1, &self);
|
921
|
+
|
922
|
+
GetNArray(self,na);
|
923
|
+
nd = na->ndim;
|
924
|
+
|
925
|
+
view = na_s_allocate_view(CLASS_OF(self));
|
926
|
+
|
927
|
+
na_copy_flags(self, view);
|
928
|
+
GetNArrayView(view, na2);
|
929
|
+
|
930
|
+
na_setup_shape((narray_t*)na2, nd, na->shape);
|
931
|
+
na2->stridx = ALLOC_N(stridx_t,nd);
|
932
|
+
|
933
|
+
switch(na->type) {
|
934
|
+
case NARRAY_DATA_T:
|
935
|
+
case NARRAY_FILEMAP_T:
|
936
|
+
stride = na_get_elmsz(self);
|
937
|
+
offset = 0;
|
938
|
+
for (i=nd; i--;) {
|
939
|
+
if (na_test_reduce(reduce,i)) {
|
940
|
+
offset += (na->shape[i]-1)*stride;
|
941
|
+
sign = -1;
|
942
|
+
} else {
|
943
|
+
sign = 1;
|
944
|
+
}
|
945
|
+
SDX_SET_STRIDE(na2->stridx[i],stride*sign);
|
946
|
+
stride *= na->shape[i];
|
947
|
+
}
|
948
|
+
na2->offset = offset;
|
949
|
+
na2->data = self;
|
950
|
+
break;
|
951
|
+
case NARRAY_VIEW_T:
|
952
|
+
GetNArrayView(self, na1);
|
953
|
+
offset = na1->offset;
|
954
|
+
for (i=0; i<nd; i++) {
|
955
|
+
n = na1->base.shape[i];
|
956
|
+
if (SDX_IS_INDEX(na1->stridx[i])) {
|
957
|
+
idx1 = SDX_GET_INDEX(na1->stridx[i]);
|
958
|
+
idx2 = ALLOC_N(size_t,n);
|
959
|
+
if (na_test_reduce(reduce,i)) {
|
960
|
+
for (j=0; j<n; j++) {
|
961
|
+
idx2[n-1-j] = idx1[j];
|
962
|
+
}
|
963
|
+
} else {
|
964
|
+
for (j=0; j<n; j++) {
|
965
|
+
idx2[j] = idx1[j];
|
966
|
+
}
|
967
|
+
}
|
968
|
+
SDX_SET_INDEX(na2->stridx[i],idx2);
|
969
|
+
} else {
|
970
|
+
stride = SDX_GET_STRIDE(na1->stridx[i]);
|
971
|
+
if (na_test_reduce(reduce,i)) {
|
972
|
+
offset += (n-1)*stride;
|
973
|
+
SDX_SET_STRIDE(na2->stridx[i],-stride);
|
974
|
+
} else {
|
975
|
+
na2->stridx[i] = na1->stridx[i];
|
976
|
+
}
|
977
|
+
}
|
978
|
+
}
|
979
|
+
na2->offset = offset;
|
980
|
+
na2->data = na1->data;
|
981
|
+
break;
|
982
|
+
}
|
983
|
+
|
984
|
+
return view;
|
985
|
+
}
|
986
|
+
|
987
|
+
//----------------------------------------------------------------------
|
988
|
+
|
989
|
+
VALUE
|
990
|
+
numo_na_upcast(VALUE type1, VALUE type2)
|
991
|
+
{
|
992
|
+
VALUE upcast_hash;
|
993
|
+
VALUE result_type;
|
994
|
+
|
995
|
+
if (type1==type2) {
|
996
|
+
return type1;
|
997
|
+
}
|
998
|
+
upcast_hash = rb_const_get(type1, rb_intern("UPCAST"));
|
999
|
+
result_type = rb_hash_aref(upcast_hash, type2);
|
1000
|
+
if (NIL_P(result_type)) {
|
1001
|
+
if (TYPE(type2)==T_CLASS) {
|
1002
|
+
if (RTEST(rb_class_inherited_p(type2,cNArray))) {
|
1003
|
+
upcast_hash = rb_const_get(type2, rb_intern("UPCAST"));
|
1004
|
+
result_type = rb_hash_aref(upcast_hash, type1);
|
1005
|
+
}
|
1006
|
+
}
|
1007
|
+
}
|
1008
|
+
return result_type;
|
1009
|
+
}
|
1010
|
+
|
1011
|
+
/*
|
1012
|
+
Returns an array containing other and self,
|
1013
|
+
both are converted to upcasted type of NArray.
|
1014
|
+
Note that NArray has distinct UPCAST mechanism.
|
1015
|
+
Coerce is used for operation between non-NArray and NArray.
|
1016
|
+
@overload coerce(other)
|
1017
|
+
@param [Object] other numeric object.
|
1018
|
+
@return [Array] NArray-casted [other,self]
|
1019
|
+
*/
|
1020
|
+
static VALUE
|
1021
|
+
nary_coerce(VALUE x, VALUE y)
|
1022
|
+
{
|
1023
|
+
VALUE type;
|
1024
|
+
|
1025
|
+
type = numo_na_upcast(CLASS_OF(x), CLASS_OF(y));
|
1026
|
+
y = rb_funcall(type,rb_intern("cast"),1,y);
|
1027
|
+
return rb_assoc_new(y , x);
|
1028
|
+
}
|
1029
|
+
|
1030
|
+
|
1031
|
+
/*
|
1032
|
+
Returns total byte size of NArray.
|
1033
|
+
@return [Integer] byte size.
|
1034
|
+
*/
|
1035
|
+
static VALUE
|
1036
|
+
nary_byte_size(VALUE self)
|
1037
|
+
{
|
1038
|
+
VALUE velmsz; //klass,
|
1039
|
+
narray_t *na;
|
1040
|
+
size_t sz;
|
1041
|
+
|
1042
|
+
GetNArray(self,na);
|
1043
|
+
velmsz = rb_const_get(CLASS_OF(self), rb_intern(ELEMENT_BYTE_SIZE));
|
1044
|
+
sz = SIZE2NUM(NUM2SIZE(velmsz) * na->size);
|
1045
|
+
return sz;
|
1046
|
+
}
|
1047
|
+
|
1048
|
+
/*
|
1049
|
+
Returns byte size of one element of NArray.
|
1050
|
+
@return [Numeric] byte size.
|
1051
|
+
*/
|
1052
|
+
static VALUE
|
1053
|
+
nary_s_byte_size(VALUE type)
|
1054
|
+
{
|
1055
|
+
return rb_const_get(type, rb_intern(ELEMENT_BYTE_SIZE));
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
|
1059
|
+
/*
|
1060
|
+
Returns a new 1-D array initialized from binary raw data in a string.
|
1061
|
+
@overload from_string(string,[shape])
|
1062
|
+
@param [String] string Binary raw data.
|
1063
|
+
@param [Array] shape array of integers representing array shape.
|
1064
|
+
@return [Numo::NArray] NArray containing binary data.
|
1065
|
+
*/
|
1066
|
+
static VALUE
|
1067
|
+
nary_s_from_string(int argc, VALUE *argv, VALUE type)
|
1068
|
+
{
|
1069
|
+
size_t len, str_len, elmsz;
|
1070
|
+
size_t *shape;
|
1071
|
+
char *ptr;
|
1072
|
+
int i, nd, narg;
|
1073
|
+
VALUE vstr,vshape,vna;
|
1074
|
+
|
1075
|
+
narg = rb_scan_args(argc,argv,"11",&vstr,&vshape);
|
1076
|
+
str_len = RSTRING_LEN(vstr);
|
1077
|
+
elmsz = na_dtype_elmsz(type);
|
1078
|
+
if (narg==2) {
|
1079
|
+
nd = RARRAY_LEN(vshape);
|
1080
|
+
if (nd == 0 || nd > NA_MAX_DIMENSION) {
|
1081
|
+
rb_raise(nary_eDimensionError,"too long or empty shape (%d)", nd);
|
1082
|
+
}
|
1083
|
+
shape = ALLOCA_N(size_t,nd);
|
1084
|
+
len = 1;
|
1085
|
+
for (i=0; i<nd; ++i) {
|
1086
|
+
len *= shape[i] = NUM2SIZE(RARRAY_AREF(vshape,i));
|
1087
|
+
}
|
1088
|
+
if (len*elmsz != str_len) {
|
1089
|
+
rb_raise(rb_eArgError, "size mismatch");
|
1090
|
+
}
|
1091
|
+
} else {
|
1092
|
+
nd = 1;
|
1093
|
+
shape = ALLOCA_N(size_t,nd);
|
1094
|
+
shape[0] = len = str_len / elmsz;
|
1095
|
+
if (len == 0) {
|
1096
|
+
rb_raise(rb_eArgError, "string is empty or too short");
|
1097
|
+
}
|
1098
|
+
}
|
1099
|
+
|
1100
|
+
vna = rb_narray_new(type, nd, shape);
|
1101
|
+
ptr = na_get_pointer_for_write(vna);
|
1102
|
+
|
1103
|
+
memcpy(ptr, RSTRING_PTR(vstr), elmsz*len);
|
1104
|
+
|
1105
|
+
return vna;
|
1106
|
+
}
|
1107
|
+
|
1108
|
+
/*
|
1109
|
+
Returns string containing the raw data bytes in NArray.
|
1110
|
+
@overload to_string()
|
1111
|
+
@return [String] String object containing binary raw data.
|
1112
|
+
*/
|
1113
|
+
static VALUE
|
1114
|
+
nary_to_string(VALUE self)
|
1115
|
+
{
|
1116
|
+
size_t len, esz;
|
1117
|
+
char *ptr;
|
1118
|
+
VALUE str;
|
1119
|
+
narray_t *na;
|
1120
|
+
|
1121
|
+
GetNArray(self,na);
|
1122
|
+
if (na->type == NARRAY_VIEW_T) {
|
1123
|
+
self = na_copy(self);
|
1124
|
+
}
|
1125
|
+
esz = na_get_elmsz(self);
|
1126
|
+
len = na->size * esz;
|
1127
|
+
ptr = na_get_pointer_for_read(self);
|
1128
|
+
str = rb_usascii_str_new(ptr,len);
|
1129
|
+
RB_GC_GUARD(self);
|
1130
|
+
return str;
|
1131
|
+
}
|
1132
|
+
|
1133
|
+
|
1134
|
+
/*
|
1135
|
+
Cast self to another NArray datatype.
|
1136
|
+
@overload cast_to(datatype)
|
1137
|
+
@param [Class] datatype NArray datatype.
|
1138
|
+
@return [Numo::NArray]
|
1139
|
+
*/
|
1140
|
+
static VALUE
|
1141
|
+
nary_cast_to(VALUE obj, VALUE type)
|
1142
|
+
{
|
1143
|
+
return rb_funcall(type, rb_intern("cast"), 1, obj);
|
1144
|
+
}
|
1145
|
+
|
1146
|
+
|
1147
|
+
|
1148
|
+
bool
|
1149
|
+
na_test_reduce(VALUE reduce, int dim)
|
1150
|
+
{
|
1151
|
+
size_t m;
|
1152
|
+
|
1153
|
+
if (!RTEST(reduce))
|
1154
|
+
return 0;
|
1155
|
+
if (FIXNUM_P(reduce)) {
|
1156
|
+
m = FIX2LONG(reduce);
|
1157
|
+
if (m==0) return 1;
|
1158
|
+
return (m & (1u<<dim)) ? 1 : 0;
|
1159
|
+
} else {
|
1160
|
+
return (rb_funcall(reduce,rb_intern("[]"),1,INT2FIX(dim))==INT2FIX(1)) ?
|
1161
|
+
1 : 0 ;
|
1162
|
+
}
|
1163
|
+
}
|
1164
|
+
|
1165
|
+
|
1166
|
+
VALUE
|
1167
|
+
na_reduce_dimension(int argc, VALUE *argv, int naryc, VALUE *naryv)
|
1168
|
+
{
|
1169
|
+
int ndim, ndim0;
|
1170
|
+
int row_major;
|
1171
|
+
int i, r;
|
1172
|
+
size_t j;
|
1173
|
+
size_t len;
|
1174
|
+
ssize_t beg, step;
|
1175
|
+
VALUE v;
|
1176
|
+
narray_t *na;
|
1177
|
+
size_t m;
|
1178
|
+
VALUE reduce;
|
1179
|
+
|
1180
|
+
if (naryc<1) {
|
1181
|
+
rb_raise(rb_eRuntimeError,"must be positive: naryc=%d", naryc);
|
1182
|
+
}
|
1183
|
+
GetNArray(naryv[0],na);
|
1184
|
+
reduce = na->reduce;
|
1185
|
+
if (argc==0) {
|
1186
|
+
//printf("pass argc=0 reduce=%d\n",NUM2INT(reduce));
|
1187
|
+
return reduce;
|
1188
|
+
}
|
1189
|
+
ndim = ndim0 = na->ndim;
|
1190
|
+
row_major = TEST_COLUMN_MAJOR(naryv[0]);
|
1191
|
+
for (i=1; i<naryc; i++) {
|
1192
|
+
GetNArray(naryv[i],na);
|
1193
|
+
if (TEST_COLUMN_MAJOR(naryv[i]) != row_major) {
|
1194
|
+
rb_raise(nary_eDimensionError,"dimension order is different");
|
1195
|
+
}
|
1196
|
+
if (na->ndim > ndim) {
|
1197
|
+
ndim = na->ndim;
|
1198
|
+
}
|
1199
|
+
}
|
1200
|
+
if (ndim != ndim0) {
|
1201
|
+
j = FIX2ULONG(reduce) << (ndim-ndim0);
|
1202
|
+
reduce = ULONG2NUM(j);
|
1203
|
+
if (!FIXNUM_P(reduce)) {
|
1204
|
+
rb_raise(nary_eDimensionError,"reduce has too many bits");
|
1205
|
+
}
|
1206
|
+
}
|
1207
|
+
//printf("argc=%d\n",argc);
|
1208
|
+
|
1209
|
+
m = 0;
|
1210
|
+
reduce = Qnil;
|
1211
|
+
for (i=0; i<argc; i++) {
|
1212
|
+
v = argv[i];
|
1213
|
+
//printf("argv[%d]=",i);rb_p(v);
|
1214
|
+
if (TYPE(v)==T_FIXNUM) {
|
1215
|
+
beg = FIX2INT(v);
|
1216
|
+
if (beg<0) beg+=ndim;
|
1217
|
+
if (beg>=ndim || beg<0) {
|
1218
|
+
rb_raise(nary_eDimensionError,"dimension is out of range");
|
1219
|
+
}
|
1220
|
+
len = 1;
|
1221
|
+
step = 0;
|
1222
|
+
//printf("beg=%d step=%d len=%d\n",beg,step,len);
|
1223
|
+
} else if (rb_obj_is_kind_of(v,rb_cRange) ||
|
1224
|
+
rb_obj_is_kind_of(v,na_cStep)) {
|
1225
|
+
nary_step_array_index( v, ndim, &len, &beg, &step );
|
1226
|
+
} else {
|
1227
|
+
rb_raise(nary_eDimensionError, "invalid dimension argument %s",
|
1228
|
+
rb_obj_classname(v));
|
1229
|
+
}
|
1230
|
+
for (j=0; j<len; j++) {
|
1231
|
+
r = beg + step*j;
|
1232
|
+
if (row_major)
|
1233
|
+
r = ndim-1-r;
|
1234
|
+
if (reduce==Qnil) {
|
1235
|
+
if ( r < (ssize_t)sizeof(size_t) ) {
|
1236
|
+
m |= ((size_t)1) << r;
|
1237
|
+
continue;
|
1238
|
+
} else {
|
1239
|
+
reduce = SIZE2NUM(m);
|
1240
|
+
}
|
1241
|
+
}
|
1242
|
+
v = rb_funcall( INT2FIX(1), rb_intern("<<"), 1, INT2FIX(r) );
|
1243
|
+
reduce = rb_funcall( reduce, rb_intern("|"), 1, v );
|
1244
|
+
}
|
1245
|
+
}
|
1246
|
+
if (reduce==Qnil) reduce = SIZE2NUM(m);
|
1247
|
+
return reduce;
|
1248
|
+
}
|
1249
|
+
|
1250
|
+
//--------------------------------------
|
1251
|
+
|
1252
|
+
/*
|
1253
|
+
void
|
1254
|
+
na_index_arg_to_internal_order( int argc, VALUE *argv, VALUE self )
|
1255
|
+
{
|
1256
|
+
int i,j;
|
1257
|
+
VALUE tmp;
|
1258
|
+
|
1259
|
+
if (TEST_COLUMN_MAJOR(self)) {
|
1260
|
+
for (i=0,j=argc-1; i<argc/2; i++,j--) {
|
1261
|
+
tmp = argv[i];
|
1262
|
+
argv[i] = argv[j];
|
1263
|
+
argv[j] = tmp;
|
1264
|
+
}
|
1265
|
+
}
|
1266
|
+
}
|
1267
|
+
|
1268
|
+
VALUE
|
1269
|
+
na_index_array_to_internal_order( VALUE args, VALUE self )
|
1270
|
+
{
|
1271
|
+
int i,j;
|
1272
|
+
|
1273
|
+
if (TEST_COLUMN_MAJOR(self)) {
|
1274
|
+
return rb_funcall( args, rb_intern("reverse"), 0 );
|
1275
|
+
}
|
1276
|
+
return args;
|
1277
|
+
}
|
1278
|
+
*/
|
1279
|
+
|
1280
|
+
|
1281
|
+
/*
|
1282
|
+
Return true if column major.
|
1283
|
+
*/
|
1284
|
+
VALUE na_column_major_p( VALUE self )
|
1285
|
+
{
|
1286
|
+
if (TEST_COLUMN_MAJOR(self))
|
1287
|
+
return Qtrue;
|
1288
|
+
else
|
1289
|
+
return Qfalse;
|
1290
|
+
}
|
1291
|
+
|
1292
|
+
/*
|
1293
|
+
Return true if row major.
|
1294
|
+
*/
|
1295
|
+
VALUE na_row_major_p( VALUE self )
|
1296
|
+
{
|
1297
|
+
if (TEST_ROW_MAJOR(self))
|
1298
|
+
return Qtrue;
|
1299
|
+
else
|
1300
|
+
return Qfalse;
|
1301
|
+
}
|
1302
|
+
|
1303
|
+
|
1304
|
+
/*
|
1305
|
+
Return true if byte swapped.
|
1306
|
+
*/
|
1307
|
+
VALUE na_byte_swapped_p( VALUE self )
|
1308
|
+
{
|
1309
|
+
if (TEST_BYTE_SWAPPED(self))
|
1310
|
+
return Qtrue;
|
1311
|
+
return Qfalse;
|
1312
|
+
}
|
1313
|
+
|
1314
|
+
/*
|
1315
|
+
Return true if not byte swapped.
|
1316
|
+
*/
|
1317
|
+
VALUE na_host_order_p( VALUE self )
|
1318
|
+
{
|
1319
|
+
if (TEST_BYTE_SWAPPED(self))
|
1320
|
+
return Qfalse;
|
1321
|
+
return Qtrue;
|
1322
|
+
}
|
1323
|
+
|
1324
|
+
|
1325
|
+
/*
|
1326
|
+
Returns view of narray with inplace flagged.
|
1327
|
+
@return [Numo::NArray] view of narray with inplace flag.
|
1328
|
+
*/
|
1329
|
+
VALUE na_inplace( VALUE self )
|
1330
|
+
{
|
1331
|
+
VALUE view = self;
|
1332
|
+
//view = na_clone(self);
|
1333
|
+
SET_INPLACE(view);
|
1334
|
+
return view;
|
1335
|
+
}
|
1336
|
+
|
1337
|
+
/*
|
1338
|
+
Set inplace flag to self.
|
1339
|
+
@return [Numo::NArray] self
|
1340
|
+
*/
|
1341
|
+
VALUE na_inplace_bang( VALUE self )
|
1342
|
+
{
|
1343
|
+
SET_INPLACE(self);
|
1344
|
+
return self;
|
1345
|
+
}
|
1346
|
+
|
1347
|
+
VALUE na_inplace_store( VALUE self, VALUE val )
|
1348
|
+
{
|
1349
|
+
if (self==val)
|
1350
|
+
return self;
|
1351
|
+
else
|
1352
|
+
return na_store( self, val );
|
1353
|
+
}
|
1354
|
+
|
1355
|
+
/*
|
1356
|
+
Return true if inplace flagged.
|
1357
|
+
*/
|
1358
|
+
VALUE na_inplace_p( VALUE self )
|
1359
|
+
{
|
1360
|
+
if (TEST_INPLACE(self))
|
1361
|
+
return Qtrue;
|
1362
|
+
else
|
1363
|
+
return Qfalse;
|
1364
|
+
}
|
1365
|
+
|
1366
|
+
/*
|
1367
|
+
Unset inplace flag to self.
|
1368
|
+
@return [Numo::NArray] self
|
1369
|
+
*/
|
1370
|
+
VALUE na_out_of_place_bang( VALUE self )
|
1371
|
+
{
|
1372
|
+
UNSET_INPLACE(self);
|
1373
|
+
return self;
|
1374
|
+
}
|
1375
|
+
|
1376
|
+
int na_debug_flag=0;
|
1377
|
+
|
1378
|
+
VALUE na_debug_set(VALUE mod, VALUE flag)
|
1379
|
+
{
|
1380
|
+
na_debug_flag = RTEST(flag);
|
1381
|
+
return Qnil;
|
1382
|
+
}
|
1383
|
+
|
1384
|
+
double na_profile_value=0;
|
1385
|
+
|
1386
|
+
VALUE na_profile(VALUE mod)
|
1387
|
+
{
|
1388
|
+
return rb_float_new(na_profile_value);
|
1389
|
+
}
|
1390
|
+
|
1391
|
+
VALUE na_profile_set(VALUE mod, VALUE val)
|
1392
|
+
{
|
1393
|
+
na_profile_value = NUM2DBL(val);
|
1394
|
+
return val;
|
1395
|
+
}
|
1396
|
+
|
1397
|
+
|
1398
|
+
/*
|
1399
|
+
Equality of self and other in view of numerical array.
|
1400
|
+
i.e., both arrays have same shape and corresponding elements are equal.
|
1401
|
+
@overload == other
|
1402
|
+
@param [Object] other
|
1403
|
+
@return [Boolean] true if self and other is equal.
|
1404
|
+
*/
|
1405
|
+
VALUE
|
1406
|
+
na_equal(VALUE self, volatile VALUE other)
|
1407
|
+
{
|
1408
|
+
volatile VALUE vbool;
|
1409
|
+
narray_t *na1, *na2;
|
1410
|
+
int i;
|
1411
|
+
|
1412
|
+
GetNArray(self,na1);
|
1413
|
+
|
1414
|
+
if (!rb_obj_is_kind_of(other,cNArray)) {
|
1415
|
+
other = rb_funcall(CLASS_OF(self), rb_intern("cast"), 1, other);
|
1416
|
+
}
|
1417
|
+
|
1418
|
+
GetNArray(other,na2);
|
1419
|
+
if (na1->ndim != na2->ndim) {
|
1420
|
+
return Qfalse;
|
1421
|
+
}
|
1422
|
+
for (i=0; i<na1->ndim; i++) {
|
1423
|
+
if (na1->shape[i] != na2->shape[i]) {
|
1424
|
+
return Qfalse;
|
1425
|
+
}
|
1426
|
+
}
|
1427
|
+
vbool = rb_funcall(self, rb_intern("eq"), 1, other);
|
1428
|
+
return (rb_funcall(vbool, rb_intern("count_false"), 0)==INT2FIX(0)) ? Qtrue : Qfalse;
|
1429
|
+
}
|
1430
|
+
|
1431
|
+
|
1432
|
+
|
1433
|
+
/* initialization of NArray Class */
|
1434
|
+
void
|
1435
|
+
Init_narray()
|
1436
|
+
{
|
1437
|
+
mNumo = rb_define_module("Numo");
|
1438
|
+
|
1439
|
+
/* define NArray class */
|
1440
|
+
cNArray = rb_define_class_under(mNumo, "NArray", rb_cObject);
|
1441
|
+
|
1442
|
+
#ifndef HAVE_RB_CCOMPLEX
|
1443
|
+
rb_require("complex");
|
1444
|
+
rb_cComplex = rb_const_get(rb_cObject, rb_intern("Complex"));
|
1445
|
+
#endif
|
1446
|
+
|
1447
|
+
nary_eCastError = rb_define_class_under(cNArray, "CastError", rb_eStandardError);
|
1448
|
+
nary_eShapeError = rb_define_class_under(cNArray, "ShapeError", rb_eStandardError);
|
1449
|
+
nary_eOperationError = rb_define_class_under(cNArray, "OperationError", rb_eStandardError);
|
1450
|
+
nary_eDimensionError = rb_define_class_under(cNArray, "DimensionError", rb_eStandardError);
|
1451
|
+
|
1452
|
+
rb_define_singleton_method(cNArray, "debug=", na_debug_set, 1);
|
1453
|
+
rb_define_singleton_method(cNArray, "profile", na_profile, 0);
|
1454
|
+
rb_define_singleton_method(cNArray, "profile=", na_profile_set, 1);
|
1455
|
+
|
1456
|
+
/* Ruby allocation framework */
|
1457
|
+
rb_define_alloc_func(cNArray, na_s_allocate);
|
1458
|
+
rb_define_method(cNArray, "initialize", na_initialize, -2);
|
1459
|
+
rb_define_method(cNArray, "initialize_copy", na_initialize_copy, 1);
|
1460
|
+
|
1461
|
+
rb_define_singleton_method(cNArray, "zeros", na_s_zeros, -1);
|
1462
|
+
rb_define_singleton_method(cNArray, "ones", na_s_ones, -1);
|
1463
|
+
rb_define_singleton_method(cNArray, "eye", na_s_eye, -1);
|
1464
|
+
|
1465
|
+
rb_define_method(cNArray, "size", na_size, 0);
|
1466
|
+
rb_define_alias (cNArray, "length","size");
|
1467
|
+
rb_define_alias (cNArray, "total","size");
|
1468
|
+
rb_define_method(cNArray, "shape", na_shape, 0);
|
1469
|
+
rb_define_method(cNArray, "ndim", na_ndim,0);
|
1470
|
+
rb_define_alias (cNArray, "rank","ndim");
|
1471
|
+
|
1472
|
+
rb_define_method(cNArray, "debug_info", rb_narray_debug_info, 0);
|
1473
|
+
|
1474
|
+
rb_define_method(cNArray, "view", na_make_view, 0);
|
1475
|
+
rb_define_method(cNArray, "expand_dims", na_expand_dims, 1);
|
1476
|
+
rb_define_method(cNArray, "reverse", nary_reverse, -1);
|
1477
|
+
|
1478
|
+
rb_define_singleton_method(cNArray, "upcast", numo_na_upcast, 1);
|
1479
|
+
rb_define_singleton_method(cNArray, "byte_size", nary_s_byte_size, 0);
|
1480
|
+
|
1481
|
+
rb_define_singleton_method(cNArray, "from_string", nary_s_from_string, -1);
|
1482
|
+
rb_define_method(cNArray, "to_string", nary_to_string, 0);
|
1483
|
+
|
1484
|
+
rb_define_method(cNArray, "byte_size", nary_byte_size, 0);
|
1485
|
+
|
1486
|
+
rb_define_method(cNArray, "cast_to", nary_cast_to, 1);
|
1487
|
+
|
1488
|
+
rb_define_method(cNArray, "coerce", nary_coerce, 1);
|
1489
|
+
|
1490
|
+
rb_define_method(cNArray, "column_major?", na_column_major_p, 0);
|
1491
|
+
rb_define_method(cNArray, "row_major?", na_row_major_p, 0);
|
1492
|
+
rb_define_method(cNArray, "byte_swapped?", na_byte_swapped_p, 0);
|
1493
|
+
rb_define_method(cNArray, "host_order?", na_host_order_p, 0);
|
1494
|
+
|
1495
|
+
rb_define_method(cNArray, "inplace", na_inplace, 0);
|
1496
|
+
rb_define_method(cNArray, "inplace?", na_inplace_p, 0);
|
1497
|
+
rb_define_method(cNArray, "inplace!", na_inplace_bang, 0);
|
1498
|
+
rb_define_method(cNArray, "out_of_place!", na_out_of_place_bang, 0);
|
1499
|
+
rb_define_alias (cNArray, "not_inplace!", "out_of_place!");
|
1500
|
+
|
1501
|
+
rb_define_method(cNArray, "==", na_equal, 1);
|
1502
|
+
|
1503
|
+
id_allocate = rb_intern("allocate");
|
1504
|
+
id_contiguous_stride = rb_intern(CONTIGUOUS_STRIDE);
|
1505
|
+
//id_element_bit_size = rb_intern(ELEMENT_BIT_SIZE);
|
1506
|
+
//id_element_byte_size = rb_intern(ELEMENT_BYTE_SIZE);
|
1507
|
+
|
1508
|
+
sym_reduce = ID2SYM(rb_intern("reduce"));
|
1509
|
+
sym_option = ID2SYM(rb_intern("option"));
|
1510
|
+
sym_loop_opt = ID2SYM(rb_intern("loop_opt"));
|
1511
|
+
sym_init = ID2SYM(rb_intern("init"));
|
1512
|
+
|
1513
|
+
Init_nary_step();
|
1514
|
+
Init_nary_index();
|
1515
|
+
|
1516
|
+
Init_nary_data();
|
1517
|
+
|
1518
|
+
Init_nary_dcomplex();
|
1519
|
+
Init_nary_dfloat();
|
1520
|
+
Init_nary_scomplex();
|
1521
|
+
Init_nary_sfloat();
|
1522
|
+
|
1523
|
+
Init_nary_int64();
|
1524
|
+
Init_nary_uint64();
|
1525
|
+
Init_nary_int32();
|
1526
|
+
Init_nary_uint32();
|
1527
|
+
Init_nary_int16();
|
1528
|
+
Init_nary_uint16();
|
1529
|
+
Init_nary_int8();
|
1530
|
+
Init_nary_uint8();
|
1531
|
+
Init_nary_bit();
|
1532
|
+
|
1533
|
+
Init_nary_math();
|
1534
|
+
|
1535
|
+
Init_nary_rand();
|
1536
|
+
Init_nary_array();
|
1537
|
+
Init_nary_struct();
|
1538
|
+
Init_nary_robject();
|
1539
|
+
}
|