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,10 @@ 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"
|
|
80
|
+
#include "mh/kahan_sum.h"
|
|
67
81
|
#include "mh/comp/eq.h"
|
|
68
82
|
#include "mh/comp/ne.h"
|
|
69
83
|
#include "mh/comp/nearly_eq.h"
|
|
@@ -101,6 +115,9 @@ extern VALUE cRT;
|
|
|
101
115
|
#include "mh/eye.h"
|
|
102
116
|
#include "mh/rand.h"
|
|
103
117
|
#include "mh/rand_norm.h"
|
|
118
|
+
#include "mh/poly.h"
|
|
119
|
+
#include "mh/sort.h"
|
|
120
|
+
#include "mh/median.h"
|
|
104
121
|
#include "mh/math/sqrt.h"
|
|
105
122
|
#include "mh/math/cbrt.h"
|
|
106
123
|
#include "mh/math/log.h"
|
|
@@ -133,12 +150,23 @@ extern VALUE cRT;
|
|
|
133
150
|
|
|
134
151
|
typedef double dfloat; // Type aliases for shorter notation
|
|
135
152
|
// following the codebase naming convention.
|
|
153
|
+
DEF_NARRAY_STORE_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
154
|
+
DEF_NARRAY_S_CAST_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
155
|
+
DEF_NARRAY_EXTRACT_METHOD_FUNC(dfloat)
|
|
156
|
+
DEF_NARRAY_AREF_METHOD_FUNC(dfloat)
|
|
157
|
+
DEF_EXTRACT_DATA_FUNC(dfloat, numo_cDFloat)
|
|
158
|
+
DEF_NARRAY_ASET_METHOD_FUNC(dfloat)
|
|
136
159
|
DEF_NARRAY_COERCE_CAST_METHOD_FUNC(dfloat)
|
|
137
160
|
DEF_NARRAY_TO_A_METHOD_FUNC(dfloat)
|
|
138
161
|
DEF_NARRAY_FILL_METHOD_FUNC(dfloat)
|
|
139
162
|
DEF_NARRAY_FORMAT_METHOD_FUNC(dfloat)
|
|
140
163
|
DEF_NARRAY_FORMAT_TO_A_METHOD_FUNC(dfloat)
|
|
141
164
|
DEF_NARRAY_INSPECT_METHOD_FUNC(dfloat)
|
|
165
|
+
DEF_NARRAY_EACH_METHOD_FUNC(dfloat)
|
|
166
|
+
DEF_NARRAY_MAP_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
167
|
+
DEF_NARRAY_EACH_WITH_INDEX_METHOD_FUNC(dfloat)
|
|
168
|
+
DEF_NARRAY_MAP_WITH_INDEX_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
169
|
+
DEF_NARRAY_ABS_METHOD_FUNC(dfloat, numo_cDFloat, dfloat, numo_cDFloat)
|
|
142
170
|
#ifdef __SSE2__
|
|
143
171
|
DEF_NARRAY_DFLT_ADD_SSE2_METHOD_FUNC()
|
|
144
172
|
DEF_NARRAY_DFLT_SUB_SSE2_METHOD_FUNC()
|
|
@@ -162,6 +190,10 @@ DEF_NARRAY_FLT_ROUND_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
|
162
190
|
DEF_NARRAY_FLT_CEIL_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
163
191
|
DEF_NARRAY_FLT_TRUNC_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
164
192
|
DEF_NARRAY_FLT_RINT_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
193
|
+
DEF_NARRAY_COPYSIGN_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
194
|
+
DEF_NARRAY_SIGNBIT_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
195
|
+
DEF_NARRAY_MODF_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
196
|
+
DEF_NARRAY_KAHAN_SUM_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
165
197
|
DEF_NARRAY_EQ_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
166
198
|
DEF_NARRAY_NE_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
167
199
|
DEF_NARRAY_NEARLY_EQ_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
@@ -199,6 +231,18 @@ DEF_NARRAY_FLT_LOGSEQ_METHOD_FUNC(dfloat)
|
|
|
199
231
|
DEF_NARRAY_EYE_METHOD_FUNC(dfloat)
|
|
200
232
|
DEF_NARRAY_FLT_RAND_METHOD_FUNC(dfloat)
|
|
201
233
|
DEF_NARRAY_FLT_RAND_NORM_METHOD_FUNC(dfloat)
|
|
234
|
+
DEF_NARRAY_POLY_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
235
|
+
#undef qsort_dtype
|
|
236
|
+
#define qsort_dtype dfloat
|
|
237
|
+
#undef qsort_cast
|
|
238
|
+
#define qsort_cast *(dfloat*)
|
|
239
|
+
DEF_NARRAY_FLT_SORT_METHOD_FUNC(dfloat)
|
|
240
|
+
#undef qsort_dtype
|
|
241
|
+
#define qsort_dtype dfloat*
|
|
242
|
+
#undef qsort_cast
|
|
243
|
+
#define qsort_cast **(dfloat**)
|
|
244
|
+
DEF_NARRAY_FLT_SORT_INDEX_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
245
|
+
DEF_NARRAY_FLT_MEDIAN_METHOD_FUNC(dfloat)
|
|
202
246
|
#ifdef __SSE2__
|
|
203
247
|
DEF_NARRAY_FLT_SQRT_SSE2_DBL_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
204
248
|
#else
|
|
@@ -233,8 +277,6 @@ DEF_NARRAY_FLT_EXPM1_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
|
233
277
|
DEF_NARRAY_FLT_LDEXP_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
234
278
|
DEF_NARRAY_FLT_FREXP_METHOD_FUNC(dfloat, numo_cDFloat)
|
|
235
279
|
|
|
236
|
-
static VALUE dfloat_store(VALUE, VALUE);
|
|
237
|
-
|
|
238
280
|
static size_t dfloat_memsize(const void* ptr) {
|
|
239
281
|
size_t size = sizeof(narray_data_t);
|
|
240
282
|
const narray_data_t* na = (const narray_data_t*)ptr;
|
|
@@ -336,2447 +378,44 @@ static VALUE dfloat_allocate(VALUE self) {
|
|
|
336
378
|
return self;
|
|
337
379
|
}
|
|
338
380
|
|
|
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 dfloat_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 dfloat_store_numeric(VALUE self, VALUE obj) {
|
|
366
|
-
dtype x;
|
|
367
|
-
x = m_num_to_data(obj);
|
|
368
|
-
obj = dfloat_new_dim0(x);
|
|
369
|
-
dfloat_store(self, obj);
|
|
370
|
-
return self;
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
static void iter_dfloat_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 dfloat_store_bit(VALUE self, VALUE obj) {
|
|
421
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
422
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_dfloat(VALUE self, VALUE obj) {
|
|
470
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
471
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_sfloat(VALUE self, VALUE obj) {
|
|
519
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
520
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_int64(VALUE self, VALUE obj) {
|
|
568
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
569
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_int32(VALUE self, VALUE obj) {
|
|
617
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
618
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_int16(VALUE self, VALUE obj) {
|
|
666
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
667
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_int8(VALUE self, VALUE obj) {
|
|
715
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
716
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_uint64(VALUE self, VALUE obj) {
|
|
764
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
765
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_uint32(VALUE self, VALUE obj) {
|
|
813
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
814
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_uint16(VALUE self, VALUE obj) {
|
|
862
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
863
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_uint8(VALUE self, VALUE obj) {
|
|
911
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
912
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_store_robject(VALUE self, VALUE obj) {
|
|
960
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
|
|
961
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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_dfloat_store_dfloat(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 dfloat_store_array(VALUE self, VALUE rary) {
|
|
1069
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { rb_cArray, 0 } };
|
|
1070
|
-
ndfunc_t ndf = { iter_dfloat_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 dfloat_store(VALUE self, VALUE obj) {
|
|
1077
|
-
VALUE r, klass;
|
|
1078
|
-
|
|
1079
|
-
klass = rb_obj_class(obj);
|
|
1080
|
-
|
|
1081
|
-
if (klass == numo_cDFloat) {
|
|
1082
|
-
dfloat_store_dfloat(self, obj);
|
|
1083
|
-
return self;
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
if (IS_INTEGER_CLASS(klass) || klass == rb_cFloat || klass == rb_cComplex) {
|
|
1087
|
-
dfloat_store_numeric(self, obj);
|
|
1088
|
-
return self;
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
if (klass == numo_cBit) {
|
|
1092
|
-
dfloat_store_bit(self, obj);
|
|
1093
|
-
return self;
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
if (klass == numo_cSFloat) {
|
|
1097
|
-
dfloat_store_sfloat(self, obj);
|
|
1098
|
-
return self;
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
if (klass == numo_cInt64) {
|
|
1102
|
-
dfloat_store_int64(self, obj);
|
|
1103
|
-
return self;
|
|
1104
|
-
}
|
|
1105
|
-
|
|
1106
|
-
if (klass == numo_cInt32) {
|
|
1107
|
-
dfloat_store_int32(self, obj);
|
|
1108
|
-
return self;
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
if (klass == numo_cInt16) {
|
|
1112
|
-
dfloat_store_int16(self, obj);
|
|
1113
|
-
return self;
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
if (klass == numo_cInt8) {
|
|
1117
|
-
dfloat_store_int8(self, obj);
|
|
1118
|
-
return self;
|
|
1119
|
-
}
|
|
1120
|
-
|
|
1121
|
-
if (klass == numo_cUInt64) {
|
|
1122
|
-
dfloat_store_uint64(self, obj);
|
|
1123
|
-
return self;
|
|
1124
|
-
}
|
|
1125
|
-
|
|
1126
|
-
if (klass == numo_cUInt32) {
|
|
1127
|
-
dfloat_store_uint32(self, obj);
|
|
1128
|
-
return self;
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
if (klass == numo_cUInt16) {
|
|
1132
|
-
dfloat_store_uint16(self, obj);
|
|
1133
|
-
return self;
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1136
|
-
if (klass == numo_cUInt8) {
|
|
1137
|
-
dfloat_store_uint8(self, obj);
|
|
1138
|
-
return self;
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
if (klass == numo_cRObject) {
|
|
1142
|
-
dfloat_store_robject(self, obj);
|
|
1143
|
-
return self;
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
if (klass == rb_cArray) {
|
|
1147
|
-
dfloat_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
|
-
dfloat_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 dfloat_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_cDFloat) {
|
|
1187
|
-
x = m_from_real(*(double*)(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_cSFloat) {
|
|
1201
|
-
x = m_from_real(*(float*)(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
|
-
}
|
|
381
|
+
VALUE mTM;
|
|
1214
382
|
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
return x;
|
|
1218
|
-
}
|
|
383
|
+
void Init_numo_dfloat(void) {
|
|
384
|
+
VALUE hCast, mNumo;
|
|
1219
385
|
|
|
1220
|
-
|
|
1221
|
-
x = m_from_sint(*(int8_t*)(ptr + pos));
|
|
1222
|
-
return x;
|
|
1223
|
-
}
|
|
386
|
+
mNumo = rb_define_module("Numo");
|
|
1224
387
|
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
388
|
+
id_pow = rb_intern("**");
|
|
389
|
+
id_cast = rb_intern("cast");
|
|
390
|
+
id_copysign = rb_intern("copysign");
|
|
391
|
+
id_divmod = rb_intern("divmod");
|
|
392
|
+
id_eq = rb_intern("eq");
|
|
393
|
+
id_ge = rb_intern("ge");
|
|
394
|
+
id_gt = rb_intern("gt");
|
|
395
|
+
id_le = rb_intern("le");
|
|
396
|
+
id_lt = rb_intern("lt");
|
|
397
|
+
id_mulsum = rb_intern("mulsum");
|
|
398
|
+
id_nan = rb_intern("nan");
|
|
399
|
+
id_ne = rb_intern("ne");
|
|
400
|
+
id_nearly_eq = rb_intern("nearly_eq");
|
|
401
|
+
id_to_a = rb_intern("to_a");
|
|
1229
402
|
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
403
|
+
/**
|
|
404
|
+
* Document-class: Numo::DFloat
|
|
405
|
+
*
|
|
406
|
+
* Double precision floating point number (64-bit float) N-dimensional array class.
|
|
407
|
+
*/
|
|
408
|
+
cT = rb_define_class_under(mNumo, "DFloat", cNArray);
|
|
1234
409
|
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
return x;
|
|
1238
|
-
}
|
|
410
|
+
// alias of DFloat
|
|
411
|
+
rb_define_const(mNumo, "Float64", numo_cDFloat);
|
|
1239
412
|
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
413
|
+
hCast = rb_hash_new();
|
|
414
|
+
/* Upcasting rules of DFloat. */
|
|
415
|
+
rb_define_const(cT, "UPCAST", hCast);
|
|
416
|
+
rb_hash_aset(hCast, rb_cArray, cT);
|
|
1244
417
|
|
|
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 dfloat_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 dfloat_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
|
-
dfloat_store_array(nary, rary);
|
|
1278
|
-
}
|
|
1279
|
-
return nary;
|
|
1280
|
-
}
|
|
1281
|
-
|
|
1282
|
-
static VALUE dfloat_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 dfloat_new_dim0(x);
|
|
1293
|
-
}
|
|
1294
|
-
if (RTEST(rb_obj_is_kind_of(obj, rb_cArray))) {
|
|
1295
|
-
return dfloat_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
|
-
dfloat_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 dfloat_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 dfloat_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 dfloat_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
|
-
dfloat_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
|
-
dfloat_store(a, argv[argc]);
|
|
1346
|
-
} else {
|
|
1347
|
-
x = dfloat_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_dfloat_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 dfloat_each(VALUE self) {
|
|
1380
|
-
ndfunc_arg_in_t ain[1] = { { Qnil, 0 } };
|
|
1381
|
-
ndfunc_t ndf = { iter_dfloat_each, FULL_LOOP_NIP, 1, 0, ain, 0 };
|
|
1382
|
-
|
|
1383
|
-
na_ndloop(&ndf, 1, self);
|
|
1384
|
-
return self;
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
static void iter_dfloat_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 dfloat_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_dfloat_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_dfloat_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 dfloat_each_with_index(VALUE self) {
|
|
1503
|
-
ndfunc_arg_in_t ain[1] = { { Qnil, 0 } };
|
|
1504
|
-
ndfunc_t ndf = { iter_dfloat_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_dfloat_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 dfloat_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_dfloat_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_dfloat_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 dfloat_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_dfloat_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_dfloat_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 dfloat_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_dfloat_copysign, STRIDE_LOOP, 2, 1, ain, aout };
|
|
1732
|
-
|
|
1733
|
-
return na_ndloop(&ndf, 2, self, other);
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
|
-
static VALUE dfloat_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 dfloat_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_dfloat_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 dfloat_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_dfloat_signbit, FULL_LOOP, 1, 1, ain, aout };
|
|
1782
|
-
|
|
1783
|
-
return na_ndloop(&ndf, 1, self);
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
static void iter_dfloat_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 dfloat_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_dfloat_modf, STRIDE_LOOP, 1, 2, ain, aout };
|
|
1807
|
-
|
|
1808
|
-
return na_ndloop(&ndf, 1, self);
|
|
1809
|
-
}
|
|
1810
|
-
|
|
1811
|
-
static void iter_dfloat_kahan_sum(na_loop_t* const lp) {
|
|
1812
|
-
size_t n;
|
|
1813
|
-
char *p1, *p2;
|
|
1814
|
-
ssize_t s1;
|
|
1815
|
-
|
|
1816
|
-
INIT_COUNTER(lp, n);
|
|
1817
|
-
INIT_PTR(lp, 0, p1, s1);
|
|
1818
|
-
p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
|
|
1819
|
-
|
|
1820
|
-
*(dtype*)p2 = f_kahan_sum(n, p1, s1);
|
|
1821
|
-
}
|
|
1822
|
-
static void iter_dfloat_kahan_sum_nan(na_loop_t* const lp) {
|
|
1823
|
-
size_t n;
|
|
1824
|
-
char *p1, *p2;
|
|
1825
|
-
ssize_t s1;
|
|
1826
|
-
|
|
1827
|
-
INIT_COUNTER(lp, n);
|
|
1828
|
-
INIT_PTR(lp, 0, p1, s1);
|
|
1829
|
-
p2 = lp->args[1].ptr + lp->args[1].iter[0].pos;
|
|
1830
|
-
|
|
1831
|
-
*(dtype*)p2 = f_kahan_sum_nan(n, p1, s1);
|
|
1832
|
-
}
|
|
1833
|
-
|
|
1834
|
-
static VALUE dfloat_kahan_sum(int argc, VALUE* argv, VALUE self) {
|
|
1835
|
-
VALUE v, reduce;
|
|
1836
|
-
ndfunc_arg_in_t ain[2] = { { cT, 0 }, { sym_reduce, 0 } };
|
|
1837
|
-
ndfunc_arg_out_t aout[1] = { { cT, 0 } };
|
|
1838
|
-
ndfunc_t ndf = { iter_dfloat_kahan_sum, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
|
|
1839
|
-
|
|
1840
|
-
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_dfloat_kahan_sum_nan);
|
|
1841
|
-
|
|
1842
|
-
v = na_ndloop(&ndf, 2, self, reduce);
|
|
1843
|
-
|
|
1844
|
-
return dfloat_extract(v);
|
|
1845
|
-
}
|
|
1846
|
-
|
|
1847
|
-
static void iter_dfloat_poly(na_loop_t* const lp) {
|
|
1848
|
-
size_t i;
|
|
1849
|
-
dtype x, y, a;
|
|
1850
|
-
|
|
1851
|
-
x = *(dtype*)(lp->args[0].ptr + lp->args[0].iter[0].pos);
|
|
1852
|
-
i = lp->narg - 2;
|
|
1853
|
-
y = *(dtype*)(lp->args[i].ptr + lp->args[i].iter[0].pos);
|
|
1854
|
-
for (; --i;) {
|
|
1855
|
-
y = m_mul(x, y);
|
|
1856
|
-
a = *(dtype*)(lp->args[i].ptr + lp->args[i].iter[0].pos);
|
|
1857
|
-
y = m_add(y, a);
|
|
1858
|
-
}
|
|
1859
|
-
i = lp->narg - 1;
|
|
1860
|
-
*(dtype*)(lp->args[i].ptr + lp->args[i].iter[0].pos) = y;
|
|
1861
|
-
}
|
|
1862
|
-
|
|
1863
|
-
static VALUE dfloat_poly(VALUE self, VALUE args) {
|
|
1864
|
-
int argc, i;
|
|
1865
|
-
VALUE* argv;
|
|
1866
|
-
volatile VALUE v, a;
|
|
1867
|
-
ndfunc_arg_out_t aout[1] = { { cT, 0 } };
|
|
1868
|
-
ndfunc_t ndf = { iter_dfloat_poly, NO_LOOP, 0, 1, 0, aout };
|
|
1869
|
-
|
|
1870
|
-
argc = (int)RARRAY_LEN(args);
|
|
1871
|
-
ndf.nin = argc + 1;
|
|
1872
|
-
ndf.ain = ALLOCA_N(ndfunc_arg_in_t, argc + 1);
|
|
1873
|
-
for (i = 0; i < argc + 1; i++) {
|
|
1874
|
-
ndf.ain[i].type = cT;
|
|
1875
|
-
}
|
|
1876
|
-
argv = ALLOCA_N(VALUE, argc + 1);
|
|
1877
|
-
argv[0] = self;
|
|
1878
|
-
for (i = 0; i < argc; i++) {
|
|
1879
|
-
argv[i + 1] = RARRAY_PTR(args)[i];
|
|
1880
|
-
}
|
|
1881
|
-
a = rb_ary_new4(argc + 1, argv);
|
|
1882
|
-
v = na_ndloop2(&ndf, a);
|
|
1883
|
-
return dfloat_extract(v);
|
|
1884
|
-
}
|
|
1885
|
-
|
|
1886
|
-
/*
|
|
1887
|
-
qsort.c
|
|
1888
|
-
Ruby/Numo::NArray - Numerical Array class for Ruby
|
|
1889
|
-
modified by Masahiro TANAKA
|
|
1890
|
-
*/
|
|
1891
|
-
|
|
1892
|
-
/*
|
|
1893
|
-
* qsort.c: standard quicksort algorithm
|
|
1894
|
-
*
|
|
1895
|
-
* Modifications from vanilla NetBSD source:
|
|
1896
|
-
* Add do ... while() macro fix
|
|
1897
|
-
* Remove __inline, _DIAGASSERTs, __P
|
|
1898
|
-
* Remove ill-considered "swap_cnt" switch to insertion sort,
|
|
1899
|
-
* in favor of a simple check for presorted input.
|
|
1900
|
-
*
|
|
1901
|
-
* CAUTION: if you change this file, see also qsort_arg.c
|
|
1902
|
-
*
|
|
1903
|
-
* $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
|
|
1904
|
-
*/
|
|
1905
|
-
|
|
1906
|
-
/* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
|
|
1907
|
-
|
|
1908
|
-
/*-
|
|
1909
|
-
* Copyright (c) 1992, 1993
|
|
1910
|
-
* The Regents of the University of California. All rights reserved.
|
|
1911
|
-
*
|
|
1912
|
-
* Redistribution and use in source and binary forms, with or without
|
|
1913
|
-
* modification, are permitted provided that the following conditions
|
|
1914
|
-
* are met:
|
|
1915
|
-
* 1. Redistributions of source code must retain the above copyright
|
|
1916
|
-
* notice, this list of conditions and the following disclaimer.
|
|
1917
|
-
* 2. Redistributions in binary form must reproduce the above copyright
|
|
1918
|
-
* notice, this list of conditions and the following disclaimer in the
|
|
1919
|
-
* documentation and/or other materials provided with the distribution.
|
|
1920
|
-
* 3. Neither the name of the University nor the names of its contributors
|
|
1921
|
-
* may be used to endorse or promote products derived from this software
|
|
1922
|
-
* without specific prior written permission.
|
|
1923
|
-
*
|
|
1924
|
-
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
1925
|
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
1926
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
1927
|
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
1928
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
1929
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
1930
|
-
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
1931
|
-
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
1932
|
-
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
1933
|
-
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
1934
|
-
* SUCH DAMAGE.
|
|
1935
|
-
*/
|
|
1936
|
-
|
|
1937
|
-
#ifndef QSORT_INCL
|
|
1938
|
-
#define QSORT_INCL
|
|
1939
|
-
#define Min(x, y) ((x) < (y) ? (x) : (y))
|
|
1940
|
-
|
|
1941
|
-
/*
|
|
1942
|
-
* Qsort routine based on J. L. Bentley and M. D. McIlroy,
|
|
1943
|
-
* "Engineering a sort function",
|
|
1944
|
-
* Software--Practice and Experience 23 (1993) 1249-1265.
|
|
1945
|
-
* We have modified their original by adding a check for already-sorted input,
|
|
1946
|
-
* which seems to be a win per discussions on pgsql-hackers around 2006-03-21.
|
|
1947
|
-
*/
|
|
1948
|
-
#define swapcode(TYPE, parmi, parmj, n) \
|
|
1949
|
-
do { \
|
|
1950
|
-
size_t i = (n) / sizeof(TYPE); \
|
|
1951
|
-
TYPE* pi = (TYPE*)(void*)(parmi); \
|
|
1952
|
-
TYPE* pj = (TYPE*)(void*)(parmj); \
|
|
1953
|
-
do { \
|
|
1954
|
-
TYPE t = *pi; \
|
|
1955
|
-
*pi++ = *pj; \
|
|
1956
|
-
*pj++ = t; \
|
|
1957
|
-
} while (--i > 0); \
|
|
1958
|
-
} while (0)
|
|
1959
|
-
|
|
1960
|
-
#ifdef HAVE_STDINT_H
|
|
1961
|
-
#define SWAPINIT(a, es) \
|
|
1962
|
-
swaptype = (uintptr_t)a % sizeof(long) || (es) % sizeof(long) ? 2 \
|
|
1963
|
-
: (es) == sizeof(long) ? 0 \
|
|
1964
|
-
: 1;
|
|
1965
|
-
#else
|
|
1966
|
-
#define SWAPINIT(a, es) \
|
|
1967
|
-
swaptype = ((char*)(a) - (char*)0) % sizeof(long) || (es) % sizeof(long) ? 2 \
|
|
1968
|
-
: (es) == sizeof(long) ? 0 \
|
|
1969
|
-
: 1;
|
|
1970
|
-
#endif
|
|
1971
|
-
|
|
1972
|
-
static inline void swapfunc(char* a, char* b, size_t n, int swaptype) {
|
|
1973
|
-
if (swaptype <= 1)
|
|
1974
|
-
swapcode(long, a, b, n);
|
|
1975
|
-
else
|
|
1976
|
-
swapcode(char, a, b, n);
|
|
1977
|
-
}
|
|
1978
|
-
|
|
1979
|
-
#define swap(a, b) \
|
|
1980
|
-
if (swaptype == 0) { \
|
|
1981
|
-
long t = *(long*)(void*)(a); \
|
|
1982
|
-
*(long*)(void*)(a) = *(long*)(void*)(b); \
|
|
1983
|
-
*(long*)(void*)(b) = t; \
|
|
1984
|
-
} else \
|
|
1985
|
-
swapfunc(a, b, es, swaptype)
|
|
1986
|
-
|
|
1987
|
-
#define vecswap(a, b, n) \
|
|
1988
|
-
if ((n) > 0) swapfunc((a), (b), (size_t)(n), swaptype)
|
|
1989
|
-
|
|
1990
|
-
#define med3(a, b, c, _cmp) \
|
|
1991
|
-
(cmpgt(b, a) ? (cmpgt(c, b) ? b : (cmpgt(c, a) ? c : a)) \
|
|
1992
|
-
: (cmpgt(b, c) ? b : (cmpgt(c, a) ? a : c)))
|
|
1993
|
-
#endif
|
|
1994
|
-
|
|
1995
|
-
#undef qsort_dtype
|
|
1996
|
-
#define qsort_dtype dtype
|
|
1997
|
-
#undef qsort_cast
|
|
1998
|
-
#define qsort_cast *(dtype*)
|
|
1999
|
-
#undef cmp
|
|
2000
|
-
#define cmp(a, b) cmp_prnan(a, b)
|
|
2001
|
-
#undef cmpgt
|
|
2002
|
-
#define cmpgt(a, b) cmpgt_prnan(a, b)
|
|
2003
|
-
|
|
2004
|
-
static void dfloat_qsort_prnan(void* a, size_t n, ssize_t es) {
|
|
2005
|
-
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
|
2006
|
-
int d, r, swaptype, presorted;
|
|
2007
|
-
|
|
2008
|
-
loop:
|
|
2009
|
-
SWAPINIT(a, es);
|
|
2010
|
-
if (n < 7) {
|
|
2011
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
|
|
2012
|
-
for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
|
|
2013
|
-
return;
|
|
2014
|
-
}
|
|
2015
|
-
presorted = 1;
|
|
2016
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
|
|
2017
|
-
if (cmpgt(pm - es, pm)) {
|
|
2018
|
-
presorted = 0;
|
|
2019
|
-
break;
|
|
2020
|
-
}
|
|
2021
|
-
}
|
|
2022
|
-
if (presorted) return;
|
|
2023
|
-
pm = (char*)a + (n / 2) * es;
|
|
2024
|
-
if (n > 7) {
|
|
2025
|
-
pl = (char*)a;
|
|
2026
|
-
pn = (char*)a + (n - 1) * es;
|
|
2027
|
-
if (n > 40) {
|
|
2028
|
-
d = (int)((n / 8) * es);
|
|
2029
|
-
pl = med3(pl, pl + d, pl + 2 * d, cmp);
|
|
2030
|
-
pm = med3(pm - d, pm, pm + d, cmp);
|
|
2031
|
-
pn = med3(pn - 2 * d, pn - d, pn, cmp);
|
|
2032
|
-
}
|
|
2033
|
-
pm = med3(pl, pm, pn, cmp);
|
|
2034
|
-
}
|
|
2035
|
-
swap(a, pm);
|
|
2036
|
-
pa = pb = (char*)a + es;
|
|
2037
|
-
pc = pd = (char*)a + (n - 1) * es;
|
|
2038
|
-
for (;;) {
|
|
2039
|
-
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
|
|
2040
|
-
if (r == 0) {
|
|
2041
|
-
swap(pa, pb);
|
|
2042
|
-
pa += es;
|
|
2043
|
-
}
|
|
2044
|
-
pb += es;
|
|
2045
|
-
}
|
|
2046
|
-
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
|
|
2047
|
-
if (r == 0) {
|
|
2048
|
-
swap(pc, pd);
|
|
2049
|
-
pd -= es;
|
|
2050
|
-
}
|
|
2051
|
-
pc -= es;
|
|
2052
|
-
}
|
|
2053
|
-
if (pb > pc) break;
|
|
2054
|
-
swap(pb, pc);
|
|
2055
|
-
pb += es;
|
|
2056
|
-
pc -= es;
|
|
2057
|
-
}
|
|
2058
|
-
pn = (char*)a + n * es;
|
|
2059
|
-
r = (int)Min(pa - (char*)a, pb - pa);
|
|
2060
|
-
vecswap(a, pb - r, r);
|
|
2061
|
-
r = (int)Min(pd - pc, pn - pd - es);
|
|
2062
|
-
vecswap(pb, pn - r, r);
|
|
2063
|
-
if ((r = (int)(pb - pa)) > es) dfloat_qsort_prnan(a, r / es, es);
|
|
2064
|
-
if ((r = (int)(pd - pc)) > es) {
|
|
2065
|
-
/* Iterate rather than recurse to save stack space */
|
|
2066
|
-
a = pn - r;
|
|
2067
|
-
n = r / es;
|
|
2068
|
-
goto loop;
|
|
2069
|
-
}
|
|
2070
|
-
/* qsort(pn - r, r / es, es, cmp);*/
|
|
2071
|
-
}
|
|
2072
|
-
|
|
2073
|
-
/*
|
|
2074
|
-
qsort.c
|
|
2075
|
-
Ruby/Numo::NArray - Numerical Array class for Ruby
|
|
2076
|
-
modified by Masahiro TANAKA
|
|
2077
|
-
*/
|
|
2078
|
-
|
|
2079
|
-
/*
|
|
2080
|
-
* qsort.c: standard quicksort algorithm
|
|
2081
|
-
*
|
|
2082
|
-
* Modifications from vanilla NetBSD source:
|
|
2083
|
-
* Add do ... while() macro fix
|
|
2084
|
-
* Remove __inline, _DIAGASSERTs, __P
|
|
2085
|
-
* Remove ill-considered "swap_cnt" switch to insertion sort,
|
|
2086
|
-
* in favor of a simple check for presorted input.
|
|
2087
|
-
*
|
|
2088
|
-
* CAUTION: if you change this file, see also qsort_arg.c
|
|
2089
|
-
*
|
|
2090
|
-
* $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
|
|
2091
|
-
*/
|
|
2092
|
-
|
|
2093
|
-
/* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
|
|
2094
|
-
|
|
2095
|
-
/*-
|
|
2096
|
-
* Copyright (c) 1992, 1993
|
|
2097
|
-
* The Regents of the University of California. All rights reserved.
|
|
2098
|
-
*
|
|
2099
|
-
* Redistribution and use in source and binary forms, with or without
|
|
2100
|
-
* modification, are permitted provided that the following conditions
|
|
2101
|
-
* are met:
|
|
2102
|
-
* 1. Redistributions of source code must retain the above copyright
|
|
2103
|
-
* notice, this list of conditions and the following disclaimer.
|
|
2104
|
-
* 2. Redistributions in binary form must reproduce the above copyright
|
|
2105
|
-
* notice, this list of conditions and the following disclaimer in the
|
|
2106
|
-
* documentation and/or other materials provided with the distribution.
|
|
2107
|
-
* 3. Neither the name of the University nor the names of its contributors
|
|
2108
|
-
* may be used to endorse or promote products derived from this software
|
|
2109
|
-
* without specific prior written permission.
|
|
2110
|
-
*
|
|
2111
|
-
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
2112
|
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
2113
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
2114
|
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
2115
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
2116
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
2117
|
-
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
2118
|
-
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
2119
|
-
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
2120
|
-
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
2121
|
-
* SUCH DAMAGE.
|
|
2122
|
-
*/
|
|
2123
|
-
|
|
2124
|
-
#undef qsort_dtype
|
|
2125
|
-
#define qsort_dtype dtype
|
|
2126
|
-
#undef qsort_cast
|
|
2127
|
-
#define qsort_cast *(dtype*)
|
|
2128
|
-
#undef cmp
|
|
2129
|
-
#define cmp(a, b) cmp_ignan(a, b)
|
|
2130
|
-
#undef cmpgt
|
|
2131
|
-
#define cmpgt(a, b) cmpgt_ignan(a, b)
|
|
2132
|
-
|
|
2133
|
-
static void dfloat_qsort_ignan(void* a, size_t n, ssize_t es) {
|
|
2134
|
-
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
|
2135
|
-
int d, r, swaptype, presorted;
|
|
2136
|
-
|
|
2137
|
-
loop:
|
|
2138
|
-
SWAPINIT(a, es);
|
|
2139
|
-
if (n < 7) {
|
|
2140
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
|
|
2141
|
-
for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
|
|
2142
|
-
return;
|
|
2143
|
-
}
|
|
2144
|
-
presorted = 1;
|
|
2145
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
|
|
2146
|
-
if (cmpgt(pm - es, pm)) {
|
|
2147
|
-
presorted = 0;
|
|
2148
|
-
break;
|
|
2149
|
-
}
|
|
2150
|
-
}
|
|
2151
|
-
if (presorted) return;
|
|
2152
|
-
pm = (char*)a + (n / 2) * es;
|
|
2153
|
-
if (n > 7) {
|
|
2154
|
-
pl = (char*)a;
|
|
2155
|
-
pn = (char*)a + (n - 1) * es;
|
|
2156
|
-
if (n > 40) {
|
|
2157
|
-
d = (int)((n / 8) * es);
|
|
2158
|
-
pl = med3(pl, pl + d, pl + 2 * d, cmp);
|
|
2159
|
-
pm = med3(pm - d, pm, pm + d, cmp);
|
|
2160
|
-
pn = med3(pn - 2 * d, pn - d, pn, cmp);
|
|
2161
|
-
}
|
|
2162
|
-
pm = med3(pl, pm, pn, cmp);
|
|
2163
|
-
}
|
|
2164
|
-
swap(a, pm);
|
|
2165
|
-
pa = pb = (char*)a + es;
|
|
2166
|
-
pc = pd = (char*)a + (n - 1) * es;
|
|
2167
|
-
for (;;) {
|
|
2168
|
-
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
|
|
2169
|
-
if (r == 0) {
|
|
2170
|
-
swap(pa, pb);
|
|
2171
|
-
pa += es;
|
|
2172
|
-
}
|
|
2173
|
-
pb += es;
|
|
2174
|
-
}
|
|
2175
|
-
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
|
|
2176
|
-
if (r == 0) {
|
|
2177
|
-
swap(pc, pd);
|
|
2178
|
-
pd -= es;
|
|
2179
|
-
}
|
|
2180
|
-
pc -= es;
|
|
2181
|
-
}
|
|
2182
|
-
if (pb > pc) break;
|
|
2183
|
-
swap(pb, pc);
|
|
2184
|
-
pb += es;
|
|
2185
|
-
pc -= es;
|
|
2186
|
-
}
|
|
2187
|
-
pn = (char*)a + n * es;
|
|
2188
|
-
r = (int)Min(pa - (char*)a, pb - pa);
|
|
2189
|
-
vecswap(a, pb - r, r);
|
|
2190
|
-
r = (int)Min(pd - pc, pn - pd - es);
|
|
2191
|
-
vecswap(pb, pn - r, r);
|
|
2192
|
-
if ((r = (int)(pb - pa)) > es) dfloat_qsort_ignan(a, r / es, es);
|
|
2193
|
-
if ((r = (int)(pd - pc)) > es) {
|
|
2194
|
-
/* Iterate rather than recurse to save stack space */
|
|
2195
|
-
a = pn - r;
|
|
2196
|
-
n = r / es;
|
|
2197
|
-
goto loop;
|
|
2198
|
-
}
|
|
2199
|
-
/* qsort(pn - r, r / es, es, cmp);*/
|
|
2200
|
-
}
|
|
2201
|
-
|
|
2202
|
-
static void iter_dfloat_sort_ignan(na_loop_t* const lp) {
|
|
2203
|
-
size_t n;
|
|
2204
|
-
char* ptr;
|
|
2205
|
-
ssize_t step;
|
|
2206
|
-
|
|
2207
|
-
INIT_COUNTER(lp, n);
|
|
2208
|
-
INIT_PTR(lp, 0, ptr, step);
|
|
2209
|
-
dfloat_qsort_ignan(ptr, n, step);
|
|
2210
|
-
}
|
|
2211
|
-
static void iter_dfloat_sort_prnan(na_loop_t* const lp) {
|
|
2212
|
-
size_t n;
|
|
2213
|
-
char* ptr;
|
|
2214
|
-
ssize_t step;
|
|
2215
|
-
|
|
2216
|
-
INIT_COUNTER(lp, n);
|
|
2217
|
-
INIT_PTR(lp, 0, ptr, step);
|
|
2218
|
-
dfloat_qsort_prnan(ptr, n, step);
|
|
2219
|
-
}
|
|
2220
|
-
|
|
2221
|
-
static VALUE dfloat_sort(int argc, VALUE* argv, VALUE self) {
|
|
2222
|
-
VALUE reduce;
|
|
2223
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_reduce, 0 } };
|
|
2224
|
-
ndfunc_t ndf = { 0, NDF_HAS_LOOP | NDF_FLAT_REDUCE, 2, 0, ain, 0 };
|
|
2225
|
-
|
|
2226
|
-
if (!TEST_INPLACE(self)) {
|
|
2227
|
-
self = na_copy(self);
|
|
2228
|
-
}
|
|
2229
|
-
|
|
2230
|
-
ndf.func = iter_dfloat_sort_ignan;
|
|
2231
|
-
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_dfloat_sort_prnan);
|
|
2232
|
-
|
|
2233
|
-
na_ndloop(&ndf, 2, self, reduce);
|
|
2234
|
-
return self;
|
|
2235
|
-
}
|
|
2236
|
-
|
|
2237
|
-
/*
|
|
2238
|
-
qsort.c
|
|
2239
|
-
Ruby/Numo::NArray - Numerical Array class for Ruby
|
|
2240
|
-
modified by Masahiro TANAKA
|
|
2241
|
-
*/
|
|
2242
|
-
|
|
2243
|
-
/*
|
|
2244
|
-
* qsort.c: standard quicksort algorithm
|
|
2245
|
-
*
|
|
2246
|
-
* Modifications from vanilla NetBSD source:
|
|
2247
|
-
* Add do ... while() macro fix
|
|
2248
|
-
* Remove __inline, _DIAGASSERTs, __P
|
|
2249
|
-
* Remove ill-considered "swap_cnt" switch to insertion sort,
|
|
2250
|
-
* in favor of a simple check for presorted input.
|
|
2251
|
-
*
|
|
2252
|
-
* CAUTION: if you change this file, see also qsort_arg.c
|
|
2253
|
-
*
|
|
2254
|
-
* $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
|
|
2255
|
-
*/
|
|
2256
|
-
|
|
2257
|
-
/* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
|
|
2258
|
-
|
|
2259
|
-
/*-
|
|
2260
|
-
* Copyright (c) 1992, 1993
|
|
2261
|
-
* The Regents of the University of California. All rights reserved.
|
|
2262
|
-
*
|
|
2263
|
-
* Redistribution and use in source and binary forms, with or without
|
|
2264
|
-
* modification, are permitted provided that the following conditions
|
|
2265
|
-
* are met:
|
|
2266
|
-
* 1. Redistributions of source code must retain the above copyright
|
|
2267
|
-
* notice, this list of conditions and the following disclaimer.
|
|
2268
|
-
* 2. Redistributions in binary form must reproduce the above copyright
|
|
2269
|
-
* notice, this list of conditions and the following disclaimer in the
|
|
2270
|
-
* documentation and/or other materials provided with the distribution.
|
|
2271
|
-
* 3. Neither the name of the University nor the names of its contributors
|
|
2272
|
-
* may be used to endorse or promote products derived from this software
|
|
2273
|
-
* without specific prior written permission.
|
|
2274
|
-
*
|
|
2275
|
-
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
2276
|
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
2277
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
2278
|
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
2279
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
2280
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
2281
|
-
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
2282
|
-
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
2283
|
-
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
2284
|
-
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
2285
|
-
* SUCH DAMAGE.
|
|
2286
|
-
*/
|
|
2287
|
-
|
|
2288
|
-
#undef qsort_dtype
|
|
2289
|
-
#define qsort_dtype dtype*
|
|
2290
|
-
#undef qsort_cast
|
|
2291
|
-
#define qsort_cast **(dtype**)
|
|
2292
|
-
#undef cmp
|
|
2293
|
-
#define cmp(a, b) cmp_prnan(a, b)
|
|
2294
|
-
#undef cmpgt
|
|
2295
|
-
#define cmpgt(a, b) cmpgt_prnan(a, b)
|
|
2296
|
-
|
|
2297
|
-
static void dfloat_index_qsort_prnan(void* a, size_t n, ssize_t es) {
|
|
2298
|
-
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
|
2299
|
-
int d, r, swaptype, presorted;
|
|
2300
|
-
|
|
2301
|
-
loop:
|
|
2302
|
-
SWAPINIT(a, es);
|
|
2303
|
-
if (n < 7) {
|
|
2304
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
|
|
2305
|
-
for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
|
|
2306
|
-
return;
|
|
2307
|
-
}
|
|
2308
|
-
presorted = 1;
|
|
2309
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
|
|
2310
|
-
if (cmpgt(pm - es, pm)) {
|
|
2311
|
-
presorted = 0;
|
|
2312
|
-
break;
|
|
2313
|
-
}
|
|
2314
|
-
}
|
|
2315
|
-
if (presorted) return;
|
|
2316
|
-
pm = (char*)a + (n / 2) * es;
|
|
2317
|
-
if (n > 7) {
|
|
2318
|
-
pl = (char*)a;
|
|
2319
|
-
pn = (char*)a + (n - 1) * es;
|
|
2320
|
-
if (n > 40) {
|
|
2321
|
-
d = (int)((n / 8) * es);
|
|
2322
|
-
pl = med3(pl, pl + d, pl + 2 * d, cmp);
|
|
2323
|
-
pm = med3(pm - d, pm, pm + d, cmp);
|
|
2324
|
-
pn = med3(pn - 2 * d, pn - d, pn, cmp);
|
|
2325
|
-
}
|
|
2326
|
-
pm = med3(pl, pm, pn, cmp);
|
|
2327
|
-
}
|
|
2328
|
-
swap(a, pm);
|
|
2329
|
-
for (pa = pb = (char*)a + es, pc = pd = (char*)a + (n - 1) * es; pb <= pc;
|
|
2330
|
-
pb += es, pc -= es) {
|
|
2331
|
-
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
|
|
2332
|
-
if (r == 0) {
|
|
2333
|
-
swap(pa, pb);
|
|
2334
|
-
pa += es;
|
|
2335
|
-
}
|
|
2336
|
-
pb += es;
|
|
2337
|
-
}
|
|
2338
|
-
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
|
|
2339
|
-
if (r == 0) {
|
|
2340
|
-
swap(pc, pd);
|
|
2341
|
-
pd -= es;
|
|
2342
|
-
}
|
|
2343
|
-
pc -= es;
|
|
2344
|
-
}
|
|
2345
|
-
if (pb > pc) break;
|
|
2346
|
-
swap(pb, pc);
|
|
2347
|
-
}
|
|
2348
|
-
pn = (char*)a + n * es;
|
|
2349
|
-
r = (int)Min(pa - (char*)a, pb - pa);
|
|
2350
|
-
vecswap(a, pb - r, r);
|
|
2351
|
-
r = (int)Min(pd - pc, pn - pd - es);
|
|
2352
|
-
vecswap(pb, pn - r, r);
|
|
2353
|
-
if ((r = (int)(pb - pa)) > es) dfloat_index_qsort_prnan(a, r / es, es);
|
|
2354
|
-
if ((r = (int)(pd - pc)) > es) {
|
|
2355
|
-
/* Iterate rather than recurse to save stack space */
|
|
2356
|
-
a = pn - r;
|
|
2357
|
-
n = r / es;
|
|
2358
|
-
goto loop;
|
|
2359
|
-
}
|
|
2360
|
-
/* qsort(pn - r, r / es, es, cmp);*/
|
|
2361
|
-
}
|
|
2362
|
-
|
|
2363
|
-
/*
|
|
2364
|
-
qsort.c
|
|
2365
|
-
Ruby/Numo::NArray - Numerical Array class for Ruby
|
|
2366
|
-
modified by Masahiro TANAKA
|
|
2367
|
-
*/
|
|
2368
|
-
|
|
2369
|
-
/*
|
|
2370
|
-
* qsort.c: standard quicksort algorithm
|
|
2371
|
-
*
|
|
2372
|
-
* Modifications from vanilla NetBSD source:
|
|
2373
|
-
* Add do ... while() macro fix
|
|
2374
|
-
* Remove __inline, _DIAGASSERTs, __P
|
|
2375
|
-
* Remove ill-considered "swap_cnt" switch to insertion sort,
|
|
2376
|
-
* in favor of a simple check for presorted input.
|
|
2377
|
-
*
|
|
2378
|
-
* CAUTION: if you change this file, see also qsort_arg.c
|
|
2379
|
-
*
|
|
2380
|
-
* $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
|
|
2381
|
-
*/
|
|
2382
|
-
|
|
2383
|
-
/* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
|
|
2384
|
-
|
|
2385
|
-
/*-
|
|
2386
|
-
* Copyright (c) 1992, 1993
|
|
2387
|
-
* The Regents of the University of California. All rights reserved.
|
|
2388
|
-
*
|
|
2389
|
-
* Redistribution and use in source and binary forms, with or without
|
|
2390
|
-
* modification, are permitted provided that the following conditions
|
|
2391
|
-
* are met:
|
|
2392
|
-
* 1. Redistributions of source code must retain the above copyright
|
|
2393
|
-
* notice, this list of conditions and the following disclaimer.
|
|
2394
|
-
* 2. Redistributions in binary form must reproduce the above copyright
|
|
2395
|
-
* notice, this list of conditions and the following disclaimer in the
|
|
2396
|
-
* documentation and/or other materials provided with the distribution.
|
|
2397
|
-
* 3. Neither the name of the University nor the names of its contributors
|
|
2398
|
-
* may be used to endorse or promote products derived from this software
|
|
2399
|
-
* without specific prior written permission.
|
|
2400
|
-
*
|
|
2401
|
-
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
2402
|
-
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
2403
|
-
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
2404
|
-
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
2405
|
-
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
2406
|
-
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
2407
|
-
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
2408
|
-
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
2409
|
-
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
2410
|
-
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
2411
|
-
* SUCH DAMAGE.
|
|
2412
|
-
*/
|
|
2413
|
-
|
|
2414
|
-
#undef qsort_dtype
|
|
2415
|
-
#define qsort_dtype dtype*
|
|
2416
|
-
#undef qsort_cast
|
|
2417
|
-
#define qsort_cast **(dtype**)
|
|
2418
|
-
#undef cmp
|
|
2419
|
-
#define cmp(a, b) cmp_ignan(a, b)
|
|
2420
|
-
#undef cmpgt
|
|
2421
|
-
#define cmpgt(a, b) cmpgt_ignan(a, b)
|
|
2422
|
-
|
|
2423
|
-
static void dfloat_index_qsort_ignan(void* a, size_t n, ssize_t es) {
|
|
2424
|
-
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
|
|
2425
|
-
int d, r, swaptype, presorted;
|
|
2426
|
-
|
|
2427
|
-
loop:
|
|
2428
|
-
SWAPINIT(a, es);
|
|
2429
|
-
if (n < 7) {
|
|
2430
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
|
|
2431
|
-
for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
|
|
2432
|
-
return;
|
|
2433
|
-
}
|
|
2434
|
-
presorted = 1;
|
|
2435
|
-
for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
|
|
2436
|
-
if (cmpgt(pm - es, pm)) {
|
|
2437
|
-
presorted = 0;
|
|
2438
|
-
break;
|
|
2439
|
-
}
|
|
2440
|
-
}
|
|
2441
|
-
if (presorted) return;
|
|
2442
|
-
pm = (char*)a + (n / 2) * es;
|
|
2443
|
-
if (n > 7) {
|
|
2444
|
-
pl = (char*)a;
|
|
2445
|
-
pn = (char*)a + (n - 1) * es;
|
|
2446
|
-
if (n > 40) {
|
|
2447
|
-
d = (int)((n / 8) * es);
|
|
2448
|
-
pl = med3(pl, pl + d, pl + 2 * d, cmp);
|
|
2449
|
-
pm = med3(pm - d, pm, pm + d, cmp);
|
|
2450
|
-
pn = med3(pn - 2 * d, pn - d, pn, cmp);
|
|
2451
|
-
}
|
|
2452
|
-
pm = med3(pl, pm, pn, cmp);
|
|
2453
|
-
}
|
|
2454
|
-
swap(a, pm);
|
|
2455
|
-
for (pa = pb = (char*)a + es, pc = pd = (char*)a + (n - 1) * es; pb <= pc;
|
|
2456
|
-
pb += es, pc -= es) {
|
|
2457
|
-
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
|
|
2458
|
-
if (r == 0) {
|
|
2459
|
-
swap(pa, pb);
|
|
2460
|
-
pa += es;
|
|
2461
|
-
}
|
|
2462
|
-
pb += es;
|
|
2463
|
-
}
|
|
2464
|
-
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
|
|
2465
|
-
if (r == 0) {
|
|
2466
|
-
swap(pc, pd);
|
|
2467
|
-
pd -= es;
|
|
2468
|
-
}
|
|
2469
|
-
pc -= es;
|
|
2470
|
-
}
|
|
2471
|
-
if (pb > pc) break;
|
|
2472
|
-
swap(pb, pc);
|
|
2473
|
-
}
|
|
2474
|
-
pn = (char*)a + n * es;
|
|
2475
|
-
r = (int)Min(pa - (char*)a, pb - pa);
|
|
2476
|
-
vecswap(a, pb - r, r);
|
|
2477
|
-
r = (int)Min(pd - pc, pn - pd - es);
|
|
2478
|
-
vecswap(pb, pn - r, r);
|
|
2479
|
-
if ((r = (int)(pb - pa)) > es) dfloat_index_qsort_ignan(a, r / es, es);
|
|
2480
|
-
if ((r = (int)(pd - pc)) > es) {
|
|
2481
|
-
/* Iterate rather than recurse to save stack space */
|
|
2482
|
-
a = pn - r;
|
|
2483
|
-
n = r / es;
|
|
2484
|
-
goto loop;
|
|
2485
|
-
}
|
|
2486
|
-
/* qsort(pn - r, r / es, es, cmp);*/
|
|
2487
|
-
}
|
|
2488
|
-
|
|
2489
|
-
#define idx_t int64_t
|
|
2490
|
-
static void dfloat_index64_qsort_ignan(na_loop_t* const lp) {
|
|
2491
|
-
size_t i, n, idx;
|
|
2492
|
-
char *d_ptr, *i_ptr, *o_ptr;
|
|
2493
|
-
ssize_t d_step, i_step, o_step;
|
|
2494
|
-
char** ptr;
|
|
2495
|
-
|
|
2496
|
-
INIT_COUNTER(lp, n);
|
|
2497
|
-
INIT_PTR(lp, 0, d_ptr, d_step);
|
|
2498
|
-
INIT_PTR(lp, 1, i_ptr, i_step);
|
|
2499
|
-
INIT_PTR(lp, 2, o_ptr, o_step);
|
|
2500
|
-
|
|
2501
|
-
ptr = (char**)(lp->opt_ptr);
|
|
2502
|
-
|
|
2503
|
-
// 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);
|
|
2504
|
-
|
|
2505
|
-
if (n == 1) {
|
|
2506
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr);
|
|
2507
|
-
return;
|
|
2508
|
-
}
|
|
2509
|
-
|
|
2510
|
-
for (i = 0; i < n; i++) {
|
|
2511
|
-
ptr[i] = d_ptr + d_step * i;
|
|
2512
|
-
}
|
|
2513
|
-
|
|
2514
|
-
dfloat_index_qsort_ignan(ptr, n, sizeof(dtype*));
|
|
2515
|
-
|
|
2516
|
-
// d_ptr = lp->args[0].ptr;
|
|
2517
|
-
|
|
2518
|
-
for (i = 0; i < n; i++) {
|
|
2519
|
-
idx = (ptr[i] - d_ptr) / d_step;
|
|
2520
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
|
|
2521
|
-
o_ptr += o_step;
|
|
2522
|
-
}
|
|
2523
|
-
}
|
|
2524
|
-
#undef idx_t
|
|
2525
|
-
|
|
2526
|
-
#define idx_t int32_t
|
|
2527
|
-
static void dfloat_index32_qsort_ignan(na_loop_t* const lp) {
|
|
2528
|
-
size_t i, n, idx;
|
|
2529
|
-
char *d_ptr, *i_ptr, *o_ptr;
|
|
2530
|
-
ssize_t d_step, i_step, o_step;
|
|
2531
|
-
char** ptr;
|
|
2532
|
-
|
|
2533
|
-
INIT_COUNTER(lp, n);
|
|
2534
|
-
INIT_PTR(lp, 0, d_ptr, d_step);
|
|
2535
|
-
INIT_PTR(lp, 1, i_ptr, i_step);
|
|
2536
|
-
INIT_PTR(lp, 2, o_ptr, o_step);
|
|
2537
|
-
|
|
2538
|
-
ptr = (char**)(lp->opt_ptr);
|
|
2539
|
-
|
|
2540
|
-
// 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);
|
|
2541
|
-
|
|
2542
|
-
if (n == 1) {
|
|
2543
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr);
|
|
2544
|
-
return;
|
|
2545
|
-
}
|
|
2546
|
-
|
|
2547
|
-
for (i = 0; i < n; i++) {
|
|
2548
|
-
ptr[i] = d_ptr + d_step * i;
|
|
2549
|
-
}
|
|
2550
|
-
|
|
2551
|
-
dfloat_index_qsort_ignan(ptr, n, sizeof(dtype*));
|
|
2552
|
-
|
|
2553
|
-
// d_ptr = lp->args[0].ptr;
|
|
2554
|
-
|
|
2555
|
-
for (i = 0; i < n; i++) {
|
|
2556
|
-
idx = (ptr[i] - d_ptr) / d_step;
|
|
2557
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
|
|
2558
|
-
o_ptr += o_step;
|
|
2559
|
-
}
|
|
2560
|
-
}
|
|
2561
|
-
#undef idx_t
|
|
2562
|
-
|
|
2563
|
-
#define idx_t int64_t
|
|
2564
|
-
static void dfloat_index64_qsort_prnan(na_loop_t* const lp) {
|
|
2565
|
-
size_t i, n, idx;
|
|
2566
|
-
char *d_ptr, *i_ptr, *o_ptr;
|
|
2567
|
-
ssize_t d_step, i_step, o_step;
|
|
2568
|
-
char** ptr;
|
|
2569
|
-
|
|
2570
|
-
INIT_COUNTER(lp, n);
|
|
2571
|
-
INIT_PTR(lp, 0, d_ptr, d_step);
|
|
2572
|
-
INIT_PTR(lp, 1, i_ptr, i_step);
|
|
2573
|
-
INIT_PTR(lp, 2, o_ptr, o_step);
|
|
2574
|
-
|
|
2575
|
-
ptr = (char**)(lp->opt_ptr);
|
|
2576
|
-
|
|
2577
|
-
// 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);
|
|
2578
|
-
|
|
2579
|
-
if (n == 1) {
|
|
2580
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr);
|
|
2581
|
-
return;
|
|
2582
|
-
}
|
|
2583
|
-
|
|
2584
|
-
for (i = 0; i < n; i++) {
|
|
2585
|
-
ptr[i] = d_ptr + d_step * i;
|
|
2586
|
-
}
|
|
2587
|
-
|
|
2588
|
-
dfloat_index_qsort_prnan(ptr, n, sizeof(dtype*));
|
|
2589
|
-
|
|
2590
|
-
// d_ptr = lp->args[0].ptr;
|
|
2591
|
-
|
|
2592
|
-
for (i = 0; i < n; i++) {
|
|
2593
|
-
idx = (ptr[i] - d_ptr) / d_step;
|
|
2594
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
|
|
2595
|
-
o_ptr += o_step;
|
|
2596
|
-
}
|
|
2597
|
-
}
|
|
2598
|
-
#undef idx_t
|
|
2599
|
-
|
|
2600
|
-
#define idx_t int32_t
|
|
2601
|
-
static void dfloat_index32_qsort_prnan(na_loop_t* const lp) {
|
|
2602
|
-
size_t i, n, idx;
|
|
2603
|
-
char *d_ptr, *i_ptr, *o_ptr;
|
|
2604
|
-
ssize_t d_step, i_step, o_step;
|
|
2605
|
-
char** ptr;
|
|
2606
|
-
|
|
2607
|
-
INIT_COUNTER(lp, n);
|
|
2608
|
-
INIT_PTR(lp, 0, d_ptr, d_step);
|
|
2609
|
-
INIT_PTR(lp, 1, i_ptr, i_step);
|
|
2610
|
-
INIT_PTR(lp, 2, o_ptr, o_step);
|
|
2611
|
-
|
|
2612
|
-
ptr = (char**)(lp->opt_ptr);
|
|
2613
|
-
|
|
2614
|
-
// 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);
|
|
2615
|
-
|
|
2616
|
-
if (n == 1) {
|
|
2617
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr);
|
|
2618
|
-
return;
|
|
2619
|
-
}
|
|
2620
|
-
|
|
2621
|
-
for (i = 0; i < n; i++) {
|
|
2622
|
-
ptr[i] = d_ptr + d_step * i;
|
|
2623
|
-
}
|
|
2624
|
-
|
|
2625
|
-
dfloat_index_qsort_prnan(ptr, n, sizeof(dtype*));
|
|
2626
|
-
|
|
2627
|
-
// d_ptr = lp->args[0].ptr;
|
|
2628
|
-
|
|
2629
|
-
for (i = 0; i < n; i++) {
|
|
2630
|
-
idx = (ptr[i] - d_ptr) / d_step;
|
|
2631
|
-
*(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
|
|
2632
|
-
o_ptr += o_step;
|
|
2633
|
-
}
|
|
2634
|
-
}
|
|
2635
|
-
#undef idx_t
|
|
2636
|
-
|
|
2637
|
-
static VALUE dfloat_sort_index(int argc, VALUE* argv, VALUE self) {
|
|
2638
|
-
size_t size;
|
|
2639
|
-
narray_t* na;
|
|
2640
|
-
VALUE idx, tmp, reduce, res;
|
|
2641
|
-
char* buf;
|
|
2642
|
-
ndfunc_arg_in_t ain[3] = { { cT, 0 }, { 0, 0 }, { sym_reduce, 0 } };
|
|
2643
|
-
ndfunc_arg_out_t aout[1] = { { 0, 0, 0 } };
|
|
2644
|
-
ndfunc_t ndf = { 0, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE | NDF_CUM, 3, 1, ain, aout };
|
|
2645
|
-
|
|
2646
|
-
GetNArray(self, na);
|
|
2647
|
-
if (na->ndim == 0) {
|
|
2648
|
-
return INT2FIX(0);
|
|
2649
|
-
}
|
|
2650
|
-
if (na->size > (~(u_int32_t)0)) {
|
|
2651
|
-
ain[1].type = aout[0].type = numo_cInt64;
|
|
2652
|
-
idx = nary_new(numo_cInt64, na->ndim, na->shape);
|
|
2653
|
-
|
|
2654
|
-
ndf.func = dfloat_index64_qsort_ignan;
|
|
2655
|
-
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, dfloat_index64_qsort_prnan);
|
|
2656
|
-
|
|
2657
|
-
} else {
|
|
2658
|
-
ain[1].type = aout[0].type = numo_cInt32;
|
|
2659
|
-
idx = nary_new(numo_cInt32, na->ndim, na->shape);
|
|
2660
|
-
|
|
2661
|
-
ndf.func = dfloat_index32_qsort_ignan;
|
|
2662
|
-
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, dfloat_index32_qsort_prnan);
|
|
2663
|
-
}
|
|
2664
|
-
rb_funcall(idx, rb_intern("seq"), 0);
|
|
2665
|
-
|
|
2666
|
-
size = na->size * sizeof(void*); // max capa
|
|
2667
|
-
buf = rb_alloc_tmp_buffer(&tmp, size);
|
|
2668
|
-
res = na_ndloop3(&ndf, buf, 3, self, idx, reduce);
|
|
2669
|
-
rb_free_tmp_buffer(&tmp);
|
|
2670
|
-
return res;
|
|
2671
|
-
}
|
|
2672
|
-
|
|
2673
|
-
static void iter_dfloat_median_ignan(na_loop_t* const lp) {
|
|
2674
|
-
size_t n;
|
|
2675
|
-
char *p1, *p2;
|
|
2676
|
-
dtype* buf;
|
|
2677
|
-
|
|
2678
|
-
INIT_COUNTER(lp, n);
|
|
2679
|
-
p1 = (lp->args[0]).ptr + (lp->args[0].iter[0]).pos;
|
|
2680
|
-
p2 = (lp->args[1]).ptr + (lp->args[1].iter[0]).pos;
|
|
2681
|
-
buf = (dtype*)p1;
|
|
2682
|
-
|
|
2683
|
-
dfloat_qsort_ignan(buf, n, sizeof(dtype));
|
|
2684
|
-
|
|
2685
|
-
for (; n; n--) {
|
|
2686
|
-
if (!isnan(buf[n - 1])) break;
|
|
2687
|
-
}
|
|
2688
|
-
|
|
2689
|
-
if (n == 0) {
|
|
2690
|
-
*(dtype*)p2 = buf[0];
|
|
2691
|
-
} else if (n % 2 == 0) {
|
|
2692
|
-
*(dtype*)p2 = (buf[n / 2 - 1] + buf[n / 2]) / 2;
|
|
2693
|
-
} else {
|
|
2694
|
-
*(dtype*)p2 = buf[(n - 1) / 2];
|
|
2695
|
-
}
|
|
2696
|
-
}
|
|
2697
|
-
static void iter_dfloat_median_prnan(na_loop_t* const lp) {
|
|
2698
|
-
size_t n;
|
|
2699
|
-
char *p1, *p2;
|
|
2700
|
-
dtype* buf;
|
|
2701
|
-
|
|
2702
|
-
INIT_COUNTER(lp, n);
|
|
2703
|
-
p1 = (lp->args[0]).ptr + (lp->args[0].iter[0]).pos;
|
|
2704
|
-
p2 = (lp->args[1]).ptr + (lp->args[1].iter[0]).pos;
|
|
2705
|
-
buf = (dtype*)p1;
|
|
2706
|
-
|
|
2707
|
-
dfloat_qsort_prnan(buf, n, sizeof(dtype));
|
|
2708
|
-
|
|
2709
|
-
for (; n; n--) {
|
|
2710
|
-
if (!isnan(buf[n - 1])) break;
|
|
2711
|
-
}
|
|
2712
|
-
|
|
2713
|
-
if (n == 0) {
|
|
2714
|
-
*(dtype*)p2 = buf[0];
|
|
2715
|
-
} else if (n % 2 == 0) {
|
|
2716
|
-
*(dtype*)p2 = (buf[n / 2 - 1] + buf[n / 2]) / 2;
|
|
2717
|
-
} else {
|
|
2718
|
-
*(dtype*)p2 = buf[(n - 1) / 2];
|
|
2719
|
-
}
|
|
2720
|
-
}
|
|
2721
|
-
|
|
2722
|
-
static VALUE dfloat_median(int argc, VALUE* argv, VALUE self) {
|
|
2723
|
-
VALUE v, reduce;
|
|
2724
|
-
ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_reduce, 0 } };
|
|
2725
|
-
ndfunc_arg_out_t aout[1] = { { INT2FIX(0), 0 } };
|
|
2726
|
-
ndfunc_t ndf = { 0, NDF_HAS_LOOP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
|
|
2727
|
-
|
|
2728
|
-
self = na_copy(self); // as temporary buffer
|
|
2729
|
-
|
|
2730
|
-
ndf.func = iter_dfloat_median_ignan;
|
|
2731
|
-
reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_dfloat_median_prnan);
|
|
2732
|
-
|
|
2733
|
-
v = na_ndloop(&ndf, 2, self, reduce);
|
|
2734
|
-
return dfloat_extract(v);
|
|
2735
|
-
}
|
|
2736
|
-
|
|
2737
|
-
VALUE mTM;
|
|
2738
|
-
|
|
2739
|
-
void Init_numo_dfloat(void) {
|
|
2740
|
-
VALUE hCast, mNumo;
|
|
2741
|
-
|
|
2742
|
-
mNumo = rb_define_module("Numo");
|
|
2743
|
-
|
|
2744
|
-
id_pow = rb_intern("**");
|
|
2745
|
-
id_cast = rb_intern("cast");
|
|
2746
|
-
id_copysign = rb_intern("copysign");
|
|
2747
|
-
id_divmod = rb_intern("divmod");
|
|
2748
|
-
id_eq = rb_intern("eq");
|
|
2749
|
-
id_ge = rb_intern("ge");
|
|
2750
|
-
id_gt = rb_intern("gt");
|
|
2751
|
-
id_le = rb_intern("le");
|
|
2752
|
-
id_lt = rb_intern("lt");
|
|
2753
|
-
id_mulsum = rb_intern("mulsum");
|
|
2754
|
-
id_nan = rb_intern("nan");
|
|
2755
|
-
id_ne = rb_intern("ne");
|
|
2756
|
-
id_nearly_eq = rb_intern("nearly_eq");
|
|
2757
|
-
id_to_a = rb_intern("to_a");
|
|
2758
|
-
|
|
2759
|
-
/**
|
|
2760
|
-
* Document-class: Numo::DFloat
|
|
2761
|
-
*
|
|
2762
|
-
* Double precision floating point number (64-bit float) N-dimensional array class.
|
|
2763
|
-
*/
|
|
2764
|
-
cT = rb_define_class_under(mNumo, "DFloat", cNArray);
|
|
2765
|
-
|
|
2766
|
-
// alias of DFloat
|
|
2767
|
-
rb_define_const(mNumo, "Float64", numo_cDFloat);
|
|
2768
|
-
|
|
2769
|
-
hCast = rb_hash_new();
|
|
2770
|
-
/* Upcasting rules of DFloat. */
|
|
2771
|
-
rb_define_const(cT, "UPCAST", hCast);
|
|
2772
|
-
rb_hash_aset(hCast, rb_cArray, cT);
|
|
2773
|
-
|
|
2774
|
-
#ifdef RUBY_INTEGER_UNIFICATION
|
|
2775
418
|
rb_hash_aset(hCast, rb_cInteger, cT);
|
|
2776
|
-
#else
|
|
2777
|
-
rb_hash_aset(hCast, rb_cFixnum, cT);
|
|
2778
|
-
rb_hash_aset(hCast, rb_cBignum, cT);
|
|
2779
|
-
#endif
|
|
2780
419
|
rb_hash_aset(hCast, rb_cFloat, cT);
|
|
2781
420
|
rb_hash_aset(hCast, rb_cComplex, numo_cDComplex);
|
|
2782
421
|
rb_hash_aset(hCast, numo_cRObject, numo_cRObject);
|