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