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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/ext/numo/narray/array.c +1 -9
  4. data/ext/numo/narray/extconf.rb +0 -11
  5. data/ext/numo/narray/index.c +5 -39
  6. data/ext/numo/narray/math.c +0 -5
  7. data/ext/numo/narray/narray.c +13 -19
  8. data/ext/numo/narray/numo/narray.h +6 -8
  9. data/ext/numo/narray/src/mh/abs.h +56 -0
  10. data/ext/numo/narray/src/mh/aref.h +28 -0
  11. data/ext/numo/narray/src/mh/arg.h +56 -0
  12. data/ext/numo/narray/src/mh/aset.h +169 -0
  13. data/ext/numo/narray/src/mh/conj.h +71 -0
  14. data/ext/numo/narray/src/mh/copysign.h +97 -0
  15. data/ext/numo/narray/src/mh/each.h +71 -0
  16. data/ext/numo/narray/src/mh/each_with_index.h +98 -0
  17. data/ext/numo/narray/src/mh/extract.h +36 -0
  18. data/ext/numo/narray/src/mh/im.h +71 -0
  19. data/ext/numo/narray/src/mh/imag.h +56 -0
  20. data/ext/numo/narray/src/mh/kahan_sum.h +39 -0
  21. data/ext/numo/narray/src/mh/map.h +126 -0
  22. data/ext/numo/narray/src/mh/map_with_index.h +76 -0
  23. data/ext/numo/narray/src/mh/median.h +85 -0
  24. data/ext/numo/narray/src/mh/modf.h +35 -0
  25. data/ext/numo/narray/src/mh/poly.h +42 -0
  26. data/ext/numo/narray/src/mh/real.h +56 -0
  27. data/ext/numo/narray/src/mh/s_cast.h +80 -0
  28. data/ext/numo/narray/src/mh/set_imag.h +60 -0
  29. data/ext/numo/narray/src/mh/set_real.h +60 -0
  30. data/ext/numo/narray/src/mh/signbit.h +42 -0
  31. data/ext/numo/narray/src/mh/sort.h +484 -0
  32. data/ext/numo/narray/src/mh/store.h +496 -0
  33. data/ext/numo/narray/src/t_bit.c +65 -195
  34. data/ext/numo/narray/src/t_dcomplex.c +244 -2216
  35. data/ext/numo/narray/src/t_dfloat.c +74 -2435
  36. data/ext/numo/narray/src/t_int16.c +225 -2015
  37. data/ext/numo/narray/src/t_int32.c +225 -2015
  38. data/ext/numo/narray/src/t_int64.c +225 -2015
  39. data/ext/numo/narray/src/t_int8.c +225 -1998
  40. data/ext/numo/narray/src/t_robject.c +114 -1413
  41. data/ext/numo/narray/src/t_scomplex.c +232 -2168
  42. data/ext/numo/narray/src/t_sfloat.c +72 -2399
  43. data/ext/numo/narray/src/t_uint16.c +225 -2015
  44. data/ext/numo/narray/src/t_uint32.c +225 -2015
  45. data/ext/numo/narray/src/t_uint64.c +225 -2015
  46. data/ext/numo/narray/src/t_uint8.c +225 -1998
  47. data/ext/numo/narray/step.c +2 -59
  48. data/numo-narray-alt.gemspec +1 -1
  49. 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
- static VALUE dfloat_extract(VALUE self) {
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
- if (klass == numo_cInt16) {
1216
- x = m_from_sint(*(int16_t*)(ptr + pos));
1217
- return x;
1218
- }
383
+ void Init_numo_dfloat(void) {
384
+ VALUE hCast, mNumo;
1219
385
 
1220
- if (klass == numo_cInt8) {
1221
- x = m_from_sint(*(int8_t*)(ptr + pos));
1222
- return x;
1223
- }
386
+ mNumo = rb_define_module("Numo");
1224
387
 
1225
- if (klass == numo_cUInt64) {
1226
- x = m_from_uint64(*(u_int64_t*)(ptr + pos));
1227
- return x;
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
- if (klass == numo_cUInt32) {
1231
- x = m_from_uint32(*(u_int32_t*)(ptr + pos));
1232
- return x;
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
- if (klass == numo_cUInt16) {
1236
- x = m_from_sint(*(u_int16_t*)(ptr + pos));
1237
- return x;
1238
- }
410
+ // alias of DFloat
411
+ rb_define_const(mNumo, "Float64", numo_cDFloat);
1239
412
 
1240
- if (klass == numo_cUInt8) {
1241
- x = m_from_sint(*(u_int8_t*)(ptr + pos));
1242
- return x;
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);