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