numo-narray-alt 0.9.13 → 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 +4 -4
- data/Gemfile +1 -1
- data/ext/numo/narray/array.c +1 -9
- data/ext/numo/narray/extconf.rb +0 -11
- data/ext/numo/narray/index.c +5 -39
- data/ext/numo/narray/math.c +0 -5
- data/ext/numo/narray/narray.c +13 -19
- data/ext/numo/narray/numo/narray.h +6 -8
- data/ext/numo/narray/src/mh/abs.h +56 -0
- data/ext/numo/narray/src/mh/aref.h +28 -0
- data/ext/numo/narray/src/mh/arg.h +56 -0
- data/ext/numo/narray/src/mh/aset.h +169 -0
- data/ext/numo/narray/src/mh/conj.h +71 -0
- data/ext/numo/narray/src/mh/copysign.h +97 -0
- data/ext/numo/narray/src/mh/each.h +71 -0
- data/ext/numo/narray/src/mh/each_with_index.h +98 -0
- data/ext/numo/narray/src/mh/extract.h +36 -0
- data/ext/numo/narray/src/mh/im.h +71 -0
- data/ext/numo/narray/src/mh/imag.h +56 -0
- data/ext/numo/narray/src/mh/kahan_sum.h +39 -0
- data/ext/numo/narray/src/mh/map.h +126 -0
- data/ext/numo/narray/src/mh/map_with_index.h +76 -0
- data/ext/numo/narray/src/mh/median.h +85 -0
- data/ext/numo/narray/src/mh/modf.h +35 -0
- data/ext/numo/narray/src/mh/poly.h +42 -0
- data/ext/numo/narray/src/mh/real.h +56 -0
- data/ext/numo/narray/src/mh/s_cast.h +80 -0
- data/ext/numo/narray/src/mh/set_imag.h +60 -0
- data/ext/numo/narray/src/mh/set_real.h +60 -0
- data/ext/numo/narray/src/mh/signbit.h +42 -0
- data/ext/numo/narray/src/mh/sort.h +484 -0
- data/ext/numo/narray/src/mh/store.h +496 -0
- data/ext/numo/narray/src/t_bit.c +65 -195
- data/ext/numo/narray/src/t_dcomplex.c +244 -2216
- data/ext/numo/narray/src/t_dfloat.c +74 -2435
- data/ext/numo/narray/src/t_int16.c +225 -2015
- data/ext/numo/narray/src/t_int32.c +225 -2015
- data/ext/numo/narray/src/t_int64.c +225 -2015
- data/ext/numo/narray/src/t_int8.c +225 -1998
- data/ext/numo/narray/src/t_robject.c +114 -1413
- data/ext/numo/narray/src/t_scomplex.c +232 -2168
- data/ext/numo/narray/src/t_sfloat.c +72 -2399
- data/ext/numo/narray/src/t_uint16.c +225 -2015
- data/ext/numo/narray/src/t_uint32.c +225 -2015
- data/ext/numo/narray/src/t_uint64.c +225 -2015
- data/ext/numo/narray/src/t_uint8.c +225 -1998
- data/ext/numo/narray/step.c +2 -59
- data/numo-narray-alt.gemspec +1 -1
- metadata +27 -3
|
@@ -42,12 +42,22 @@ static ID id_to_a;
|
|
|
42
42
|
VALUE cT;
|
|
43
43
|
extern VALUE cRT;
|
|
44
44
|
|
|
45
|
+
#include "mh/store.h"
|
|
46
|
+
#include "mh/s_cast.h"
|
|
47
|
+
#include "mh/extract.h"
|
|
48
|
+
#include "mh/aref.h"
|
|
49
|
+
#include "mh/aset.h"
|
|
45
50
|
#include "mh/coerce_cast.h"
|
|
46
51
|
#include "mh/to_a.h"
|
|
47
52
|
#include "mh/fill.h"
|
|
48
53
|
#include "mh/format.h"
|
|
49
54
|
#include "mh/format_to_a.h"
|
|
50
55
|
#include "mh/inspect.h"
|
|
56
|
+
#include "mh/each.h"
|
|
57
|
+
#include "mh/map.h"
|
|
58
|
+
#include "mh/each_with_index.h"
|
|
59
|
+
#include "mh/map_with_index.h"
|
|
60
|
+
#include "mh/abs.h"
|
|
51
61
|
#include "mh/op/add.h"
|
|
52
62
|
#include "mh/op/sub.h"
|
|
53
63
|
#include "mh/op/mul.h"
|
|
@@ -64,6 +74,9 @@ extern VALUE cRT;
|
|
|
64
74
|
#include "mh/round/ceil.h"
|
|
65
75
|
#include "mh/round/trunc.h"
|
|
66
76
|
#include "mh/round/rint.h"
|
|
77
|
+
#include "mh/copysign.h"
|
|
78
|
+
#include "mh/signbit.h"
|
|
79
|
+
#include "mh/modf.h"
|
|
67
80
|
#include "mh/comp/eq.h"
|
|
68
81
|
#include "mh/comp/ne.h"
|
|
69
82
|
#include "mh/comp/nearly_eq.h"
|
|
@@ -101,6 +114,9 @@ extern VALUE cRT;
|
|
|
101
114
|
#include "mh/eye.h"
|
|
102
115
|
#include "mh/rand.h"
|
|
103
116
|
#include "mh/rand_norm.h"
|
|
117
|
+
#include "mh/poly.h"
|
|
118
|
+
#include "mh/sort.h"
|
|
119
|
+
#include "mh/median.h"
|
|
104
120
|
#include "mh/math/sqrt.h"
|
|
105
121
|
#include "mh/math/cbrt.h"
|
|
106
122
|
#include "mh/math/log.h"
|
|
@@ -133,12 +149,23 @@ extern VALUE cRT;
|
|
|
133
149
|
|
|
134
150
|
typedef float sfloat; // Type aliases for shorter notation
|
|
135
151
|
// following the codebase naming convention.
|
|
152
|
+
DEF_NARRAY_STORE_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
153
|
+
DEF_NARRAY_S_CAST_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
154
|
+
DEF_NARRAY_EXTRACT_METHOD_FUNC(sfloat)
|
|
155
|
+
DEF_NARRAY_AREF_METHOD_FUNC(sfloat)
|
|
156
|
+
DEF_EXTRACT_DATA_FUNC(sfloat, numo_cSFloat)
|
|
157
|
+
DEF_NARRAY_ASET_METHOD_FUNC(sfloat)
|
|
136
158
|
DEF_NARRAY_COERCE_CAST_METHOD_FUNC(sfloat)
|
|
137
159
|
DEF_NARRAY_TO_A_METHOD_FUNC(sfloat)
|
|
138
160
|
DEF_NARRAY_FILL_METHOD_FUNC(sfloat)
|
|
139
161
|
DEF_NARRAY_FORMAT_METHOD_FUNC(sfloat)
|
|
140
162
|
DEF_NARRAY_FORMAT_TO_A_METHOD_FUNC(sfloat)
|
|
141
163
|
DEF_NARRAY_INSPECT_METHOD_FUNC(sfloat)
|
|
164
|
+
DEF_NARRAY_EACH_METHOD_FUNC(sfloat)
|
|
165
|
+
DEF_NARRAY_MAP_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
166
|
+
DEF_NARRAY_EACH_WITH_INDEX_METHOD_FUNC(sfloat)
|
|
167
|
+
DEF_NARRAY_MAP_WITH_INDEX_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
168
|
+
DEF_NARRAY_ABS_METHOD_FUNC(sfloat, numo_cSFloat, sfloat, numo_cSFloat)
|
|
142
169
|
#ifdef __SSE2__
|
|
143
170
|
DEF_NARRAY_SFLT_ADD_SSE2_METHOD_FUNC()
|
|
144
171
|
DEF_NARRAY_SFLT_SUB_SSE2_METHOD_FUNC()
|
|
@@ -162,6 +189,9 @@ DEF_NARRAY_FLT_ROUND_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
|
162
189
|
DEF_NARRAY_FLT_CEIL_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
163
190
|
DEF_NARRAY_FLT_TRUNC_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
164
191
|
DEF_NARRAY_FLT_RINT_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
192
|
+
DEF_NARRAY_COPYSIGN_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
193
|
+
DEF_NARRAY_SIGNBIT_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
194
|
+
DEF_NARRAY_MODF_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
165
195
|
DEF_NARRAY_EQ_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
166
196
|
DEF_NARRAY_NE_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
167
197
|
DEF_NARRAY_NEARLY_EQ_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
@@ -199,6 +229,18 @@ DEF_NARRAY_FLT_LOGSEQ_METHOD_FUNC(sfloat)
|
|
|
199
229
|
DEF_NARRAY_EYE_METHOD_FUNC(sfloat)
|
|
200
230
|
DEF_NARRAY_FLT_RAND_METHOD_FUNC(sfloat)
|
|
201
231
|
DEF_NARRAY_FLT_RAND_NORM_METHOD_FUNC(sfloat)
|
|
232
|
+
DEF_NARRAY_POLY_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
233
|
+
#undef qsort_dtype
|
|
234
|
+
#define qsort_dtype sfloat
|
|
235
|
+
#undef qsort_cast
|
|
236
|
+
#define qsort_cast *(sfloat*)
|
|
237
|
+
DEF_NARRAY_FLT_SORT_METHOD_FUNC(sfloat)
|
|
238
|
+
#undef qsort_dtype
|
|
239
|
+
#define qsort_dtype *sfloat
|
|
240
|
+
#undef qsort_cast
|
|
241
|
+
#define qsort_cast **(sfloat**)
|
|
242
|
+
DEF_NARRAY_FLT_SORT_INDEX_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
243
|
+
DEF_NARRAY_FLT_MEDIAN_METHOD_FUNC(sfloat)
|
|
202
244
|
#ifdef __SSE2__
|
|
203
245
|
DEF_NARRAY_FLT_SQRT_SSE2_SGL_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
204
246
|
#else
|
|
@@ -233,8 +275,6 @@ DEF_NARRAY_FLT_EXPM1_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
|
233
275
|
DEF_NARRAY_FLT_LDEXP_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
234
276
|
DEF_NARRAY_FLT_FREXP_METHOD_FUNC(sfloat, numo_cSFloat)
|
|
235
277
|
|
|
236
|
-
static VALUE sfloat_store(VALUE, VALUE);
|
|
237
|
-
|
|
238
278
|
static size_t sfloat_memsize(const void* ptr) {
|
|
239
279
|
size_t size = sizeof(narray_data_t);
|
|
240
280
|
const narray_data_t* na = (const narray_data_t*)ptr;
|
|
@@ -336,2411 +376,44 @@ static VALUE sfloat_allocate(VALUE self) {
|
|
|
336
376
|
return self;
|
|
337
377
|
}
|
|
338
378
|
|
|
339
|
-
|
|
340
|
-
volatile VALUE v;
|
|
341
|
-
char* ptr;
|
|
342
|
-
narray_t* na;
|
|
343
|
-
GetNArray(self, na);
|
|
344
|
-
|
|
345
|
-
if (na->ndim == 0) {
|
|
346
|
-
ptr = na_get_pointer_for_read(self) + na_get_offset(self);
|
|
347
|
-
v = m_extract(ptr);
|
|
348
|
-
na_release_lock(self);
|
|
349
|
-
return v;
|
|
350
|
-
}
|
|
351
|
-
return self;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
static VALUE sfloat_new_dim0(dtype x) {
|
|
355
|
-
VALUE v;
|
|
356
|
-
dtype* ptr;
|
|
357
|
-
|
|
358
|
-
v = nary_new(cT, 0, NULL);
|
|
359
|
-
ptr = (dtype*)(char*)na_get_pointer_for_write(v);
|
|
360
|
-
*ptr = x;
|
|
361
|
-
na_release_lock(v);
|
|
362
|
-
return v;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
static VALUE sfloat_store_numeric(VALUE self, VALUE obj) {
|
|
366
|
-
dtype x;
|
|
367
|
-
x = m_num_to_data(obj);
|
|
368
|
-
obj = sfloat_new_dim0(x);
|
|
369
|
-
sfloat_store(self, obj);
|
|
370
|
-
return self;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
static void iter_sfloat_store_bit(na_loop_t* const lp) {
|
|
374
|
-
size_t i;
|
|
375
|
-
char* p1;
|
|
376
|
-
size_t p2;
|
|
377
|
-
ssize_t s1, s2;
|
|
378
|
-
size_t *idx1, *idx2;
|
|
379
|
-
BIT_DIGIT *a2, x;
|
|
380
|
-
dtype y;
|
|
381
|
-
|
|
382
|
-
INIT_COUNTER(lp, i);
|
|
383
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
384
|
-
INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2);
|
|
385
|
-
if (idx2) {
|
|
386
|
-
if (idx1) {
|
|
387
|
-
for (; i--;) {
|
|
388
|
-
LOAD_BIT(a2, p2 + *idx2, x);
|
|
389
|
-
idx2++;
|
|
390
|
-
y = m_from_sint(x);
|
|
391
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
392
|
-
}
|
|
393
|
-
} else {
|
|
394
|
-
for (; i--;) {
|
|
395
|
-
LOAD_BIT(a2, p2 + *idx2, x);
|
|
396
|
-
idx2++;
|
|
397
|
-
y = m_from_sint(x);
|
|
398
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
} else {
|
|
402
|
-
if (idx1) {
|
|
403
|
-
for (; i--;) {
|
|
404
|
-
LOAD_BIT(a2, p2, x);
|
|
405
|
-
p2 += s2;
|
|
406
|
-
y = m_from_sint(x);
|
|
407
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
408
|
-
}
|
|
409
|
-
} else {
|
|
410
|
-
for (; i--;) {
|
|
411
|
-
LOAD_BIT(a2, p2, x);
|
|
412
|
-
p2 += s2;
|
|
413
|
-
y = m_from_sint(x);
|
|
414
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
static VALUE sfloat_store_bit(VALUE self, VALUE obj) {
|
|
421
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
422
|
-
ndfunc_t ndf = { iter_sfloat_store_bit, FULL_LOOP, 2, 0, ain, 0 };
|
|
423
|
-
|
|
424
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
425
|
-
return self;
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
static void iter_sfloat_store_dfloat(na_loop_t* const lp) {
|
|
429
|
-
size_t i, s1, s2;
|
|
430
|
-
char *p1, *p2;
|
|
431
|
-
size_t *idx1, *idx2;
|
|
432
|
-
double x;
|
|
433
|
-
dtype y;
|
|
434
|
-
|
|
435
|
-
INIT_COUNTER(lp, i);
|
|
436
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
437
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
438
|
-
if (idx2) {
|
|
439
|
-
if (idx1) {
|
|
440
|
-
for (; i--;) {
|
|
441
|
-
GET_DATA_INDEX(p2, idx2, double, x);
|
|
442
|
-
y = m_from_real(x);
|
|
443
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
444
|
-
}
|
|
445
|
-
} else {
|
|
446
|
-
for (; i--;) {
|
|
447
|
-
GET_DATA_INDEX(p2, idx2, double, x);
|
|
448
|
-
y = m_from_real(x);
|
|
449
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
} else {
|
|
453
|
-
if (idx1) {
|
|
454
|
-
for (; i--;) {
|
|
455
|
-
GET_DATA_STRIDE(p2, s2, double, x);
|
|
456
|
-
y = m_from_real(x);
|
|
457
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
458
|
-
}
|
|
459
|
-
} else {
|
|
460
|
-
for (; i--;) {
|
|
461
|
-
GET_DATA_STRIDE(p2, s2, double, x);
|
|
462
|
-
y = m_from_real(x);
|
|
463
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
static VALUE sfloat_store_dfloat(VALUE self, VALUE obj) {
|
|
470
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
471
|
-
ndfunc_t ndf = { iter_sfloat_store_dfloat, FULL_LOOP, 2, 0, ain, 0 };
|
|
472
|
-
|
|
473
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
474
|
-
return self;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
static void iter_sfloat_store_sfloat(na_loop_t* const lp) {
|
|
478
|
-
size_t i, s1, s2;
|
|
479
|
-
char *p1, *p2;
|
|
480
|
-
size_t *idx1, *idx2;
|
|
481
|
-
float x;
|
|
482
|
-
dtype y;
|
|
483
|
-
|
|
484
|
-
INIT_COUNTER(lp, i);
|
|
485
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
486
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
487
|
-
if (idx2) {
|
|
488
|
-
if (idx1) {
|
|
489
|
-
for (; i--;) {
|
|
490
|
-
GET_DATA_INDEX(p2, idx2, float, x);
|
|
491
|
-
y = m_from_real(x);
|
|
492
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
493
|
-
}
|
|
494
|
-
} else {
|
|
495
|
-
for (; i--;) {
|
|
496
|
-
GET_DATA_INDEX(p2, idx2, float, x);
|
|
497
|
-
y = m_from_real(x);
|
|
498
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
} else {
|
|
502
|
-
if (idx1) {
|
|
503
|
-
for (; i--;) {
|
|
504
|
-
GET_DATA_STRIDE(p2, s2, float, x);
|
|
505
|
-
y = m_from_real(x);
|
|
506
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
507
|
-
}
|
|
508
|
-
} else {
|
|
509
|
-
for (; i--;) {
|
|
510
|
-
GET_DATA_STRIDE(p2, s2, float, x);
|
|
511
|
-
y = m_from_real(x);
|
|
512
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
static VALUE sfloat_store_sfloat(VALUE self, VALUE obj) {
|
|
519
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
520
|
-
ndfunc_t ndf = { iter_sfloat_store_sfloat, FULL_LOOP, 2, 0, ain, 0 };
|
|
521
|
-
|
|
522
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
523
|
-
return self;
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
static void iter_sfloat_store_int64(na_loop_t* const lp) {
|
|
527
|
-
size_t i, s1, s2;
|
|
528
|
-
char *p1, *p2;
|
|
529
|
-
size_t *idx1, *idx2;
|
|
530
|
-
int64_t x;
|
|
531
|
-
dtype y;
|
|
532
|
-
|
|
533
|
-
INIT_COUNTER(lp, i);
|
|
534
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
535
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
536
|
-
if (idx2) {
|
|
537
|
-
if (idx1) {
|
|
538
|
-
for (; i--;) {
|
|
539
|
-
GET_DATA_INDEX(p2, idx2, int64_t, x);
|
|
540
|
-
y = m_from_int64(x);
|
|
541
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
542
|
-
}
|
|
543
|
-
} else {
|
|
544
|
-
for (; i--;) {
|
|
545
|
-
GET_DATA_INDEX(p2, idx2, int64_t, x);
|
|
546
|
-
y = m_from_int64(x);
|
|
547
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
} else {
|
|
551
|
-
if (idx1) {
|
|
552
|
-
for (; i--;) {
|
|
553
|
-
GET_DATA_STRIDE(p2, s2, int64_t, x);
|
|
554
|
-
y = m_from_int64(x);
|
|
555
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
556
|
-
}
|
|
557
|
-
} else {
|
|
558
|
-
for (; i--;) {
|
|
559
|
-
GET_DATA_STRIDE(p2, s2, int64_t, x);
|
|
560
|
-
y = m_from_int64(x);
|
|
561
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
static VALUE sfloat_store_int64(VALUE self, VALUE obj) {
|
|
568
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
569
|
-
ndfunc_t ndf = { iter_sfloat_store_int64, FULL_LOOP, 2, 0, ain, 0 };
|
|
570
|
-
|
|
571
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
572
|
-
return self;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
static void iter_sfloat_store_int32(na_loop_t* const lp) {
|
|
576
|
-
size_t i, s1, s2;
|
|
577
|
-
char *p1, *p2;
|
|
578
|
-
size_t *idx1, *idx2;
|
|
579
|
-
int32_t x;
|
|
580
|
-
dtype y;
|
|
581
|
-
|
|
582
|
-
INIT_COUNTER(lp, i);
|
|
583
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
584
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
585
|
-
if (idx2) {
|
|
586
|
-
if (idx1) {
|
|
587
|
-
for (; i--;) {
|
|
588
|
-
GET_DATA_INDEX(p2, idx2, int32_t, x);
|
|
589
|
-
y = m_from_int32(x);
|
|
590
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
591
|
-
}
|
|
592
|
-
} else {
|
|
593
|
-
for (; i--;) {
|
|
594
|
-
GET_DATA_INDEX(p2, idx2, int32_t, x);
|
|
595
|
-
y = m_from_int32(x);
|
|
596
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
} else {
|
|
600
|
-
if (idx1) {
|
|
601
|
-
for (; i--;) {
|
|
602
|
-
GET_DATA_STRIDE(p2, s2, int32_t, x);
|
|
603
|
-
y = m_from_int32(x);
|
|
604
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
605
|
-
}
|
|
606
|
-
} else {
|
|
607
|
-
for (; i--;) {
|
|
608
|
-
GET_DATA_STRIDE(p2, s2, int32_t, x);
|
|
609
|
-
y = m_from_int32(x);
|
|
610
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
static VALUE sfloat_store_int32(VALUE self, VALUE obj) {
|
|
617
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
618
|
-
ndfunc_t ndf = { iter_sfloat_store_int32, FULL_LOOP, 2, 0, ain, 0 };
|
|
619
|
-
|
|
620
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
621
|
-
return self;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
static void iter_sfloat_store_int16(na_loop_t* const lp) {
|
|
625
|
-
size_t i, s1, s2;
|
|
626
|
-
char *p1, *p2;
|
|
627
|
-
size_t *idx1, *idx2;
|
|
628
|
-
int16_t x;
|
|
629
|
-
dtype y;
|
|
630
|
-
|
|
631
|
-
INIT_COUNTER(lp, i);
|
|
632
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
633
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
634
|
-
if (idx2) {
|
|
635
|
-
if (idx1) {
|
|
636
|
-
for (; i--;) {
|
|
637
|
-
GET_DATA_INDEX(p2, idx2, int16_t, x);
|
|
638
|
-
y = m_from_sint(x);
|
|
639
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
640
|
-
}
|
|
641
|
-
} else {
|
|
642
|
-
for (; i--;) {
|
|
643
|
-
GET_DATA_INDEX(p2, idx2, int16_t, x);
|
|
644
|
-
y = m_from_sint(x);
|
|
645
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
} else {
|
|
649
|
-
if (idx1) {
|
|
650
|
-
for (; i--;) {
|
|
651
|
-
GET_DATA_STRIDE(p2, s2, int16_t, x);
|
|
652
|
-
y = m_from_sint(x);
|
|
653
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
654
|
-
}
|
|
655
|
-
} else {
|
|
656
|
-
for (; i--;) {
|
|
657
|
-
GET_DATA_STRIDE(p2, s2, int16_t, x);
|
|
658
|
-
y = m_from_sint(x);
|
|
659
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
660
|
-
}
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
static VALUE sfloat_store_int16(VALUE self, VALUE obj) {
|
|
666
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
667
|
-
ndfunc_t ndf = { iter_sfloat_store_int16, FULL_LOOP, 2, 0, ain, 0 };
|
|
668
|
-
|
|
669
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
670
|
-
return self;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
static void iter_sfloat_store_int8(na_loop_t* const lp) {
|
|
674
|
-
size_t i, s1, s2;
|
|
675
|
-
char *p1, *p2;
|
|
676
|
-
size_t *idx1, *idx2;
|
|
677
|
-
int8_t x;
|
|
678
|
-
dtype y;
|
|
679
|
-
|
|
680
|
-
INIT_COUNTER(lp, i);
|
|
681
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
682
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
683
|
-
if (idx2) {
|
|
684
|
-
if (idx1) {
|
|
685
|
-
for (; i--;) {
|
|
686
|
-
GET_DATA_INDEX(p2, idx2, int8_t, x);
|
|
687
|
-
y = m_from_sint(x);
|
|
688
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
689
|
-
}
|
|
690
|
-
} else {
|
|
691
|
-
for (; i--;) {
|
|
692
|
-
GET_DATA_INDEX(p2, idx2, int8_t, x);
|
|
693
|
-
y = m_from_sint(x);
|
|
694
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
} else {
|
|
698
|
-
if (idx1) {
|
|
699
|
-
for (; i--;) {
|
|
700
|
-
GET_DATA_STRIDE(p2, s2, int8_t, x);
|
|
701
|
-
y = m_from_sint(x);
|
|
702
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
703
|
-
}
|
|
704
|
-
} else {
|
|
705
|
-
for (; i--;) {
|
|
706
|
-
GET_DATA_STRIDE(p2, s2, int8_t, x);
|
|
707
|
-
y = m_from_sint(x);
|
|
708
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
static VALUE sfloat_store_int8(VALUE self, VALUE obj) {
|
|
715
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
716
|
-
ndfunc_t ndf = { iter_sfloat_store_int8, FULL_LOOP, 2, 0, ain, 0 };
|
|
717
|
-
|
|
718
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
719
|
-
return self;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
static void iter_sfloat_store_uint64(na_loop_t* const lp) {
|
|
723
|
-
size_t i, s1, s2;
|
|
724
|
-
char *p1, *p2;
|
|
725
|
-
size_t *idx1, *idx2;
|
|
726
|
-
u_int64_t x;
|
|
727
|
-
dtype y;
|
|
728
|
-
|
|
729
|
-
INIT_COUNTER(lp, i);
|
|
730
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
731
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
732
|
-
if (idx2) {
|
|
733
|
-
if (idx1) {
|
|
734
|
-
for (; i--;) {
|
|
735
|
-
GET_DATA_INDEX(p2, idx2, u_int64_t, x);
|
|
736
|
-
y = m_from_uint64(x);
|
|
737
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
738
|
-
}
|
|
739
|
-
} else {
|
|
740
|
-
for (; i--;) {
|
|
741
|
-
GET_DATA_INDEX(p2, idx2, u_int64_t, x);
|
|
742
|
-
y = m_from_uint64(x);
|
|
743
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
} else {
|
|
747
|
-
if (idx1) {
|
|
748
|
-
for (; i--;) {
|
|
749
|
-
GET_DATA_STRIDE(p2, s2, u_int64_t, x);
|
|
750
|
-
y = m_from_uint64(x);
|
|
751
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
752
|
-
}
|
|
753
|
-
} else {
|
|
754
|
-
for (; i--;) {
|
|
755
|
-
GET_DATA_STRIDE(p2, s2, u_int64_t, x);
|
|
756
|
-
y = m_from_uint64(x);
|
|
757
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
static VALUE sfloat_store_uint64(VALUE self, VALUE obj) {
|
|
764
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
765
|
-
ndfunc_t ndf = { iter_sfloat_store_uint64, FULL_LOOP, 2, 0, ain, 0 };
|
|
766
|
-
|
|
767
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
768
|
-
return self;
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
static void iter_sfloat_store_uint32(na_loop_t* const lp) {
|
|
772
|
-
size_t i, s1, s2;
|
|
773
|
-
char *p1, *p2;
|
|
774
|
-
size_t *idx1, *idx2;
|
|
775
|
-
u_int32_t x;
|
|
776
|
-
dtype y;
|
|
777
|
-
|
|
778
|
-
INIT_COUNTER(lp, i);
|
|
779
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
780
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
781
|
-
if (idx2) {
|
|
782
|
-
if (idx1) {
|
|
783
|
-
for (; i--;) {
|
|
784
|
-
GET_DATA_INDEX(p2, idx2, u_int32_t, x);
|
|
785
|
-
y = m_from_uint32(x);
|
|
786
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
787
|
-
}
|
|
788
|
-
} else {
|
|
789
|
-
for (; i--;) {
|
|
790
|
-
GET_DATA_INDEX(p2, idx2, u_int32_t, x);
|
|
791
|
-
y = m_from_uint32(x);
|
|
792
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
} else {
|
|
796
|
-
if (idx1) {
|
|
797
|
-
for (; i--;) {
|
|
798
|
-
GET_DATA_STRIDE(p2, s2, u_int32_t, x);
|
|
799
|
-
y = m_from_uint32(x);
|
|
800
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
801
|
-
}
|
|
802
|
-
} else {
|
|
803
|
-
for (; i--;) {
|
|
804
|
-
GET_DATA_STRIDE(p2, s2, u_int32_t, x);
|
|
805
|
-
y = m_from_uint32(x);
|
|
806
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
static VALUE sfloat_store_uint32(VALUE self, VALUE obj) {
|
|
813
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
814
|
-
ndfunc_t ndf = { iter_sfloat_store_uint32, FULL_LOOP, 2, 0, ain, 0 };
|
|
815
|
-
|
|
816
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
817
|
-
return self;
|
|
818
|
-
}
|
|
819
|
-
|
|
820
|
-
static void iter_sfloat_store_uint16(na_loop_t* const lp) {
|
|
821
|
-
size_t i, s1, s2;
|
|
822
|
-
char *p1, *p2;
|
|
823
|
-
size_t *idx1, *idx2;
|
|
824
|
-
u_int16_t x;
|
|
825
|
-
dtype y;
|
|
826
|
-
|
|
827
|
-
INIT_COUNTER(lp, i);
|
|
828
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
829
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
830
|
-
if (idx2) {
|
|
831
|
-
if (idx1) {
|
|
832
|
-
for (; i--;) {
|
|
833
|
-
GET_DATA_INDEX(p2, idx2, u_int16_t, x);
|
|
834
|
-
y = m_from_sint(x);
|
|
835
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
836
|
-
}
|
|
837
|
-
} else {
|
|
838
|
-
for (; i--;) {
|
|
839
|
-
GET_DATA_INDEX(p2, idx2, u_int16_t, x);
|
|
840
|
-
y = m_from_sint(x);
|
|
841
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
} else {
|
|
845
|
-
if (idx1) {
|
|
846
|
-
for (; i--;) {
|
|
847
|
-
GET_DATA_STRIDE(p2, s2, u_int16_t, x);
|
|
848
|
-
y = m_from_sint(x);
|
|
849
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
850
|
-
}
|
|
851
|
-
} else {
|
|
852
|
-
for (; i--;) {
|
|
853
|
-
GET_DATA_STRIDE(p2, s2, u_int16_t, x);
|
|
854
|
-
y = m_from_sint(x);
|
|
855
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
856
|
-
}
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
|
|
861
|
-
static VALUE sfloat_store_uint16(VALUE self, VALUE obj) {
|
|
862
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
863
|
-
ndfunc_t ndf = { iter_sfloat_store_uint16, FULL_LOOP, 2, 0, ain, 0 };
|
|
864
|
-
|
|
865
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
866
|
-
return self;
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
static void iter_sfloat_store_uint8(na_loop_t* const lp) {
|
|
870
|
-
size_t i, s1, s2;
|
|
871
|
-
char *p1, *p2;
|
|
872
|
-
size_t *idx1, *idx2;
|
|
873
|
-
u_int8_t x;
|
|
874
|
-
dtype y;
|
|
875
|
-
|
|
876
|
-
INIT_COUNTER(lp, i);
|
|
877
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
878
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
879
|
-
if (idx2) {
|
|
880
|
-
if (idx1) {
|
|
881
|
-
for (; i--;) {
|
|
882
|
-
GET_DATA_INDEX(p2, idx2, u_int8_t, x);
|
|
883
|
-
y = m_from_sint(x);
|
|
884
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
885
|
-
}
|
|
886
|
-
} else {
|
|
887
|
-
for (; i--;) {
|
|
888
|
-
GET_DATA_INDEX(p2, idx2, u_int8_t, x);
|
|
889
|
-
y = m_from_sint(x);
|
|
890
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
} else {
|
|
894
|
-
if (idx1) {
|
|
895
|
-
for (; i--;) {
|
|
896
|
-
GET_DATA_STRIDE(p2, s2, u_int8_t, x);
|
|
897
|
-
y = m_from_sint(x);
|
|
898
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
899
|
-
}
|
|
900
|
-
} else {
|
|
901
|
-
for (; i--;) {
|
|
902
|
-
GET_DATA_STRIDE(p2, s2, u_int8_t, x);
|
|
903
|
-
y = m_from_sint(x);
|
|
904
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
905
|
-
}
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
static VALUE sfloat_store_uint8(VALUE self, VALUE obj) {
|
|
911
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
912
|
-
ndfunc_t ndf = { iter_sfloat_store_uint8, FULL_LOOP, 2, 0, ain, 0 };
|
|
913
|
-
|
|
914
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
915
|
-
return self;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
static void iter_sfloat_store_robject(na_loop_t* const lp) {
|
|
919
|
-
size_t i, s1, s2;
|
|
920
|
-
char *p1, *p2;
|
|
921
|
-
size_t *idx1, *idx2;
|
|
922
|
-
VALUE x;
|
|
923
|
-
dtype y;
|
|
924
|
-
|
|
925
|
-
INIT_COUNTER(lp, i);
|
|
926
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
927
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
928
|
-
if (idx2) {
|
|
929
|
-
if (idx1) {
|
|
930
|
-
for (; i--;) {
|
|
931
|
-
GET_DATA_INDEX(p2, idx2, VALUE, x);
|
|
932
|
-
y = m_num_to_data(x);
|
|
933
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
934
|
-
}
|
|
935
|
-
} else {
|
|
936
|
-
for (; i--;) {
|
|
937
|
-
GET_DATA_INDEX(p2, idx2, VALUE, x);
|
|
938
|
-
y = m_num_to_data(x);
|
|
939
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
|
-
} else {
|
|
943
|
-
if (idx1) {
|
|
944
|
-
for (; i--;) {
|
|
945
|
-
GET_DATA_STRIDE(p2, s2, VALUE, x);
|
|
946
|
-
y = m_num_to_data(x);
|
|
947
|
-
SET_DATA_INDEX(p1, idx1, dtype, y);
|
|
948
|
-
}
|
|
949
|
-
} else {
|
|
950
|
-
for (; i--;) {
|
|
951
|
-
GET_DATA_STRIDE(p2, s2, VALUE, x);
|
|
952
|
-
y = m_num_to_data(x);
|
|
953
|
-
SET_DATA_STRIDE(p1, s1, dtype, y);
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
|
|
959
|
-
static VALUE sfloat_store_robject(VALUE self, VALUE obj) {
|
|
960
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
961
|
-
ndfunc_t ndf = { iter_sfloat_store_robject, FULL_LOOP, 2, 0, ain, 0 };
|
|
962
|
-
|
|
963
|
-
na_ndloop(&ndf, 2, self, obj);
|
|
964
|
-
return self;
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
static void iter_sfloat_store_array(na_loop_t* const lp) {
|
|
968
|
-
size_t i, n;
|
|
969
|
-
size_t i1, n1;
|
|
970
|
-
VALUE v1, *ptr;
|
|
971
|
-
char* p1;
|
|
972
|
-
size_t s1, *idx1;
|
|
973
|
-
VALUE x;
|
|
974
|
-
double y;
|
|
975
|
-
dtype z;
|
|
976
|
-
size_t len, c;
|
|
977
|
-
double beg, step;
|
|
978
|
-
|
|
979
|
-
INIT_COUNTER(lp, n);
|
|
980
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
981
|
-
v1 = lp->args[1].value;
|
|
982
|
-
i = 0;
|
|
983
|
-
|
|
984
|
-
if (lp->args[1].ptr) {
|
|
985
|
-
if (v1 == Qtrue) {
|
|
986
|
-
iter_sfloat_store_sfloat(lp);
|
|
987
|
-
i = lp->args[1].shape[0];
|
|
988
|
-
if (idx1) {
|
|
989
|
-
idx1 += i;
|
|
990
|
-
} else {
|
|
991
|
-
p1 += s1 * i;
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
goto loop_end;
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
ptr = &v1;
|
|
998
|
-
|
|
999
|
-
switch (TYPE(v1)) {
|
|
1000
|
-
case T_ARRAY:
|
|
1001
|
-
n1 = RARRAY_LEN(v1);
|
|
1002
|
-
ptr = RARRAY_PTR(v1);
|
|
1003
|
-
break;
|
|
1004
|
-
case T_NIL:
|
|
1005
|
-
n1 = 0;
|
|
1006
|
-
break;
|
|
1007
|
-
default:
|
|
1008
|
-
n1 = 1;
|
|
1009
|
-
}
|
|
1010
|
-
|
|
1011
|
-
if (idx1) {
|
|
1012
|
-
for (i = i1 = 0; i1 < n1 && i < n; i++, i1++) {
|
|
1013
|
-
x = ptr[i1];
|
|
1014
|
-
if (rb_obj_is_kind_of(x, rb_cRange)
|
|
1015
|
-
#ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
|
|
1016
|
-
|| rb_obj_is_kind_of(x, rb_cArithSeq)
|
|
1017
|
-
#else
|
|
1018
|
-
|| rb_obj_is_kind_of(x, rb_cEnumerator)
|
|
1019
|
-
#endif
|
|
1020
|
-
) {
|
|
1021
|
-
nary_step_sequence(x, &len, &beg, &step);
|
|
1022
|
-
for (c = 0; c < len && i < n; c++, i++) {
|
|
1023
|
-
y = beg + step * c;
|
|
1024
|
-
z = m_from_double(y);
|
|
1025
|
-
SET_DATA_INDEX(p1, idx1, dtype, z);
|
|
1026
|
-
}
|
|
1027
|
-
} else if (TYPE(x) != T_ARRAY) {
|
|
1028
|
-
z = m_num_to_data(x);
|
|
1029
|
-
SET_DATA_INDEX(p1, idx1, dtype, z);
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
} else {
|
|
1033
|
-
for (i = i1 = 0; i1 < n1 && i < n; i++, i1++) {
|
|
1034
|
-
x = ptr[i1];
|
|
1035
|
-
if (rb_obj_is_kind_of(x, rb_cRange)
|
|
1036
|
-
#ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
|
|
1037
|
-
|| rb_obj_is_kind_of(x, rb_cArithSeq)
|
|
1038
|
-
#else
|
|
1039
|
-
|| rb_obj_is_kind_of(x, rb_cEnumerator)
|
|
1040
|
-
#endif
|
|
1041
|
-
) {
|
|
1042
|
-
nary_step_sequence(x, &len, &beg, &step);
|
|
1043
|
-
for (c = 0; c < len && i < n; c++, i++) {
|
|
1044
|
-
y = beg + step * c;
|
|
1045
|
-
z = m_from_double(y);
|
|
1046
|
-
SET_DATA_STRIDE(p1, s1, dtype, z);
|
|
1047
|
-
}
|
|
1048
|
-
} else if (TYPE(x) != T_ARRAY) {
|
|
1049
|
-
z = m_num_to_data(x);
|
|
1050
|
-
SET_DATA_STRIDE(p1, s1, dtype, z);
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
loop_end:
|
|
1056
|
-
z = m_zero;
|
|
1057
|
-
if (idx1) {
|
|
1058
|
-
for (; i < n; i++) {
|
|
1059
|
-
SET_DATA_INDEX(p1, idx1, dtype, z);
|
|
1060
|
-
}
|
|
1061
|
-
} else {
|
|
1062
|
-
for (; i < n; i++) {
|
|
1063
|
-
SET_DATA_STRIDE(p1, s1, dtype, z);
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
-
|
|
1068
|
-
static VALUE sfloat_store_array(VALUE self, VALUE rary) {
|
|
1069
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { rb_cArray, 0 } };
|
|
1070
|
-
ndfunc_t ndf = { iter_sfloat_store_array, FULL_LOOP, 2, 0, ain, 0 };
|
|
1071
|
-
|
|
1072
|
-
na_ndloop_store_rarray(&ndf, self, rary);
|
|
1073
|
-
return self;
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
static VALUE sfloat_store(VALUE self, VALUE obj) {
|
|
1077
|
-
VALUE r, klass;
|
|
1078
|
-
|
|
1079
|
-
klass = rb_obj_class(obj);
|
|
1080
|
-
|
|
1081
|
-
if (klass == numo_cSFloat) {
|
|
1082
|
-
sfloat_store_sfloat(self, obj);
|
|
1083
|
-
return self;
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
if (IS_INTEGER_CLASS(klass) || klass == rb_cFloat || klass == rb_cComplex) {
|
|
1087
|
-
sfloat_store_numeric(self, obj);
|
|
1088
|
-
return self;
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
if (klass == numo_cBit) {
|
|
1092
|
-
sfloat_store_bit(self, obj);
|
|
1093
|
-
return self;
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
if (klass == numo_cDFloat) {
|
|
1097
|
-
sfloat_store_dfloat(self, obj);
|
|
1098
|
-
return self;
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
if (klass == numo_cInt64) {
|
|
1102
|
-
sfloat_store_int64(self, obj);
|
|
1103
|
-
return self;
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
if (klass == numo_cInt32) {
|
|
1107
|
-
sfloat_store_int32(self, obj);
|
|
1108
|
-
return self;
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
if (klass == numo_cInt16) {
|
|
1112
|
-
sfloat_store_int16(self, obj);
|
|
1113
|
-
return self;
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
if (klass == numo_cInt8) {
|
|
1117
|
-
sfloat_store_int8(self, obj);
|
|
1118
|
-
return self;
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
if (klass == numo_cUInt64) {
|
|
1122
|
-
sfloat_store_uint64(self, obj);
|
|
1123
|
-
return self;
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
if (klass == numo_cUInt32) {
|
|
1127
|
-
sfloat_store_uint32(self, obj);
|
|
1128
|
-
return self;
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
if (klass == numo_cUInt16) {
|
|
1132
|
-
sfloat_store_uint16(self, obj);
|
|
1133
|
-
return self;
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
if (klass == numo_cUInt8) {
|
|
1137
|
-
sfloat_store_uint8(self, obj);
|
|
1138
|
-
return self;
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
if (klass == numo_cRObject) {
|
|
1142
|
-
sfloat_store_robject(self, obj);
|
|
1143
|
-
return self;
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
if (klass == rb_cArray) {
|
|
1147
|
-
sfloat_store_array(self, obj);
|
|
1148
|
-
return self;
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
if (IsNArray(obj)) {
|
|
1152
|
-
r = rb_funcall(obj, rb_intern("coerce_cast"), 1, cT);
|
|
1153
|
-
if (rb_obj_class(r) == cT) {
|
|
1154
|
-
sfloat_store(self, r);
|
|
1155
|
-
return self;
|
|
1156
|
-
}
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
rb_raise(
|
|
1160
|
-
nary_eCastError, "unknown conversion from %s to %s", rb_class2name(rb_obj_class(obj)),
|
|
1161
|
-
rb_class2name(rb_obj_class(self))
|
|
1162
|
-
);
|
|
1163
|
-
|
|
1164
|
-
return self;
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
/*
|
|
1168
|
-
Convert a data value of obj (with a single element) to dtype.
|
|
1169
|
-
*/
|
|
1170
|
-
static dtype sfloat_extract_data(VALUE obj) {
|
|
1171
|
-
narray_t* na;
|
|
1172
|
-
dtype x;
|
|
1173
|
-
char* ptr;
|
|
1174
|
-
size_t pos;
|
|
1175
|
-
VALUE r, klass;
|
|
1176
|
-
|
|
1177
|
-
if (IsNArray(obj)) {
|
|
1178
|
-
GetNArray(obj, na);
|
|
1179
|
-
if (na->size != 1) {
|
|
1180
|
-
rb_raise(nary_eShapeError, "narray size should be 1");
|
|
1181
|
-
}
|
|
1182
|
-
klass = rb_obj_class(obj);
|
|
1183
|
-
ptr = na_get_pointer_for_read(obj);
|
|
1184
|
-
pos = na_get_offset(obj);
|
|
1185
|
-
|
|
1186
|
-
if (klass == numo_cSFloat) {
|
|
1187
|
-
x = m_from_real(*(float*)(ptr + pos));
|
|
1188
|
-
return x;
|
|
1189
|
-
}
|
|
1190
|
-
|
|
1191
|
-
if (klass == numo_cBit) {
|
|
1192
|
-
{
|
|
1193
|
-
BIT_DIGIT b;
|
|
1194
|
-
LOAD_BIT(ptr, pos, b);
|
|
1195
|
-
x = m_from_sint(b);
|
|
1196
|
-
};
|
|
1197
|
-
return x;
|
|
1198
|
-
}
|
|
1199
|
-
|
|
1200
|
-
if (klass == numo_cDFloat) {
|
|
1201
|
-
x = m_from_real(*(double*)(ptr + pos));
|
|
1202
|
-
return x;
|
|
1203
|
-
}
|
|
1204
|
-
|
|
1205
|
-
if (klass == numo_cInt64) {
|
|
1206
|
-
x = m_from_int64(*(int64_t*)(ptr + pos));
|
|
1207
|
-
return x;
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
if (klass == numo_cInt32) {
|
|
1211
|
-
x = m_from_int32(*(int32_t*)(ptr + pos));
|
|
1212
|
-
return x;
|
|
1213
|
-
}
|
|
379
|
+
VALUE mTM;
|
|
1214
380
|
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
return x;
|
|
1218
|
-
}
|
|
381
|
+
void Init_numo_sfloat(void) {
|
|
382
|
+
VALUE hCast, mNumo;
|
|
1219
383
|
|
|
1220
|
-
|
|
1221
|
-
x = m_from_sint(*(int8_t*)(ptr + pos));
|
|
1222
|
-
return x;
|
|
1223
|
-
}
|
|
384
|
+
mNumo = rb_define_module("Numo");
|
|
1224
385
|
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
386
|
+
id_pow = rb_intern("**");
|
|
387
|
+
id_cast = rb_intern("cast");
|
|
388
|
+
id_copysign = rb_intern("copysign");
|
|
389
|
+
id_divmod = rb_intern("divmod");
|
|
390
|
+
id_eq = rb_intern("eq");
|
|
391
|
+
id_ge = rb_intern("ge");
|
|
392
|
+
id_gt = rb_intern("gt");
|
|
393
|
+
id_le = rb_intern("le");
|
|
394
|
+
id_lt = rb_intern("lt");
|
|
395
|
+
id_mulsum = rb_intern("mulsum");
|
|
396
|
+
id_nan = rb_intern("nan");
|
|
397
|
+
id_ne = rb_intern("ne");
|
|
398
|
+
id_nearly_eq = rb_intern("nearly_eq");
|
|
399
|
+
id_to_a = rb_intern("to_a");
|
|
1229
400
|
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
401
|
+
/**
|
|
402
|
+
* Document-class: Numo::SFloat
|
|
403
|
+
*
|
|
404
|
+
* Single precision floating point number (32-bit float) N-dimensional array class.
|
|
405
|
+
*/
|
|
406
|
+
cT = rb_define_class_under(mNumo, "SFloat", cNArray);
|
|
1234
407
|
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
return x;
|
|
1238
|
-
}
|
|
408
|
+
// alias of SFloat
|
|
409
|
+
rb_define_const(mNumo, "Float32", numo_cSFloat);
|
|
1239
410
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
411
|
+
hCast = rb_hash_new();
|
|
412
|
+
/* Upcasting rules of SFloat. */
|
|
413
|
+
rb_define_const(cT, "UPCAST", hCast);
|
|
414
|
+
rb_hash_aset(hCast, rb_cArray, cT);
|
|
1244
415
|
|
|
1245
|
-
if (klass == numo_cRObject) {
|
|
1246
|
-
x = m_num_to_data(*(VALUE*)(ptr + pos));
|
|
1247
|
-
return x;
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
|
-
// coerce
|
|
1251
|
-
r = rb_funcall(obj, rb_intern("coerce_cast"), 1, cT);
|
|
1252
|
-
if (rb_obj_class(r) == cT) {
|
|
1253
|
-
return sfloat_extract_data(r);
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
rb_raise(
|
|
1257
|
-
nary_eCastError, "unknown conversion from %s to %s", rb_class2name(rb_obj_class(obj)),
|
|
1258
|
-
rb_class2name(cT)
|
|
1259
|
-
);
|
|
1260
|
-
}
|
|
1261
|
-
if (TYPE(obj) == T_ARRAY) {
|
|
1262
|
-
if (RARRAY_LEN(obj) != 1) {
|
|
1263
|
-
rb_raise(nary_eShapeError, "array size should be 1");
|
|
1264
|
-
}
|
|
1265
|
-
return m_num_to_data(RARRAY_AREF(obj, 0));
|
|
1266
|
-
}
|
|
1267
|
-
return m_num_to_data(obj);
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
static VALUE sfloat_cast_array(VALUE rary) {
|
|
1271
|
-
VALUE nary;
|
|
1272
|
-
narray_t* na;
|
|
1273
|
-
|
|
1274
|
-
nary = na_s_new_like(cT, rary);
|
|
1275
|
-
GetNArray(nary, na);
|
|
1276
|
-
if (na->size > 0) {
|
|
1277
|
-
sfloat_store_array(nary, rary);
|
|
1278
|
-
}
|
|
1279
|
-
return nary;
|
|
1280
|
-
}
|
|
1281
|
-
|
|
1282
|
-
static VALUE sfloat_s_cast(VALUE type, VALUE obj) {
|
|
1283
|
-
VALUE v;
|
|
1284
|
-
narray_t* na;
|
|
1285
|
-
dtype x;
|
|
1286
|
-
|
|
1287
|
-
if (rb_obj_class(obj) == cT) {
|
|
1288
|
-
return obj;
|
|
1289
|
-
}
|
|
1290
|
-
if (RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) {
|
|
1291
|
-
x = m_num_to_data(obj);
|
|
1292
|
-
return sfloat_new_dim0(x);
|
|
1293
|
-
}
|
|
1294
|
-
if (RTEST(rb_obj_is_kind_of(obj, rb_cArray))) {
|
|
1295
|
-
return sfloat_cast_array(obj);
|
|
1296
|
-
}
|
|
1297
|
-
if (IsNArray(obj)) {
|
|
1298
|
-
GetNArray(obj, na);
|
|
1299
|
-
v = nary_new(cT, NA_NDIM(na), NA_SHAPE(na));
|
|
1300
|
-
if (NA_SIZE(na) > 0) {
|
|
1301
|
-
sfloat_store(v, obj);
|
|
1302
|
-
}
|
|
1303
|
-
return v;
|
|
1304
|
-
}
|
|
1305
|
-
if (rb_respond_to(obj, id_to_a)) {
|
|
1306
|
-
obj = rb_funcall(obj, id_to_a, 0);
|
|
1307
|
-
if (TYPE(obj) != T_ARRAY) {
|
|
1308
|
-
rb_raise(rb_eTypeError, "`to_a' did not return Array");
|
|
1309
|
-
}
|
|
1310
|
-
return sfloat_cast_array(obj);
|
|
1311
|
-
}
|
|
1312
|
-
|
|
1313
|
-
rb_raise(nary_eCastError, "cannot cast to %s", rb_class2name(type));
|
|
1314
|
-
return Qnil;
|
|
1315
|
-
}
|
|
1316
|
-
|
|
1317
|
-
static VALUE sfloat_aref(int argc, VALUE* argv, VALUE self) {
|
|
1318
|
-
int nd;
|
|
1319
|
-
size_t pos;
|
|
1320
|
-
char* ptr;
|
|
1321
|
-
|
|
1322
|
-
nd = na_get_result_dimension(self, argc, argv, sizeof(dtype), &pos);
|
|
1323
|
-
if (nd) {
|
|
1324
|
-
return na_aref_main(argc, argv, self, 0, nd);
|
|
1325
|
-
} else {
|
|
1326
|
-
ptr = na_get_pointer_for_read(self) + pos;
|
|
1327
|
-
return m_extract(ptr);
|
|
1328
|
-
}
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
static VALUE sfloat_aset(int argc, VALUE* argv, VALUE self) {
|
|
1332
|
-
int nd;
|
|
1333
|
-
size_t pos;
|
|
1334
|
-
char* ptr;
|
|
1335
|
-
VALUE a;
|
|
1336
|
-
dtype x;
|
|
1337
|
-
|
|
1338
|
-
argc--;
|
|
1339
|
-
if (argc == 0) {
|
|
1340
|
-
sfloat_store(self, argv[argc]);
|
|
1341
|
-
} else {
|
|
1342
|
-
nd = na_get_result_dimension(self, argc, argv, sizeof(dtype), &pos);
|
|
1343
|
-
if (nd) {
|
|
1344
|
-
a = na_aref_main(argc, argv, self, 0, nd);
|
|
1345
|
-
sfloat_store(a, argv[argc]);
|
|
1346
|
-
} else {
|
|
1347
|
-
x = sfloat_extract_data(argv[argc]);
|
|
1348
|
-
ptr = na_get_pointer_for_read_write(self) + pos;
|
|
1349
|
-
*(dtype*)ptr = x;
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
return argv[argc];
|
|
1353
|
-
}
|
|
1354
|
-
|
|
1355
|
-
static void iter_sfloat_each(na_loop_t* const lp) {
|
|
1356
|
-
size_t i, s1;
|
|
1357
|
-
char* p1;
|
|
1358
|
-
size_t* idx1;
|
|
1359
|
-
dtype x;
|
|
1360
|
-
VALUE y;
|
|
1361
|
-
|
|
1362
|
-
INIT_COUNTER(lp, i);
|
|
1363
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
1364
|
-
if (idx1) {
|
|
1365
|
-
for (; i--;) {
|
|
1366
|
-
GET_DATA_INDEX(p1, idx1, dtype, x);
|
|
1367
|
-
y = m_data_to_num(x);
|
|
1368
|
-
rb_yield(y);
|
|
1369
|
-
}
|
|
1370
|
-
} else {
|
|
1371
|
-
for (; i--;) {
|
|
1372
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1373
|
-
y = m_data_to_num(x);
|
|
1374
|
-
rb_yield(y);
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
}
|
|
1378
|
-
|
|
1379
|
-
static VALUE sfloat_each(VALUE self) {
|
|
1380
|
-
ndfunc_arg_in_t ain[1] = { { Qnil, 0 } };
|
|
1381
|
-
ndfunc_t ndf = { iter_sfloat_each, FULL_LOOP_NIP, 1, 0, ain, 0 };
|
|
1382
|
-
|
|
1383
|
-
na_ndloop(&ndf, 1, self);
|
|
1384
|
-
return self;
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
static void iter_sfloat_map(na_loop_t* const lp) {
|
|
1388
|
-
size_t i, n;
|
|
1389
|
-
char *p1, *p2;
|
|
1390
|
-
ssize_t s1, s2;
|
|
1391
|
-
size_t *idx1, *idx2;
|
|
1392
|
-
dtype x;
|
|
1393
|
-
|
|
1394
|
-
INIT_COUNTER(lp, n);
|
|
1395
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
1396
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
1397
|
-
|
|
1398
|
-
if (idx1) {
|
|
1399
|
-
if (idx2) {
|
|
1400
|
-
for (i = 0; i < n; i++) {
|
|
1401
|
-
GET_DATA_INDEX(p1, idx1, dtype, x);
|
|
1402
|
-
x = m_map(x);
|
|
1403
|
-
SET_DATA_INDEX(p2, idx2, dtype, x);
|
|
1404
|
-
}
|
|
1405
|
-
} else {
|
|
1406
|
-
for (i = 0; i < n; i++) {
|
|
1407
|
-
GET_DATA_INDEX(p1, idx1, dtype, x);
|
|
1408
|
-
x = m_map(x);
|
|
1409
|
-
SET_DATA_STRIDE(p2, s2, dtype, x);
|
|
1410
|
-
}
|
|
1411
|
-
}
|
|
1412
|
-
} else {
|
|
1413
|
-
if (idx2) {
|
|
1414
|
-
for (i = 0; i < n; i++) {
|
|
1415
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1416
|
-
x = m_map(x);
|
|
1417
|
-
SET_DATA_INDEX(p2, idx2, dtype, x);
|
|
1418
|
-
}
|
|
1419
|
-
} else {
|
|
1420
|
-
//
|
|
1421
|
-
if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype))) {
|
|
1422
|
-
if (s1 == sizeof(dtype) && s2 == sizeof(dtype)) {
|
|
1423
|
-
for (i = 0; i < n; i++) {
|
|
1424
|
-
((dtype*)p2)[i] = m_map(((dtype*)p1)[i]);
|
|
1425
|
-
}
|
|
1426
|
-
return;
|
|
1427
|
-
}
|
|
1428
|
-
if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype))) {
|
|
1429
|
-
//
|
|
1430
|
-
for (i = 0; i < n; i++) {
|
|
1431
|
-
*(dtype*)p2 = m_map(*(dtype*)p1);
|
|
1432
|
-
p1 += s1;
|
|
1433
|
-
p2 += s2;
|
|
1434
|
-
}
|
|
1435
|
-
return;
|
|
1436
|
-
//
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
for (i = 0; i < n; i++) {
|
|
1440
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1441
|
-
x = m_map(x);
|
|
1442
|
-
SET_DATA_STRIDE(p2, s2, dtype, x);
|
|
1443
|
-
}
|
|
1444
|
-
//
|
|
1445
|
-
}
|
|
1446
|
-
}
|
|
1447
|
-
}
|
|
1448
|
-
|
|
1449
|
-
static VALUE sfloat_map(VALUE self) {
|
|
1450
|
-
ndfunc_arg_in_t ain[1] = { { cT, 0 } };
|
|
1451
|
-
ndfunc_arg_out_t aout[1] = { { cT, 0 } };
|
|
1452
|
-
ndfunc_t ndf = { iter_sfloat_map, FULL_LOOP, 1, 1, ain, aout };
|
|
1453
|
-
|
|
1454
|
-
return na_ndloop(&ndf, 1, self);
|
|
1455
|
-
}
|
|
1456
|
-
|
|
1457
|
-
static inline void yield_each_with_index(dtype x, size_t* c, VALUE* a, int nd, int md) {
|
|
1458
|
-
int j;
|
|
1459
|
-
|
|
1460
|
-
a[0] = m_data_to_num(x);
|
|
1461
|
-
for (j = 0; j <= nd; j++) {
|
|
1462
|
-
a[j + 1] = SIZET2NUM(c[j]);
|
|
1463
|
-
}
|
|
1464
|
-
rb_yield(rb_ary_new4(md, a));
|
|
1465
|
-
}
|
|
1466
|
-
|
|
1467
|
-
static void iter_sfloat_each_with_index(na_loop_t* const lp) {
|
|
1468
|
-
size_t i, s1;
|
|
1469
|
-
char* p1;
|
|
1470
|
-
size_t* idx1;
|
|
1471
|
-
dtype x;
|
|
1472
|
-
VALUE* a;
|
|
1473
|
-
size_t* c;
|
|
1474
|
-
int nd, md;
|
|
1475
|
-
|
|
1476
|
-
c = (size_t*)(lp->opt_ptr);
|
|
1477
|
-
nd = lp->ndim;
|
|
1478
|
-
if (nd > 0) {
|
|
1479
|
-
nd--;
|
|
1480
|
-
}
|
|
1481
|
-
md = nd + 2;
|
|
1482
|
-
a = ALLOCA_N(VALUE, md);
|
|
1483
|
-
|
|
1484
|
-
INIT_COUNTER(lp, i);
|
|
1485
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
1486
|
-
c[nd] = 0;
|
|
1487
|
-
if (idx1) {
|
|
1488
|
-
for (; i--;) {
|
|
1489
|
-
GET_DATA_INDEX(p1, idx1, dtype, x);
|
|
1490
|
-
yield_each_with_index(x, c, a, nd, md);
|
|
1491
|
-
c[nd]++;
|
|
1492
|
-
}
|
|
1493
|
-
} else {
|
|
1494
|
-
for (; i--;) {
|
|
1495
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1496
|
-
yield_each_with_index(x, c, a, nd, md);
|
|
1497
|
-
c[nd]++;
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
static VALUE sfloat_each_with_index(VALUE self) {
|
|
1503
|
-
ndfunc_arg_in_t ain[1] = { { Qnil, 0 } };
|
|
1504
|
-
ndfunc_t ndf = { iter_sfloat_each_with_index, FULL_LOOP_NIP, 1, 0, ain, 0 };
|
|
1505
|
-
|
|
1506
|
-
na_ndloop_with_index(&ndf, 1, self);
|
|
1507
|
-
return self;
|
|
1508
|
-
}
|
|
1509
|
-
|
|
1510
|
-
static inline dtype yield_map_with_index(dtype x, size_t* c, VALUE* a, int nd, int md) {
|
|
1511
|
-
int j;
|
|
1512
|
-
VALUE y;
|
|
1513
|
-
|
|
1514
|
-
a[0] = m_data_to_num(x);
|
|
1515
|
-
for (j = 0; j <= nd; j++) {
|
|
1516
|
-
a[j + 1] = SIZET2NUM(c[j]);
|
|
1517
|
-
}
|
|
1518
|
-
y = rb_yield(rb_ary_new4(md, a));
|
|
1519
|
-
return m_num_to_data(y);
|
|
1520
|
-
}
|
|
1521
|
-
|
|
1522
|
-
static void iter_sfloat_map_with_index(na_loop_t* const lp) {
|
|
1523
|
-
size_t i;
|
|
1524
|
-
char *p1, *p2;
|
|
1525
|
-
ssize_t s1, s2;
|
|
1526
|
-
size_t *idx1, *idx2;
|
|
1527
|
-
dtype x;
|
|
1528
|
-
VALUE* a;
|
|
1529
|
-
size_t* c;
|
|
1530
|
-
int nd, md;
|
|
1531
|
-
|
|
1532
|
-
c = (size_t*)(lp->opt_ptr);
|
|
1533
|
-
nd = lp->ndim;
|
|
1534
|
-
if (nd > 0) {
|
|
1535
|
-
nd--;
|
|
1536
|
-
}
|
|
1537
|
-
md = nd + 2;
|
|
1538
|
-
a = ALLOCA_N(VALUE, md);
|
|
1539
|
-
|
|
1540
|
-
INIT_COUNTER(lp, i);
|
|
1541
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
1542
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
1543
|
-
|
|
1544
|
-
c[nd] = 0;
|
|
1545
|
-
if (idx1) {
|
|
1546
|
-
if (idx2) {
|
|
1547
|
-
for (; i--;) {
|
|
1548
|
-
GET_DATA_INDEX(p1, idx1, dtype, x);
|
|
1549
|
-
x = yield_map_with_index(x, c, a, nd, md);
|
|
1550
|
-
SET_DATA_INDEX(p2, idx2, dtype, x);
|
|
1551
|
-
c[nd]++;
|
|
1552
|
-
}
|
|
1553
|
-
} else {
|
|
1554
|
-
for (; i--;) {
|
|
1555
|
-
GET_DATA_INDEX(p1, idx1, dtype, x);
|
|
1556
|
-
x = yield_map_with_index(x, c, a, nd, md);
|
|
1557
|
-
SET_DATA_STRIDE(p2, s2, dtype, x);
|
|
1558
|
-
c[nd]++;
|
|
1559
|
-
}
|
|
1560
|
-
}
|
|
1561
|
-
} else {
|
|
1562
|
-
if (idx2) {
|
|
1563
|
-
for (; i--;) {
|
|
1564
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1565
|
-
x = yield_map_with_index(x, c, a, nd, md);
|
|
1566
|
-
SET_DATA_INDEX(p2, idx2, dtype, x);
|
|
1567
|
-
c[nd]++;
|
|
1568
|
-
}
|
|
1569
|
-
} else {
|
|
1570
|
-
for (; i--;) {
|
|
1571
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1572
|
-
x = yield_map_with_index(x, c, a, nd, md);
|
|
1573
|
-
SET_DATA_STRIDE(p2, s2, dtype, x);
|
|
1574
|
-
c[nd]++;
|
|
1575
|
-
}
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
static VALUE sfloat_map_with_index(VALUE self) {
|
|
1581
|
-
ndfunc_arg_in_t ain[1] = { { Qnil, 0 } };
|
|
1582
|
-
ndfunc_arg_out_t aout[1] = { { cT, 0 } };
|
|
1583
|
-
ndfunc_t ndf = { iter_sfloat_map_with_index, FULL_LOOP, 1, 1, ain, aout };
|
|
1584
|
-
|
|
1585
|
-
return na_ndloop_with_index(&ndf, 1, self);
|
|
1586
|
-
}
|
|
1587
|
-
|
|
1588
|
-
static void iter_sfloat_abs(na_loop_t* const lp) {
|
|
1589
|
-
size_t i;
|
|
1590
|
-
char *p1, *p2;
|
|
1591
|
-
ssize_t s1, s2;
|
|
1592
|
-
size_t *idx1, *idx2;
|
|
1593
|
-
dtype x;
|
|
1594
|
-
rtype y;
|
|
1595
|
-
INIT_COUNTER(lp, i);
|
|
1596
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
1597
|
-
INIT_PTR_IDX(lp, 1, p2, s2, idx2);
|
|
1598
|
-
if (idx1) {
|
|
1599
|
-
if (idx2) {
|
|
1600
|
-
for (; i--;) {
|
|
1601
|
-
GET_DATA_INDEX(p1, idx1, dtype, x);
|
|
1602
|
-
y = m_abs(x);
|
|
1603
|
-
SET_DATA_INDEX(p2, idx2, rtype, y);
|
|
1604
|
-
}
|
|
1605
|
-
} else {
|
|
1606
|
-
for (; i--;) {
|
|
1607
|
-
GET_DATA_INDEX(p1, idx1, dtype, x);
|
|
1608
|
-
y = m_abs(x);
|
|
1609
|
-
SET_DATA_STRIDE(p2, s2, rtype, y);
|
|
1610
|
-
}
|
|
1611
|
-
}
|
|
1612
|
-
} else {
|
|
1613
|
-
if (idx2) {
|
|
1614
|
-
for (; i--;) {
|
|
1615
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1616
|
-
y = m_abs(x);
|
|
1617
|
-
SET_DATA_INDEX(p2, idx2, rtype, y);
|
|
1618
|
-
}
|
|
1619
|
-
} else {
|
|
1620
|
-
for (; i--;) {
|
|
1621
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1622
|
-
y = m_abs(x);
|
|
1623
|
-
SET_DATA_STRIDE(p2, s2, rtype, y);
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1626
|
-
}
|
|
1627
|
-
}
|
|
1628
|
-
|
|
1629
|
-
static VALUE sfloat_abs(VALUE self) {
|
|
1630
|
-
ndfunc_arg_in_t ain[1] = { { cT, 0 } };
|
|
1631
|
-
ndfunc_arg_out_t aout[1] = { { cRT, 0 } };
|
|
1632
|
-
ndfunc_t ndf = { iter_sfloat_abs, FULL_LOOP, 1, 1, ain, aout };
|
|
1633
|
-
|
|
1634
|
-
return na_ndloop(&ndf, 1, self);
|
|
1635
|
-
}
|
|
1636
|
-
|
|
1637
|
-
#define check_intdivzero(y) \
|
|
1638
|
-
{}
|
|
1639
|
-
|
|
1640
|
-
static void iter_sfloat_copysign(na_loop_t* const lp) {
|
|
1641
|
-
size_t i = 0;
|
|
1642
|
-
size_t n;
|
|
1643
|
-
char *p1, *p2, *p3;
|
|
1644
|
-
ssize_t s1, s2, s3;
|
|
1645
|
-
|
|
1646
|
-
INIT_COUNTER(lp, n);
|
|
1647
|
-
INIT_PTR(lp, 0, p1, s1);
|
|
1648
|
-
INIT_PTR(lp, 1, p2, s2);
|
|
1649
|
-
INIT_PTR(lp, 2, p3, s3);
|
|
1650
|
-
|
|
1651
|
-
//
|
|
1652
|
-
if (is_aligned(p1, sizeof(dtype)) && is_aligned(p2, sizeof(dtype)) &&
|
|
1653
|
-
is_aligned(p3, sizeof(dtype))) {
|
|
1654
|
-
|
|
1655
|
-
if (s1 == sizeof(dtype) && s2 == sizeof(dtype) && s3 == sizeof(dtype)) {
|
|
1656
|
-
if (p1 == p3) { // inplace case
|
|
1657
|
-
for (; i < n; i++) {
|
|
1658
|
-
check_intdivzero(((dtype*)p2)[i]);
|
|
1659
|
-
((dtype*)p1)[i] = m_copysign(((dtype*)p1)[i], ((dtype*)p2)[i]);
|
|
1660
|
-
}
|
|
1661
|
-
} else {
|
|
1662
|
-
for (; i < n; i++) {
|
|
1663
|
-
check_intdivzero(((dtype*)p2)[i]);
|
|
1664
|
-
((dtype*)p3)[i] = m_copysign(((dtype*)p1)[i], ((dtype*)p2)[i]);
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
return;
|
|
1668
|
-
}
|
|
1669
|
-
|
|
1670
|
-
if (is_aligned_step(s1, sizeof(dtype)) && is_aligned_step(s2, sizeof(dtype)) &&
|
|
1671
|
-
is_aligned_step(s3, sizeof(dtype))) {
|
|
1672
|
-
//
|
|
1673
|
-
|
|
1674
|
-
if (s2 == 0) { // Broadcasting from scalar value.
|
|
1675
|
-
check_intdivzero(*(dtype*)p2);
|
|
1676
|
-
if (s1 == sizeof(dtype) && s3 == sizeof(dtype)) {
|
|
1677
|
-
if (p1 == p3) { // inplace case
|
|
1678
|
-
for (; i < n; i++) {
|
|
1679
|
-
((dtype*)p1)[i] = m_copysign(((dtype*)p1)[i], *(dtype*)p2);
|
|
1680
|
-
}
|
|
1681
|
-
} else {
|
|
1682
|
-
for (; i < n; i++) {
|
|
1683
|
-
((dtype*)p3)[i] = m_copysign(((dtype*)p1)[i], *(dtype*)p2);
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
} else {
|
|
1687
|
-
for (i = 0; i < n; i++) {
|
|
1688
|
-
*(dtype*)p3 = m_copysign(*(dtype*)p1, *(dtype*)p2);
|
|
1689
|
-
p1 += s1;
|
|
1690
|
-
p3 += s3;
|
|
1691
|
-
}
|
|
1692
|
-
}
|
|
1693
|
-
} else {
|
|
1694
|
-
if (p1 == p3) { // inplace case
|
|
1695
|
-
for (i = 0; i < n; i++) {
|
|
1696
|
-
check_intdivzero(*(dtype*)p2);
|
|
1697
|
-
*(dtype*)p1 = m_copysign(*(dtype*)p1, *(dtype*)p2);
|
|
1698
|
-
p1 += s1;
|
|
1699
|
-
p2 += s2;
|
|
1700
|
-
}
|
|
1701
|
-
} else {
|
|
1702
|
-
for (i = 0; i < n; i++) {
|
|
1703
|
-
check_intdivzero(*(dtype*)p2);
|
|
1704
|
-
*(dtype*)p3 = m_copysign(*(dtype*)p1, *(dtype*)p2);
|
|
1705
|
-
p1 += s1;
|
|
1706
|
-
p2 += s2;
|
|
1707
|
-
p3 += s3;
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
}
|
|
1711
|
-
|
|
1712
|
-
return;
|
|
1713
|
-
//
|
|
1714
|
-
}
|
|
1715
|
-
}
|
|
1716
|
-
for (i = 0; i < n; i++) {
|
|
1717
|
-
dtype x, y, z;
|
|
1718
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1719
|
-
GET_DATA_STRIDE(p2, s2, dtype, y);
|
|
1720
|
-
check_intdivzero(y);
|
|
1721
|
-
z = m_copysign(x, y);
|
|
1722
|
-
SET_DATA_STRIDE(p3, s3, dtype, z);
|
|
1723
|
-
}
|
|
1724
|
-
//
|
|
1725
|
-
}
|
|
1726
|
-
#undef check_intdivzero
|
|
1727
|
-
|
|
1728
|
-
static VALUE sfloat_copysign_self(VALUE self, VALUE other) {
|
|
1729
|
-
ndfunc_arg_in_t ain[2] = { { cT, 0 }, { cT, 0 } };
|
|
1730
|
-
ndfunc_arg_out_t aout[1] = { { cT, 0 } };
|
|
1731
|
-
ndfunc_t ndf = { iter_sfloat_copysign, STRIDE_LOOP, 2, 1, ain, aout };
|
|
1732
|
-
|
|
1733
|
-
return na_ndloop(&ndf, 2, self, other);
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
|
-
static VALUE sfloat_copysign(VALUE self, VALUE other) {
|
|
1737
|
-
|
|
1738
|
-
VALUE klass, v;
|
|
1739
|
-
|
|
1740
|
-
klass = na_upcast(rb_obj_class(self), rb_obj_class(other));
|
|
1741
|
-
if (klass == cT) {
|
|
1742
|
-
return sfloat_copysign_self(self, other);
|
|
1743
|
-
} else {
|
|
1744
|
-
v = rb_funcall(klass, id_cast, 1, self);
|
|
1745
|
-
return rb_funcall(v, id_copysign, 1, other);
|
|
1746
|
-
}
|
|
1747
|
-
}
|
|
1748
|
-
|
|
1749
|
-
static void iter_sfloat_signbit(na_loop_t* const lp) {
|
|
1750
|
-
size_t i;
|
|
1751
|
-
char* p1;
|
|
1752
|
-
BIT_DIGIT* a2;
|
|
1753
|
-
size_t p2;
|
|
1754
|
-
ssize_t s1, s2;
|
|
1755
|
-
size_t* idx1;
|
|
1756
|
-
dtype x;
|
|
1757
|
-
BIT_DIGIT b;
|
|
1758
|
-
INIT_COUNTER(lp, i);
|
|
1759
|
-
INIT_PTR_IDX(lp, 0, p1, s1, idx1);
|
|
1760
|
-
INIT_PTR_BIT(lp, 1, a2, p2, s2);
|
|
1761
|
-
if (idx1) {
|
|
1762
|
-
for (; i--;) {
|
|
1763
|
-
GET_DATA_INDEX(p1, idx1, dtype, x);
|
|
1764
|
-
b = (m_signbit(x)) ? 1 : 0;
|
|
1765
|
-
STORE_BIT(a2, p2, b);
|
|
1766
|
-
p2 += s2;
|
|
1767
|
-
}
|
|
1768
|
-
} else {
|
|
1769
|
-
for (; i--;) {
|
|
1770
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1771
|
-
b = (m_signbit(x)) ? 1 : 0;
|
|
1772
|
-
STORE_BIT(a2, p2, b);
|
|
1773
|
-
p2 += s2;
|
|
1774
|
-
}
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
|
|
1778
|
-
static VALUE sfloat_signbit(VALUE self) {
|
|
1779
|
-
ndfunc_arg_in_t ain[1] = { { cT, 0 } };
|
|
1780
|
-
ndfunc_arg_out_t aout[1] = { { numo_cBit, 0 } };
|
|
1781
|
-
ndfunc_t ndf = { iter_sfloat_signbit, FULL_LOOP, 1, 1, ain, aout };
|
|
1782
|
-
|
|
1783
|
-
return na_ndloop(&ndf, 1, self);
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
static void iter_sfloat_modf(na_loop_t* const lp) {
|
|
1787
|
-
size_t i;
|
|
1788
|
-
char *p1, *p2, *p3;
|
|
1789
|
-
ssize_t s1, s2, s3;
|
|
1790
|
-
dtype x, y, z;
|
|
1791
|
-
INIT_COUNTER(lp, i);
|
|
1792
|
-
INIT_PTR(lp, 0, p1, s1);
|
|
1793
|
-
INIT_PTR(lp, 1, p2, s2);
|
|
1794
|
-
INIT_PTR(lp, 2, p3, s3);
|
|
1795
|
-
for (; i--;) {
|
|
1796
|
-
GET_DATA_STRIDE(p1, s1, dtype, x);
|
|
1797
|
-
m_modf(x, y, z);
|
|
1798
|
-
SET_DATA_STRIDE(p2, s2, dtype, y);
|
|
1799
|
-
SET_DATA_STRIDE(p3, s3, dtype, z);
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
|
-
static VALUE sfloat_modf(VALUE self) {
|
|
1804
|
-
ndfunc_arg_in_t ain[1] = { { cT, 0 } };
|
|
1805
|
-
ndfunc_arg_out_t aout[2] = { { cT, 0 }, { cT, 0 } };
|
|
1806
|
-
ndfunc_t ndf = { iter_sfloat_modf, STRIDE_LOOP, 1, 2, ain, aout };
|
|
1807
|
-
|
|
1808
|
-
return na_ndloop(&ndf, 1, self);
|
|
1809
|
-
}
|
|
1810
|
-
|
|
1811
|
-
static void iter_sfloat_poly(na_loop_t* const lp) {
|
|
1812
|
-
size_t i;
|
|
1813
|
-
dtype x, y, a;
|
|
1814
|
-
|
|
1815
|
-
x = *(dtype*)(lp->args[0].ptr + lp->args[0].iter[0].pos);
|
|
1816
|
-
i = lp->narg - 2;
|
|
1817
|
-
y = *(dtype*)(lp->args[i].ptr + lp->args[i].iter[0].pos);
|
|
1818
|
-
for (; --i;) {
|
|
1819
|
-
y = m_mul(x, y);
|
|
1820
|
-
a = *(dtype*)(lp->args[i].ptr + lp->args[i].iter[0].pos);
|
|
1821
|
-
y = m_add(y, a);
|
|
1822
|
-
}
|
|
1823
|
-
i = lp->narg - 1;
|
|
1824
|
-
*(dtype*)(lp->args[i].ptr + lp->args[i].iter[0].pos) = y;
|
|
1825
|
-
}
|
|
1826
|
-
|
|
1827
|
-
static VALUE sfloat_poly(VALUE self, VALUE args) {
|
|
1828
|
-
int argc, i;
|
|
1829
|
-
VALUE* argv;
|
|
1830
|
-
volatile VALUE v, a;
|
|
1831
|
-
ndfunc_arg_out_t aout[1] = { { cT, 0 } };
|
|
1832
|
-
ndfunc_t ndf = { iter_sfloat_poly, NO_LOOP, 0, 1, 0, aout };
|
|
1833
|
-
|
|
1834
|
-
argc = (int)RARRAY_LEN(args);
|
|
1835
|
-
ndf.nin = argc + 1;
|
|
1836
|
-
ndf.ain = ALLOCA_N(ndfunc_arg_in_t, argc + 1);
|
|
1837
|
-
for (i = 0; i < argc + 1; i++) {
|
|
1838
|
-
ndf.ain[i].type = cT;
|
|
1839
|
-
}
|
|
1840
|
-
argv = ALLOCA_N(VALUE, argc + 1);
|
|
1841
|
-
argv[0] = self;
|
|
1842
|
-
for (i = 0; i < argc; i++) {
|
|
1843
|
-
argv[i + 1] = RARRAY_PTR(args)[i];
|
|
1844
|
-
}
|
|
1845
|
-
a = rb_ary_new4(argc + 1, argv);
|
|
1846
|
-
v = na_ndloop2(&ndf, a);
|
|
1847
|
-
return sfloat_extract(v);
|
|
1848
|
-
}
|
|
1849
|
-
|
|
1850
|
-
/*
|
|
1851
|
-
qsort.c
|
|
1852
|
-
Ruby/Numo::NArray - Numerical Array class for Ruby
|
|
1853
|
-
modified by Masahiro TANAKA
|
|
1854
|
-
*/
|
|
1855
|
-
|
|
1856
|
-
/*
|
|
1857
|
-
* qsort.c: standard quicksort algorithm
|
|
1858
|
-
*
|
|
1859
|
-
* Modifications from vanilla NetBSD source:
|
|
1860
|
-
* Add do ... while() macro fix
|
|
1861
|
-
* Remove __inline, _DIAGASSERTs, __P
|
|
1862
|
-
* Remove ill-considered "swap_cnt" switch to insertion sort,
|
|
1863
|
-
* in favor of a simple check for presorted input.
|
|
1864
|
-
*
|
|
1865
|
-
* CAUTION: if you change this file, see also qsort_arg.c
|
|
1866
|
-
*
|
|
1867
|
-
* $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
|
|
1868
|
-
*/
|
|
1869
|
-
|
|
1870
|
-
/* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
|
|
1871
|
-
|
|
1872
|
-
/*-
|
|
1873
|
-
* Copyright (c) 1992, 1993
|
|
1874
|
-
* The Regents of the University of California. All rights reserved.
|
|
1875
|
-
*
|
|
1876
|
-
* Redistribution and use in source and binary forms, with or without
|
|
1877
|
-
* modification, are permitted provided that the following conditions
|
|
1878
|
-
* are met:
|
|
1879
|
-
* 1. Redistributions of source code must retain the above copyright
|
|
1880
|
-
* notice, this list of conditions and the following disclaimer.
|
|
1881
|
-
* 2. Redistributions in binary form must reproduce the above copyright
|
|
1882
|
-
* notice, this list of conditions and the following disclaimer in the
|
|
1883
|
-
* documentation and/or other materials provided with the distribution.
|
|
1884
|
-
* 3. Neither the name of the University nor the names of its contributors
|
|
1885
|
-
* may be used to endorse or promote products derived from this software
|
|
1886
|
-
* without specific prior written permission.
|
|
1887
|
-
*
|
|
1888
|
-
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
1889
|
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
1890
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
1891
|
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
1892
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
1893
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
1894
|
-
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
1895
|
-
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
1896
|
-
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
1897
|
-
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
1898
|
-
* SUCH DAMAGE.
|
|
1899
|
-
*/
|
|
1900
|
-
|
|
1901
|
-
#ifndef QSORT_INCL
|
|
1902
|
-
#define QSORT_INCL
|
|
1903
|
-
#define Min(x, y) ((x) < (y) ? (x) : (y))
|
|
1904
|
-
|
|
1905
|
-
/*
|
|
1906
|
-
* Qsort routine based on J. L. Bentley and M. D. McIlroy,
|
|
1907
|
-
* "Engineering a sort function",
|
|
1908
|
-
* Software--Practice and Experience 23 (1993) 1249-1265.
|
|
1909
|
-
* We have modified their original by adding a check for already-sorted input,
|
|
1910
|
-
* which seems to be a win per discussions on pgsql-hackers around 2006-03-21.
|
|
1911
|
-
*/
|
|
1912
|
-
#define swapcode(TYPE, parmi, parmj, n) \
|
|
1913
|
-
do { \
|
|
1914
|
-
size_t i = (n) / sizeof(TYPE); \
|
|
1915
|
-
TYPE* pi = (TYPE*)(void*)(parmi); \
|
|
1916
|
-
TYPE* pj = (TYPE*)(void*)(parmj); \
|
|
1917
|
-
do { \
|
|
1918
|
-
TYPE t = *pi; \
|
|
1919
|
-
*pi++ = *pj; \
|
|
1920
|
-
*pj++ = t; \
|
|
1921
|
-
} while (--i > 0); \
|
|
1922
|
-
} while (0)
|
|
1923
|
-
|
|
1924
|
-
#ifdef HAVE_STDINT_H
|
|
1925
|
-
#define SWAPINIT(a, es) \
|
|
1926
|
-
swaptype = (uintptr_t)(a) % sizeof(long) || (es) % sizeof(long) ? 2 \
|
|
1927
|
-
: (es) == sizeof(long) ? 0 \
|
|
1928
|
-
: 1;
|
|
1929
|
-
#else
|
|
1930
|
-
#define SWAPINIT(a, es) \
|
|
1931
|
-
swaptype = ((char*)(a) - (char*)0) % sizeof(long) || (es) % sizeof(long) ? 2 \
|
|
1932
|
-
: (es) == sizeof(long) ? 0 \
|
|
1933
|
-
: 1;
|
|
1934
|
-
#endif
|
|
1935
|
-
|
|
1936
|
-
static inline void swapfunc(char* a, char* b, size_t n, int swaptype) {
|
|
1937
|
-
if (swaptype <= 1)
|
|
1938
|
-
swapcode(long, a, b, n);
|
|
1939
|
-
else
|
|
1940
|
-
swapcode(char, a, b, n);
|
|
1941
|
-
}
|
|
1942
|
-
|
|
1943
|
-
#define swap(a, b) \
|
|
1944
|
-
if (swaptype == 0) { \
|
|
1945
|
-
long t = *(long*)(void*)(a); \
|
|
1946
|
-
*(long*)(void*)(a) = *(long*)(void*)(b); \
|
|
1947
|
-
*(long*)(void*)(b) = t; \
|
|
1948
|
-
} else \
|
|
1949
|
-
swapfunc(a, b, es, swaptype)
|
|
1950
|
-
|
|
1951
|
-
#define vecswap(a, b, n) \
|
|
1952
|
-
if ((n) > 0) swapfunc((a), (b), (size_t)(n), swaptype)
|
|
1953
|
-
|
|
1954
|
-
#define med3(a, b, c, _cmp) \
|
|
1955
|
-
(cmpgt(b, a) ? (cmpgt(c, b) ? b : (cmpgt(c, a) ? c : a)) \
|
|
1956
|
-
: (cmpgt(b, c) ? b : (cmpgt(c, a) ? a : c)))
|
|
1957
|
-
#endif
|
|
1958
|
-
|
|
1959
|
-
#undef qsort_dtype
|
|
1960
|
-
#define qsort_dtype dtype
|
|
1961
|
-
#undef qsort_cast
|
|
1962
|
-
#define qsort_cast *(dtype*)
|
|
1963
|
-
#undef cmp
|
|
1964
|
-
#define cmp(a, b) cmp_prnan(a, b)
|
|
1965
|
-
#undef cmpgt
|
|
1966
|
-
#define cmpgt(a, b) cmpgt_prnan(a, b)
|
|
1967
|
-
|
|
1968
|
-
static void sfloat_qsort_prnan(void* a, size_t n, ssize_t es) {
|
|
1969
|
-
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
|
1970
|
-
int d, r, swaptype, presorted;
|
|
1971
|
-
|
|
1972
|
-
loop:
|
|
1973
|
-
SWAPINIT(a, es);
|
|
1974
|
-
if (n < 7) {
|
|
1975
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
|
|
1976
|
-
for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
|
|
1977
|
-
return;
|
|
1978
|
-
}
|
|
1979
|
-
presorted = 1;
|
|
1980
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
|
|
1981
|
-
if (cmpgt(pm - es, pm)) {
|
|
1982
|
-
presorted = 0;
|
|
1983
|
-
break;
|
|
1984
|
-
}
|
|
1985
|
-
}
|
|
1986
|
-
if (presorted) return;
|
|
1987
|
-
pm = (char*)a + (n / 2) * es;
|
|
1988
|
-
if (n > 7) {
|
|
1989
|
-
pl = (char*)a;
|
|
1990
|
-
pn = (char*)a + (n - 1) * es;
|
|
1991
|
-
if (n > 40) {
|
|
1992
|
-
d = (int)((n / 8) * es);
|
|
1993
|
-
pl = med3(pl, pl + d, pl + 2 * d, cmp);
|
|
1994
|
-
pm = med3(pm - d, pm, pm + d, cmp);
|
|
1995
|
-
pn = med3(pn - 2 * d, pn - d, pn, cmp);
|
|
1996
|
-
}
|
|
1997
|
-
pm = med3(pl, pm, pn, cmp);
|
|
1998
|
-
}
|
|
1999
|
-
swap(a, pm);
|
|
2000
|
-
pa = pb = (char*)a + es;
|
|
2001
|
-
pc = pd = (char*)a + (n - 1) * es;
|
|
2002
|
-
for (;;) {
|
|
2003
|
-
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
|
|
2004
|
-
if (r == 0) {
|
|
2005
|
-
swap(pa, pb);
|
|
2006
|
-
pa += es;
|
|
2007
|
-
}
|
|
2008
|
-
pb += es;
|
|
2009
|
-
}
|
|
2010
|
-
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
|
|
2011
|
-
if (r == 0) {
|
|
2012
|
-
swap(pc, pd);
|
|
2013
|
-
pd -= es;
|
|
2014
|
-
}
|
|
2015
|
-
pc -= es;
|
|
2016
|
-
}
|
|
2017
|
-
if (pb > pc) break;
|
|
2018
|
-
swap(pb, pc);
|
|
2019
|
-
pb += es;
|
|
2020
|
-
pc -= es;
|
|
2021
|
-
}
|
|
2022
|
-
pn = (char*)a + n * es;
|
|
2023
|
-
r = (int)Min(pa - (char*)a, pb - pa);
|
|
2024
|
-
vecswap(a, pb - r, r);
|
|
2025
|
-
r = (int)Min(pd - pc, pn - pd - es);
|
|
2026
|
-
vecswap(pb, pn - r, r);
|
|
2027
|
-
if ((r = (int)(pb - pa)) > es) sfloat_qsort_prnan(a, r / es, es);
|
|
2028
|
-
if ((r = (int)(pd - pc)) > es) {
|
|
2029
|
-
/* Iterate rather than recurse to save stack space */
|
|
2030
|
-
a = pn - r;
|
|
2031
|
-
n = r / es;
|
|
2032
|
-
goto loop;
|
|
2033
|
-
}
|
|
2034
|
-
/* qsort(pn - r, r / es, es, cmp);*/
|
|
2035
|
-
}
|
|
2036
|
-
|
|
2037
|
-
/*
|
|
2038
|
-
qsort.c
|
|
2039
|
-
Ruby/Numo::NArray - Numerical Array class for Ruby
|
|
2040
|
-
modified by Masahiro TANAKA
|
|
2041
|
-
*/
|
|
2042
|
-
|
|
2043
|
-
/*
|
|
2044
|
-
* qsort.c: standard quicksort algorithm
|
|
2045
|
-
*
|
|
2046
|
-
* Modifications from vanilla NetBSD source:
|
|
2047
|
-
* Add do ... while() macro fix
|
|
2048
|
-
* Remove __inline, _DIAGASSERTs, __P
|
|
2049
|
-
* Remove ill-considered "swap_cnt" switch to insertion sort,
|
|
2050
|
-
* in favor of a simple check for presorted input.
|
|
2051
|
-
*
|
|
2052
|
-
* CAUTION: if you change this file, see also qsort_arg.c
|
|
2053
|
-
*
|
|
2054
|
-
* $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
|
|
2055
|
-
*/
|
|
2056
|
-
|
|
2057
|
-
/* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
|
|
2058
|
-
|
|
2059
|
-
/*-
|
|
2060
|
-
* Copyright (c) 1992, 1993
|
|
2061
|
-
* The Regents of the University of California. All rights reserved.
|
|
2062
|
-
*
|
|
2063
|
-
* Redistribution and use in source and binary forms, with or without
|
|
2064
|
-
* modification, are permitted provided that the following conditions
|
|
2065
|
-
* are met:
|
|
2066
|
-
* 1. Redistributions of source code must retain the above copyright
|
|
2067
|
-
* notice, this list of conditions and the following disclaimer.
|
|
2068
|
-
* 2. Redistributions in binary form must reproduce the above copyright
|
|
2069
|
-
* notice, this list of conditions and the following disclaimer in the
|
|
2070
|
-
* documentation and/or other materials provided with the distribution.
|
|
2071
|
-
* 3. Neither the name of the University nor the names of its contributors
|
|
2072
|
-
* may be used to endorse or promote products derived from this software
|
|
2073
|
-
* without specific prior written permission.
|
|
2074
|
-
*
|
|
2075
|
-
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
2076
|
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
2077
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
2078
|
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
2079
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
2080
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
2081
|
-
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
2082
|
-
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
2083
|
-
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
2084
|
-
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
2085
|
-
* SUCH DAMAGE.
|
|
2086
|
-
*/
|
|
2087
|
-
|
|
2088
|
-
#undef qsort_dtype
|
|
2089
|
-
#define qsort_dtype dtype
|
|
2090
|
-
#undef qsort_cast
|
|
2091
|
-
#define qsort_cast *(dtype*)
|
|
2092
|
-
#undef cmp
|
|
2093
|
-
#define cmp(a, b) cmp_ignan(a, b)
|
|
2094
|
-
#undef cmpgt
|
|
2095
|
-
#define cmpgt(a, b) cmpgt_ignan(a, b)
|
|
2096
|
-
|
|
2097
|
-
static void sfloat_qsort_ignan(void* a, size_t n, ssize_t es) {
|
|
2098
|
-
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
|
2099
|
-
int d, r, swaptype, presorted;
|
|
2100
|
-
|
|
2101
|
-
loop:
|
|
2102
|
-
SWAPINIT(a, es);
|
|
2103
|
-
if (n < 7) {
|
|
2104
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
|
|
2105
|
-
for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
|
|
2106
|
-
return;
|
|
2107
|
-
}
|
|
2108
|
-
presorted = 1;
|
|
2109
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
|
|
2110
|
-
if (cmpgt(pm - es, pm)) {
|
|
2111
|
-
presorted = 0;
|
|
2112
|
-
break;
|
|
2113
|
-
}
|
|
2114
|
-
}
|
|
2115
|
-
if (presorted) return;
|
|
2116
|
-
pm = (char*)a + (n / 2) * es;
|
|
2117
|
-
if (n > 7) {
|
|
2118
|
-
pl = (char*)a;
|
|
2119
|
-
pn = (char*)a + (n - 1) * es;
|
|
2120
|
-
if (n > 40) {
|
|
2121
|
-
d = (int)((n / 8) * es);
|
|
2122
|
-
pl = med3(pl, pl + d, pl + 2 * d, cmp);
|
|
2123
|
-
pm = med3(pm - d, pm, pm + d, cmp);
|
|
2124
|
-
pn = med3(pn - 2 * d, pn - d, pn, cmp);
|
|
2125
|
-
}
|
|
2126
|
-
pm = med3(pl, pm, pn, cmp);
|
|
2127
|
-
}
|
|
2128
|
-
swap(a, pm);
|
|
2129
|
-
pa = pb = (char*)a + es;
|
|
2130
|
-
pc = pd = (char*)a + (n - 1) * es;
|
|
2131
|
-
for (;;) {
|
|
2132
|
-
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
|
|
2133
|
-
if (r == 0) {
|
|
2134
|
-
swap(pa, pb);
|
|
2135
|
-
pa += es;
|
|
2136
|
-
}
|
|
2137
|
-
pb += es;
|
|
2138
|
-
}
|
|
2139
|
-
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
|
|
2140
|
-
if (r == 0) {
|
|
2141
|
-
swap(pc, pd);
|
|
2142
|
-
pd -= es;
|
|
2143
|
-
}
|
|
2144
|
-
pc -= es;
|
|
2145
|
-
}
|
|
2146
|
-
if (pb > pc) break;
|
|
2147
|
-
swap(pb, pc);
|
|
2148
|
-
pb += es;
|
|
2149
|
-
pc -= es;
|
|
2150
|
-
}
|
|
2151
|
-
pn = (char*)a + n * es;
|
|
2152
|
-
r = (int)Min(pa - (char*)a, pb - pa);
|
|
2153
|
-
vecswap(a, pb - r, r);
|
|
2154
|
-
r = (int)Min(pd - pc, pn - pd - es);
|
|
2155
|
-
vecswap(pb, pn - r, r);
|
|
2156
|
-
if ((r = (int)(pb - pa)) > es) sfloat_qsort_ignan(a, r / es, es);
|
|
2157
|
-
if ((r = (int)(pd - pc)) > es) {
|
|
2158
|
-
/* Iterate rather than recurse to save stack space */
|
|
2159
|
-
a = pn - r;
|
|
2160
|
-
n = r / es;
|
|
2161
|
-
goto loop;
|
|
2162
|
-
}
|
|
2163
|
-
/* qsort(pn - r, r / es, es, cmp);*/
|
|
2164
|
-
}
|
|
2165
|
-
|
|
2166
|
-
static void iter_sfloat_sort_ignan(na_loop_t* const lp) {
|
|
2167
|
-
size_t n;
|
|
2168
|
-
char* ptr;
|
|
2169
|
-
ssize_t step;
|
|
2170
|
-
|
|
2171
|
-
INIT_COUNTER(lp, n);
|
|
2172
|
-
INIT_PTR(lp, 0, ptr, step);
|
|
2173
|
-
sfloat_qsort_ignan(ptr, n, step);
|
|
2174
|
-
}
|
|
2175
|
-
static void iter_sfloat_sort_prnan(na_loop_t* const lp) {
|
|
2176
|
-
size_t n;
|
|
2177
|
-
char* ptr;
|
|
2178
|
-
ssize_t step;
|
|
2179
|
-
|
|
2180
|
-
INIT_COUNTER(lp, n);
|
|
2181
|
-
INIT_PTR(lp, 0, ptr, step);
|
|
2182
|
-
sfloat_qsort_prnan(ptr, n, step);
|
|
2183
|
-
}
|
|
2184
|
-
|
|
2185
|
-
static VALUE sfloat_sort(int argc, VALUE* argv, VALUE self) {
|
|
2186
|
-
VALUE reduce;
|
|
2187
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_reduce, 0 } };
|
|
2188
|
-
ndfunc_t ndf = { 0, NDF_HAS_LOOP | NDF_FLAT_REDUCE, 2, 0, ain, 0 };
|
|
2189
|
-
|
|
2190
|
-
if (!TEST_INPLACE(self)) {
|
|
2191
|
-
self = na_copy(self);
|
|
2192
|
-
}
|
|
2193
|
-
|
|
2194
|
-
ndf.func = iter_sfloat_sort_ignan;
|
|
2195
|
-
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_sfloat_sort_prnan);
|
|
2196
|
-
|
|
2197
|
-
na_ndloop(&ndf, 2, self, reduce);
|
|
2198
|
-
return self;
|
|
2199
|
-
}
|
|
2200
|
-
|
|
2201
|
-
/*
|
|
2202
|
-
qsort.c
|
|
2203
|
-
Ruby/Numo::NArray - Numerical Array class for Ruby
|
|
2204
|
-
modified by Masahiro TANAKA
|
|
2205
|
-
*/
|
|
2206
|
-
|
|
2207
|
-
/*
|
|
2208
|
-
* qsort.c: standard quicksort algorithm
|
|
2209
|
-
*
|
|
2210
|
-
* Modifications from vanilla NetBSD source:
|
|
2211
|
-
* Add do ... while() macro fix
|
|
2212
|
-
* Remove __inline, _DIAGASSERTs, __P
|
|
2213
|
-
* Remove ill-considered "swap_cnt" switch to insertion sort,
|
|
2214
|
-
* in favor of a simple check for presorted input.
|
|
2215
|
-
*
|
|
2216
|
-
* CAUTION: if you change this file, see also qsort_arg.c
|
|
2217
|
-
*
|
|
2218
|
-
* $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
|
|
2219
|
-
*/
|
|
2220
|
-
|
|
2221
|
-
/* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
|
|
2222
|
-
|
|
2223
|
-
/*-
|
|
2224
|
-
* Copyright (c) 1992, 1993
|
|
2225
|
-
* The Regents of the University of California. All rights reserved.
|
|
2226
|
-
*
|
|
2227
|
-
* Redistribution and use in source and binary forms, with or without
|
|
2228
|
-
* modification, are permitted provided that the following conditions
|
|
2229
|
-
* are met:
|
|
2230
|
-
* 1. Redistributions of source code must retain the above copyright
|
|
2231
|
-
* notice, this list of conditions and the following disclaimer.
|
|
2232
|
-
* 2. Redistributions in binary form must reproduce the above copyright
|
|
2233
|
-
* notice, this list of conditions and the following disclaimer in the
|
|
2234
|
-
* documentation and/or other materials provided with the distribution.
|
|
2235
|
-
* 3. Neither the name of the University nor the names of its contributors
|
|
2236
|
-
* may be used to endorse or promote products derived from this software
|
|
2237
|
-
* without specific prior written permission.
|
|
2238
|
-
*
|
|
2239
|
-
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
2240
|
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
2241
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
2242
|
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
2243
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
2244
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
2245
|
-
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
2246
|
-
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
2247
|
-
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
2248
|
-
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
2249
|
-
* SUCH DAMAGE.
|
|
2250
|
-
*/
|
|
2251
|
-
|
|
2252
|
-
#undef qsort_dtype
|
|
2253
|
-
#define qsort_dtype dtype*
|
|
2254
|
-
#undef qsort_cast
|
|
2255
|
-
#define qsort_cast **(dtype**)
|
|
2256
|
-
#undef cmp
|
|
2257
|
-
#define cmp(a, b) cmp_prnan(a, b)
|
|
2258
|
-
#undef cmpgt
|
|
2259
|
-
#define cmpgt(a, b) cmpgt_prnan(a, b)
|
|
2260
|
-
|
|
2261
|
-
static void sfloat_index_qsort_prnan(void* a, size_t n, ssize_t es) {
|
|
2262
|
-
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
|
2263
|
-
int d, r, swaptype, presorted;
|
|
2264
|
-
|
|
2265
|
-
loop:
|
|
2266
|
-
SWAPINIT(a, es);
|
|
2267
|
-
if (n < 7) {
|
|
2268
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
|
|
2269
|
-
for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
|
|
2270
|
-
return;
|
|
2271
|
-
}
|
|
2272
|
-
presorted = 1;
|
|
2273
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
|
|
2274
|
-
if (cmpgt(pm - es, pm)) {
|
|
2275
|
-
presorted = 0;
|
|
2276
|
-
break;
|
|
2277
|
-
}
|
|
2278
|
-
}
|
|
2279
|
-
if (presorted) return;
|
|
2280
|
-
pm = (char*)a + (n / 2) * es;
|
|
2281
|
-
if (n > 7) {
|
|
2282
|
-
pl = (char*)a;
|
|
2283
|
-
pn = (char*)a + (n - 1) * es;
|
|
2284
|
-
if (n > 40) {
|
|
2285
|
-
d = (int)((n / 8) * es);
|
|
2286
|
-
pl = med3(pl, pl + d, pl + 2 * d, cmp);
|
|
2287
|
-
pm = med3(pm - d, pm, pm + d, cmp);
|
|
2288
|
-
pn = med3(pn - 2 * d, pn - d, pn, cmp);
|
|
2289
|
-
}
|
|
2290
|
-
pm = med3(pl, pm, pn, cmp);
|
|
2291
|
-
}
|
|
2292
|
-
swap(a, pm);
|
|
2293
|
-
for (pa = pb = (char*)a + es, pc = pd = (char*)a + (n - 1) * es; pb <= pc;
|
|
2294
|
-
pb += es, pc -= es) {
|
|
2295
|
-
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
|
|
2296
|
-
if (r == 0) {
|
|
2297
|
-
swap(pa, pb);
|
|
2298
|
-
pa += es;
|
|
2299
|
-
}
|
|
2300
|
-
pb += es;
|
|
2301
|
-
}
|
|
2302
|
-
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
|
|
2303
|
-
if (r == 0) {
|
|
2304
|
-
swap(pc, pd);
|
|
2305
|
-
pd -= es;
|
|
2306
|
-
}
|
|
2307
|
-
pc -= es;
|
|
2308
|
-
}
|
|
2309
|
-
if (pb > pc) break;
|
|
2310
|
-
swap(pb, pc);
|
|
2311
|
-
}
|
|
2312
|
-
pn = (char*)a + n * es;
|
|
2313
|
-
r = (int)Min(pa - (char*)a, pb - pa);
|
|
2314
|
-
vecswap(a, pb - r, r);
|
|
2315
|
-
r = (int)Min(pd - pc, pn - pd - es);
|
|
2316
|
-
vecswap(pb, pn - r, r);
|
|
2317
|
-
if ((r = (int)(pb - pa)) > es) sfloat_index_qsort_prnan(a, r / es, es);
|
|
2318
|
-
if ((r = (int)(pd - pc)) > es) {
|
|
2319
|
-
/* Iterate rather than recurse to save stack space */
|
|
2320
|
-
a = pn - r;
|
|
2321
|
-
n = r / es;
|
|
2322
|
-
goto loop;
|
|
2323
|
-
}
|
|
2324
|
-
/* qsort(pn - r, r / es, es, cmp);*/
|
|
2325
|
-
}
|
|
2326
|
-
|
|
2327
|
-
/*
|
|
2328
|
-
qsort.c
|
|
2329
|
-
Ruby/Numo::NArray - Numerical Array class for Ruby
|
|
2330
|
-
modified by Masahiro TANAKA
|
|
2331
|
-
*/
|
|
2332
|
-
|
|
2333
|
-
/*
|
|
2334
|
-
* qsort.c: standard quicksort algorithm
|
|
2335
|
-
*
|
|
2336
|
-
* Modifications from vanilla NetBSD source:
|
|
2337
|
-
* Add do ... while() macro fix
|
|
2338
|
-
* Remove __inline, _DIAGASSERTs, __P
|
|
2339
|
-
* Remove ill-considered "swap_cnt" switch to insertion sort,
|
|
2340
|
-
* in favor of a simple check for presorted input.
|
|
2341
|
-
*
|
|
2342
|
-
* CAUTION: if you change this file, see also qsort_arg.c
|
|
2343
|
-
*
|
|
2344
|
-
* $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
|
|
2345
|
-
*/
|
|
2346
|
-
|
|
2347
|
-
/* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
|
|
2348
|
-
|
|
2349
|
-
/*-
|
|
2350
|
-
* Copyright (c) 1992, 1993
|
|
2351
|
-
* The Regents of the University of California. All rights reserved.
|
|
2352
|
-
*
|
|
2353
|
-
* Redistribution and use in source and binary forms, with or without
|
|
2354
|
-
* modification, are permitted provided that the following conditions
|
|
2355
|
-
* are met:
|
|
2356
|
-
* 1. Redistributions of source code must retain the above copyright
|
|
2357
|
-
* notice, this list of conditions and the following disclaimer.
|
|
2358
|
-
* 2. Redistributions in binary form must reproduce the above copyright
|
|
2359
|
-
* notice, this list of conditions and the following disclaimer in the
|
|
2360
|
-
* documentation and/or other materials provided with the distribution.
|
|
2361
|
-
* 3. Neither the name of the University nor the names of its contributors
|
|
2362
|
-
* may be used to endorse or promote products derived from this software
|
|
2363
|
-
* without specific prior written permission.
|
|
2364
|
-
*
|
|
2365
|
-
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
2366
|
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
2367
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
2368
|
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
2369
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
2370
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
2371
|
-
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
2372
|
-
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
2373
|
-
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
2374
|
-
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
2375
|
-
* SUCH DAMAGE.
|
|
2376
|
-
*/
|
|
2377
|
-
|
|
2378
|
-
#undef qsort_dtype
|
|
2379
|
-
#define qsort_dtype dtype*
|
|
2380
|
-
#undef qsort_cast
|
|
2381
|
-
#define qsort_cast **(dtype**)
|
|
2382
|
-
#undef cmp
|
|
2383
|
-
#define cmp(a, b) cmp_ignan(a, b)
|
|
2384
|
-
#undef cmpgt
|
|
2385
|
-
#define cmpgt(a, b) cmpgt_ignan(a, b)
|
|
2386
|
-
|
|
2387
|
-
static void sfloat_index_qsort_ignan(void* a, size_t n, ssize_t es) {
|
|
2388
|
-
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
|
2389
|
-
int d, r, swaptype, presorted;
|
|
2390
|
-
|
|
2391
|
-
loop:
|
|
2392
|
-
SWAPINIT(a, es);
|
|
2393
|
-
if (n < 7) {
|
|
2394
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
|
|
2395
|
-
for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
|
|
2396
|
-
return;
|
|
2397
|
-
}
|
|
2398
|
-
presorted = 1;
|
|
2399
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
|
|
2400
|
-
if (cmpgt(pm - es, pm)) {
|
|
2401
|
-
presorted = 0;
|
|
2402
|
-
break;
|
|
2403
|
-
}
|
|
2404
|
-
}
|
|
2405
|
-
if (presorted) return;
|
|
2406
|
-
pm = (char*)a + (n / 2) * es;
|
|
2407
|
-
if (n > 7) {
|
|
2408
|
-
pl = (char*)a;
|
|
2409
|
-
pn = (char*)a + (n - 1) * es;
|
|
2410
|
-
if (n > 40) {
|
|
2411
|
-
d = (int)((n / 8) * es);
|
|
2412
|
-
pl = med3(pl, pl + d, pl + 2 * d, cmp);
|
|
2413
|
-
pm = med3(pm - d, pm, pm + d, cmp);
|
|
2414
|
-
pn = med3(pn - 2 * d, pn - d, pn, cmp);
|
|
2415
|
-
}
|
|
2416
|
-
pm = med3(pl, pm, pn, cmp);
|
|
2417
|
-
}
|
|
2418
|
-
swap(a, pm);
|
|
2419
|
-
for (pa = pb = (char*)a + es, pc = pd = (char*)a + (n - 1) * es; pb <= pc;
|
|
2420
|
-
pb += es, pc -= es) {
|
|
2421
|
-
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
|
|
2422
|
-
if (r == 0) {
|
|
2423
|
-
swap(pa, pb);
|
|
2424
|
-
pa += es;
|
|
2425
|
-
}
|
|
2426
|
-
pb += es;
|
|
2427
|
-
}
|
|
2428
|
-
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
|
|
2429
|
-
if (r == 0) {
|
|
2430
|
-
swap(pc, pd);
|
|
2431
|
-
pd -= es;
|
|
2432
|
-
}
|
|
2433
|
-
pc -= es;
|
|
2434
|
-
}
|
|
2435
|
-
if (pb > pc) break;
|
|
2436
|
-
swap(pb, pc);
|
|
2437
|
-
}
|
|
2438
|
-
pn = (char*)a + n * es;
|
|
2439
|
-
r = (int)Min(pa - (char*)a, pb - pa);
|
|
2440
|
-
vecswap(a, pb - r, r);
|
|
2441
|
-
r = (int)Min(pd - pc, pn - pd - es);
|
|
2442
|
-
vecswap(pb, pn - r, r);
|
|
2443
|
-
if ((r = (int)(pb - pa)) > es) sfloat_index_qsort_ignan(a, r / es, es);
|
|
2444
|
-
if ((r = (int)(pd - pc)) > es) {
|
|
2445
|
-
/* Iterate rather than recurse to save stack space */
|
|
2446
|
-
a = pn - r;
|
|
2447
|
-
n = r / es;
|
|
2448
|
-
goto loop;
|
|
2449
|
-
}
|
|
2450
|
-
/* qsort(pn - r, r / es, es, cmp);*/
|
|
2451
|
-
}
|
|
2452
|
-
|
|
2453
|
-
#define idx_t int64_t
|
|
2454
|
-
static void sfloat_index64_qsort_ignan(na_loop_t* const lp) {
|
|
2455
|
-
size_t i, n, idx;
|
|
2456
|
-
char *d_ptr, *i_ptr, *o_ptr;
|
|
2457
|
-
ssize_t d_step, i_step, o_step;
|
|
2458
|
-
char** ptr;
|
|
2459
|
-
|
|
2460
|
-
INIT_COUNTER(lp, n);
|
|
2461
|
-
INIT_PTR(lp, 0, d_ptr, d_step);
|
|
2462
|
-
INIT_PTR(lp, 1, i_ptr, i_step);
|
|
2463
|
-
INIT_PTR(lp, 2, o_ptr, o_step);
|
|
2464
|
-
|
|
2465
|
-
ptr = (char**)(lp->opt_ptr);
|
|
2466
|
-
|
|
2467
|
-
// o_ptr=%lx,o_step=%ld)\n",(size_t)ptr,(size_t)d_ptr,(ssize_t)d_step,(size_t)i_ptr,(ssize_t)i_step,(size_t)o_ptr,(ssize_t)o_step);
|
|
2468
|
-
|
|
2469
|
-
if (n == 1) {
|
|
2470
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr);
|
|
2471
|
-
return;
|
|
2472
|
-
}
|
|
2473
|
-
|
|
2474
|
-
for (i = 0; i < n; i++) {
|
|
2475
|
-
ptr[i] = d_ptr + d_step * i;
|
|
2476
|
-
}
|
|
2477
|
-
|
|
2478
|
-
sfloat_index_qsort_ignan(ptr, n, sizeof(dtype*));
|
|
2479
|
-
|
|
2480
|
-
// d_ptr = lp->args[0].ptr;
|
|
2481
|
-
|
|
2482
|
-
for (i = 0; i < n; i++) {
|
|
2483
|
-
idx = (ptr[i] - d_ptr) / d_step;
|
|
2484
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
|
|
2485
|
-
o_ptr += o_step;
|
|
2486
|
-
}
|
|
2487
|
-
}
|
|
2488
|
-
#undef idx_t
|
|
2489
|
-
|
|
2490
|
-
#define idx_t int32_t
|
|
2491
|
-
static void sfloat_index32_qsort_ignan(na_loop_t* const lp) {
|
|
2492
|
-
size_t i, n, idx;
|
|
2493
|
-
char *d_ptr, *i_ptr, *o_ptr;
|
|
2494
|
-
ssize_t d_step, i_step, o_step;
|
|
2495
|
-
char** ptr;
|
|
2496
|
-
|
|
2497
|
-
INIT_COUNTER(lp, n);
|
|
2498
|
-
INIT_PTR(lp, 0, d_ptr, d_step);
|
|
2499
|
-
INIT_PTR(lp, 1, i_ptr, i_step);
|
|
2500
|
-
INIT_PTR(lp, 2, o_ptr, o_step);
|
|
2501
|
-
|
|
2502
|
-
ptr = (char**)(lp->opt_ptr);
|
|
2503
|
-
|
|
2504
|
-
// o_ptr=%lx,o_step=%ld)\n",(size_t)ptr,(size_t)d_ptr,(ssize_t)d_step,(size_t)i_ptr,(ssize_t)i_step,(size_t)o_ptr,(ssize_t)o_step);
|
|
2505
|
-
|
|
2506
|
-
if (n == 1) {
|
|
2507
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr);
|
|
2508
|
-
return;
|
|
2509
|
-
}
|
|
2510
|
-
|
|
2511
|
-
for (i = 0; i < n; i++) {
|
|
2512
|
-
ptr[i] = d_ptr + d_step * i;
|
|
2513
|
-
}
|
|
2514
|
-
|
|
2515
|
-
sfloat_index_qsort_ignan(ptr, n, sizeof(dtype*));
|
|
2516
|
-
|
|
2517
|
-
// d_ptr = lp->args[0].ptr;
|
|
2518
|
-
|
|
2519
|
-
for (i = 0; i < n; i++) {
|
|
2520
|
-
idx = (ptr[i] - d_ptr) / d_step;
|
|
2521
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
|
|
2522
|
-
o_ptr += o_step;
|
|
2523
|
-
}
|
|
2524
|
-
}
|
|
2525
|
-
#undef idx_t
|
|
2526
|
-
|
|
2527
|
-
#define idx_t int64_t
|
|
2528
|
-
static void sfloat_index64_qsort_prnan(na_loop_t* const lp) {
|
|
2529
|
-
size_t i, n, idx;
|
|
2530
|
-
char *d_ptr, *i_ptr, *o_ptr;
|
|
2531
|
-
ssize_t d_step, i_step, o_step;
|
|
2532
|
-
char** ptr;
|
|
2533
|
-
|
|
2534
|
-
INIT_COUNTER(lp, n);
|
|
2535
|
-
INIT_PTR(lp, 0, d_ptr, d_step);
|
|
2536
|
-
INIT_PTR(lp, 1, i_ptr, i_step);
|
|
2537
|
-
INIT_PTR(lp, 2, o_ptr, o_step);
|
|
2538
|
-
|
|
2539
|
-
ptr = (char**)(lp->opt_ptr);
|
|
2540
|
-
|
|
2541
|
-
// o_ptr=%lx,o_step=%ld)\n",(size_t)ptr,(size_t)d_ptr,(ssize_t)d_step,(size_t)i_ptr,(ssize_t)i_step,(size_t)o_ptr,(ssize_t)o_step);
|
|
2542
|
-
|
|
2543
|
-
if (n == 1) {
|
|
2544
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr);
|
|
2545
|
-
return;
|
|
2546
|
-
}
|
|
2547
|
-
|
|
2548
|
-
for (i = 0; i < n; i++) {
|
|
2549
|
-
ptr[i] = d_ptr + d_step * i;
|
|
2550
|
-
}
|
|
2551
|
-
|
|
2552
|
-
sfloat_index_qsort_prnan(ptr, n, sizeof(dtype*));
|
|
2553
|
-
|
|
2554
|
-
// d_ptr = lp->args[0].ptr;
|
|
2555
|
-
|
|
2556
|
-
for (i = 0; i < n; i++) {
|
|
2557
|
-
idx = (ptr[i] - d_ptr) / d_step;
|
|
2558
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
|
|
2559
|
-
o_ptr += o_step;
|
|
2560
|
-
}
|
|
2561
|
-
}
|
|
2562
|
-
#undef idx_t
|
|
2563
|
-
|
|
2564
|
-
#define idx_t int32_t
|
|
2565
|
-
static void sfloat_index32_qsort_prnan(na_loop_t* const lp) {
|
|
2566
|
-
size_t i, n, idx;
|
|
2567
|
-
char *d_ptr, *i_ptr, *o_ptr;
|
|
2568
|
-
ssize_t d_step, i_step, o_step;
|
|
2569
|
-
char** ptr;
|
|
2570
|
-
|
|
2571
|
-
INIT_COUNTER(lp, n);
|
|
2572
|
-
INIT_PTR(lp, 0, d_ptr, d_step);
|
|
2573
|
-
INIT_PTR(lp, 1, i_ptr, i_step);
|
|
2574
|
-
INIT_PTR(lp, 2, o_ptr, o_step);
|
|
2575
|
-
|
|
2576
|
-
ptr = (char**)(lp->opt_ptr);
|
|
2577
|
-
|
|
2578
|
-
// o_ptr=%lx,o_step=%ld)\n",(size_t)ptr,(size_t)d_ptr,(ssize_t)d_step,(size_t)i_ptr,(ssize_t)i_step,(size_t)o_ptr,(ssize_t)o_step);
|
|
2579
|
-
|
|
2580
|
-
if (n == 1) {
|
|
2581
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr);
|
|
2582
|
-
return;
|
|
2583
|
-
}
|
|
2584
|
-
|
|
2585
|
-
for (i = 0; i < n; i++) {
|
|
2586
|
-
ptr[i] = d_ptr + d_step * i;
|
|
2587
|
-
}
|
|
2588
|
-
|
|
2589
|
-
sfloat_index_qsort_prnan(ptr, n, sizeof(dtype*));
|
|
2590
|
-
|
|
2591
|
-
// d_ptr = lp->args[0].ptr;
|
|
2592
|
-
|
|
2593
|
-
for (i = 0; i < n; i++) {
|
|
2594
|
-
idx = (ptr[i] - d_ptr) / d_step;
|
|
2595
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
|
|
2596
|
-
o_ptr += o_step;
|
|
2597
|
-
}
|
|
2598
|
-
}
|
|
2599
|
-
#undef idx_t
|
|
2600
|
-
|
|
2601
|
-
static VALUE sfloat_sort_index(int argc, VALUE* argv, VALUE self) {
|
|
2602
|
-
size_t size;
|
|
2603
|
-
narray_t* na;
|
|
2604
|
-
VALUE idx, tmp, reduce, res;
|
|
2605
|
-
char* buf;
|
|
2606
|
-
ndfunc_arg_in_t ain[3] = { { cT, 0 }, { 0, 0 }, { sym_reduce, 0 } };
|
|
2607
|
-
ndfunc_arg_out_t aout[1] = { { 0, 0, 0 } };
|
|
2608
|
-
ndfunc_t ndf = { 0, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE | NDF_CUM, 3, 1, ain, aout };
|
|
2609
|
-
|
|
2610
|
-
GetNArray(self, na);
|
|
2611
|
-
if (na->ndim == 0) {
|
|
2612
|
-
return INT2FIX(0);
|
|
2613
|
-
}
|
|
2614
|
-
if (na->size > (~(u_int32_t)0)) {
|
|
2615
|
-
ain[1].type = aout[0].type = numo_cInt64;
|
|
2616
|
-
idx = nary_new(numo_cInt64, na->ndim, na->shape);
|
|
2617
|
-
|
|
2618
|
-
ndf.func = sfloat_index64_qsort_ignan;
|
|
2619
|
-
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, sfloat_index64_qsort_prnan);
|
|
2620
|
-
|
|
2621
|
-
} else {
|
|
2622
|
-
ain[1].type = aout[0].type = numo_cInt32;
|
|
2623
|
-
idx = nary_new(numo_cInt32, na->ndim, na->shape);
|
|
2624
|
-
|
|
2625
|
-
ndf.func = sfloat_index32_qsort_ignan;
|
|
2626
|
-
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, sfloat_index32_qsort_prnan);
|
|
2627
|
-
}
|
|
2628
|
-
rb_funcall(idx, rb_intern("seq"), 0);
|
|
2629
|
-
|
|
2630
|
-
size = na->size * sizeof(void*); // max capa
|
|
2631
|
-
buf = rb_alloc_tmp_buffer(&tmp, size);
|
|
2632
|
-
res = na_ndloop3(&ndf, buf, 3, self, idx, reduce);
|
|
2633
|
-
rb_free_tmp_buffer(&tmp);
|
|
2634
|
-
return res;
|
|
2635
|
-
}
|
|
2636
|
-
|
|
2637
|
-
static void iter_sfloat_median_ignan(na_loop_t* const lp) {
|
|
2638
|
-
size_t n;
|
|
2639
|
-
char *p1, *p2;
|
|
2640
|
-
dtype* buf;
|
|
2641
|
-
|
|
2642
|
-
INIT_COUNTER(lp, n);
|
|
2643
|
-
p1 = (lp->args[0]).ptr + (lp->args[0].iter[0]).pos;
|
|
2644
|
-
p2 = (lp->args[1]).ptr + (lp->args[1].iter[0]).pos;
|
|
2645
|
-
buf = (dtype*)p1;
|
|
2646
|
-
|
|
2647
|
-
sfloat_qsort_ignan(buf, n, sizeof(dtype));
|
|
2648
|
-
|
|
2649
|
-
for (; n; n--) {
|
|
2650
|
-
if (!isnan(buf[n - 1])) break;
|
|
2651
|
-
}
|
|
2652
|
-
|
|
2653
|
-
if (n == 0) {
|
|
2654
|
-
*(dtype*)p2 = buf[0];
|
|
2655
|
-
} else if (n % 2 == 0) {
|
|
2656
|
-
*(dtype*)p2 = (buf[n / 2 - 1] + buf[n / 2]) / 2;
|
|
2657
|
-
} else {
|
|
2658
|
-
*(dtype*)p2 = buf[(n - 1) / 2];
|
|
2659
|
-
}
|
|
2660
|
-
}
|
|
2661
|
-
static void iter_sfloat_median_prnan(na_loop_t* const lp) {
|
|
2662
|
-
size_t n;
|
|
2663
|
-
char *p1, *p2;
|
|
2664
|
-
dtype* buf;
|
|
2665
|
-
|
|
2666
|
-
INIT_COUNTER(lp, n);
|
|
2667
|
-
p1 = (lp->args[0]).ptr + (lp->args[0].iter[0]).pos;
|
|
2668
|
-
p2 = (lp->args[1]).ptr + (lp->args[1].iter[0]).pos;
|
|
2669
|
-
buf = (dtype*)p1;
|
|
2670
|
-
|
|
2671
|
-
sfloat_qsort_prnan(buf, n, sizeof(dtype));
|
|
2672
|
-
|
|
2673
|
-
for (; n; n--) {
|
|
2674
|
-
if (!isnan(buf[n - 1])) break;
|
|
2675
|
-
}
|
|
2676
|
-
|
|
2677
|
-
if (n == 0) {
|
|
2678
|
-
*(dtype*)p2 = buf[0];
|
|
2679
|
-
} else if (n % 2 == 0) {
|
|
2680
|
-
*(dtype*)p2 = (buf[n / 2 - 1] + buf[n / 2]) / 2;
|
|
2681
|
-
} else {
|
|
2682
|
-
*(dtype*)p2 = buf[(n - 1) / 2];
|
|
2683
|
-
}
|
|
2684
|
-
}
|
|
2685
|
-
|
|
2686
|
-
static VALUE sfloat_median(int argc, VALUE* argv, VALUE self) {
|
|
2687
|
-
VALUE v, reduce;
|
|
2688
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_reduce, 0 } };
|
|
2689
|
-
ndfunc_arg_out_t aout[1] = { { INT2FIX(0), 0 } };
|
|
2690
|
-
ndfunc_t ndf = { 0, NDF_HAS_LOOP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
|
|
2691
|
-
|
|
2692
|
-
self = na_copy(self); // as temporary buffer
|
|
2693
|
-
|
|
2694
|
-
ndf.func = iter_sfloat_median_ignan;
|
|
2695
|
-
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_sfloat_median_prnan);
|
|
2696
|
-
|
|
2697
|
-
v = na_ndloop(&ndf, 2, self, reduce);
|
|
2698
|
-
return sfloat_extract(v);
|
|
2699
|
-
}
|
|
2700
|
-
|
|
2701
|
-
VALUE mTM;
|
|
2702
|
-
|
|
2703
|
-
void Init_numo_sfloat(void) {
|
|
2704
|
-
VALUE hCast, mNumo;
|
|
2705
|
-
|
|
2706
|
-
mNumo = rb_define_module("Numo");
|
|
2707
|
-
|
|
2708
|
-
id_pow = rb_intern("**");
|
|
2709
|
-
id_cast = rb_intern("cast");
|
|
2710
|
-
id_copysign = rb_intern("copysign");
|
|
2711
|
-
id_divmod = rb_intern("divmod");
|
|
2712
|
-
id_eq = rb_intern("eq");
|
|
2713
|
-
id_ge = rb_intern("ge");
|
|
2714
|
-
id_gt = rb_intern("gt");
|
|
2715
|
-
id_le = rb_intern("le");
|
|
2716
|
-
id_lt = rb_intern("lt");
|
|
2717
|
-
id_mulsum = rb_intern("mulsum");
|
|
2718
|
-
id_nan = rb_intern("nan");
|
|
2719
|
-
id_ne = rb_intern("ne");
|
|
2720
|
-
id_nearly_eq = rb_intern("nearly_eq");
|
|
2721
|
-
id_to_a = rb_intern("to_a");
|
|
2722
|
-
|
|
2723
|
-
/**
|
|
2724
|
-
* Document-class: Numo::SFloat
|
|
2725
|
-
*
|
|
2726
|
-
* Single precision floating point number (32-bit float) N-dimensional array class.
|
|
2727
|
-
*/
|
|
2728
|
-
cT = rb_define_class_under(mNumo, "SFloat", cNArray);
|
|
2729
|
-
|
|
2730
|
-
// alias of SFloat
|
|
2731
|
-
rb_define_const(mNumo, "Float32", numo_cSFloat);
|
|
2732
|
-
|
|
2733
|
-
hCast = rb_hash_new();
|
|
2734
|
-
/* Upcasting rules of SFloat. */
|
|
2735
|
-
rb_define_const(cT, "UPCAST", hCast);
|
|
2736
|
-
rb_hash_aset(hCast, rb_cArray, cT);
|
|
2737
|
-
|
|
2738
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
|
2739
416
|
rb_hash_aset(hCast, rb_cInteger, cT);
|
|
2740
|
-
#else
|
|
2741
|
-
rb_hash_aset(hCast, rb_cFixnum, cT);
|
|
2742
|
-
rb_hash_aset(hCast, rb_cBignum, cT);
|
|
2743
|
-
#endif
|
|
2744
417
|
rb_hash_aset(hCast, rb_cFloat, cT);
|
|
2745
418
|
rb_hash_aset(hCast, rb_cComplex, numo_cSComplex);
|
|
2746
419
|
rb_hash_aset(hCast, numo_cRObject, numo_cRObject);
|