numo-narray-alt 0.9.14 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7de5c728642f2cb9d047ab64f482f61d4aaeedf984058fed44145f0e726231dc
4
- data.tar.gz: 93a64459c21e12ed5944b1b56db9ac90c7a2d6a0ac919e65c7acb08b3b5274bb
3
+ metadata.gz: e2514ae8d0bcdfaaad3dee1d3c082e9439ff20fd70d4b8177bfab43f480912dc
4
+ data.tar.gz: 116204c7ba7d8aecc77a89bf202adad0ac1aad126495956fc12305045b8cc91d
5
5
  SHA512:
6
- metadata.gz: d20f999447d51edf842a44960efc93cd4d8ee03c6c75d162b8b345e76fcd824b910bbe230e88f9e6ab2bb25212f7c2b00b49b713e567f5e1380e3184e36ac608
7
- data.tar.gz: 62e52d72edba09bc200f13796f7f842feadebea070c3b90e3fee9fd82d3fea0ac7e7a1267750f9bbc90ddfc9b48b02a77cc845aa12bee5893601c53330e9e67e
6
+ metadata.gz: b6936f60723f6e5e84998deb9ecccb1a9390973880f5b0b264dd6a972878cae27570e03cfd84d36f996efacbf53548aa8237785b0df36704bf3fa3a4ccc02295
7
+ data.tar.gz: 51d5f9120ba716fcfde216f0fd2dc9039eaa44c372ca449050dc89f75a49b8ed4b7a93d83c95e1c23606d3794c015291e9215930559611242973362a55224e13
data/Gemfile CHANGED
@@ -18,5 +18,5 @@ gem 'simplecov', '~> 0.22.0'
18
18
  gem 'yard', '~> 0.9.37'
19
19
 
20
20
  group :memcheck, optional: true do
21
- gem 'ruby_memcheck', '~> 3.0' if RUBY_VERSION.split('.')[0].to_i >= 3
21
+ gem 'ruby_memcheck', '~> 3.0'
22
22
  end
@@ -104,12 +104,10 @@ static int na_mdai_object_type(int type, VALUE v) {
104
104
  if (rb_obj_is_kind_of(v, rb_cRange)) {
105
105
  type = (int)na_object_type(type, rb_funcall(v, id_begin, 0));
106
106
  type = (int)na_object_type(type, rb_funcall(v, id_end, 0));
107
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
108
107
  } else if (rb_obj_is_kind_of(v, rb_cArithSeq)) {
109
108
  type = (int)na_object_type(type, rb_funcall(v, id_begin, 0));
110
109
  type = (int)na_object_type(type, rb_funcall(v, id_end, 0));
111
110
  type = (int)na_object_type(type, rb_funcall(v, id_step, 0));
112
- #endif
113
111
  } else {
114
112
  type = (int)na_object_type(type, v);
115
113
  }
@@ -181,13 +179,7 @@ static int na_mdai_investigate(na_mdai_t* mdai, int ndim) {
181
179
  if (na_mdai_investigate(mdai, ndim + 1)) {
182
180
  len--; /* Array is empty */
183
181
  }
184
- } else if (rb_obj_is_kind_of(v, rb_cRange)
185
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
186
- || rb_obj_is_kind_of(v, rb_cArithSeq)
187
- #else
188
- || rb_obj_is_kind_of(v, rb_cEnumerator)
189
- #endif
190
- ) {
182
+ } else if (rb_obj_is_kind_of(v, rb_cRange) || rb_obj_is_kind_of(v, rb_cArithSeq)) {
191
183
  nary_step_sequence(v, &length, &dbeg, &dstep);
192
184
  len += length - 1;
193
185
  mdai->type = na_mdai_object_type(mdai->type, v);
@@ -3,11 +3,6 @@
3
3
  require 'rbconfig'
4
4
  require 'mkmf'
5
5
 
6
- if RUBY_VERSION < '2.1.0'
7
- puts 'Numo::NArray requires Ruby version 2.1 or later.'
8
- exit(1)
9
- end
10
-
11
6
  def d(file)
12
7
  File.join(__dir__, file)
13
8
  end
@@ -51,11 +46,6 @@ srcs = %w[
51
46
  rand
52
47
  ]
53
48
 
54
- if RUBY_VERSION[0..3] == '2.1.'
55
- puts 'add kwargs'
56
- srcs << 'kwargs'
57
- end
58
-
59
49
  stdbool = ('stdbool.h' if have_header('stdbool.h'))
60
50
 
61
51
  stdint = if have_header('stdint.h')
@@ -72,7 +62,6 @@ have_type('uint32_t', stdint) unless have_type('u_int32_t', stdint)
72
62
  have_type('int64_t', stdint)
73
63
  have_type('uint64_t', stdint) unless have_type('u_int64_t', stdint)
74
64
  have_func('exp10')
75
- have_func('rb_arithmetic_sequence_extract')
76
65
  have_func('RTYPEDDATA_GET_DATA')
77
66
 
78
67
  have_var('rb_cComplex')
@@ -181,7 +181,6 @@ na_parse_range(VALUE range, ssize_t step, int orig_dim, ssize_t size, na_index_a
181
181
  ssize_t beg, end, beg_orig, end_orig;
182
182
  const char *dot = "..", *edot = "...";
183
183
 
184
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
185
184
  rb_arithmetic_sequence_components_t x;
186
185
  rb_arithmetic_sequence_extract(range, &x);
187
186
  step = NUM2SSIZET(x.step);
@@ -216,29 +215,6 @@ na_parse_range(VALUE range, ssize_t step, int orig_dim, ssize_t size, na_index_a
216
215
  );
217
216
  }
218
217
  }
219
- #else
220
- VALUE excl_end;
221
-
222
- beg = beg_orig = NUM2SSIZET(rb_funcall(range, id_beg, 0));
223
- if (beg < 0) {
224
- beg += size;
225
- }
226
- end = end_orig = NUM2SSIZET(rb_funcall(range, id_end, 0));
227
- if (end < 0) {
228
- end += size;
229
- }
230
- excl_end = rb_funcall(range, id_exclude_end, 0);
231
- if (RTEST(excl_end)) {
232
- end--;
233
- dot = edot;
234
- }
235
- if (beg < 0 || beg >= size || end < 0 || end >= size) {
236
- rb_raise(
237
- rb_eRangeError, "%" SZF "d%s%" SZF "d is out of range for size=%" SZF "d", beg_orig, dot,
238
- end_orig, size
239
- );
240
- }
241
- #endif
242
218
  n = (int)((end - beg) / step + 1);
243
219
  if (n < 0) n = 0;
244
220
  na_index_set_step(q, orig_dim, n, beg, step);
@@ -335,18 +311,12 @@ static void na_index_parse_each(volatile VALUE a, ssize_t size, int i, na_index_
335
311
  default:
336
312
  if (rb_obj_is_kind_of(a, rb_cRange)) {
337
313
  na_parse_range(a, 1, i, size, q);
338
- }
339
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
340
- else if (rb_obj_is_kind_of(a, rb_cArithSeq)) {
314
+ } else if (rb_obj_is_kind_of(a, rb_cArithSeq)) {
341
315
  // na_parse_arith_seq(a, i, size, q);
342
316
  na_parse_range(a, 1, i, size, q);
343
- }
344
- #endif
345
- else if (rb_obj_is_kind_of(a, rb_cEnumerator)) {
317
+ } else if (rb_obj_is_kind_of(a, rb_cEnumerator)) {
346
318
  na_parse_enumerator(a, i, size, q);
347
- }
348
- // NArray index
349
- else if (NA_IsNArray(a)) {
319
+ } else if (NA_IsNArray(a)) { // NArray index
350
320
  na_parse_narray_index(a, i, size, q);
351
321
  } else {
352
322
  rb_raise(rb_eIndexError, "not allowed type");
@@ -414,13 +384,9 @@ na_at_parse_each(volatile VALUE a, ssize_t size, int i, VALUE* idx, ssize_t stri
414
384
  return;
415
385
  } else if (rb_obj_is_kind_of(a, rb_cRange)) {
416
386
  na_parse_range(a, 1, i, size, &q);
417
- }
418
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
419
- else if (rb_obj_is_kind_of(a, rb_cArithSeq)) {
387
+ } else if (rb_obj_is_kind_of(a, rb_cArithSeq)) {
420
388
  na_parse_range(a, 1, i, size, &q);
421
- }
422
- #endif
423
- else if (rb_obj_is_kind_of(a, rb_cEnumerator)) {
389
+ } else if (rb_obj_is_kind_of(a, rb_cEnumerator)) {
424
390
  na_parse_enumerator(a, i, size, &q);
425
391
  } else {
426
392
  rb_raise(rb_eIndexError, "not allowed type");
@@ -123,12 +123,7 @@ void Init_nary_math(void) {
123
123
  rb_hash_aset(hCast, numo_cDComplex, numo_mDComplexMath);
124
124
  rb_hash_aset(hCast, numo_cSFloat, numo_mSFloatMath);
125
125
  rb_hash_aset(hCast, numo_cSComplex, numo_mSComplexMath);
126
- #ifdef RUBY_INTEGER_UNIFICATION
127
126
  rb_hash_aset(hCast, rb_cInteger, rb_mMath);
128
- #else
129
- rb_hash_aset(hCast, rb_cFixnum, rb_mMath);
130
- rb_hash_aset(hCast, rb_cBignum, rb_mMath);
131
- #endif
132
127
  rb_hash_aset(hCast, rb_cFloat, rb_mMath);
133
128
  rb_hash_aset(hCast, rb_cComplex, numo_mDComplexMath);
134
129
  /* Dispatch table representing the corresponding Math module. */
@@ -7,6 +7,14 @@
7
7
  #include <assert.h>
8
8
  #include <ruby.h>
9
9
 
10
+ #ifndef RBASIC_FLAGS
11
+ #define RBASIC_FLAGS(obj) (RBASIC(obj)->flags)
12
+ #endif
13
+
14
+ #ifndef RBASIC_SET_FLAGS
15
+ #define RBASIC_SET_FLAGS(obj, flags_to_set) (RBASIC(obj)->flags = (flags_to_set))
16
+ #endif
17
+
10
18
  /* global variables within this module */
11
19
  VALUE numo_cNArray;
12
20
  VALUE rb_mNumo;
@@ -46,18 +54,13 @@ VALUE sym_init;
46
54
  #ifndef HAVE_RB_CCOMPLEX
47
55
  VALUE rb_cComplex;
48
56
  #endif
49
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
50
57
  VALUE rb_cArithSeq;
51
- #endif
52
58
 
53
59
  int numo_na_inspect_rows = 20;
54
60
  int numo_na_inspect_cols = 80;
55
61
 
56
62
  void Init_nary_data();
57
63
  void Init_nary_ndloop();
58
- #ifndef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
59
- void Init_nary_step();
60
- #endif
61
64
  void Init_nary_index();
62
65
  void Init_numo_bit();
63
66
  void Init_numo_int8();
@@ -857,8 +860,10 @@ void na_copy_flags(VALUE src, VALUE dst) {
857
860
  na2->flag[0] = na1->flag[0];
858
861
  // na2->flag[1] = NA_FL1_INIT;
859
862
 
860
- RBASIC(dst)->flags |= (RBASIC(src)->flags) & (FL_USER1 | FL_USER2 | FL_USER3 | FL_USER4 |
861
- FL_USER5 | FL_USER6 | FL_USER7);
863
+ RBASIC_SET_FLAGS(
864
+ dst, RBASIC_FLAGS(dst) | (RBASIC_FLAGS(src) & (FL_USER1 | FL_USER2 | FL_USER3 | FL_USER4 |
865
+ FL_USER5 | FL_USER6 | FL_USER7))
866
+ );
862
867
  }
863
868
 
864
869
  // fix name, ex, allow_stride_for_flatten_view
@@ -1550,13 +1555,7 @@ static VALUE na_get_reduce_flag_from_axes(VALUE na_obj, VALUE axes) {
1550
1555
  }
1551
1556
  len = 1;
1552
1557
  step = 0;
1553
- } else if (rb_obj_is_kind_of(v, rb_cRange)
1554
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
1555
- || rb_obj_is_kind_of(v, rb_cArithSeq)
1556
- #else
1557
- || rb_obj_is_kind_of(v, rb_cEnumerator)
1558
- #endif
1559
- ) {
1558
+ } else if (rb_obj_is_kind_of(v, rb_cRange) || rb_obj_is_kind_of(v, rb_cArithSeq)) {
1560
1559
  nary_step_array_index(v, ndim, &len, &beg, &step);
1561
1560
  } else {
1562
1561
  rb_raise(nary_eDimensionError, "invalid dimension argument %s", rb_obj_classname(v));
@@ -1845,9 +1844,7 @@ void Init_narray(void) {
1845
1844
  rb_require("complex");
1846
1845
  rb_cComplex = rb_const_get(rb_cObject, rb_intern("Complex"));
1847
1846
  #endif
1848
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
1849
1847
  rb_cArithSeq = rb_path2class("Enumerator::ArithmeticSequence");
1850
- #endif
1851
1848
 
1852
1849
  /* The version of Numo::NArray Alternative. */
1853
1850
  rb_define_const(cNArray, "VERSION", rb_str_new2(NARRAY_VERSION));
@@ -1978,9 +1975,6 @@ void Init_narray(void) {
1978
1975
  sym_loop_opt = ID2SYM(rb_intern("loop_opt"));
1979
1976
  sym_init = ID2SYM(rb_intern("init"));
1980
1977
 
1981
- #ifndef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
1982
- Init_nary_step();
1983
- #endif
1984
1978
  Init_nary_index();
1985
1979
 
1986
1980
  Init_nary_data();
@@ -13,8 +13,12 @@ extern "C" {
13
13
  #endif
14
14
  #endif
15
15
 
16
- #define NARRAY_VERSION "0.9.14"
17
- #define NARRAY_VERSION_CODE 9140
16
+ #define NARRAY_VERSION "0.10.0"
17
+ #define NARRAY_VERSION_MAJOR 0
18
+ #define NARRAY_VERSION_MINOR 10
19
+ #define NARRAY_VERSION_PATCH 0
20
+ #define NARRAY_VERSION_CODE \
21
+ (NARRAY_VERSION_MAJOR * 10000 + NARRAY_VERSION_MINOR * 100 + NARRAY_VERSION_PATCH)
18
22
 
19
23
  #include <math.h>
20
24
  #include "numo/compat.h"
@@ -174,9 +178,7 @@ extern VALUE numo_cRObject;
174
178
  #ifndef HAVE_RB_CCOMPLEX
175
179
  extern VALUE rb_cComplex;
176
180
  #endif
177
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
178
181
  extern VALUE rb_cArithSeq;
179
- #endif
180
182
 
181
183
  extern VALUE sym_reduce;
182
184
  extern VALUE sym_option;
@@ -455,11 +457,7 @@ typedef unsigned int BIT_DIGIT;
455
457
  #define ELEMENT_BYTE_SIZE "ELEMENT_BYTE_SIZE"
456
458
  #define CONTIGUOUS_STRIDE "CONTIGUOUS_STRIDE"
457
459
 
458
- #ifdef RUBY_INTEGER_UNIFICATION
459
460
  #define IS_INTEGER_CLASS(c) ((c) == rb_cInteger)
460
- #else
461
- #define IS_INTEGER_CLASS(c) ((c) == rb_cFixnum || (c) == rb_cBignum)
462
- #endif
463
461
 
464
462
  #include "numo/ndloop.h"
465
463
  #include "numo/intern.h"
@@ -0,0 +1,169 @@
1
+ #ifndef NUMO_NARRAY_MH_ASET_H
2
+ #define NUMO_NARRAY_MH_ASET_H 1
3
+
4
+ /**
5
+ * Convert a data value of obj (with a single element) to dtype.
6
+ */
7
+ #define DEF_EXTRACT_DATA_FUNC(tDType, tNAryClass) \
8
+ static tDType tDType##_extract_data(VALUE obj) { \
9
+ if (IsNArray(obj)) { \
10
+ narray_t* na; \
11
+ GetNArray(obj, na); \
12
+ if (na->size != 1) { \
13
+ rb_raise(nary_eShapeError, "narray size should be 1"); \
14
+ } \
15
+ VALUE klass = rb_obj_class(obj); \
16
+ char* ptr = na_get_pointer_for_read(obj); \
17
+ size_t pos = na_get_offset(obj); \
18
+ if (klass == numo_cBit) { \
19
+ BIT_DIGIT b; \
20
+ LOAD_BIT(ptr, pos, b); \
21
+ return m_from_sint(b); \
22
+ } \
23
+ if (klass == numo_cDFloat) { \
24
+ return m_from_real(*(double*)(ptr + pos)); \
25
+ } \
26
+ if (klass == numo_cSFloat) { \
27
+ return m_from_real(*(float*)(ptr + pos)); \
28
+ } \
29
+ if (klass == numo_cInt64) { \
30
+ return m_from_int64(*(int64_t*)(ptr + pos)); \
31
+ } \
32
+ if (klass == numo_cInt32) { \
33
+ return m_from_int32(*(int32_t*)(ptr + pos)); \
34
+ } \
35
+ if (klass == numo_cInt16) { \
36
+ return m_from_sint(*(int16_t*)(ptr + pos)); \
37
+ } \
38
+ if (klass == numo_cInt8) { \
39
+ return m_from_sint(*(int8_t*)(ptr + pos)); \
40
+ } \
41
+ if (klass == numo_cUInt64) { \
42
+ return m_from_uint64(*(u_int64_t*)(ptr + pos)); \
43
+ } \
44
+ if (klass == numo_cUInt32) { \
45
+ return m_from_uint32(*(u_int32_t*)(ptr + pos)); \
46
+ } \
47
+ if (klass == numo_cUInt16) { \
48
+ return m_from_sint(*(u_int16_t*)(ptr + pos)); \
49
+ } \
50
+ if (klass == numo_cUInt8) { \
51
+ return m_from_sint(*(u_int8_t*)(ptr + pos)); \
52
+ } \
53
+ if (klass == numo_cRObject) { \
54
+ return m_num_to_data(*(VALUE*)(ptr + pos)); \
55
+ } \
56
+ VALUE r = rb_funcall(obj, rb_intern("coerce_cast"), 1, tNAryClass); \
57
+ if (rb_obj_class(r) == tNAryClass) { \
58
+ return tDType##_extract_data(r); \
59
+ } \
60
+ rb_raise( \
61
+ nary_eCastError, "unknown conversion from %s to %s", rb_class2name(rb_obj_class(obj)), \
62
+ rb_class2name(tNAryClass) \
63
+ ); \
64
+ } \
65
+ if (TYPE(obj) == T_ARRAY) { \
66
+ if (RARRAY_LEN(obj) != 1) { \
67
+ rb_raise(nary_eShapeError, "array size should be 1"); \
68
+ } \
69
+ return m_num_to_data(RARRAY_AREF(obj, 0)); \
70
+ } \
71
+ return m_num_to_data(obj); \
72
+ }
73
+
74
+ #define DEF_CMP_EXTRACT_DATA_FUNC(tDType, tNAryClass) \
75
+ static tDType tDType##_extract_data(VALUE obj) { \
76
+ if (IsNArray(obj)) { \
77
+ narray_t* na; \
78
+ GetNArray(obj, na); \
79
+ if (na->size != 1) { \
80
+ rb_raise(nary_eShapeError, "narray size should be 1"); \
81
+ } \
82
+ VALUE klass = rb_obj_class(obj); \
83
+ char* ptr = na_get_pointer_for_read(obj); \
84
+ size_t pos = na_get_offset(obj); \
85
+ if (klass == numo_cBit) { \
86
+ BIT_DIGIT b; \
87
+ LOAD_BIT(ptr, pos, b); \
88
+ return m_from_sint(b); \
89
+ } \
90
+ if (klass == numo_cDComplex) { \
91
+ dcomplex* p = (dcomplex*)(ptr + pos); \
92
+ return c_new(REAL(*p), IMAG(*p)); \
93
+ } \
94
+ if (klass == numo_cSComplex) { \
95
+ scomplex* p = (scomplex*)(ptr + pos); \
96
+ return c_new(REAL(*p), IMAG(*p)); \
97
+ } \
98
+ if (klass == numo_cDFloat) { \
99
+ return m_from_real(*(double*)(ptr + pos)); \
100
+ } \
101
+ if (klass == numo_cSFloat) { \
102
+ return m_from_real(*(float*)(ptr + pos)); \
103
+ } \
104
+ if (klass == numo_cInt64) { \
105
+ return m_from_int64(*(int64_t*)(ptr + pos)); \
106
+ } \
107
+ if (klass == numo_cInt32) { \
108
+ return m_from_int32(*(int32_t*)(ptr + pos)); \
109
+ } \
110
+ if (klass == numo_cInt16) { \
111
+ return m_from_sint(*(int16_t*)(ptr + pos)); \
112
+ } \
113
+ if (klass == numo_cInt8) { \
114
+ return m_from_sint(*(int8_t*)(ptr + pos)); \
115
+ } \
116
+ if (klass == numo_cUInt64) { \
117
+ return m_from_uint64(*(u_int64_t*)(ptr + pos)); \
118
+ } \
119
+ if (klass == numo_cUInt32) { \
120
+ return m_from_uint32(*(u_int32_t*)(ptr + pos)); \
121
+ } \
122
+ if (klass == numo_cUInt16) { \
123
+ return m_from_sint(*(u_int16_t*)(ptr + pos)); \
124
+ } \
125
+ if (klass == numo_cUInt8) { \
126
+ return m_from_sint(*(u_int8_t*)(ptr + pos)); \
127
+ } \
128
+ if (klass == numo_cRObject) { \
129
+ return m_num_to_data(*(VALUE*)(ptr + pos)); \
130
+ } \
131
+ VALUE r = rb_funcall(obj, rb_intern("coerce_cast"), 1, tNAryClass); \
132
+ if (rb_obj_class(r) == tNAryClass) { \
133
+ return tDType##_extract_data(r); \
134
+ } \
135
+ rb_raise( \
136
+ nary_eCastError, "unknown conversion from %s to %s", rb_class2name(rb_obj_class(obj)), \
137
+ rb_class2name(tNAryClass) \
138
+ ); \
139
+ } \
140
+ if (TYPE(obj) == T_ARRAY) { \
141
+ if (RARRAY_LEN(obj) != 1) { \
142
+ rb_raise(nary_eShapeError, "array size should be 1"); \
143
+ } \
144
+ return m_num_to_data(RARRAY_AREF(obj, 0)); \
145
+ } \
146
+ return m_num_to_data(obj); \
147
+ }
148
+
149
+ #define DEF_NARRAY_ASET_METHOD_FUNC(tDType) \
150
+ static VALUE tDType##_aset(int argc, VALUE* argv, VALUE self) { \
151
+ argc--; \
152
+ if (argc == 0) { \
153
+ tDType##_store(self, argv[argc]); \
154
+ } else { \
155
+ size_t pos; \
156
+ int nd = na_get_result_dimension(self, argc, argv, sizeof(tDType), &pos); \
157
+ if (nd) { \
158
+ VALUE a = na_aref_main(argc, argv, self, 0, nd); \
159
+ tDType##_store(a, argv[argc]); \
160
+ } else { \
161
+ tDType x = tDType##_extract_data(argv[argc]); \
162
+ char* ptr = na_get_pointer_for_read_write(self) + pos; \
163
+ *(tDType*)ptr = x; \
164
+ } \
165
+ } \
166
+ return argv[argc]; \
167
+ }
168
+
169
+ #endif /* NUMO_NARRAY_MH_ASET_H */
@@ -0,0 +1,85 @@
1
+ #ifndef NUMO_NARRAY_MH_MEDIAN_H
2
+ #define NUMO_NARRAY_MH_MEDIAN_H 1
3
+
4
+ #define DEF_NARRAY_INT_MEDIAN_METHOD_FUNC(tDType) \
5
+ static void iter_##tDType##_median(na_loop_t* const lp) { \
6
+ size_t n; \
7
+ INIT_COUNTER(lp, n); \
8
+ char* p1 = NDL_PTR(lp, 0); \
9
+ char* p2 = NDL_PTR(lp, 1); \
10
+ tDType* buf = (tDType*)p1; \
11
+ tDType##_qsort(buf, n, sizeof(tDType)); \
12
+ if (n == 0) { \
13
+ *(tDType*)p2 = buf[0]; \
14
+ } else if (n % 2 == 0) { \
15
+ *(tDType*)p2 = (buf[n / 2 - 1] + buf[n / 2]) / 2; \
16
+ } else { \
17
+ *(tDType*)p2 = buf[(n - 1) / 2]; \
18
+ } \
19
+ } \
20
+ \
21
+ static VALUE tDType##_median(int argc, VALUE* argv, VALUE self) { \
22
+ ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_reduce, 0 } }; \
23
+ ndfunc_arg_out_t aout[1] = { { INT2FIX(0), 0 } }; \
24
+ ndfunc_t ndf = { \
25
+ iter_##tDType##_median, NDF_HAS_LOOP | NDF_FLAT_REDUCE, 2, 1, ain, aout \
26
+ }; \
27
+ self = na_copy(self); \
28
+ VALUE reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, 0); \
29
+ VALUE v = na_ndloop(&ndf, 2, self, reduce); \
30
+ return tDType##_extract(v); \
31
+ }
32
+
33
+ #define DEF_NARRAY_FLT_MEDIAN_METHOD_FUNC(tDType) \
34
+ static void iter_##tDType##_median_ignan(na_loop_t* const lp) { \
35
+ size_t n; \
36
+ INIT_COUNTER(lp, n); \
37
+ char* p1 = NDL_PTR(lp, 0); \
38
+ char* p2 = NDL_PTR(lp, 1); \
39
+ tDType* buf = (tDType*)p1; \
40
+ tDType##_qsort_ignan(buf, n, sizeof(tDType)); \
41
+ for (size_t i = 0; i < n; i++) { \
42
+ if (!isnan(buf[i])) break; \
43
+ } \
44
+ if (n == 0) { \
45
+ *(tDType*)p2 = buf[0]; \
46
+ } else if (n % 2 == 0) { \
47
+ *(tDType*)p2 = (buf[n / 2 - 1] + buf[n / 2]) / 2; \
48
+ } else { \
49
+ *(tDType*)p2 = buf[(n - 1) / 2]; \
50
+ } \
51
+ } \
52
+ \
53
+ static void iter_##tDType##_median_prnan(na_loop_t* const lp) { \
54
+ size_t n; \
55
+ INIT_COUNTER(lp, n); \
56
+ char* p1 = NDL_PTR(lp, 0); \
57
+ char* p2 = NDL_PTR(lp, 1); \
58
+ tDType* buf = (tDType*)p1; \
59
+ tDType##_qsort_prnan(buf, n, sizeof(tDType)); \
60
+ for (size_t i = 0; i < n; i++) { \
61
+ if (!isnan(buf[i])) break; \
62
+ } \
63
+ if (n == 0) { \
64
+ *(tDType*)p2 = buf[0]; \
65
+ } else if (n % 2 == 0) { \
66
+ *(tDType*)p2 = (buf[n / 2 - 1] + buf[n / 2]) / 2; \
67
+ } else { \
68
+ *(tDType*)p2 = buf[(n - 1) / 2]; \
69
+ } \
70
+ } \
71
+ \
72
+ static VALUE tDType##_median(int argc, VALUE* argv, VALUE self) { \
73
+ ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_reduce, 0 } }; \
74
+ ndfunc_arg_out_t aout[1] = { { INT2FIX(0), 0 } }; \
75
+ ndfunc_t ndf = { \
76
+ iter_##tDType##_median_ignan, NDF_HAS_LOOP | NDF_FLAT_REDUCE, 2, 1, ain, aout \
77
+ }; \
78
+ self = na_copy(self); \
79
+ VALUE reduce = \
80
+ na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_##tDType##_median_prnan); \
81
+ VALUE v = na_ndloop(&ndf, 2, self, reduce); \
82
+ return tDType##_extract(v); \
83
+ }
84
+
85
+ #endif /* NUMO_NARRAY_MH_MEDIAN_H */
@@ -0,0 +1,80 @@
1
+ #ifndef NUMO_NARRAY_MH_S_CAST_H
2
+ #define NUMO_NARRAY_MH_S_CAST_H 1
3
+
4
+ #define DEF_CAST_ARRAY_FUNC(tDType, tNAryClass) \
5
+ static VALUE tDType##_cast_array(VALUE rary) { \
6
+ VALUE nary = na_s_new_like(tNAryClass, rary); \
7
+ narray_t* na; \
8
+ GetNArray(nary, na); \
9
+ if (na->size > 0) { \
10
+ tDType##_store_array(nary, rary); \
11
+ } \
12
+ return nary; \
13
+ }
14
+
15
+ #define DEF_NARRAY_S_CAST_METHOD_FUNC(tDType, tNAryClass) \
16
+ DEF_CAST_ARRAY_FUNC(tDType, tNAryClass) \
17
+ static VALUE tDType##_s_cast(VALUE type, VALUE obj) { \
18
+ if (rb_obj_class(obj) == tNAryClass) { \
19
+ return obj; \
20
+ } \
21
+ if (RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) { \
22
+ tDType x = m_num_to_data(obj); \
23
+ return tDType##_new_dim0(x); \
24
+ } \
25
+ if (RTEST(rb_obj_is_kind_of(obj, rb_cArray))) { \
26
+ return tDType##_cast_array(obj); \
27
+ } \
28
+ if (IsNArray(obj)) { \
29
+ narray_t* na; \
30
+ GetNArray(obj, na); \
31
+ VALUE v = nary_new(cT, NA_NDIM(na), NA_SHAPE(na)); \
32
+ if (NA_SIZE(na) > 0) { \
33
+ tDType##_store(v, obj); \
34
+ } \
35
+ return v; \
36
+ } \
37
+ if (rb_respond_to(obj, id_to_a)) { \
38
+ obj = rb_funcall(obj, id_to_a, 0); \
39
+ if (TYPE(obj) != T_ARRAY) { \
40
+ rb_raise(rb_eTypeError, "`to_a' did not return Array"); \
41
+ } \
42
+ return tDType##_cast_array(obj); \
43
+ } \
44
+ rb_raise(nary_eCastError, "cannot cast to %s", rb_class2name(type)); \
45
+ return Qnil; \
46
+ }
47
+
48
+ #define DEF_NARRAY_ROBJ_S_CAST_METHOD_FUNC() \
49
+ DEF_CAST_ARRAY_FUNC(robject, numo_cRObject) \
50
+ static VALUE robject_s_cast(VALUE type, VALUE obj) { \
51
+ if (rb_obj_class(obj) == numo_cRObject) { \
52
+ return obj; \
53
+ } \
54
+ if (RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) { \
55
+ robject x = m_num_to_data(obj); \
56
+ return robject_new_dim0(x); \
57
+ } \
58
+ if (RTEST(rb_obj_is_kind_of(obj, rb_cArray))) { \
59
+ return robject_cast_array(obj); \
60
+ } \
61
+ if (IsNArray(obj)) { \
62
+ narray_t* na; \
63
+ GetNArray(obj, na); \
64
+ VALUE v = nary_new(numo_cRObject, NA_NDIM(na), NA_SHAPE(na)); \
65
+ if (NA_SIZE(na) > 0) { \
66
+ robject_store(v, obj); \
67
+ } \
68
+ return v; \
69
+ } \
70
+ if (rb_respond_to(obj, id_to_a)) { \
71
+ obj = rb_funcall(obj, id_to_a, 0); \
72
+ if (TYPE(obj) != T_ARRAY) { \
73
+ rb_raise(rb_eTypeError, "`to_a' did not return Array"); \
74
+ } \
75
+ return robject_cast_array(obj); \
76
+ } \
77
+ return robject_new_dim0(obj); \
78
+ }
79
+
80
+ #endif /* NUMO_NARRAY_MH_S_CAST_H */