Mercurial > octave
comparison liboctave/oct-sort.cc @ 11586:12df7854fa7c
strip trailing whitespace from source files
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 20 Jan 2011 17:24:59 -0500 |
parents | fd0a3ac60b0e |
children | 01b7a60e2ff0 |
comparison
equal
deleted
inserted
replaced
11585:1473d0cf86d2 | 11586:12df7854fa7c |
---|---|
25 code I ripped-off. | 25 code I ripped-off. |
26 | 26 |
27 As required in the Python license the short description of the changes | 27 As required in the Python license the short description of the changes |
28 made are | 28 made are |
29 | 29 |
30 * convert the sorting code in listobject.cc into a generic class, | 30 * convert the sorting code in listobject.cc into a generic class, |
31 replacing PyObject* with the type of the class T. | 31 replacing PyObject* with the type of the class T. |
32 | 32 |
33 * replaced usages of malloc, free, memcpy and memmove by standard C++ | 33 * replaced usages of malloc, free, memcpy and memmove by standard C++ |
34 new [], delete [] and std::copy and std::copy_backward. Note that replacing | 34 new [], delete [] and std::copy and std::copy_backward. Note that replacing |
35 memmove by std::copy is possible if the destination starts before the source. | 35 memmove by std::copy is possible if the destination starts before the source. |
36 If not, std::copy_backward needs to be used. | 36 If not, std::copy_backward needs to be used. |
37 | 37 |
38 * templatize comparison operator in most methods, provide possible dispatch | 38 * templatize comparison operator in most methods, provide possible dispatch |
39 | 39 |
40 * duplicate methods to avoid by-the-way indexed sorting | 40 * duplicate methods to avoid by-the-way indexed sorting |
41 | 41 |
42 * add methods for verifying sortedness of array | 42 * add methods for verifying sortedness of array |
115 #include "quit.h" | 115 #include "quit.h" |
116 #include "oct-sort.h" | 116 #include "oct-sort.h" |
117 #include "oct-locbuf.h" | 117 #include "oct-locbuf.h" |
118 | 118 |
119 template <class T> | 119 template <class T> |
120 octave_sort<T>::octave_sort (void) : | 120 octave_sort<T>::octave_sort (void) : |
121 compare (ascending_compare), ms (0) | 121 compare (ascending_compare), ms (0) |
122 { | 122 { |
123 } | 123 } |
124 | 124 |
125 template <class T> | 125 template <class T> |
126 octave_sort<T>::octave_sort (compare_fcn_type comp) | 126 octave_sort<T>::octave_sort (compare_fcn_type comp) |
127 : compare (comp), ms (0) | 127 : compare (comp), ms (0) |
128 { | 128 { |
129 } | 129 } |
130 | 130 |
131 template <class T> | 131 template <class T> |
132 octave_sort<T>::~octave_sort () | 132 octave_sort<T>::~octave_sort () |
133 { | 133 { |
134 delete ms; | 134 delete ms; |
135 } | 135 } |
136 | 136 |
137 template <class T> | 137 template <class T> |
138 void | 138 void |
147 } | 147 } |
148 | 148 |
149 template <class T> | 149 template <class T> |
150 template <class Comp> | 150 template <class Comp> |
151 void | 151 void |
152 octave_sort<T>::binarysort (T *data, octave_idx_type nel, | 152 octave_sort<T>::binarysort (T *data, octave_idx_type nel, |
153 octave_idx_type start, Comp comp) | 153 octave_idx_type start, Comp comp) |
154 { | 154 { |
155 if (start == 0) | 155 if (start == 0) |
156 ++start; | 156 ++start; |
157 | 157 |
158 for (; start < nel; ++start) | 158 for (; start < nel; ++start) |
159 { | 159 { |
160 /* set l to where *start belongs */ | 160 /* set l to where *start belongs */ |
161 octave_idx_type l = 0, r = start; | 161 octave_idx_type l = 0, r = start; |
162 T pivot = data[start]; | 162 T pivot = data[start]; |
163 /* Invariants: | 163 /* Invariants: |
164 * pivot >= all in [lo, l). | 164 * pivot >= all in [lo, l). |
165 * pivot < all in [r, start). | 165 * pivot < all in [r, start). |
166 * The second is vacuously true at the start. | 166 * The second is vacuously true at the start. |
167 */ | 167 */ |
168 do | 168 do |
169 { | 169 { |
170 octave_idx_type p = l + ((r - l) >> 1); | 170 octave_idx_type p = l + ((r - l) >> 1); |
171 if (comp (pivot, data[p])) | 171 if (comp (pivot, data[p])) |
172 r = p; | 172 r = p; |
173 else | 173 else |
174 l = p+1; | 174 l = p+1; |
175 } | 175 } |
176 while (l < r); | 176 while (l < r); |
177 /* The invariants still hold, so pivot >= all in [lo, l) and | 177 /* The invariants still hold, so pivot >= all in [lo, l) and |
178 pivot < all in [l, start), so pivot belongs at l. Note | 178 pivot < all in [l, start), so pivot belongs at l. Note |
179 that if there are elements equal to pivot, l points to the | 179 that if there are elements equal to pivot, l points to the |
180 first slot after them -- that's why this sort is stable. | 180 first slot after them -- that's why this sort is stable. |
191 } | 191 } |
192 | 192 |
193 template <class T> | 193 template <class T> |
194 template <class Comp> | 194 template <class Comp> |
195 void | 195 void |
196 octave_sort<T>::binarysort (T *data, octave_idx_type *idx, octave_idx_type nel, | 196 octave_sort<T>::binarysort (T *data, octave_idx_type *idx, octave_idx_type nel, |
197 octave_idx_type start, Comp comp) | 197 octave_idx_type start, Comp comp) |
198 { | 198 { |
199 if (start == 0) | 199 if (start == 0) |
200 ++start; | 200 ++start; |
201 | 201 |
202 for (; start < nel; ++start) | 202 for (; start < nel; ++start) |
203 { | 203 { |
204 /* set l to where *start belongs */ | 204 /* set l to where *start belongs */ |
205 octave_idx_type l = 0, r = start; | 205 octave_idx_type l = 0, r = start; |
206 T pivot = data[start]; | 206 T pivot = data[start]; |
207 /* Invariants: | 207 /* Invariants: |
208 * pivot >= all in [lo, l). | 208 * pivot >= all in [lo, l). |
209 * pivot < all in [r, start). | 209 * pivot < all in [r, start). |
210 * The second is vacuously true at the start. | 210 * The second is vacuously true at the start. |
211 */ | 211 */ |
212 do | 212 do |
213 { | 213 { |
214 octave_idx_type p = l + ((r - l) >> 1); | 214 octave_idx_type p = l + ((r - l) >> 1); |
215 if (comp (pivot, data[p])) | 215 if (comp (pivot, data[p])) |
216 r = p; | 216 r = p; |
217 else | 217 else |
218 l = p+1; | 218 l = p+1; |
219 } | 219 } |
220 while (l < r); | 220 while (l < r); |
221 /* The invariants still hold, so pivot >= all in [lo, l) and | 221 /* The invariants still hold, so pivot >= all in [lo, l) and |
222 pivot < all in [l, start), so pivot belongs at l. Note | 222 pivot < all in [l, start), so pivot belongs at l. Note |
223 that if there are elements equal to pivot, l points to the | 223 that if there are elements equal to pivot, l points to the |
224 first slot after them -- that's why this sort is stable. | 224 first slot after them -- that's why this sort is stable. |
272 n = 2; | 272 n = 2; |
273 | 273 |
274 if (comp (*lo, *(lo-1))) | 274 if (comp (*lo, *(lo-1))) |
275 { | 275 { |
276 descending = true; | 276 descending = true; |
277 for (lo = lo+1; lo < hi; ++lo, ++n) | 277 for (lo = lo+1; lo < hi; ++lo, ++n) |
278 { | 278 { |
279 if (comp (*lo, *(lo-1))) | 279 if (comp (*lo, *(lo-1))) |
280 ; | 280 ; |
281 else | 281 else |
282 break; | 282 break; |
283 } | 283 } |
284 } | 284 } |
285 else | 285 else |
286 { | 286 { |
287 for (lo = lo+1; lo < hi; ++lo, ++n) | 287 for (lo = lo+1; lo < hi; ++lo, ++n) |
288 { | 288 { |
289 if (comp (*lo, *(lo-1))) | 289 if (comp (*lo, *(lo-1))) |
290 break; | 290 break; |
291 } | 291 } |
292 } | 292 } |
332 { | 332 { |
333 /* a[hint] < key -- gallop right, until | 333 /* a[hint] < key -- gallop right, until |
334 * a[hint + lastofs] < key <= a[hint + ofs] | 334 * a[hint + lastofs] < key <= a[hint + ofs] |
335 */ | 335 */ |
336 const octave_idx_type maxofs = n - hint; /* &a[n-1] is highest */ | 336 const octave_idx_type maxofs = n - hint; /* &a[n-1] is highest */ |
337 while (ofs < maxofs) | 337 while (ofs < maxofs) |
338 { | 338 { |
339 if (comp (a[ofs], key)) | 339 if (comp (a[ofs], key)) |
340 { | 340 { |
341 lastofs = ofs; | 341 lastofs = ofs; |
342 ofs = (ofs << 1) + 1; | 342 ofs = (ofs << 1) + 1; |
350 ofs = maxofs; | 350 ofs = maxofs; |
351 /* Translate back to offsets relative to &a[0]. */ | 351 /* Translate back to offsets relative to &a[0]. */ |
352 lastofs += hint; | 352 lastofs += hint; |
353 ofs += hint; | 353 ofs += hint; |
354 } | 354 } |
355 else | 355 else |
356 { | 356 { |
357 /* key <= a[hint] -- gallop left, until | 357 /* key <= a[hint] -- gallop left, until |
358 * a[hint - ofs] < key <= a[hint - lastofs] | 358 * a[hint - ofs] < key <= a[hint - lastofs] |
359 */ | 359 */ |
360 const octave_idx_type maxofs = hint + 1; /* &a[0] is lowest */ | 360 const octave_idx_type maxofs = hint + 1; /* &a[0] is lowest */ |
361 while (ofs < maxofs) | 361 while (ofs < maxofs) |
362 { | 362 { |
363 if (comp (*(a-ofs), key)) | 363 if (comp (*(a-ofs), key)) |
364 break; | 364 break; |
365 /* key <= a[hint - ofs] */ | 365 /* key <= a[hint - ofs] */ |
366 lastofs = ofs; | 366 lastofs = ofs; |
380 /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the | 380 /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the |
381 * right of lastofs but no farther right than ofs. Do a binary | 381 * right of lastofs but no farther right than ofs. Do a binary |
382 * search, with invariant a[lastofs-1] < key <= a[ofs]. | 382 * search, with invariant a[lastofs-1] < key <= a[ofs]. |
383 */ | 383 */ |
384 ++lastofs; | 384 ++lastofs; |
385 while (lastofs < ofs) | 385 while (lastofs < ofs) |
386 { | 386 { |
387 octave_idx_type m = lastofs + ((ofs - lastofs) >> 1); | 387 octave_idx_type m = lastofs + ((ofs - lastofs) >> 1); |
388 | 388 |
389 if (comp (a[m], key)) | 389 if (comp (a[m], key)) |
390 lastofs = m+1; /* a[m] < key */ | 390 lastofs = m+1; /* a[m] < key */ |
426 { | 426 { |
427 /* key < a[hint] -- gallop left, until | 427 /* key < a[hint] -- gallop left, until |
428 * a[hint - ofs] <= key < a[hint - lastofs] | 428 * a[hint - ofs] <= key < a[hint - lastofs] |
429 */ | 429 */ |
430 const octave_idx_type maxofs = hint + 1; /* &a[0] is lowest */ | 430 const octave_idx_type maxofs = hint + 1; /* &a[0] is lowest */ |
431 while (ofs < maxofs) | 431 while (ofs < maxofs) |
432 { | 432 { |
433 if (comp (key, *(a-ofs))) | 433 if (comp (key, *(a-ofs))) |
434 { | 434 { |
435 lastofs = ofs; | 435 lastofs = ofs; |
436 ofs = (ofs << 1) + 1; | 436 ofs = (ofs << 1) + 1; |
445 /* Translate back to positive offsets relative to &a[0]. */ | 445 /* Translate back to positive offsets relative to &a[0]. */ |
446 k = lastofs; | 446 k = lastofs; |
447 lastofs = hint - ofs; | 447 lastofs = hint - ofs; |
448 ofs = hint - k; | 448 ofs = hint - k; |
449 } | 449 } |
450 else | 450 else |
451 { | 451 { |
452 /* a[hint] <= key -- gallop right, until | 452 /* a[hint] <= key -- gallop right, until |
453 * a[hint + lastofs] <= key < a[hint + ofs] | 453 * a[hint + lastofs] <= key < a[hint + ofs] |
454 */ | 454 */ |
455 const octave_idx_type maxofs = n - hint; /* &a[n-1] is highest */ | 455 const octave_idx_type maxofs = n - hint; /* &a[n-1] is highest */ |
456 while (ofs < maxofs) | 456 while (ofs < maxofs) |
457 { | 457 { |
458 if (comp (key, a[ofs])) | 458 if (comp (key, a[ofs])) |
459 break; | 459 break; |
460 /* a[hint + ofs] <= key */ | 460 /* a[hint + ofs] <= key */ |
461 lastofs = ofs; | 461 lastofs = ofs; |
474 /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the | 474 /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the |
475 * right of lastofs but no farther right than ofs. Do a binary | 475 * right of lastofs but no farther right than ofs. Do a binary |
476 * search, with invariant a[lastofs-1] <= key < a[ofs]. | 476 * search, with invariant a[lastofs-1] <= key < a[ofs]. |
477 */ | 477 */ |
478 ++lastofs; | 478 ++lastofs; |
479 while (lastofs < ofs) | 479 while (lastofs < ofs) |
480 { | 480 { |
481 octave_idx_type m = lastofs + ((ofs - lastofs) >> 1); | 481 octave_idx_type m = lastofs + ((ofs - lastofs) >> 1); |
482 | 482 |
483 if (comp (key, a[m])) | 483 if (comp (key, a[m])) |
484 ofs = m; /* key < a[m] */ | 484 ofs = m; /* key < a[m] */ |
534 octave_sort<T>::MergeState::getmem (octave_idx_type need) | 534 octave_sort<T>::MergeState::getmem (octave_idx_type need) |
535 { | 535 { |
536 if (need <= alloced) | 536 if (need <= alloced) |
537 return; | 537 return; |
538 | 538 |
539 need = roundupsize (need); | 539 need = roundupsize (need); |
540 /* Don't realloc! That can cost cycles to copy the old data, but | 540 /* Don't realloc! That can cost cycles to copy the old data, but |
541 * we don't care what's in the block. | 541 * we don't care what's in the block. |
542 */ | 542 */ |
543 delete [] a; | 543 delete [] a; |
544 delete [] ia; // Must do this or fool possible next getmemi. | 544 delete [] ia; // Must do this or fool possible next getmemi. |
552 octave_sort<T>::MergeState::getmemi (octave_idx_type need) | 552 octave_sort<T>::MergeState::getmemi (octave_idx_type need) |
553 { | 553 { |
554 if (ia && need <= alloced) | 554 if (ia && need <= alloced) |
555 return; | 555 return; |
556 | 556 |
557 need = roundupsize (need); | 557 need = roundupsize (need); |
558 /* Don't realloc! That can cost cycles to copy the old data, but | 558 /* Don't realloc! That can cost cycles to copy the old data, but |
559 * we don't care what's in the block. | 559 * we don't care what's in the block. |
560 */ | 560 */ |
561 delete [] a; | 561 delete [] a; |
562 delete [] ia; | 562 delete [] ia; |
573 * Return 0 if successful, -1 if error. | 573 * Return 0 if successful, -1 if error. |
574 */ | 574 */ |
575 template <class T> | 575 template <class T> |
576 template <class Comp> | 576 template <class Comp> |
577 int | 577 int |
578 octave_sort<T>::merge_lo (T *pa, octave_idx_type na, | 578 octave_sort<T>::merge_lo (T *pa, octave_idx_type na, |
579 T *pb, octave_idx_type nb, | 579 T *pb, octave_idx_type nb, |
580 Comp comp) | 580 Comp comp) |
581 { | 581 { |
582 octave_idx_type k; | 582 octave_idx_type k; |
583 T *dest; | 583 T *dest; |
608 for (;;) | 608 for (;;) |
609 { | 609 { |
610 | 610 |
611 // FIXME: these loops are candidates for further optimizations. | 611 // FIXME: these loops are candidates for further optimizations. |
612 // Rather than testing everything in each cycle, it may be more | 612 // Rather than testing everything in each cycle, it may be more |
613 // efficient to do it in hunks. | 613 // efficient to do it in hunks. |
614 if (comp (*pb, *pa)) | 614 if (comp (*pb, *pa)) |
615 { | 615 { |
616 *dest++ = *pb++; | 616 *dest++ = *pb++; |
617 ++bcount; | 617 ++bcount; |
618 acount = 0; | 618 acount = 0; |
708 } | 708 } |
709 | 709 |
710 template <class T> | 710 template <class T> |
711 template <class Comp> | 711 template <class Comp> |
712 int | 712 int |
713 octave_sort<T>::merge_lo (T *pa, octave_idx_type *ipa, octave_idx_type na, | 713 octave_sort<T>::merge_lo (T *pa, octave_idx_type *ipa, octave_idx_type na, |
714 T *pb, octave_idx_type *ipb, octave_idx_type nb, | 714 T *pb, octave_idx_type *ipb, octave_idx_type nb, |
715 Comp comp) | 715 Comp comp) |
716 { | 716 { |
717 octave_idx_type k; | 717 octave_idx_type k; |
718 T *dest; | 718 T *dest; |
855 * Return 0 if successful, -1 if error. | 855 * Return 0 if successful, -1 if error. |
856 */ | 856 */ |
857 template <class T> | 857 template <class T> |
858 template <class Comp> | 858 template <class Comp> |
859 int | 859 int |
860 octave_sort<T>::merge_hi (T *pa, octave_idx_type na, | 860 octave_sort<T>::merge_hi (T *pa, octave_idx_type na, |
861 T *pb, octave_idx_type nb, | 861 T *pb, octave_idx_type nb, |
862 Comp comp) | 862 Comp comp) |
863 { | 863 { |
864 octave_idx_type k; | 864 octave_idx_type k; |
865 T *dest; | 865 T *dest; |
881 if (na == 0) | 881 if (na == 0) |
882 goto Succeed; | 882 goto Succeed; |
883 if (nb == 1) | 883 if (nb == 1) |
884 goto CopyA; | 884 goto CopyA; |
885 | 885 |
886 for (;;) | 886 for (;;) |
887 { | 887 { |
888 octave_idx_type acount = 0; /* # of times A won in a row */ | 888 octave_idx_type acount = 0; /* # of times A won in a row */ |
889 octave_idx_type bcount = 0; /* # of times B won in a row */ | 889 octave_idx_type bcount = 0; /* # of times B won in a row */ |
890 | 890 |
891 /* Do the straightforward thing until (if ever) one run | 891 /* Do the straightforward thing until (if ever) one run |
892 * appears to win consistently. | 892 * appears to win consistently. |
893 */ | 893 */ |
894 for (;;) | 894 for (;;) |
895 { | 895 { |
896 if (comp (*pb, *pa)) | 896 if (comp (*pb, *pa)) |
897 { | 897 { |
898 *dest-- = *pa--; | 898 *dest-- = *pa--; |
899 ++acount; | 899 ++acount; |
902 if (na == 0) | 902 if (na == 0) |
903 goto Succeed; | 903 goto Succeed; |
904 if (acount >= min_gallop) | 904 if (acount >= min_gallop) |
905 break; | 905 break; |
906 } | 906 } |
907 else | 907 else |
908 { | 908 { |
909 *dest-- = *pb--; | 909 *dest-- = *pb--; |
910 ++bcount; | 910 ++bcount; |
911 acount = 0; | 911 acount = 0; |
912 --nb; | 912 --nb; |
921 * be a huge win. So try that, and continue galloping until | 921 * be a huge win. So try that, and continue galloping until |
922 * (if ever) neither run appears to be winning consistently | 922 * (if ever) neither run appears to be winning consistently |
923 * anymore. | 923 * anymore. |
924 */ | 924 */ |
925 ++min_gallop; | 925 ++min_gallop; |
926 do | 926 do |
927 { | 927 { |
928 min_gallop -= min_gallop > 1; | 928 min_gallop -= min_gallop > 1; |
929 ms->min_gallop = min_gallop; | 929 ms->min_gallop = min_gallop; |
930 k = gallop_right (*pb, basea, na, na-1, comp); | 930 k = gallop_right (*pb, basea, na, na-1, comp); |
931 if (k < 0) | 931 if (k < 0) |
932 goto Fail; | 932 goto Fail; |
933 k = na - k; | 933 k = na - k; |
934 acount = k; | 934 acount = k; |
935 if (k) | 935 if (k) |
936 { | 936 { |
937 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1; | 937 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1; |
938 pa -= k; | 938 pa -= k; |
939 na -= k; | 939 na -= k; |
940 if (na == 0) | 940 if (na == 0) |
948 k = gallop_left (*pa, baseb, nb, nb-1, comp); | 948 k = gallop_left (*pa, baseb, nb, nb-1, comp); |
949 if (k < 0) | 949 if (k < 0) |
950 goto Fail; | 950 goto Fail; |
951 k = nb - k; | 951 k = nb - k; |
952 bcount = k; | 952 bcount = k; |
953 if (k) | 953 if (k) |
954 { | 954 { |
955 dest -= k; | 955 dest -= k; |
956 pb -= k; | 956 pb -= k; |
957 std::copy (pb+1, pb+1 + k, dest+1); | 957 std::copy (pb+1, pb+1 + k, dest+1); |
958 nb -= k; | 958 nb -= k; |
992 } | 992 } |
993 | 993 |
994 template <class T> | 994 template <class T> |
995 template <class Comp> | 995 template <class Comp> |
996 int | 996 int |
997 octave_sort<T>::merge_hi (T *pa, octave_idx_type *ipa, octave_idx_type na, | 997 octave_sort<T>::merge_hi (T *pa, octave_idx_type *ipa, octave_idx_type na, |
998 T *pb, octave_idx_type *ipb, octave_idx_type nb, | 998 T *pb, octave_idx_type *ipb, octave_idx_type nb, |
999 Comp comp) | 999 Comp comp) |
1000 { | 1000 { |
1001 octave_idx_type k; | 1001 octave_idx_type k; |
1002 T *dest; | 1002 T *dest; |
1022 if (na == 0) | 1022 if (na == 0) |
1023 goto Succeed; | 1023 goto Succeed; |
1024 if (nb == 1) | 1024 if (nb == 1) |
1025 goto CopyA; | 1025 goto CopyA; |
1026 | 1026 |
1027 for (;;) | 1027 for (;;) |
1028 { | 1028 { |
1029 octave_idx_type acount = 0; /* # of times A won in a row */ | 1029 octave_idx_type acount = 0; /* # of times A won in a row */ |
1030 octave_idx_type bcount = 0; /* # of times B won in a row */ | 1030 octave_idx_type bcount = 0; /* # of times B won in a row */ |
1031 | 1031 |
1032 /* Do the straightforward thing until (if ever) one run | 1032 /* Do the straightforward thing until (if ever) one run |
1033 * appears to win consistently. | 1033 * appears to win consistently. |
1034 */ | 1034 */ |
1035 for (;;) | 1035 for (;;) |
1036 { | 1036 { |
1037 if (comp (*pb, *pa)) | 1037 if (comp (*pb, *pa)) |
1038 { | 1038 { |
1039 *dest-- = *pa--; *idest-- = *ipa--; | 1039 *dest-- = *pa--; *idest-- = *ipa--; |
1040 ++acount; | 1040 ++acount; |
1043 if (na == 0) | 1043 if (na == 0) |
1044 goto Succeed; | 1044 goto Succeed; |
1045 if (acount >= min_gallop) | 1045 if (acount >= min_gallop) |
1046 break; | 1046 break; |
1047 } | 1047 } |
1048 else | 1048 else |
1049 { | 1049 { |
1050 *dest-- = *pb--; *idest-- = *ipb--; | 1050 *dest-- = *pb--; *idest-- = *ipb--; |
1051 ++bcount; | 1051 ++bcount; |
1052 acount = 0; | 1052 acount = 0; |
1053 --nb; | 1053 --nb; |
1062 * be a huge win. So try that, and continue galloping until | 1062 * be a huge win. So try that, and continue galloping until |
1063 * (if ever) neither run appears to be winning consistently | 1063 * (if ever) neither run appears to be winning consistently |
1064 * anymore. | 1064 * anymore. |
1065 */ | 1065 */ |
1066 ++min_gallop; | 1066 ++min_gallop; |
1067 do | 1067 do |
1068 { | 1068 { |
1069 min_gallop -= min_gallop > 1; | 1069 min_gallop -= min_gallop > 1; |
1070 ms->min_gallop = min_gallop; | 1070 ms->min_gallop = min_gallop; |
1071 k = gallop_right (*pb, basea, na, na-1, comp); | 1071 k = gallop_right (*pb, basea, na, na-1, comp); |
1072 if (k < 0) | 1072 if (k < 0) |
1073 goto Fail; | 1073 goto Fail; |
1074 k = na - k; | 1074 k = na - k; |
1075 acount = k; | 1075 acount = k; |
1076 if (k) | 1076 if (k) |
1077 { | 1077 { |
1078 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1; | 1078 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1; |
1079 idest = std::copy_backward (ipa+1 - k, ipa+1, idest+1) - 1; | 1079 idest = std::copy_backward (ipa+1 - k, ipa+1, idest+1) - 1; |
1080 pa -= k; ipa -= k; | 1080 pa -= k; ipa -= k; |
1081 na -= k; | 1081 na -= k; |
1090 k = gallop_left (*pa, baseb, nb, nb-1, comp); | 1090 k = gallop_left (*pa, baseb, nb, nb-1, comp); |
1091 if (k < 0) | 1091 if (k < 0) |
1092 goto Fail; | 1092 goto Fail; |
1093 k = nb - k; | 1093 k = nb - k; |
1094 bcount = k; | 1094 bcount = k; |
1095 if (k) | 1095 if (k) |
1096 { | 1096 { |
1097 dest -= k; idest -= k; | 1097 dest -= k; idest -= k; |
1098 pb -= k; ipb -= k; | 1098 pb -= k; ipb -= k; |
1099 std::copy (pb+1, pb+1 + k, dest+1); | 1099 std::copy (pb+1, pb+1 + k, dest+1); |
1100 std::copy (ipb+1, ipb+1 + k, idest+1); | 1100 std::copy (ipb+1, ipb+1 + k, idest+1); |
1261 int | 1261 int |
1262 octave_sort<T>::merge_collapse (T *data, Comp comp) | 1262 octave_sort<T>::merge_collapse (T *data, Comp comp) |
1263 { | 1263 { |
1264 struct s_slice *p = ms->pending; | 1264 struct s_slice *p = ms->pending; |
1265 | 1265 |
1266 while (ms->n > 1) | 1266 while (ms->n > 1) |
1267 { | 1267 { |
1268 octave_idx_type n = ms->n - 2; | 1268 octave_idx_type n = ms->n - 2; |
1269 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len) | 1269 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len) |
1270 { | 1270 { |
1271 if (p[n-1].len < p[n+1].len) | 1271 if (p[n-1].len < p[n+1].len) |
1272 --n; | 1272 --n; |
1273 if (merge_at (n, data, comp) < 0) | 1273 if (merge_at (n, data, comp) < 0) |
1274 return -1; | 1274 return -1; |
1275 } | 1275 } |
1276 else if (p[n].len <= p[n+1].len) | 1276 else if (p[n].len <= p[n+1].len) |
1277 { | 1277 { |
1278 if (merge_at (n, data, comp) < 0) | 1278 if (merge_at (n, data, comp) < 0) |
1279 return -1; | 1279 return -1; |
1280 } | 1280 } |
1281 else | 1281 else |
1290 int | 1290 int |
1291 octave_sort<T>::merge_collapse (T *data, octave_idx_type *idx, Comp comp) | 1291 octave_sort<T>::merge_collapse (T *data, octave_idx_type *idx, Comp comp) |
1292 { | 1292 { |
1293 struct s_slice *p = ms->pending; | 1293 struct s_slice *p = ms->pending; |
1294 | 1294 |
1295 while (ms->n > 1) | 1295 while (ms->n > 1) |
1296 { | 1296 { |
1297 octave_idx_type n = ms->n - 2; | 1297 octave_idx_type n = ms->n - 2; |
1298 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len) | 1298 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len) |
1299 { | 1299 { |
1300 if (p[n-1].len < p[n+1].len) | 1300 if (p[n-1].len < p[n+1].len) |
1301 --n; | 1301 --n; |
1302 if (merge_at (n, data, idx, comp) < 0) | 1302 if (merge_at (n, data, idx, comp) < 0) |
1303 return -1; | 1303 return -1; |
1304 } | 1304 } |
1305 else if (p[n].len <= p[n+1].len) | 1305 else if (p[n].len <= p[n+1].len) |
1306 { | 1306 { |
1307 if (merge_at (n, data, idx, comp) < 0) | 1307 if (merge_at (n, data, idx, comp) < 0) |
1308 return -1; | 1308 return -1; |
1309 } | 1309 } |
1310 else | 1310 else |
1324 int | 1324 int |
1325 octave_sort<T>::merge_force_collapse (T *data, Comp comp) | 1325 octave_sort<T>::merge_force_collapse (T *data, Comp comp) |
1326 { | 1326 { |
1327 struct s_slice *p = ms->pending; | 1327 struct s_slice *p = ms->pending; |
1328 | 1328 |
1329 while (ms->n > 1) | 1329 while (ms->n > 1) |
1330 { | 1330 { |
1331 octave_idx_type n = ms->n - 2; | 1331 octave_idx_type n = ms->n - 2; |
1332 if (n > 0 && p[n-1].len < p[n+1].len) | 1332 if (n > 0 && p[n-1].len < p[n+1].len) |
1333 --n; | 1333 --n; |
1334 if (merge_at (n, data, comp) < 0) | 1334 if (merge_at (n, data, comp) < 0) |
1343 int | 1343 int |
1344 octave_sort<T>::merge_force_collapse (T *data, octave_idx_type *idx, Comp comp) | 1344 octave_sort<T>::merge_force_collapse (T *data, octave_idx_type *idx, Comp comp) |
1345 { | 1345 { |
1346 struct s_slice *p = ms->pending; | 1346 struct s_slice *p = ms->pending; |
1347 | 1347 |
1348 while (ms->n > 1) | 1348 while (ms->n > 1) |
1349 { | 1349 { |
1350 octave_idx_type n = ms->n - 2; | 1350 octave_idx_type n = ms->n - 2; |
1351 if (n > 0 && p[n-1].len < p[n+1].len) | 1351 if (n > 0 && p[n-1].len < p[n+1].len) |
1352 --n; | 1352 --n; |
1353 if (merge_at (n, data, idx, comp) < 0) | 1353 if (merge_at (n, data, idx, comp) < 0) |
1393 ms->reset (); | 1393 ms->reset (); |
1394 ms->getmem (1024); | 1394 ms->getmem (1024); |
1395 | 1395 |
1396 if (nel > 1) | 1396 if (nel > 1) |
1397 { | 1397 { |
1398 octave_idx_type nremaining = nel; | 1398 octave_idx_type nremaining = nel; |
1399 octave_idx_type lo = 0; | 1399 octave_idx_type lo = 0; |
1400 | 1400 |
1401 /* March over the array once, left to right, finding natural runs, | 1401 /* March over the array once, left to right, finding natural runs, |
1402 * and extending short natural runs to minrun elements. | 1402 * and extending short natural runs to minrun elements. |
1403 */ | 1403 */ |
1404 octave_idx_type minrun = merge_compute_minrun (nremaining); | 1404 octave_idx_type minrun = merge_compute_minrun (nremaining); |
1405 do | 1405 do |
1406 { | 1406 { |
1407 bool descending; | 1407 bool descending; |
1408 octave_idx_type n; | 1408 octave_idx_type n; |
1409 | 1409 |
1410 /* Identify next run. */ | 1410 /* Identify next run. */ |
1412 if (n < 0) | 1412 if (n < 0) |
1413 goto fail; | 1413 goto fail; |
1414 if (descending) | 1414 if (descending) |
1415 std::reverse (data + lo, data + lo + n); | 1415 std::reverse (data + lo, data + lo + n); |
1416 /* If short, extend to min(minrun, nremaining). */ | 1416 /* If short, extend to min(minrun, nremaining). */ |
1417 if (n < minrun) | 1417 if (n < minrun) |
1418 { | 1418 { |
1419 const octave_idx_type force = nremaining <= minrun ? nremaining : minrun; | 1419 const octave_idx_type force = nremaining <= minrun ? nremaining : minrun; |
1420 binarysort (data + lo, force, n, comp); | 1420 binarysort (data + lo, force, n, comp); |
1421 n = force; | 1421 n = force; |
1422 } | 1422 } |
1441 } | 1441 } |
1442 | 1442 |
1443 template <class T> | 1443 template <class T> |
1444 template <class Comp> | 1444 template <class Comp> |
1445 void | 1445 void |
1446 octave_sort<T>::sort (T *data, octave_idx_type *idx, octave_idx_type nel, | 1446 octave_sort<T>::sort (T *data, octave_idx_type *idx, octave_idx_type nel, |
1447 Comp comp) | 1447 Comp comp) |
1448 { | 1448 { |
1449 /* Re-initialize the Mergestate as this might be the second time called */ | 1449 /* Re-initialize the Mergestate as this might be the second time called */ |
1450 if (! ms) ms = new MergeState; | 1450 if (! ms) ms = new MergeState; |
1451 | 1451 |
1452 ms->reset (); | 1452 ms->reset (); |
1453 ms->getmemi (1024); | 1453 ms->getmemi (1024); |
1454 | 1454 |
1455 if (nel > 1) | 1455 if (nel > 1) |
1456 { | 1456 { |
1457 octave_idx_type nremaining = nel; | 1457 octave_idx_type nremaining = nel; |
1458 octave_idx_type lo = 0; | 1458 octave_idx_type lo = 0; |
1459 | 1459 |
1460 /* March over the array once, left to right, finding natural runs, | 1460 /* March over the array once, left to right, finding natural runs, |
1461 * and extending short natural runs to minrun elements. | 1461 * and extending short natural runs to minrun elements. |
1462 */ | 1462 */ |
1463 octave_idx_type minrun = merge_compute_minrun (nremaining); | 1463 octave_idx_type minrun = merge_compute_minrun (nremaining); |
1464 do | 1464 do |
1465 { | 1465 { |
1466 bool descending; | 1466 bool descending; |
1467 octave_idx_type n; | 1467 octave_idx_type n; |
1468 | 1468 |
1469 /* Identify next run. */ | 1469 /* Identify next run. */ |
1474 { | 1474 { |
1475 std::reverse (data + lo, data + lo + n); | 1475 std::reverse (data + lo, data + lo + n); |
1476 std::reverse (idx + lo, idx + lo + n); | 1476 std::reverse (idx + lo, idx + lo + n); |
1477 } | 1477 } |
1478 /* If short, extend to min(minrun, nremaining). */ | 1478 /* If short, extend to min(minrun, nremaining). */ |
1479 if (n < minrun) | 1479 if (n < minrun) |
1480 { | 1480 { |
1481 const octave_idx_type force = nremaining <= minrun ? nremaining : minrun; | 1481 const octave_idx_type force = nremaining <= minrun ? nremaining : minrun; |
1482 binarysort (data + lo, idx + lo, force, n, comp); | 1482 binarysort (data + lo, idx + lo, force, n, comp); |
1483 n = force; | 1483 n = force; |
1484 } | 1484 } |
1509 #ifdef INLINE_ASCENDING_SORT | 1509 #ifdef INLINE_ASCENDING_SORT |
1510 if (compare == ascending_compare) | 1510 if (compare == ascending_compare) |
1511 sort (data, nel, std::less<T> ()); | 1511 sort (data, nel, std::less<T> ()); |
1512 else | 1512 else |
1513 #endif | 1513 #endif |
1514 #ifdef INLINE_DESCENDING_SORT | 1514 #ifdef INLINE_DESCENDING_SORT |
1515 if (compare == descending_compare) | 1515 if (compare == descending_compare) |
1516 sort (data, nel, std::greater<T> ()); | 1516 sort (data, nel, std::greater<T> ()); |
1517 else | 1517 else |
1518 #endif | 1518 #endif |
1519 if (compare) | 1519 if (compare) |
1527 #ifdef INLINE_ASCENDING_SORT | 1527 #ifdef INLINE_ASCENDING_SORT |
1528 if (compare == ascending_compare) | 1528 if (compare == ascending_compare) |
1529 sort (data, idx, nel, std::less<T> ()); | 1529 sort (data, idx, nel, std::less<T> ()); |
1530 else | 1530 else |
1531 #endif | 1531 #endif |
1532 #ifdef INLINE_DESCENDING_SORT | 1532 #ifdef INLINE_DESCENDING_SORT |
1533 if (compare == descending_compare) | 1533 if (compare == descending_compare) |
1534 sort (data, idx, nel, std::greater<T> ()); | 1534 sort (data, idx, nel, std::greater<T> ()); |
1535 else | 1535 else |
1536 #endif | 1536 #endif |
1537 if (compare) | 1537 if (compare) |
1538 sort (data, idx, nel, compare); | 1538 sort (data, idx, nel, compare); |
1539 } | 1539 } |
1540 | 1540 |
1541 template <class T> template <class Comp> | 1541 template <class T> template <class Comp> |
1542 bool | 1542 bool |
1543 octave_sort<T>::is_sorted (const T *data, octave_idx_type nel, Comp comp) | 1543 octave_sort<T>::is_sorted (const T *data, octave_idx_type nel, Comp comp) |
1544 { | 1544 { |
1545 const T *end = data + nel; | 1545 const T *end = data + nel; |
1546 if (data != end) | 1546 if (data != end) |
1547 { | 1547 { |
1556 } | 1556 } |
1557 | 1557 |
1558 return data == end; | 1558 return data == end; |
1559 } | 1559 } |
1560 | 1560 |
1561 template <class T> | 1561 template <class T> |
1562 bool | 1562 bool |
1563 octave_sort<T>::is_sorted (const T *data, octave_idx_type nel) | 1563 octave_sort<T>::is_sorted (const T *data, octave_idx_type nel) |
1564 { | 1564 { |
1565 bool retval = false; | 1565 bool retval = false; |
1566 #ifdef INLINE_ASCENDING_SORT | 1566 #ifdef INLINE_ASCENDING_SORT |
1567 if (compare == ascending_compare) | 1567 if (compare == ascending_compare) |
1568 retval = is_sorted (data, nel, std::less<T> ()); | 1568 retval = is_sorted (data, nel, std::less<T> ()); |
1569 else | 1569 else |
1570 #endif | 1570 #endif |
1571 #ifdef INLINE_DESCENDING_SORT | 1571 #ifdef INLINE_DESCENDING_SORT |
1572 if (compare == descending_compare) | 1572 if (compare == descending_compare) |
1573 retval = is_sorted (data, nel, std::greater<T> ()); | 1573 retval = is_sorted (data, nel, std::greater<T> ()); |
1574 else | 1574 else |
1575 #endif | 1575 #endif |
1576 if (compare) | 1576 if (compare) |
1587 octave_idx_type col, ofs, nel; | 1587 octave_idx_type col, ofs, nel; |
1588 }; | 1588 }; |
1589 | 1589 |
1590 | 1590 |
1591 template <class T> template <class Comp> | 1591 template <class T> template <class Comp> |
1592 void | 1592 void |
1593 octave_sort<T>::sort_rows (const T *data, octave_idx_type *idx, | 1593 octave_sort<T>::sort_rows (const T *data, octave_idx_type *idx, |
1594 octave_idx_type rows, octave_idx_type cols, | 1594 octave_idx_type rows, octave_idx_type cols, |
1595 Comp comp) | 1595 Comp comp) |
1596 { | 1596 { |
1597 OCTAVE_LOCAL_BUFFER (T, buf, rows); | 1597 OCTAVE_LOCAL_BUFFER (T, buf, rows); |
1645 } | 1645 } |
1646 } | 1646 } |
1647 } | 1647 } |
1648 | 1648 |
1649 template <class T> | 1649 template <class T> |
1650 void | 1650 void |
1651 octave_sort<T>::sort_rows (const T *data, octave_idx_type *idx, | 1651 octave_sort<T>::sort_rows (const T *data, octave_idx_type *idx, |
1652 octave_idx_type rows, octave_idx_type cols) | 1652 octave_idx_type rows, octave_idx_type cols) |
1653 { | 1653 { |
1654 #ifdef INLINE_ASCENDING_SORT | 1654 #ifdef INLINE_ASCENDING_SORT |
1655 if (compare == ascending_compare) | 1655 if (compare == ascending_compare) |
1656 sort_rows (data, idx, rows, cols, std::less<T> ()); | 1656 sort_rows (data, idx, rows, cols, std::less<T> ()); |
1657 else | 1657 else |
1658 #endif | 1658 #endif |
1659 #ifdef INLINE_DESCENDING_SORT | 1659 #ifdef INLINE_DESCENDING_SORT |
1660 if (compare == descending_compare) | 1660 if (compare == descending_compare) |
1661 sort_rows (data, idx, rows, cols, std::greater<T> ()); | 1661 sort_rows (data, idx, rows, cols, std::greater<T> ()); |
1662 else | 1662 else |
1663 #endif | 1663 #endif |
1664 if (compare) | 1664 if (compare) |
1665 sort_rows (data, idx, rows, cols, compare); | 1665 sort_rows (data, idx, rows, cols, compare); |
1666 } | 1666 } |
1667 | 1667 |
1668 template <class T> template <class Comp> | 1668 template <class T> template <class Comp> |
1669 bool | 1669 bool |
1670 octave_sort<T>::is_sorted_rows (const T *data, octave_idx_type rows, | 1670 octave_sort<T>::is_sorted_rows (const T *data, octave_idx_type rows, |
1671 octave_idx_type cols, Comp comp) | 1671 octave_idx_type cols, Comp comp) |
1672 { | 1672 { |
1673 if (rows <= 1 || cols == 0) | 1673 if (rows <= 1 || cols == 0) |
1674 return true; | 1674 return true; |
1675 | 1675 |
1676 // This is a breadth-first traversal. | 1676 // This is a breadth-first traversal. |
1677 const T *lastrow = data + rows*(cols - 1); | 1677 const T *lastrow = data + rows*(cols - 1); |
1678 typedef std::pair<const T *, octave_idx_type> run_t; | 1678 typedef std::pair<const T *, octave_idx_type> run_t; |
1679 std::stack<run_t> runs; | 1679 std::stack<run_t> runs; |
1680 | 1680 |
1715 } | 1715 } |
1716 else | 1716 else |
1717 // The final column - use fast code. | 1717 // The final column - use fast code. |
1718 sorted = is_sorted (lo, n, comp); | 1718 sorted = is_sorted (lo, n, comp); |
1719 } | 1719 } |
1720 | 1720 |
1721 return sorted; | 1721 return sorted; |
1722 } | 1722 } |
1723 | 1723 |
1724 template <class T> | 1724 template <class T> |
1725 bool | 1725 bool |
1726 octave_sort<T>::is_sorted_rows (const T *data, octave_idx_type rows, | 1726 octave_sort<T>::is_sorted_rows (const T *data, octave_idx_type rows, |
1727 octave_idx_type cols) | 1727 octave_idx_type cols) |
1728 { | 1728 { |
1729 bool retval = false; | 1729 bool retval = false; |
1730 | 1730 |
1731 #ifdef INLINE_ASCENDING_SORT | 1731 #ifdef INLINE_ASCENDING_SORT |
1732 if (compare == ascending_compare) | 1732 if (compare == ascending_compare) |
1733 retval = is_sorted_rows (data, rows, cols, std::less<T> ()); | 1733 retval = is_sorted_rows (data, rows, cols, std::less<T> ()); |
1734 else | 1734 else |
1735 #endif | 1735 #endif |
1736 #ifdef INLINE_DESCENDING_SORT | 1736 #ifdef INLINE_DESCENDING_SORT |
1737 if (compare == descending_compare) | 1737 if (compare == descending_compare) |
1738 retval = is_sorted_rows (data, rows, cols, std::greater<T> ()); | 1738 retval = is_sorted_rows (data, rows, cols, std::greater<T> ()); |
1739 else | 1739 else |
1740 #endif | 1740 #endif |
1741 if (compare) | 1741 if (compare) |
1745 } | 1745 } |
1746 | 1746 |
1747 // The simple binary lookup. | 1747 // The simple binary lookup. |
1748 | 1748 |
1749 template <class T> template <class Comp> | 1749 template <class T> template <class Comp> |
1750 octave_idx_type | 1750 octave_idx_type |
1751 octave_sort<T>::lookup (const T *data, octave_idx_type nel, | 1751 octave_sort<T>::lookup (const T *data, octave_idx_type nel, |
1752 const T& value, Comp comp) | 1752 const T& value, Comp comp) |
1753 { | 1753 { |
1754 octave_idx_type lo = 0, hi = nel; | 1754 octave_idx_type lo = 0, hi = nel; |
1755 | 1755 |
1764 | 1764 |
1765 return lo; | 1765 return lo; |
1766 } | 1766 } |
1767 | 1767 |
1768 template <class T> | 1768 template <class T> |
1769 octave_idx_type | 1769 octave_idx_type |
1770 octave_sort<T>::lookup (const T *data, octave_idx_type nel, | 1770 octave_sort<T>::lookup (const T *data, octave_idx_type nel, |
1771 const T& value) | 1771 const T& value) |
1772 { | 1772 { |
1773 octave_idx_type retval = 0; | 1773 octave_idx_type retval = 0; |
1774 | 1774 |
1775 #ifdef INLINE_ASCENDING_SORT | 1775 #ifdef INLINE_ASCENDING_SORT |
1776 if (compare == ascending_compare) | 1776 if (compare == ascending_compare) |
1777 retval = lookup (data, nel, value, std::less<T> ()); | 1777 retval = lookup (data, nel, value, std::less<T> ()); |
1778 else | 1778 else |
1779 #endif | 1779 #endif |
1780 #ifdef INLINE_DESCENDING_SORT | 1780 #ifdef INLINE_DESCENDING_SORT |
1781 if (compare == descending_compare) | 1781 if (compare == descending_compare) |
1782 retval = lookup (data, nel, value, std::greater<T> ()); | 1782 retval = lookup (data, nel, value, std::greater<T> ()); |
1783 else | 1783 else |
1784 #endif | 1784 #endif |
1785 if (compare) | 1785 if (compare) |
1787 | 1787 |
1788 return retval; | 1788 return retval; |
1789 } | 1789 } |
1790 | 1790 |
1791 template <class T> template <class Comp> | 1791 template <class T> template <class Comp> |
1792 void | 1792 void |
1793 octave_sort<T>::lookup (const T *data, octave_idx_type nel, | 1793 octave_sort<T>::lookup (const T *data, octave_idx_type nel, |
1794 const T *values, octave_idx_type nvalues, | 1794 const T *values, octave_idx_type nvalues, |
1795 octave_idx_type *idx, Comp comp) | 1795 octave_idx_type *idx, Comp comp) |
1796 { | 1796 { |
1797 // Use a sequence of binary lookups. | 1797 // Use a sequence of binary lookups. |
1800 for (octave_idx_type j = 0; j < nvalues; j++) | 1800 for (octave_idx_type j = 0; j < nvalues; j++) |
1801 idx[j] = lookup (data, nel, values[j], comp); | 1801 idx[j] = lookup (data, nel, values[j], comp); |
1802 } | 1802 } |
1803 | 1803 |
1804 template <class T> | 1804 template <class T> |
1805 void | 1805 void |
1806 octave_sort<T>::lookup (const T *data, octave_idx_type nel, | 1806 octave_sort<T>::lookup (const T *data, octave_idx_type nel, |
1807 const T* values, octave_idx_type nvalues, | 1807 const T* values, octave_idx_type nvalues, |
1808 octave_idx_type *idx) | 1808 octave_idx_type *idx) |
1809 { | 1809 { |
1810 #ifdef INLINE_ASCENDING_SORT | 1810 #ifdef INLINE_ASCENDING_SORT |
1811 if (compare == ascending_compare) | 1811 if (compare == ascending_compare) |
1812 lookup (data, nel, values, nvalues, idx, std::less<T> ()); | 1812 lookup (data, nel, values, nvalues, idx, std::less<T> ()); |
1813 else | 1813 else |
1814 #endif | 1814 #endif |
1815 #ifdef INLINE_DESCENDING_SORT | 1815 #ifdef INLINE_DESCENDING_SORT |
1816 if (compare == descending_compare) | 1816 if (compare == descending_compare) |
1817 lookup (data, nel, values, nvalues, idx, std::greater<T> ()); | 1817 lookup (data, nel, values, nvalues, idx, std::greater<T> ()); |
1818 else | 1818 else |
1819 #endif | 1819 #endif |
1820 if (compare) | 1820 if (compare) |
1821 lookup (data, nel, values, nvalues, idx, std::ptr_fun (compare)); | 1821 lookup (data, nel, values, nvalues, idx, std::ptr_fun (compare)); |
1822 } | 1822 } |
1823 | 1823 |
1824 template <class T> template <class Comp> | 1824 template <class T> template <class Comp> |
1825 void | 1825 void |
1826 octave_sort<T>::lookup_sorted (const T *data, octave_idx_type nel, | 1826 octave_sort<T>::lookup_sorted (const T *data, octave_idx_type nel, |
1827 const T *values, octave_idx_type nvalues, | 1827 const T *values, octave_idx_type nvalues, |
1828 octave_idx_type *idx, bool rev, Comp comp) | 1828 octave_idx_type *idx, bool rev, Comp comp) |
1829 { | 1829 { |
1830 if (rev) | 1830 if (rev) |
1872 idx[j] = i; | 1872 idx[j] = i; |
1873 } | 1873 } |
1874 } | 1874 } |
1875 | 1875 |
1876 template <class T> | 1876 template <class T> |
1877 void | 1877 void |
1878 octave_sort<T>::lookup_sorted (const T *data, octave_idx_type nel, | 1878 octave_sort<T>::lookup_sorted (const T *data, octave_idx_type nel, |
1879 const T* values, octave_idx_type nvalues, | 1879 const T* values, octave_idx_type nvalues, |
1880 octave_idx_type *idx, bool rev) | 1880 octave_idx_type *idx, bool rev) |
1881 { | 1881 { |
1882 #ifdef INLINE_ASCENDING_SORT | 1882 #ifdef INLINE_ASCENDING_SORT |
1883 if (compare == ascending_compare) | 1883 if (compare == ascending_compare) |
1884 lookup_sorted (data, nel, values, nvalues, idx, rev, std::less<T> ()); | 1884 lookup_sorted (data, nel, values, nvalues, idx, rev, std::less<T> ()); |
1885 else | 1885 else |
1886 #endif | 1886 #endif |
1887 #ifdef INLINE_DESCENDING_SORT | 1887 #ifdef INLINE_DESCENDING_SORT |
1888 if (compare == descending_compare) | 1888 if (compare == descending_compare) |
1889 lookup_sorted (data, nel, values, nvalues, idx, rev, std::greater<T> ()); | 1889 lookup_sorted (data, nel, values, nvalues, idx, rev, std::greater<T> ()); |
1890 else | 1890 else |
1891 #endif | 1891 #endif |
1892 if (compare) | 1892 if (compare) |
1893 lookup_sorted (data, nel, values, nvalues, idx, rev, std::ptr_fun (compare)); | 1893 lookup_sorted (data, nel, values, nvalues, idx, rev, std::ptr_fun (compare)); |
1894 } | 1894 } |
1895 | 1895 |
1896 template <class T> template <class Comp> | 1896 template <class T> template <class Comp> |
1897 void | 1897 void |
1898 octave_sort<T>::nth_element (T *data, octave_idx_type nel, | 1898 octave_sort<T>::nth_element (T *data, octave_idx_type nel, |
1899 octave_idx_type lo, octave_idx_type up, | 1899 octave_idx_type lo, octave_idx_type up, |
1900 Comp comp) | 1900 Comp comp) |
1901 { | 1901 { |
1902 // Simply wrap the STL algorithms. | 1902 // Simply wrap the STL algorithms. |
1909 { | 1909 { |
1910 std::nth_element (data, data + lo, data + nel, comp); | 1910 std::nth_element (data, data + lo, data + nel, comp); |
1911 if (up == lo + 2) | 1911 if (up == lo + 2) |
1912 { | 1912 { |
1913 // Finding two subsequent elements. | 1913 // Finding two subsequent elements. |
1914 std::swap (data[lo+1], | 1914 std::swap (data[lo+1], |
1915 *std::min_element (data + lo + 1, data + nel, comp)); | 1915 *std::min_element (data + lo + 1, data + nel, comp)); |
1916 } | 1916 } |
1917 else | 1917 else |
1918 std::partial_sort (data + lo + 1, data + up, data + nel, comp); | 1918 std::partial_sort (data + lo + 1, data + up, data + nel, comp); |
1919 } | 1919 } |
1920 } | 1920 } |
1921 | 1921 |
1922 template <class T> | 1922 template <class T> |
1923 void | 1923 void |
1924 octave_sort<T>::nth_element (T *data, octave_idx_type nel, | 1924 octave_sort<T>::nth_element (T *data, octave_idx_type nel, |
1925 octave_idx_type lo, octave_idx_type up) | 1925 octave_idx_type lo, octave_idx_type up) |
1926 { | 1926 { |
1927 if (up < 0) | 1927 if (up < 0) |
1928 up = lo + 1; | 1928 up = lo + 1; |
1929 #ifdef INLINE_ASCENDING_SORT | 1929 #ifdef INLINE_ASCENDING_SORT |
1930 if (compare == ascending_compare) | 1930 if (compare == ascending_compare) |
1931 nth_element (data, nel, lo, up, std::less<T> ()); | 1931 nth_element (data, nel, lo, up, std::less<T> ()); |
1932 else | 1932 else |
1933 #endif | 1933 #endif |
1934 #ifdef INLINE_DESCENDING_SORT | 1934 #ifdef INLINE_DESCENDING_SORT |
1935 if (compare == descending_compare) | 1935 if (compare == descending_compare) |
1936 nth_element (data, nel, lo, up, std::greater<T> ()); | 1936 nth_element (data, nel, lo, up, std::greater<T> ()); |
1937 else | 1937 else |
1938 #endif | 1938 #endif |
1939 if (compare) | 1939 if (compare) |
1940 nth_element (data, nel, lo, up, std::ptr_fun (compare)); | 1940 nth_element (data, nel, lo, up, std::ptr_fun (compare)); |
1941 } | 1941 } |
1942 | 1942 |
1943 template <class T> | 1943 template <class T> |
1944 bool | 1944 bool |
1945 octave_sort<T>::ascending_compare (typename ref_param<T>::type x, | 1945 octave_sort<T>::ascending_compare (typename ref_param<T>::type x, |
1946 typename ref_param<T>::type y) | 1946 typename ref_param<T>::type y) |
1947 { | 1947 { |
1948 return x < y; | 1948 return x < y; |
1949 } | 1949 } |
1950 | 1950 |
1951 template <class T> | 1951 template <class T> |
1952 bool | 1952 bool |
1953 octave_sort<T>::descending_compare (typename ref_param<T>::type x, | 1953 octave_sort<T>::descending_compare (typename ref_param<T>::type x, |
1954 typename ref_param<T>::type y) | 1954 typename ref_param<T>::type y) |
1955 { | 1955 { |
1956 return x > y; | 1956 return x > y; |
1957 } | 1957 } |