numo-narray-alt 0.9.14 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -42,8 +42,11 @@ 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"
45
47
  #include "mh/extract.h"
46
48
  #include "mh/aref.h"
49
+ #include "mh/aset.h"
47
50
  #include "mh/coerce_cast.h"
48
51
  #include "mh/to_a.h"
49
52
  #include "mh/fill.h"
@@ -112,6 +115,8 @@ extern VALUE cRT;
112
115
  #include "mh/rand.h"
113
116
  #include "mh/rand_norm.h"
114
117
  #include "mh/poly.h"
118
+ #include "mh/sort.h"
119
+ #include "mh/median.h"
115
120
  #include "mh/math/sqrt.h"
116
121
  #include "mh/math/cbrt.h"
117
122
  #include "mh/math/log.h"
@@ -144,8 +149,12 @@ extern VALUE cRT;
144
149
 
145
150
  typedef float sfloat; // Type aliases for shorter notation
146
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)
147
154
  DEF_NARRAY_EXTRACT_METHOD_FUNC(sfloat)
148
155
  DEF_NARRAY_AREF_METHOD_FUNC(sfloat)
156
+ DEF_EXTRACT_DATA_FUNC(sfloat, numo_cSFloat)
157
+ DEF_NARRAY_ASET_METHOD_FUNC(sfloat)
149
158
  DEF_NARRAY_COERCE_CAST_METHOD_FUNC(sfloat)
150
159
  DEF_NARRAY_TO_A_METHOD_FUNC(sfloat)
151
160
  DEF_NARRAY_FILL_METHOD_FUNC(sfloat)
@@ -221,6 +230,17 @@ DEF_NARRAY_EYE_METHOD_FUNC(sfloat)
221
230
  DEF_NARRAY_FLT_RAND_METHOD_FUNC(sfloat)
222
231
  DEF_NARRAY_FLT_RAND_NORM_METHOD_FUNC(sfloat)
223
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)
224
244
  #ifdef __SSE2__
225
245
  DEF_NARRAY_FLT_SQRT_SSE2_SGL_METHOD_FUNC(sfloat, numo_cSFloat)
226
246
  #else
@@ -255,8 +275,6 @@ DEF_NARRAY_FLT_EXPM1_METHOD_FUNC(sfloat, numo_cSFloat)
255
275
  DEF_NARRAY_FLT_LDEXP_METHOD_FUNC(sfloat, numo_cSFloat)
256
276
  DEF_NARRAY_FLT_FREXP_METHOD_FUNC(sfloat, numo_cSFloat)
257
277
 
258
- static VALUE sfloat_store(VALUE, VALUE);
259
-
260
278
  static size_t sfloat_memsize(const void* ptr) {
261
279
  size_t size = sizeof(narray_data_t);
262
280
  const narray_data_t* na = (const narray_data_t*)ptr;
@@ -358,1844 +376,6 @@ static VALUE sfloat_allocate(VALUE self) {
358
376
  return self;
359
377
  }
360
378
 
361
- static VALUE sfloat_new_dim0(dtype x) {
362
- VALUE v;
363
- dtype* ptr;
364
-
365
- v = nary_new(cT, 0, NULL);
366
- ptr = (dtype*)(char*)na_get_pointer_for_write(v);
367
- *ptr = x;
368
- na_release_lock(v);
369
- return v;
370
- }
371
-
372
- static VALUE sfloat_store_numeric(VALUE self, VALUE obj) {
373
- dtype x;
374
- x = m_num_to_data(obj);
375
- obj = sfloat_new_dim0(x);
376
- sfloat_store(self, obj);
377
- return self;
378
- }
379
-
380
- static void iter_sfloat_store_bit(na_loop_t* const lp) {
381
- size_t i;
382
- char* p1;
383
- size_t p2;
384
- ssize_t s1, s2;
385
- size_t *idx1, *idx2;
386
- BIT_DIGIT *a2, x;
387
- dtype y;
388
-
389
- INIT_COUNTER(lp, i);
390
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
391
- INIT_PTR_BIT_IDX(lp, 1, a2, p2, s2, idx2);
392
- if (idx2) {
393
- if (idx1) {
394
- for (; i--;) {
395
- LOAD_BIT(a2, p2 + *idx2, x);
396
- idx2++;
397
- y = m_from_sint(x);
398
- SET_DATA_INDEX(p1, idx1, dtype, y);
399
- }
400
- } else {
401
- for (; i--;) {
402
- LOAD_BIT(a2, p2 + *idx2, x);
403
- idx2++;
404
- y = m_from_sint(x);
405
- SET_DATA_STRIDE(p1, s1, dtype, y);
406
- }
407
- }
408
- } else {
409
- if (idx1) {
410
- for (; i--;) {
411
- LOAD_BIT(a2, p2, x);
412
- p2 += s2;
413
- y = m_from_sint(x);
414
- SET_DATA_INDEX(p1, idx1, dtype, y);
415
- }
416
- } else {
417
- for (; i--;) {
418
- LOAD_BIT(a2, p2, x);
419
- p2 += s2;
420
- y = m_from_sint(x);
421
- SET_DATA_STRIDE(p1, s1, dtype, y);
422
- }
423
- }
424
- }
425
- }
426
-
427
- static VALUE sfloat_store_bit(VALUE self, VALUE obj) {
428
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
429
- ndfunc_t ndf = { iter_sfloat_store_bit, FULL_LOOP, 2, 0, ain, 0 };
430
-
431
- na_ndloop(&ndf, 2, self, obj);
432
- return self;
433
- }
434
-
435
- static void iter_sfloat_store_dfloat(na_loop_t* const lp) {
436
- size_t i, s1, s2;
437
- char *p1, *p2;
438
- size_t *idx1, *idx2;
439
- double x;
440
- dtype y;
441
-
442
- INIT_COUNTER(lp, i);
443
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
444
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
445
- if (idx2) {
446
- if (idx1) {
447
- for (; i--;) {
448
- GET_DATA_INDEX(p2, idx2, double, x);
449
- y = m_from_real(x);
450
- SET_DATA_INDEX(p1, idx1, dtype, y);
451
- }
452
- } else {
453
- for (; i--;) {
454
- GET_DATA_INDEX(p2, idx2, double, x);
455
- y = m_from_real(x);
456
- SET_DATA_STRIDE(p1, s1, dtype, y);
457
- }
458
- }
459
- } else {
460
- if (idx1) {
461
- for (; i--;) {
462
- GET_DATA_STRIDE(p2, s2, double, x);
463
- y = m_from_real(x);
464
- SET_DATA_INDEX(p1, idx1, dtype, y);
465
- }
466
- } else {
467
- for (; i--;) {
468
- GET_DATA_STRIDE(p2, s2, double, x);
469
- y = m_from_real(x);
470
- SET_DATA_STRIDE(p1, s1, dtype, y);
471
- }
472
- }
473
- }
474
- }
475
-
476
- static VALUE sfloat_store_dfloat(VALUE self, VALUE obj) {
477
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
478
- ndfunc_t ndf = { iter_sfloat_store_dfloat, FULL_LOOP, 2, 0, ain, 0 };
479
-
480
- na_ndloop(&ndf, 2, self, obj);
481
- return self;
482
- }
483
-
484
- static void iter_sfloat_store_sfloat(na_loop_t* const lp) {
485
- size_t i, s1, s2;
486
- char *p1, *p2;
487
- size_t *idx1, *idx2;
488
- float x;
489
- dtype y;
490
-
491
- INIT_COUNTER(lp, i);
492
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
493
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
494
- if (idx2) {
495
- if (idx1) {
496
- for (; i--;) {
497
- GET_DATA_INDEX(p2, idx2, float, x);
498
- y = m_from_real(x);
499
- SET_DATA_INDEX(p1, idx1, dtype, y);
500
- }
501
- } else {
502
- for (; i--;) {
503
- GET_DATA_INDEX(p2, idx2, float, x);
504
- y = m_from_real(x);
505
- SET_DATA_STRIDE(p1, s1, dtype, y);
506
- }
507
- }
508
- } else {
509
- if (idx1) {
510
- for (; i--;) {
511
- GET_DATA_STRIDE(p2, s2, float, x);
512
- y = m_from_real(x);
513
- SET_DATA_INDEX(p1, idx1, dtype, y);
514
- }
515
- } else {
516
- for (; i--;) {
517
- GET_DATA_STRIDE(p2, s2, float, x);
518
- y = m_from_real(x);
519
- SET_DATA_STRIDE(p1, s1, dtype, y);
520
- }
521
- }
522
- }
523
- }
524
-
525
- static VALUE sfloat_store_sfloat(VALUE self, VALUE obj) {
526
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
527
- ndfunc_t ndf = { iter_sfloat_store_sfloat, FULL_LOOP, 2, 0, ain, 0 };
528
-
529
- na_ndloop(&ndf, 2, self, obj);
530
- return self;
531
- }
532
-
533
- static void iter_sfloat_store_int64(na_loop_t* const lp) {
534
- size_t i, s1, s2;
535
- char *p1, *p2;
536
- size_t *idx1, *idx2;
537
- int64_t x;
538
- dtype y;
539
-
540
- INIT_COUNTER(lp, i);
541
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
542
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
543
- if (idx2) {
544
- if (idx1) {
545
- for (; i--;) {
546
- GET_DATA_INDEX(p2, idx2, int64_t, x);
547
- y = m_from_int64(x);
548
- SET_DATA_INDEX(p1, idx1, dtype, y);
549
- }
550
- } else {
551
- for (; i--;) {
552
- GET_DATA_INDEX(p2, idx2, int64_t, x);
553
- y = m_from_int64(x);
554
- SET_DATA_STRIDE(p1, s1, dtype, y);
555
- }
556
- }
557
- } else {
558
- if (idx1) {
559
- for (; i--;) {
560
- GET_DATA_STRIDE(p2, s2, int64_t, x);
561
- y = m_from_int64(x);
562
- SET_DATA_INDEX(p1, idx1, dtype, y);
563
- }
564
- } else {
565
- for (; i--;) {
566
- GET_DATA_STRIDE(p2, s2, int64_t, x);
567
- y = m_from_int64(x);
568
- SET_DATA_STRIDE(p1, s1, dtype, y);
569
- }
570
- }
571
- }
572
- }
573
-
574
- static VALUE sfloat_store_int64(VALUE self, VALUE obj) {
575
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
576
- ndfunc_t ndf = { iter_sfloat_store_int64, FULL_LOOP, 2, 0, ain, 0 };
577
-
578
- na_ndloop(&ndf, 2, self, obj);
579
- return self;
580
- }
581
-
582
- static void iter_sfloat_store_int32(na_loop_t* const lp) {
583
- size_t i, s1, s2;
584
- char *p1, *p2;
585
- size_t *idx1, *idx2;
586
- int32_t x;
587
- dtype y;
588
-
589
- INIT_COUNTER(lp, i);
590
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
591
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
592
- if (idx2) {
593
- if (idx1) {
594
- for (; i--;) {
595
- GET_DATA_INDEX(p2, idx2, int32_t, x);
596
- y = m_from_int32(x);
597
- SET_DATA_INDEX(p1, idx1, dtype, y);
598
- }
599
- } else {
600
- for (; i--;) {
601
- GET_DATA_INDEX(p2, idx2, int32_t, x);
602
- y = m_from_int32(x);
603
- SET_DATA_STRIDE(p1, s1, dtype, y);
604
- }
605
- }
606
- } else {
607
- if (idx1) {
608
- for (; i--;) {
609
- GET_DATA_STRIDE(p2, s2, int32_t, x);
610
- y = m_from_int32(x);
611
- SET_DATA_INDEX(p1, idx1, dtype, y);
612
- }
613
- } else {
614
- for (; i--;) {
615
- GET_DATA_STRIDE(p2, s2, int32_t, x);
616
- y = m_from_int32(x);
617
- SET_DATA_STRIDE(p1, s1, dtype, y);
618
- }
619
- }
620
- }
621
- }
622
-
623
- static VALUE sfloat_store_int32(VALUE self, VALUE obj) {
624
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
625
- ndfunc_t ndf = { iter_sfloat_store_int32, FULL_LOOP, 2, 0, ain, 0 };
626
-
627
- na_ndloop(&ndf, 2, self, obj);
628
- return self;
629
- }
630
-
631
- static void iter_sfloat_store_int16(na_loop_t* const lp) {
632
- size_t i, s1, s2;
633
- char *p1, *p2;
634
- size_t *idx1, *idx2;
635
- int16_t x;
636
- dtype y;
637
-
638
- INIT_COUNTER(lp, i);
639
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
640
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
641
- if (idx2) {
642
- if (idx1) {
643
- for (; i--;) {
644
- GET_DATA_INDEX(p2, idx2, int16_t, x);
645
- y = m_from_sint(x);
646
- SET_DATA_INDEX(p1, idx1, dtype, y);
647
- }
648
- } else {
649
- for (; i--;) {
650
- GET_DATA_INDEX(p2, idx2, int16_t, x);
651
- y = m_from_sint(x);
652
- SET_DATA_STRIDE(p1, s1, dtype, y);
653
- }
654
- }
655
- } else {
656
- if (idx1) {
657
- for (; i--;) {
658
- GET_DATA_STRIDE(p2, s2, int16_t, x);
659
- y = m_from_sint(x);
660
- SET_DATA_INDEX(p1, idx1, dtype, y);
661
- }
662
- } else {
663
- for (; i--;) {
664
- GET_DATA_STRIDE(p2, s2, int16_t, x);
665
- y = m_from_sint(x);
666
- SET_DATA_STRIDE(p1, s1, dtype, y);
667
- }
668
- }
669
- }
670
- }
671
-
672
- static VALUE sfloat_store_int16(VALUE self, VALUE obj) {
673
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
674
- ndfunc_t ndf = { iter_sfloat_store_int16, FULL_LOOP, 2, 0, ain, 0 };
675
-
676
- na_ndloop(&ndf, 2, self, obj);
677
- return self;
678
- }
679
-
680
- static void iter_sfloat_store_int8(na_loop_t* const lp) {
681
- size_t i, s1, s2;
682
- char *p1, *p2;
683
- size_t *idx1, *idx2;
684
- int8_t x;
685
- dtype y;
686
-
687
- INIT_COUNTER(lp, i);
688
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
689
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
690
- if (idx2) {
691
- if (idx1) {
692
- for (; i--;) {
693
- GET_DATA_INDEX(p2, idx2, int8_t, x);
694
- y = m_from_sint(x);
695
- SET_DATA_INDEX(p1, idx1, dtype, y);
696
- }
697
- } else {
698
- for (; i--;) {
699
- GET_DATA_INDEX(p2, idx2, int8_t, x);
700
- y = m_from_sint(x);
701
- SET_DATA_STRIDE(p1, s1, dtype, y);
702
- }
703
- }
704
- } else {
705
- if (idx1) {
706
- for (; i--;) {
707
- GET_DATA_STRIDE(p2, s2, int8_t, x);
708
- y = m_from_sint(x);
709
- SET_DATA_INDEX(p1, idx1, dtype, y);
710
- }
711
- } else {
712
- for (; i--;) {
713
- GET_DATA_STRIDE(p2, s2, int8_t, x);
714
- y = m_from_sint(x);
715
- SET_DATA_STRIDE(p1, s1, dtype, y);
716
- }
717
- }
718
- }
719
- }
720
-
721
- static VALUE sfloat_store_int8(VALUE self, VALUE obj) {
722
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
723
- ndfunc_t ndf = { iter_sfloat_store_int8, FULL_LOOP, 2, 0, ain, 0 };
724
-
725
- na_ndloop(&ndf, 2, self, obj);
726
- return self;
727
- }
728
-
729
- static void iter_sfloat_store_uint64(na_loop_t* const lp) {
730
- size_t i, s1, s2;
731
- char *p1, *p2;
732
- size_t *idx1, *idx2;
733
- u_int64_t x;
734
- dtype y;
735
-
736
- INIT_COUNTER(lp, i);
737
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
738
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
739
- if (idx2) {
740
- if (idx1) {
741
- for (; i--;) {
742
- GET_DATA_INDEX(p2, idx2, u_int64_t, x);
743
- y = m_from_uint64(x);
744
- SET_DATA_INDEX(p1, idx1, dtype, y);
745
- }
746
- } else {
747
- for (; i--;) {
748
- GET_DATA_INDEX(p2, idx2, u_int64_t, x);
749
- y = m_from_uint64(x);
750
- SET_DATA_STRIDE(p1, s1, dtype, y);
751
- }
752
- }
753
- } else {
754
- if (idx1) {
755
- for (; i--;) {
756
- GET_DATA_STRIDE(p2, s2, u_int64_t, x);
757
- y = m_from_uint64(x);
758
- SET_DATA_INDEX(p1, idx1, dtype, y);
759
- }
760
- } else {
761
- for (; i--;) {
762
- GET_DATA_STRIDE(p2, s2, u_int64_t, x);
763
- y = m_from_uint64(x);
764
- SET_DATA_STRIDE(p1, s1, dtype, y);
765
- }
766
- }
767
- }
768
- }
769
-
770
- static VALUE sfloat_store_uint64(VALUE self, VALUE obj) {
771
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
772
- ndfunc_t ndf = { iter_sfloat_store_uint64, FULL_LOOP, 2, 0, ain, 0 };
773
-
774
- na_ndloop(&ndf, 2, self, obj);
775
- return self;
776
- }
777
-
778
- static void iter_sfloat_store_uint32(na_loop_t* const lp) {
779
- size_t i, s1, s2;
780
- char *p1, *p2;
781
- size_t *idx1, *idx2;
782
- u_int32_t x;
783
- dtype y;
784
-
785
- INIT_COUNTER(lp, i);
786
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
787
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
788
- if (idx2) {
789
- if (idx1) {
790
- for (; i--;) {
791
- GET_DATA_INDEX(p2, idx2, u_int32_t, x);
792
- y = m_from_uint32(x);
793
- SET_DATA_INDEX(p1, idx1, dtype, y);
794
- }
795
- } else {
796
- for (; i--;) {
797
- GET_DATA_INDEX(p2, idx2, u_int32_t, x);
798
- y = m_from_uint32(x);
799
- SET_DATA_STRIDE(p1, s1, dtype, y);
800
- }
801
- }
802
- } else {
803
- if (idx1) {
804
- for (; i--;) {
805
- GET_DATA_STRIDE(p2, s2, u_int32_t, x);
806
- y = m_from_uint32(x);
807
- SET_DATA_INDEX(p1, idx1, dtype, y);
808
- }
809
- } else {
810
- for (; i--;) {
811
- GET_DATA_STRIDE(p2, s2, u_int32_t, x);
812
- y = m_from_uint32(x);
813
- SET_DATA_STRIDE(p1, s1, dtype, y);
814
- }
815
- }
816
- }
817
- }
818
-
819
- static VALUE sfloat_store_uint32(VALUE self, VALUE obj) {
820
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
821
- ndfunc_t ndf = { iter_sfloat_store_uint32, FULL_LOOP, 2, 0, ain, 0 };
822
-
823
- na_ndloop(&ndf, 2, self, obj);
824
- return self;
825
- }
826
-
827
- static void iter_sfloat_store_uint16(na_loop_t* const lp) {
828
- size_t i, s1, s2;
829
- char *p1, *p2;
830
- size_t *idx1, *idx2;
831
- u_int16_t x;
832
- dtype y;
833
-
834
- INIT_COUNTER(lp, i);
835
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
836
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
837
- if (idx2) {
838
- if (idx1) {
839
- for (; i--;) {
840
- GET_DATA_INDEX(p2, idx2, u_int16_t, x);
841
- y = m_from_sint(x);
842
- SET_DATA_INDEX(p1, idx1, dtype, y);
843
- }
844
- } else {
845
- for (; i--;) {
846
- GET_DATA_INDEX(p2, idx2, u_int16_t, x);
847
- y = m_from_sint(x);
848
- SET_DATA_STRIDE(p1, s1, dtype, y);
849
- }
850
- }
851
- } else {
852
- if (idx1) {
853
- for (; i--;) {
854
- GET_DATA_STRIDE(p2, s2, u_int16_t, x);
855
- y = m_from_sint(x);
856
- SET_DATA_INDEX(p1, idx1, dtype, y);
857
- }
858
- } else {
859
- for (; i--;) {
860
- GET_DATA_STRIDE(p2, s2, u_int16_t, x);
861
- y = m_from_sint(x);
862
- SET_DATA_STRIDE(p1, s1, dtype, y);
863
- }
864
- }
865
- }
866
- }
867
-
868
- static VALUE sfloat_store_uint16(VALUE self, VALUE obj) {
869
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
870
- ndfunc_t ndf = { iter_sfloat_store_uint16, FULL_LOOP, 2, 0, ain, 0 };
871
-
872
- na_ndloop(&ndf, 2, self, obj);
873
- return self;
874
- }
875
-
876
- static void iter_sfloat_store_uint8(na_loop_t* const lp) {
877
- size_t i, s1, s2;
878
- char *p1, *p2;
879
- size_t *idx1, *idx2;
880
- u_int8_t x;
881
- dtype y;
882
-
883
- INIT_COUNTER(lp, i);
884
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
885
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
886
- if (idx2) {
887
- if (idx1) {
888
- for (; i--;) {
889
- GET_DATA_INDEX(p2, idx2, u_int8_t, x);
890
- y = m_from_sint(x);
891
- SET_DATA_INDEX(p1, idx1, dtype, y);
892
- }
893
- } else {
894
- for (; i--;) {
895
- GET_DATA_INDEX(p2, idx2, u_int8_t, x);
896
- y = m_from_sint(x);
897
- SET_DATA_STRIDE(p1, s1, dtype, y);
898
- }
899
- }
900
- } else {
901
- if (idx1) {
902
- for (; i--;) {
903
- GET_DATA_STRIDE(p2, s2, u_int8_t, x);
904
- y = m_from_sint(x);
905
- SET_DATA_INDEX(p1, idx1, dtype, y);
906
- }
907
- } else {
908
- for (; i--;) {
909
- GET_DATA_STRIDE(p2, s2, u_int8_t, x);
910
- y = m_from_sint(x);
911
- SET_DATA_STRIDE(p1, s1, dtype, y);
912
- }
913
- }
914
- }
915
- }
916
-
917
- static VALUE sfloat_store_uint8(VALUE self, VALUE obj) {
918
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
919
- ndfunc_t ndf = { iter_sfloat_store_uint8, FULL_LOOP, 2, 0, ain, 0 };
920
-
921
- na_ndloop(&ndf, 2, self, obj);
922
- return self;
923
- }
924
-
925
- static void iter_sfloat_store_robject(na_loop_t* const lp) {
926
- size_t i, s1, s2;
927
- char *p1, *p2;
928
- size_t *idx1, *idx2;
929
- VALUE x;
930
- dtype y;
931
-
932
- INIT_COUNTER(lp, i);
933
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
934
- INIT_PTR_IDX(lp, 1, p2, s2, idx2);
935
- if (idx2) {
936
- if (idx1) {
937
- for (; i--;) {
938
- GET_DATA_INDEX(p2, idx2, VALUE, x);
939
- y = m_num_to_data(x);
940
- SET_DATA_INDEX(p1, idx1, dtype, y);
941
- }
942
- } else {
943
- for (; i--;) {
944
- GET_DATA_INDEX(p2, idx2, VALUE, x);
945
- y = m_num_to_data(x);
946
- SET_DATA_STRIDE(p1, s1, dtype, y);
947
- }
948
- }
949
- } else {
950
- if (idx1) {
951
- for (; i--;) {
952
- GET_DATA_STRIDE(p2, s2, VALUE, x);
953
- y = m_num_to_data(x);
954
- SET_DATA_INDEX(p1, idx1, dtype, y);
955
- }
956
- } else {
957
- for (; i--;) {
958
- GET_DATA_STRIDE(p2, s2, VALUE, x);
959
- y = m_num_to_data(x);
960
- SET_DATA_STRIDE(p1, s1, dtype, y);
961
- }
962
- }
963
- }
964
- }
965
-
966
- static VALUE sfloat_store_robject(VALUE self, VALUE obj) {
967
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { Qnil, 0 } };
968
- ndfunc_t ndf = { iter_sfloat_store_robject, FULL_LOOP, 2, 0, ain, 0 };
969
-
970
- na_ndloop(&ndf, 2, self, obj);
971
- return self;
972
- }
973
-
974
- static void iter_sfloat_store_array(na_loop_t* const lp) {
975
- size_t i, n;
976
- size_t i1, n1;
977
- VALUE v1, *ptr;
978
- char* p1;
979
- size_t s1, *idx1;
980
- VALUE x;
981
- double y;
982
- dtype z;
983
- size_t len, c;
984
- double beg, step;
985
-
986
- INIT_COUNTER(lp, n);
987
- INIT_PTR_IDX(lp, 0, p1, s1, idx1);
988
- v1 = lp->args[1].value;
989
- i = 0;
990
-
991
- if (lp->args[1].ptr) {
992
- if (v1 == Qtrue) {
993
- iter_sfloat_store_sfloat(lp);
994
- i = lp->args[1].shape[0];
995
- if (idx1) {
996
- idx1 += i;
997
- } else {
998
- p1 += s1 * i;
999
- }
1000
- }
1001
- goto loop_end;
1002
- }
1003
-
1004
- ptr = &v1;
1005
-
1006
- switch (TYPE(v1)) {
1007
- case T_ARRAY:
1008
- n1 = RARRAY_LEN(v1);
1009
- ptr = RARRAY_PTR(v1);
1010
- break;
1011
- case T_NIL:
1012
- n1 = 0;
1013
- break;
1014
- default:
1015
- n1 = 1;
1016
- }
1017
-
1018
- if (idx1) {
1019
- for (i = i1 = 0; i1 < n1 && i < n; i++, i1++) {
1020
- x = ptr[i1];
1021
- if (rb_obj_is_kind_of(x, rb_cRange)
1022
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
1023
- || rb_obj_is_kind_of(x, rb_cArithSeq)
1024
- #else
1025
- || rb_obj_is_kind_of(x, rb_cEnumerator)
1026
- #endif
1027
- ) {
1028
- nary_step_sequence(x, &len, &beg, &step);
1029
- for (c = 0; c < len && i < n; c++, i++) {
1030
- y = beg + step * c;
1031
- z = m_from_double(y);
1032
- SET_DATA_INDEX(p1, idx1, dtype, z);
1033
- }
1034
- } else if (TYPE(x) != T_ARRAY) {
1035
- z = m_num_to_data(x);
1036
- SET_DATA_INDEX(p1, idx1, dtype, z);
1037
- }
1038
- }
1039
- } else {
1040
- for (i = i1 = 0; i1 < n1 && i < n; i++, i1++) {
1041
- x = ptr[i1];
1042
- if (rb_obj_is_kind_of(x, rb_cRange)
1043
- #ifdef HAVE_RB_ARITHMETIC_SEQUENCE_EXTRACT
1044
- || rb_obj_is_kind_of(x, rb_cArithSeq)
1045
- #else
1046
- || rb_obj_is_kind_of(x, rb_cEnumerator)
1047
- #endif
1048
- ) {
1049
- nary_step_sequence(x, &len, &beg, &step);
1050
- for (c = 0; c < len && i < n; c++, i++) {
1051
- y = beg + step * c;
1052
- z = m_from_double(y);
1053
- SET_DATA_STRIDE(p1, s1, dtype, z);
1054
- }
1055
- } else if (TYPE(x) != T_ARRAY) {
1056
- z = m_num_to_data(x);
1057
- SET_DATA_STRIDE(p1, s1, dtype, z);
1058
- }
1059
- }
1060
- }
1061
-
1062
- loop_end:
1063
- z = m_zero;
1064
- if (idx1) {
1065
- for (; i < n; i++) {
1066
- SET_DATA_INDEX(p1, idx1, dtype, z);
1067
- }
1068
- } else {
1069
- for (; i < n; i++) {
1070
- SET_DATA_STRIDE(p1, s1, dtype, z);
1071
- }
1072
- }
1073
- }
1074
-
1075
- static VALUE sfloat_store_array(VALUE self, VALUE rary) {
1076
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { rb_cArray, 0 } };
1077
- ndfunc_t ndf = { iter_sfloat_store_array, FULL_LOOP, 2, 0, ain, 0 };
1078
-
1079
- na_ndloop_store_rarray(&ndf, self, rary);
1080
- return self;
1081
- }
1082
-
1083
- static VALUE sfloat_store(VALUE self, VALUE obj) {
1084
- VALUE r, klass;
1085
-
1086
- klass = rb_obj_class(obj);
1087
-
1088
- if (klass == numo_cSFloat) {
1089
- sfloat_store_sfloat(self, obj);
1090
- return self;
1091
- }
1092
-
1093
- if (IS_INTEGER_CLASS(klass) || klass == rb_cFloat || klass == rb_cComplex) {
1094
- sfloat_store_numeric(self, obj);
1095
- return self;
1096
- }
1097
-
1098
- if (klass == numo_cBit) {
1099
- sfloat_store_bit(self, obj);
1100
- return self;
1101
- }
1102
-
1103
- if (klass == numo_cDFloat) {
1104
- sfloat_store_dfloat(self, obj);
1105
- return self;
1106
- }
1107
-
1108
- if (klass == numo_cInt64) {
1109
- sfloat_store_int64(self, obj);
1110
- return self;
1111
- }
1112
-
1113
- if (klass == numo_cInt32) {
1114
- sfloat_store_int32(self, obj);
1115
- return self;
1116
- }
1117
-
1118
- if (klass == numo_cInt16) {
1119
- sfloat_store_int16(self, obj);
1120
- return self;
1121
- }
1122
-
1123
- if (klass == numo_cInt8) {
1124
- sfloat_store_int8(self, obj);
1125
- return self;
1126
- }
1127
-
1128
- if (klass == numo_cUInt64) {
1129
- sfloat_store_uint64(self, obj);
1130
- return self;
1131
- }
1132
-
1133
- if (klass == numo_cUInt32) {
1134
- sfloat_store_uint32(self, obj);
1135
- return self;
1136
- }
1137
-
1138
- if (klass == numo_cUInt16) {
1139
- sfloat_store_uint16(self, obj);
1140
- return self;
1141
- }
1142
-
1143
- if (klass == numo_cUInt8) {
1144
- sfloat_store_uint8(self, obj);
1145
- return self;
1146
- }
1147
-
1148
- if (klass == numo_cRObject) {
1149
- sfloat_store_robject(self, obj);
1150
- return self;
1151
- }
1152
-
1153
- if (klass == rb_cArray) {
1154
- sfloat_store_array(self, obj);
1155
- return self;
1156
- }
1157
-
1158
- if (IsNArray(obj)) {
1159
- r = rb_funcall(obj, rb_intern("coerce_cast"), 1, cT);
1160
- if (rb_obj_class(r) == cT) {
1161
- sfloat_store(self, r);
1162
- return self;
1163
- }
1164
- }
1165
-
1166
- rb_raise(
1167
- nary_eCastError, "unknown conversion from %s to %s", rb_class2name(rb_obj_class(obj)),
1168
- rb_class2name(rb_obj_class(self))
1169
- );
1170
-
1171
- return self;
1172
- }
1173
-
1174
- /*
1175
- Convert a data value of obj (with a single element) to dtype.
1176
- */
1177
- static dtype sfloat_extract_data(VALUE obj) {
1178
- narray_t* na;
1179
- dtype x;
1180
- char* ptr;
1181
- size_t pos;
1182
- VALUE r, klass;
1183
-
1184
- if (IsNArray(obj)) {
1185
- GetNArray(obj, na);
1186
- if (na->size != 1) {
1187
- rb_raise(nary_eShapeError, "narray size should be 1");
1188
- }
1189
- klass = rb_obj_class(obj);
1190
- ptr = na_get_pointer_for_read(obj);
1191
- pos = na_get_offset(obj);
1192
-
1193
- if (klass == numo_cSFloat) {
1194
- x = m_from_real(*(float*)(ptr + pos));
1195
- return x;
1196
- }
1197
-
1198
- if (klass == numo_cBit) {
1199
- {
1200
- BIT_DIGIT b;
1201
- LOAD_BIT(ptr, pos, b);
1202
- x = m_from_sint(b);
1203
- };
1204
- return x;
1205
- }
1206
-
1207
- if (klass == numo_cDFloat) {
1208
- x = m_from_real(*(double*)(ptr + pos));
1209
- return x;
1210
- }
1211
-
1212
- if (klass == numo_cInt64) {
1213
- x = m_from_int64(*(int64_t*)(ptr + pos));
1214
- return x;
1215
- }
1216
-
1217
- if (klass == numo_cInt32) {
1218
- x = m_from_int32(*(int32_t*)(ptr + pos));
1219
- return x;
1220
- }
1221
-
1222
- if (klass == numo_cInt16) {
1223
- x = m_from_sint(*(int16_t*)(ptr + pos));
1224
- return x;
1225
- }
1226
-
1227
- if (klass == numo_cInt8) {
1228
- x = m_from_sint(*(int8_t*)(ptr + pos));
1229
- return x;
1230
- }
1231
-
1232
- if (klass == numo_cUInt64) {
1233
- x = m_from_uint64(*(u_int64_t*)(ptr + pos));
1234
- return x;
1235
- }
1236
-
1237
- if (klass == numo_cUInt32) {
1238
- x = m_from_uint32(*(u_int32_t*)(ptr + pos));
1239
- return x;
1240
- }
1241
-
1242
- if (klass == numo_cUInt16) {
1243
- x = m_from_sint(*(u_int16_t*)(ptr + pos));
1244
- return x;
1245
- }
1246
-
1247
- if (klass == numo_cUInt8) {
1248
- x = m_from_sint(*(u_int8_t*)(ptr + pos));
1249
- return x;
1250
- }
1251
-
1252
- if (klass == numo_cRObject) {
1253
- x = m_num_to_data(*(VALUE*)(ptr + pos));
1254
- return x;
1255
- }
1256
-
1257
- // coerce
1258
- r = rb_funcall(obj, rb_intern("coerce_cast"), 1, cT);
1259
- if (rb_obj_class(r) == cT) {
1260
- return sfloat_extract_data(r);
1261
- }
1262
-
1263
- rb_raise(
1264
- nary_eCastError, "unknown conversion from %s to %s", rb_class2name(rb_obj_class(obj)),
1265
- rb_class2name(cT)
1266
- );
1267
- }
1268
- if (TYPE(obj) == T_ARRAY) {
1269
- if (RARRAY_LEN(obj) != 1) {
1270
- rb_raise(nary_eShapeError, "array size should be 1");
1271
- }
1272
- return m_num_to_data(RARRAY_AREF(obj, 0));
1273
- }
1274
- return m_num_to_data(obj);
1275
- }
1276
-
1277
- static VALUE sfloat_cast_array(VALUE rary) {
1278
- VALUE nary;
1279
- narray_t* na;
1280
-
1281
- nary = na_s_new_like(cT, rary);
1282
- GetNArray(nary, na);
1283
- if (na->size > 0) {
1284
- sfloat_store_array(nary, rary);
1285
- }
1286
- return nary;
1287
- }
1288
-
1289
- static VALUE sfloat_s_cast(VALUE type, VALUE obj) {
1290
- VALUE v;
1291
- narray_t* na;
1292
- dtype x;
1293
-
1294
- if (rb_obj_class(obj) == cT) {
1295
- return obj;
1296
- }
1297
- if (RTEST(rb_obj_is_kind_of(obj, rb_cNumeric))) {
1298
- x = m_num_to_data(obj);
1299
- return sfloat_new_dim0(x);
1300
- }
1301
- if (RTEST(rb_obj_is_kind_of(obj, rb_cArray))) {
1302
- return sfloat_cast_array(obj);
1303
- }
1304
- if (IsNArray(obj)) {
1305
- GetNArray(obj, na);
1306
- v = nary_new(cT, NA_NDIM(na), NA_SHAPE(na));
1307
- if (NA_SIZE(na) > 0) {
1308
- sfloat_store(v, obj);
1309
- }
1310
- return v;
1311
- }
1312
- if (rb_respond_to(obj, id_to_a)) {
1313
- obj = rb_funcall(obj, id_to_a, 0);
1314
- if (TYPE(obj) != T_ARRAY) {
1315
- rb_raise(rb_eTypeError, "`to_a' did not return Array");
1316
- }
1317
- return sfloat_cast_array(obj);
1318
- }
1319
-
1320
- rb_raise(nary_eCastError, "cannot cast to %s", rb_class2name(type));
1321
- return Qnil;
1322
- }
1323
-
1324
- static VALUE sfloat_aset(int argc, VALUE* argv, VALUE self) {
1325
- int nd;
1326
- size_t pos;
1327
- char* ptr;
1328
- VALUE a;
1329
- dtype x;
1330
-
1331
- argc--;
1332
- if (argc == 0) {
1333
- sfloat_store(self, argv[argc]);
1334
- } else {
1335
- nd = na_get_result_dimension(self, argc, argv, sizeof(dtype), &pos);
1336
- if (nd) {
1337
- a = na_aref_main(argc, argv, self, 0, nd);
1338
- sfloat_store(a, argv[argc]);
1339
- } else {
1340
- x = sfloat_extract_data(argv[argc]);
1341
- ptr = na_get_pointer_for_read_write(self) + pos;
1342
- *(dtype*)ptr = x;
1343
- }
1344
- }
1345
- return argv[argc];
1346
- }
1347
-
1348
- /*
1349
- qsort.c
1350
- Ruby/Numo::NArray - Numerical Array class for Ruby
1351
- modified by Masahiro TANAKA
1352
- */
1353
-
1354
- /*
1355
- * qsort.c: standard quicksort algorithm
1356
- *
1357
- * Modifications from vanilla NetBSD source:
1358
- * Add do ... while() macro fix
1359
- * Remove __inline, _DIAGASSERTs, __P
1360
- * Remove ill-considered "swap_cnt" switch to insertion sort,
1361
- * in favor of a simple check for presorted input.
1362
- *
1363
- * CAUTION: if you change this file, see also qsort_arg.c
1364
- *
1365
- * $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
1366
- */
1367
-
1368
- /* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
1369
-
1370
- /*-
1371
- * Copyright (c) 1992, 1993
1372
- * The Regents of the University of California. All rights reserved.
1373
- *
1374
- * Redistribution and use in source and binary forms, with or without
1375
- * modification, are permitted provided that the following conditions
1376
- * are met:
1377
- * 1. Redistributions of source code must retain the above copyright
1378
- * notice, this list of conditions and the following disclaimer.
1379
- * 2. Redistributions in binary form must reproduce the above copyright
1380
- * notice, this list of conditions and the following disclaimer in the
1381
- * documentation and/or other materials provided with the distribution.
1382
- * 3. Neither the name of the University nor the names of its contributors
1383
- * may be used to endorse or promote products derived from this software
1384
- * without specific prior written permission.
1385
- *
1386
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1387
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1388
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1389
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1390
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1391
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1392
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1393
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1394
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1395
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1396
- * SUCH DAMAGE.
1397
- */
1398
-
1399
- #ifndef QSORT_INCL
1400
- #define QSORT_INCL
1401
- #define Min(x, y) ((x) < (y) ? (x) : (y))
1402
-
1403
- /*
1404
- * Qsort routine based on J. L. Bentley and M. D. McIlroy,
1405
- * "Engineering a sort function",
1406
- * Software--Practice and Experience 23 (1993) 1249-1265.
1407
- * We have modified their original by adding a check for already-sorted input,
1408
- * which seems to be a win per discussions on pgsql-hackers around 2006-03-21.
1409
- */
1410
- #define swapcode(TYPE, parmi, parmj, n) \
1411
- do { \
1412
- size_t i = (n) / sizeof(TYPE); \
1413
- TYPE* pi = (TYPE*)(void*)(parmi); \
1414
- TYPE* pj = (TYPE*)(void*)(parmj); \
1415
- do { \
1416
- TYPE t = *pi; \
1417
- *pi++ = *pj; \
1418
- *pj++ = t; \
1419
- } while (--i > 0); \
1420
- } while (0)
1421
-
1422
- #ifdef HAVE_STDINT_H
1423
- #define SWAPINIT(a, es) \
1424
- swaptype = (uintptr_t)(a) % sizeof(long) || (es) % sizeof(long) ? 2 \
1425
- : (es) == sizeof(long) ? 0 \
1426
- : 1;
1427
- #else
1428
- #define SWAPINIT(a, es) \
1429
- swaptype = ((char*)(a) - (char*)0) % sizeof(long) || (es) % sizeof(long) ? 2 \
1430
- : (es) == sizeof(long) ? 0 \
1431
- : 1;
1432
- #endif
1433
-
1434
- static inline void swapfunc(char* a, char* b, size_t n, int swaptype) {
1435
- if (swaptype <= 1)
1436
- swapcode(long, a, b, n);
1437
- else
1438
- swapcode(char, a, b, n);
1439
- }
1440
-
1441
- #define swap(a, b) \
1442
- if (swaptype == 0) { \
1443
- long t = *(long*)(void*)(a); \
1444
- *(long*)(void*)(a) = *(long*)(void*)(b); \
1445
- *(long*)(void*)(b) = t; \
1446
- } else \
1447
- swapfunc(a, b, es, swaptype)
1448
-
1449
- #define vecswap(a, b, n) \
1450
- if ((n) > 0) swapfunc((a), (b), (size_t)(n), swaptype)
1451
-
1452
- #define med3(a, b, c, _cmp) \
1453
- (cmpgt(b, a) ? (cmpgt(c, b) ? b : (cmpgt(c, a) ? c : a)) \
1454
- : (cmpgt(b, c) ? b : (cmpgt(c, a) ? a : c)))
1455
- #endif
1456
-
1457
- #undef qsort_dtype
1458
- #define qsort_dtype dtype
1459
- #undef qsort_cast
1460
- #define qsort_cast *(dtype*)
1461
- #undef cmp
1462
- #define cmp(a, b) cmp_prnan(a, b)
1463
- #undef cmpgt
1464
- #define cmpgt(a, b) cmpgt_prnan(a, b)
1465
-
1466
- static void sfloat_qsort_prnan(void* a, size_t n, ssize_t es) {
1467
- char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
1468
- int d, r, swaptype, presorted;
1469
-
1470
- loop:
1471
- SWAPINIT(a, es);
1472
- if (n < 7) {
1473
- for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
1474
- for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
1475
- return;
1476
- }
1477
- presorted = 1;
1478
- for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
1479
- if (cmpgt(pm - es, pm)) {
1480
- presorted = 0;
1481
- break;
1482
- }
1483
- }
1484
- if (presorted) return;
1485
- pm = (char*)a + (n / 2) * es;
1486
- if (n > 7) {
1487
- pl = (char*)a;
1488
- pn = (char*)a + (n - 1) * es;
1489
- if (n > 40) {
1490
- d = (int)((n / 8) * es);
1491
- pl = med3(pl, pl + d, pl + 2 * d, cmp);
1492
- pm = med3(pm - d, pm, pm + d, cmp);
1493
- pn = med3(pn - 2 * d, pn - d, pn, cmp);
1494
- }
1495
- pm = med3(pl, pm, pn, cmp);
1496
- }
1497
- swap(a, pm);
1498
- pa = pb = (char*)a + es;
1499
- pc = pd = (char*)a + (n - 1) * es;
1500
- for (;;) {
1501
- while (pb <= pc && (r = cmp(pb, a)) <= 0) {
1502
- if (r == 0) {
1503
- swap(pa, pb);
1504
- pa += es;
1505
- }
1506
- pb += es;
1507
- }
1508
- while (pb <= pc && (r = cmp(pc, a)) >= 0) {
1509
- if (r == 0) {
1510
- swap(pc, pd);
1511
- pd -= es;
1512
- }
1513
- pc -= es;
1514
- }
1515
- if (pb > pc) break;
1516
- swap(pb, pc);
1517
- pb += es;
1518
- pc -= es;
1519
- }
1520
- pn = (char*)a + n * es;
1521
- r = (int)Min(pa - (char*)a, pb - pa);
1522
- vecswap(a, pb - r, r);
1523
- r = (int)Min(pd - pc, pn - pd - es);
1524
- vecswap(pb, pn - r, r);
1525
- if ((r = (int)(pb - pa)) > es) sfloat_qsort_prnan(a, r / es, es);
1526
- if ((r = (int)(pd - pc)) > es) {
1527
- /* Iterate rather than recurse to save stack space */
1528
- a = pn - r;
1529
- n = r / es;
1530
- goto loop;
1531
- }
1532
- /* qsort(pn - r, r / es, es, cmp);*/
1533
- }
1534
-
1535
- /*
1536
- qsort.c
1537
- Ruby/Numo::NArray - Numerical Array class for Ruby
1538
- modified by Masahiro TANAKA
1539
- */
1540
-
1541
- /*
1542
- * qsort.c: standard quicksort algorithm
1543
- *
1544
- * Modifications from vanilla NetBSD source:
1545
- * Add do ... while() macro fix
1546
- * Remove __inline, _DIAGASSERTs, __P
1547
- * Remove ill-considered "swap_cnt" switch to insertion sort,
1548
- * in favor of a simple check for presorted input.
1549
- *
1550
- * CAUTION: if you change this file, see also qsort_arg.c
1551
- *
1552
- * $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
1553
- */
1554
-
1555
- /* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
1556
-
1557
- /*-
1558
- * Copyright (c) 1992, 1993
1559
- * The Regents of the University of California. All rights reserved.
1560
- *
1561
- * Redistribution and use in source and binary forms, with or without
1562
- * modification, are permitted provided that the following conditions
1563
- * are met:
1564
- * 1. Redistributions of source code must retain the above copyright
1565
- * notice, this list of conditions and the following disclaimer.
1566
- * 2. Redistributions in binary form must reproduce the above copyright
1567
- * notice, this list of conditions and the following disclaimer in the
1568
- * documentation and/or other materials provided with the distribution.
1569
- * 3. Neither the name of the University nor the names of its contributors
1570
- * may be used to endorse or promote products derived from this software
1571
- * without specific prior written permission.
1572
- *
1573
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1574
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1575
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1576
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1577
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1578
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1579
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1580
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1581
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1582
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1583
- * SUCH DAMAGE.
1584
- */
1585
-
1586
- #undef qsort_dtype
1587
- #define qsort_dtype dtype
1588
- #undef qsort_cast
1589
- #define qsort_cast *(dtype*)
1590
- #undef cmp
1591
- #define cmp(a, b) cmp_ignan(a, b)
1592
- #undef cmpgt
1593
- #define cmpgt(a, b) cmpgt_ignan(a, b)
1594
-
1595
- static void sfloat_qsort_ignan(void* a, size_t n, ssize_t es) {
1596
- char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
1597
- int d, r, swaptype, presorted;
1598
-
1599
- loop:
1600
- SWAPINIT(a, es);
1601
- if (n < 7) {
1602
- for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
1603
- for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
1604
- return;
1605
- }
1606
- presorted = 1;
1607
- for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
1608
- if (cmpgt(pm - es, pm)) {
1609
- presorted = 0;
1610
- break;
1611
- }
1612
- }
1613
- if (presorted) return;
1614
- pm = (char*)a + (n / 2) * es;
1615
- if (n > 7) {
1616
- pl = (char*)a;
1617
- pn = (char*)a + (n - 1) * es;
1618
- if (n > 40) {
1619
- d = (int)((n / 8) * es);
1620
- pl = med3(pl, pl + d, pl + 2 * d, cmp);
1621
- pm = med3(pm - d, pm, pm + d, cmp);
1622
- pn = med3(pn - 2 * d, pn - d, pn, cmp);
1623
- }
1624
- pm = med3(pl, pm, pn, cmp);
1625
- }
1626
- swap(a, pm);
1627
- pa = pb = (char*)a + es;
1628
- pc = pd = (char*)a + (n - 1) * es;
1629
- for (;;) {
1630
- while (pb <= pc && (r = cmp(pb, a)) <= 0) {
1631
- if (r == 0) {
1632
- swap(pa, pb);
1633
- pa += es;
1634
- }
1635
- pb += es;
1636
- }
1637
- while (pb <= pc && (r = cmp(pc, a)) >= 0) {
1638
- if (r == 0) {
1639
- swap(pc, pd);
1640
- pd -= es;
1641
- }
1642
- pc -= es;
1643
- }
1644
- if (pb > pc) break;
1645
- swap(pb, pc);
1646
- pb += es;
1647
- pc -= es;
1648
- }
1649
- pn = (char*)a + n * es;
1650
- r = (int)Min(pa - (char*)a, pb - pa);
1651
- vecswap(a, pb - r, r);
1652
- r = (int)Min(pd - pc, pn - pd - es);
1653
- vecswap(pb, pn - r, r);
1654
- if ((r = (int)(pb - pa)) > es) sfloat_qsort_ignan(a, r / es, es);
1655
- if ((r = (int)(pd - pc)) > es) {
1656
- /* Iterate rather than recurse to save stack space */
1657
- a = pn - r;
1658
- n = r / es;
1659
- goto loop;
1660
- }
1661
- /* qsort(pn - r, r / es, es, cmp);*/
1662
- }
1663
-
1664
- static void iter_sfloat_sort_ignan(na_loop_t* const lp) {
1665
- size_t n;
1666
- char* ptr;
1667
- ssize_t step;
1668
-
1669
- INIT_COUNTER(lp, n);
1670
- INIT_PTR(lp, 0, ptr, step);
1671
- sfloat_qsort_ignan(ptr, n, step);
1672
- }
1673
- static void iter_sfloat_sort_prnan(na_loop_t* const lp) {
1674
- size_t n;
1675
- char* ptr;
1676
- ssize_t step;
1677
-
1678
- INIT_COUNTER(lp, n);
1679
- INIT_PTR(lp, 0, ptr, step);
1680
- sfloat_qsort_prnan(ptr, n, step);
1681
- }
1682
-
1683
- static VALUE sfloat_sort(int argc, VALUE* argv, VALUE self) {
1684
- VALUE reduce;
1685
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_reduce, 0 } };
1686
- ndfunc_t ndf = { 0, NDF_HAS_LOOP | NDF_FLAT_REDUCE, 2, 0, ain, 0 };
1687
-
1688
- if (!TEST_INPLACE(self)) {
1689
- self = na_copy(self);
1690
- }
1691
-
1692
- ndf.func = iter_sfloat_sort_ignan;
1693
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_sfloat_sort_prnan);
1694
-
1695
- na_ndloop(&ndf, 2, self, reduce);
1696
- return self;
1697
- }
1698
-
1699
- /*
1700
- qsort.c
1701
- Ruby/Numo::NArray - Numerical Array class for Ruby
1702
- modified by Masahiro TANAKA
1703
- */
1704
-
1705
- /*
1706
- * qsort.c: standard quicksort algorithm
1707
- *
1708
- * Modifications from vanilla NetBSD source:
1709
- * Add do ... while() macro fix
1710
- * Remove __inline, _DIAGASSERTs, __P
1711
- * Remove ill-considered "swap_cnt" switch to insertion sort,
1712
- * in favor of a simple check for presorted input.
1713
- *
1714
- * CAUTION: if you change this file, see also qsort_arg.c
1715
- *
1716
- * $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
1717
- */
1718
-
1719
- /* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
1720
-
1721
- /*-
1722
- * Copyright (c) 1992, 1993
1723
- * The Regents of the University of California. All rights reserved.
1724
- *
1725
- * Redistribution and use in source and binary forms, with or without
1726
- * modification, are permitted provided that the following conditions
1727
- * are met:
1728
- * 1. Redistributions of source code must retain the above copyright
1729
- * notice, this list of conditions and the following disclaimer.
1730
- * 2. Redistributions in binary form must reproduce the above copyright
1731
- * notice, this list of conditions and the following disclaimer in the
1732
- * documentation and/or other materials provided with the distribution.
1733
- * 3. Neither the name of the University nor the names of its contributors
1734
- * may be used to endorse or promote products derived from this software
1735
- * without specific prior written permission.
1736
- *
1737
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1738
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1739
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1740
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1741
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1742
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1743
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1744
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1745
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1746
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1747
- * SUCH DAMAGE.
1748
- */
1749
-
1750
- #undef qsort_dtype
1751
- #define qsort_dtype dtype*
1752
- #undef qsort_cast
1753
- #define qsort_cast **(dtype**)
1754
- #undef cmp
1755
- #define cmp(a, b) cmp_prnan(a, b)
1756
- #undef cmpgt
1757
- #define cmpgt(a, b) cmpgt_prnan(a, b)
1758
-
1759
- static void sfloat_index_qsort_prnan(void* a, size_t n, ssize_t es) {
1760
- char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
1761
- int d, r, swaptype, presorted;
1762
-
1763
- loop:
1764
- SWAPINIT(a, es);
1765
- if (n < 7) {
1766
- for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
1767
- for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
1768
- return;
1769
- }
1770
- presorted = 1;
1771
- for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
1772
- if (cmpgt(pm - es, pm)) {
1773
- presorted = 0;
1774
- break;
1775
- }
1776
- }
1777
- if (presorted) return;
1778
- pm = (char*)a + (n / 2) * es;
1779
- if (n > 7) {
1780
- pl = (char*)a;
1781
- pn = (char*)a + (n - 1) * es;
1782
- if (n > 40) {
1783
- d = (int)((n / 8) * es);
1784
- pl = med3(pl, pl + d, pl + 2 * d, cmp);
1785
- pm = med3(pm - d, pm, pm + d, cmp);
1786
- pn = med3(pn - 2 * d, pn - d, pn, cmp);
1787
- }
1788
- pm = med3(pl, pm, pn, cmp);
1789
- }
1790
- swap(a, pm);
1791
- for (pa = pb = (char*)a + es, pc = pd = (char*)a + (n - 1) * es; pb <= pc;
1792
- pb += es, pc -= es) {
1793
- while (pb <= pc && (r = cmp(pb, a)) <= 0) {
1794
- if (r == 0) {
1795
- swap(pa, pb);
1796
- pa += es;
1797
- }
1798
- pb += es;
1799
- }
1800
- while (pb <= pc && (r = cmp(pc, a)) >= 0) {
1801
- if (r == 0) {
1802
- swap(pc, pd);
1803
- pd -= es;
1804
- }
1805
- pc -= es;
1806
- }
1807
- if (pb > pc) break;
1808
- swap(pb, pc);
1809
- }
1810
- pn = (char*)a + n * es;
1811
- r = (int)Min(pa - (char*)a, pb - pa);
1812
- vecswap(a, pb - r, r);
1813
- r = (int)Min(pd - pc, pn - pd - es);
1814
- vecswap(pb, pn - r, r);
1815
- if ((r = (int)(pb - pa)) > es) sfloat_index_qsort_prnan(a, r / es, es);
1816
- if ((r = (int)(pd - pc)) > es) {
1817
- /* Iterate rather than recurse to save stack space */
1818
- a = pn - r;
1819
- n = r / es;
1820
- goto loop;
1821
- }
1822
- /* qsort(pn - r, r / es, es, cmp);*/
1823
- }
1824
-
1825
- /*
1826
- qsort.c
1827
- Ruby/Numo::NArray - Numerical Array class for Ruby
1828
- modified by Masahiro TANAKA
1829
- */
1830
-
1831
- /*
1832
- * qsort.c: standard quicksort algorithm
1833
- *
1834
- * Modifications from vanilla NetBSD source:
1835
- * Add do ... while() macro fix
1836
- * Remove __inline, _DIAGASSERTs, __P
1837
- * Remove ill-considered "swap_cnt" switch to insertion sort,
1838
- * in favor of a simple check for presorted input.
1839
- *
1840
- * CAUTION: if you change this file, see also qsort_arg.c
1841
- *
1842
- * $PostgreSQL: pgsql/src/port/qsort.c,v 1.12 2006/10/19 20:56:22 tgl Exp $
1843
- */
1844
-
1845
- /* $NetBSD: qsort.c,v 1.13 2003/08/07 16:43:42 agc Exp $ */
1846
-
1847
- /*-
1848
- * Copyright (c) 1992, 1993
1849
- * The Regents of the University of California. All rights reserved.
1850
- *
1851
- * Redistribution and use in source and binary forms, with or without
1852
- * modification, are permitted provided that the following conditions
1853
- * are met:
1854
- * 1. Redistributions of source code must retain the above copyright
1855
- * notice, this list of conditions and the following disclaimer.
1856
- * 2. Redistributions in binary form must reproduce the above copyright
1857
- * notice, this list of conditions and the following disclaimer in the
1858
- * documentation and/or other materials provided with the distribution.
1859
- * 3. Neither the name of the University nor the names of its contributors
1860
- * may be used to endorse or promote products derived from this software
1861
- * without specific prior written permission.
1862
- *
1863
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1864
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1865
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1866
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1867
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1868
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1869
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1870
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1871
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1872
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1873
- * SUCH DAMAGE.
1874
- */
1875
-
1876
- #undef qsort_dtype
1877
- #define qsort_dtype dtype*
1878
- #undef qsort_cast
1879
- #define qsort_cast **(dtype**)
1880
- #undef cmp
1881
- #define cmp(a, b) cmp_ignan(a, b)
1882
- #undef cmpgt
1883
- #define cmpgt(a, b) cmpgt_ignan(a, b)
1884
-
1885
- static void sfloat_index_qsort_ignan(void* a, size_t n, ssize_t es) {
1886
- char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
1887
- int d, r, swaptype, presorted;
1888
-
1889
- loop:
1890
- SWAPINIT(a, es);
1891
- if (n < 7) {
1892
- for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es)
1893
- for (pl = pm; pl > (char*)a && cmpgt(pl - es, pl); pl -= es) swap(pl, pl - es);
1894
- return;
1895
- }
1896
- presorted = 1;
1897
- for (pm = (char*)a + es; pm < (char*)a + n * es; pm += es) {
1898
- if (cmpgt(pm - es, pm)) {
1899
- presorted = 0;
1900
- break;
1901
- }
1902
- }
1903
- if (presorted) return;
1904
- pm = (char*)a + (n / 2) * es;
1905
- if (n > 7) {
1906
- pl = (char*)a;
1907
- pn = (char*)a + (n - 1) * es;
1908
- if (n > 40) {
1909
- d = (int)((n / 8) * es);
1910
- pl = med3(pl, pl + d, pl + 2 * d, cmp);
1911
- pm = med3(pm - d, pm, pm + d, cmp);
1912
- pn = med3(pn - 2 * d, pn - d, pn, cmp);
1913
- }
1914
- pm = med3(pl, pm, pn, cmp);
1915
- }
1916
- swap(a, pm);
1917
- for (pa = pb = (char*)a + es, pc = pd = (char*)a + (n - 1) * es; pb <= pc;
1918
- pb += es, pc -= es) {
1919
- while (pb <= pc && (r = cmp(pb, a)) <= 0) {
1920
- if (r == 0) {
1921
- swap(pa, pb);
1922
- pa += es;
1923
- }
1924
- pb += es;
1925
- }
1926
- while (pb <= pc && (r = cmp(pc, a)) >= 0) {
1927
- if (r == 0) {
1928
- swap(pc, pd);
1929
- pd -= es;
1930
- }
1931
- pc -= es;
1932
- }
1933
- if (pb > pc) break;
1934
- swap(pb, pc);
1935
- }
1936
- pn = (char*)a + n * es;
1937
- r = (int)Min(pa - (char*)a, pb - pa);
1938
- vecswap(a, pb - r, r);
1939
- r = (int)Min(pd - pc, pn - pd - es);
1940
- vecswap(pb, pn - r, r);
1941
- if ((r = (int)(pb - pa)) > es) sfloat_index_qsort_ignan(a, r / es, es);
1942
- if ((r = (int)(pd - pc)) > es) {
1943
- /* Iterate rather than recurse to save stack space */
1944
- a = pn - r;
1945
- n = r / es;
1946
- goto loop;
1947
- }
1948
- /* qsort(pn - r, r / es, es, cmp);*/
1949
- }
1950
-
1951
- #define idx_t int64_t
1952
- static void sfloat_index64_qsort_ignan(na_loop_t* const lp) {
1953
- size_t i, n, idx;
1954
- char *d_ptr, *i_ptr, *o_ptr;
1955
- ssize_t d_step, i_step, o_step;
1956
- char** ptr;
1957
-
1958
- INIT_COUNTER(lp, n);
1959
- INIT_PTR(lp, 0, d_ptr, d_step);
1960
- INIT_PTR(lp, 1, i_ptr, i_step);
1961
- INIT_PTR(lp, 2, o_ptr, o_step);
1962
-
1963
- ptr = (char**)(lp->opt_ptr);
1964
-
1965
- // 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);
1966
-
1967
- if (n == 1) {
1968
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr);
1969
- return;
1970
- }
1971
-
1972
- for (i = 0; i < n; i++) {
1973
- ptr[i] = d_ptr + d_step * i;
1974
- }
1975
-
1976
- sfloat_index_qsort_ignan(ptr, n, sizeof(dtype*));
1977
-
1978
- // d_ptr = lp->args[0].ptr;
1979
-
1980
- for (i = 0; i < n; i++) {
1981
- idx = (ptr[i] - d_ptr) / d_step;
1982
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
1983
- o_ptr += o_step;
1984
- }
1985
- }
1986
- #undef idx_t
1987
-
1988
- #define idx_t int32_t
1989
- static void sfloat_index32_qsort_ignan(na_loop_t* const lp) {
1990
- size_t i, n, idx;
1991
- char *d_ptr, *i_ptr, *o_ptr;
1992
- ssize_t d_step, i_step, o_step;
1993
- char** ptr;
1994
-
1995
- INIT_COUNTER(lp, n);
1996
- INIT_PTR(lp, 0, d_ptr, d_step);
1997
- INIT_PTR(lp, 1, i_ptr, i_step);
1998
- INIT_PTR(lp, 2, o_ptr, o_step);
1999
-
2000
- ptr = (char**)(lp->opt_ptr);
2001
-
2002
- // 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);
2003
-
2004
- if (n == 1) {
2005
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr);
2006
- return;
2007
- }
2008
-
2009
- for (i = 0; i < n; i++) {
2010
- ptr[i] = d_ptr + d_step * i;
2011
- }
2012
-
2013
- sfloat_index_qsort_ignan(ptr, n, sizeof(dtype*));
2014
-
2015
- // d_ptr = lp->args[0].ptr;
2016
-
2017
- for (i = 0; i < n; i++) {
2018
- idx = (ptr[i] - d_ptr) / d_step;
2019
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
2020
- o_ptr += o_step;
2021
- }
2022
- }
2023
- #undef idx_t
2024
-
2025
- #define idx_t int64_t
2026
- static void sfloat_index64_qsort_prnan(na_loop_t* const lp) {
2027
- size_t i, n, idx;
2028
- char *d_ptr, *i_ptr, *o_ptr;
2029
- ssize_t d_step, i_step, o_step;
2030
- char** ptr;
2031
-
2032
- INIT_COUNTER(lp, n);
2033
- INIT_PTR(lp, 0, d_ptr, d_step);
2034
- INIT_PTR(lp, 1, i_ptr, i_step);
2035
- INIT_PTR(lp, 2, o_ptr, o_step);
2036
-
2037
- ptr = (char**)(lp->opt_ptr);
2038
-
2039
- // 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);
2040
-
2041
- if (n == 1) {
2042
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr);
2043
- return;
2044
- }
2045
-
2046
- for (i = 0; i < n; i++) {
2047
- ptr[i] = d_ptr + d_step * i;
2048
- }
2049
-
2050
- sfloat_index_qsort_prnan(ptr, n, sizeof(dtype*));
2051
-
2052
- // d_ptr = lp->args[0].ptr;
2053
-
2054
- for (i = 0; i < n; i++) {
2055
- idx = (ptr[i] - d_ptr) / d_step;
2056
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
2057
- o_ptr += o_step;
2058
- }
2059
- }
2060
- #undef idx_t
2061
-
2062
- #define idx_t int32_t
2063
- static void sfloat_index32_qsort_prnan(na_loop_t* const lp) {
2064
- size_t i, n, idx;
2065
- char *d_ptr, *i_ptr, *o_ptr;
2066
- ssize_t d_step, i_step, o_step;
2067
- char** ptr;
2068
-
2069
- INIT_COUNTER(lp, n);
2070
- INIT_PTR(lp, 0, d_ptr, d_step);
2071
- INIT_PTR(lp, 1, i_ptr, i_step);
2072
- INIT_PTR(lp, 2, o_ptr, o_step);
2073
-
2074
- ptr = (char**)(lp->opt_ptr);
2075
-
2076
- // 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);
2077
-
2078
- if (n == 1) {
2079
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr);
2080
- return;
2081
- }
2082
-
2083
- for (i = 0; i < n; i++) {
2084
- ptr[i] = d_ptr + d_step * i;
2085
- }
2086
-
2087
- sfloat_index_qsort_prnan(ptr, n, sizeof(dtype*));
2088
-
2089
- // d_ptr = lp->args[0].ptr;
2090
-
2091
- for (i = 0; i < n; i++) {
2092
- idx = (ptr[i] - d_ptr) / d_step;
2093
- *(idx_t*)o_ptr = *(idx_t*)(i_ptr + i_step * idx);
2094
- o_ptr += o_step;
2095
- }
2096
- }
2097
- #undef idx_t
2098
-
2099
- static VALUE sfloat_sort_index(int argc, VALUE* argv, VALUE self) {
2100
- size_t size;
2101
- narray_t* na;
2102
- VALUE idx, tmp, reduce, res;
2103
- char* buf;
2104
- ndfunc_arg_in_t ain[3] = { { cT, 0 }, { 0, 0 }, { sym_reduce, 0 } };
2105
- ndfunc_arg_out_t aout[1] = { { 0, 0, 0 } };
2106
- ndfunc_t ndf = { 0, STRIDE_LOOP_NIP | NDF_FLAT_REDUCE | NDF_CUM, 3, 1, ain, aout };
2107
-
2108
- GetNArray(self, na);
2109
- if (na->ndim == 0) {
2110
- return INT2FIX(0);
2111
- }
2112
- if (na->size > (~(u_int32_t)0)) {
2113
- ain[1].type = aout[0].type = numo_cInt64;
2114
- idx = nary_new(numo_cInt64, na->ndim, na->shape);
2115
-
2116
- ndf.func = sfloat_index64_qsort_ignan;
2117
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, sfloat_index64_qsort_prnan);
2118
-
2119
- } else {
2120
- ain[1].type = aout[0].type = numo_cInt32;
2121
- idx = nary_new(numo_cInt32, na->ndim, na->shape);
2122
-
2123
- ndf.func = sfloat_index32_qsort_ignan;
2124
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, sfloat_index32_qsort_prnan);
2125
- }
2126
- rb_funcall(idx, rb_intern("seq"), 0);
2127
-
2128
- size = na->size * sizeof(void*); // max capa
2129
- buf = rb_alloc_tmp_buffer(&tmp, size);
2130
- res = na_ndloop3(&ndf, buf, 3, self, idx, reduce);
2131
- rb_free_tmp_buffer(&tmp);
2132
- return res;
2133
- }
2134
-
2135
- static void iter_sfloat_median_ignan(na_loop_t* const lp) {
2136
- size_t n;
2137
- char *p1, *p2;
2138
- dtype* buf;
2139
-
2140
- INIT_COUNTER(lp, n);
2141
- p1 = (lp->args[0]).ptr + (lp->args[0].iter[0]).pos;
2142
- p2 = (lp->args[1]).ptr + (lp->args[1].iter[0]).pos;
2143
- buf = (dtype*)p1;
2144
-
2145
- sfloat_qsort_ignan(buf, n, sizeof(dtype));
2146
-
2147
- for (; n; n--) {
2148
- if (!isnan(buf[n - 1])) break;
2149
- }
2150
-
2151
- if (n == 0) {
2152
- *(dtype*)p2 = buf[0];
2153
- } else if (n % 2 == 0) {
2154
- *(dtype*)p2 = (buf[n / 2 - 1] + buf[n / 2]) / 2;
2155
- } else {
2156
- *(dtype*)p2 = buf[(n - 1) / 2];
2157
- }
2158
- }
2159
- static void iter_sfloat_median_prnan(na_loop_t* const lp) {
2160
- size_t n;
2161
- char *p1, *p2;
2162
- dtype* buf;
2163
-
2164
- INIT_COUNTER(lp, n);
2165
- p1 = (lp->args[0]).ptr + (lp->args[0].iter[0]).pos;
2166
- p2 = (lp->args[1]).ptr + (lp->args[1].iter[0]).pos;
2167
- buf = (dtype*)p1;
2168
-
2169
- sfloat_qsort_prnan(buf, n, sizeof(dtype));
2170
-
2171
- for (; n; n--) {
2172
- if (!isnan(buf[n - 1])) break;
2173
- }
2174
-
2175
- if (n == 0) {
2176
- *(dtype*)p2 = buf[0];
2177
- } else if (n % 2 == 0) {
2178
- *(dtype*)p2 = (buf[n / 2 - 1] + buf[n / 2]) / 2;
2179
- } else {
2180
- *(dtype*)p2 = buf[(n - 1) / 2];
2181
- }
2182
- }
2183
-
2184
- static VALUE sfloat_median(int argc, VALUE* argv, VALUE self) {
2185
- VALUE v, reduce;
2186
- ndfunc_arg_in_t ain[2] = { { OVERWRITE, 0 }, { sym_reduce, 0 } };
2187
- ndfunc_arg_out_t aout[1] = { { INT2FIX(0), 0 } };
2188
- ndfunc_t ndf = { 0, NDF_HAS_LOOP | NDF_FLAT_REDUCE, 2, 1, ain, aout };
2189
-
2190
- self = na_copy(self); // as temporary buffer
2191
-
2192
- ndf.func = iter_sfloat_median_ignan;
2193
- reduce = na_reduce_dimension(argc, argv, 1, &self, &ndf, iter_sfloat_median_prnan);
2194
-
2195
- v = na_ndloop(&ndf, 2, self, reduce);
2196
- return sfloat_extract(v);
2197
- }
2198
-
2199
379
  VALUE mTM;
2200
380
 
2201
381
  void Init_numo_sfloat(void) {
@@ -2233,12 +413,7 @@ void Init_numo_sfloat(void) {
2233
413
  rb_define_const(cT, "UPCAST", hCast);
2234
414
  rb_hash_aset(hCast, rb_cArray, cT);
2235
415
 
2236
- #ifdef RUBY_INTEGER_UNIFICATION
2237
416
  rb_hash_aset(hCast, rb_cInteger, cT);
2238
- #else
2239
- rb_hash_aset(hCast, rb_cFixnum, cT);
2240
- rb_hash_aset(hCast, rb_cBignum, cT);
2241
- #endif
2242
417
  rb_hash_aset(hCast, rb_cFloat, cT);
2243
418
  rb_hash_aset(hCast, rb_cComplex, numo_cSComplex);
2244
419
  rb_hash_aset(hCast, numo_cRObject, numo_cRObject);