112 #include <functional>
122 template <
typename T>
124 m_compare (ascending_compare), m_ms (nullptr)
127 template <
typename T>
129 : m_compare (comp), m_ms (nullptr)
132 template <
typename T>
138 template <
typename T>
143 m_compare = ascending_compare;
145 m_compare = descending_compare;
150 template <
typename T>
151 template <
typename Comp>
159 for (; start < nel; ++start)
164 T pivot = data[start];
173 if (comp (pivot, data[p]))
188 std::swap (pivot, data[p]);
195 template <
typename T>
196 template <
typename Comp>
204 for (; start < nel; ++start)
209 T pivot = data[start];
218 if (comp (pivot, data[p]))
233 std::swap (pivot, data[p]);
237 std::swap (ipivot, idx[p]);
262 template <
typename T>
263 template <
typename Comp>
278 if (comp (*lo, *(lo-1)))
281 for (lo = lo+1; lo < hi; ++lo, ++
n)
283 if (comp (*lo, *(lo-1)))
291 for (lo = lo+1; lo < hi; ++lo, ++
n)
293 if (comp (*lo, *(lo-1)))
322 template <
typename T>
323 template <
typename Comp>
344 if (comp (a[ofs], key))
347 ofs = (ofs << 1) + 1;
368 if (comp (*(a-ofs), key))
372 ofs = (ofs << 1) + 1;
380 lastofs = hint - ofs;
390 while (lastofs < ofs)
394 if (comp (a[
m], key))
417 template <
typename T>
418 template <
typename Comp>
439 if (comp (key, *(a-ofs)))
442 ofs = (ofs << 1) + 1;
453 lastofs = hint - ofs;
464 if (comp (key, a[ofs]))
468 ofs = (ofs << 1) + 1;
485 while (lastofs < ofs)
489 if (comp (key, a[
m]))
501 unsigned int nbits = 3;
532 size_t new_size = ((
n >> nbits) + 1) << nbits;
537 (*current_liboctave_error_handler)
538 (
"unable to allocate sufficient memory for sort");
546 template <
typename T>
564 template <
typename T>
568 if (m_ia && need <= m_alloced)
589 template <
typename T>
590 template <
typename Comp>
603 std::copy (pa, pa + na,
m_ms->
m_a);
636 if (bcount >= min_gallop)
647 if (acount >= min_gallop)
660 min_gallop -= (min_gallop > 1);
668 dest = std::copy (pa, pa + k, dest);
691 dest = std::copy (pb, pb + k, dest);
713 std::copy (pa, pa + na, dest);
718 std::copy (pb, pb + nb, dest);
724 template <
typename T>
725 template <
typename Comp>
739 std::copy (pa, pa + na,
m_ms->
m_a);
740 std::copy (ipa, ipa + na,
m_ms->
m_ia);
741 dest = pa; idest = ipa;
744 *dest++ = *pb++; *idest++ = *ipb++;
764 *dest++ = *pb++; *idest++ = *ipb++;
770 if (bcount >= min_gallop)
775 *dest++ = *pa++; *idest++ = *ipa++;
781 if (acount >= min_gallop)
794 min_gallop -= (min_gallop > 1);
802 dest = std::copy (pa, pa + k, dest);
803 idest = std::copy (ipa, ipa + k, idest);
815 *dest++ = *pb++; *idest++ = *ipb++;
826 dest = std::copy (pb, pb + k, dest);
827 idest = std::copy (ipb, ipb + k, idest);
833 *dest++ = *pa++; *idest++ = *ipa++;
850 std::copy (pa, pa + na, dest);
851 std::copy (ipa, ipa + na, idest);
857 std::copy (pb, pb + nb, dest);
858 std::copy (ipb, ipb + nb, idest);
871 template <
typename T>
872 template <
typename Comp>
887 std::copy (pb, pb + nb,
m_ms->
m_a);
918 if (acount >= min_gallop)
929 if (bcount >= min_gallop)
942 min_gallop -= (min_gallop > 1);
951 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1;
971 std::copy (pb+1, pb+1 + k, dest+1);
996 std::copy (baseb, baseb + nb, dest-(nb-1));
1001 dest = std::copy_backward (pa+1 - na, pa+1, dest+1) - 1;
1008 template <
typename T>
1009 template <
typename Comp>
1026 idest = ipb + nb - 1;
1027 std::copy (pb, pb + nb,
m_ms->
m_a);
1028 std::copy (ipb, ipb + nb,
m_ms->
m_ia);
1032 pa += na - 1; ipa += na - 1;
1034 *dest-- = *pa--; *idest-- = *ipa--;
1051 if (comp (*pb, *pa))
1053 *dest-- = *pa--; *idest-- = *ipa--;
1059 if (acount >= min_gallop)
1064 *dest-- = *pb--; *idest-- = *ipb--;
1070 if (bcount >= min_gallop)
1083 min_gallop -= (min_gallop > 1);
1092 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1;
1093 idest = std::copy_backward (ipa+1 - k, ipa+1, idest+1) - 1;
1099 *dest-- = *pb--; *idest-- = *ipb--;
1111 dest -= k; idest -= k;
1113 std::copy (pb+1, pb+1 + k, dest+1);
1114 std::copy (ipb+1, ipb+1 + k, idest+1);
1125 *dest-- = *pa--; *idest-- = *ipa--;
1140 std::copy (baseb, baseb + nb, dest-(nb-1));
1141 std::copy (ibaseb, ibaseb + nb, idest-(nb-1));
1147 dest = std::copy_backward (pa+1 - na, pa+1, dest+1) - 1;
1148 idest = std::copy_backward (ipa+1 - na, ipa+1, idest+1) - 1;
1149 pa -= na; ipa -= na;
1150 *dest = *pb; *idest = *ipb;
1158 template <
typename T>
1159 template <
typename Comp>
1204 return merge_lo (pa, na, pb, nb, comp);
1206 return merge_hi (pa, na, pb, nb, comp);
1209 template <
typename T>
1210 template <
typename Comp>
1258 return merge_lo (pa, ipa, na, pb, ipb, nb, comp);
1260 return merge_hi (pa, ipa, na, pb, ipb, nb, comp);
1273 template <
typename T>
1274 template <
typename Comp>
1283 if (
n > 0 && p[
n-1].m_len <= p[
n].m_len + p[
n+1].m_len)
1285 if (p[
n-1].m_len < p[
n+1].m_len)
1290 else if (p[
n].m_len <= p[
n+1].m_len)
1302 template <
typename T>
1303 template <
typename Comp>
1312 if (
n > 0 && p[
n-1].m_len <= p[
n].m_len + p[
n+1].m_len)
1314 if (p[
n-1].m_len < p[
n+1].m_len)
1319 else if (p[
n].m_len <= p[
n+1].m_len)
1336 template <
typename T>
1337 template <
typename Comp>
1346 if (
n > 0 && p[
n-1].m_len < p[
n+1].m_len)
1355 template <
typename T>
1356 template <
typename Comp>
1365 if (
n > 0 && p[
n-1].m_len < p[
n+1].m_len)
1384 template <
typename T>
1399 template <
typename T>
1400 template <
typename Comp>
1425 n =
count_run (data + lo, nremaining, descending, comp);
1429 std::reverse (data + lo, data + lo +
n);
1455 template <
typename T>
1456 template <
typename Comp>
1482 n =
count_run (data + lo, nremaining, descending, comp);
1487 std::reverse (data + lo, data + lo +
n);
1488 std::reverse (idx + lo, idx + lo +
n);
1515 template <
typename T>
1519 #if defined (INLINE_ASCENDING_SORT)
1521 sort (data, nel, std::less<T> ());
1524 #if defined (INLINE_DESCENDING_SORT)
1526 sort (data, nel, std::greater<T> ());
1533 template <
typename T>
1537 #if defined (INLINE_ASCENDING_SORT)
1539 sort (data, idx, nel, std::less<T> ());
1542 #if defined (INLINE_DESCENDING_SORT)
1544 sort (data, idx, nel, std::greater<T> ());
1551 template <
typename T>
1552 template <
typename Comp>
1556 const T *end = data + nel;
1559 const T *
next = data;
1560 while (++
next != end)
1562 if (comp (*
next, *data))
1572 template <
typename T>
1577 #if defined (INLINE_ASCENDING_SORT)
1582 #if defined (INLINE_DESCENDING_SORT)
1597 : col (c), ofs (o), nel (
n) { }
1601 template <
typename T>
1602 template <
typename Comp>
1612 if (cols == 0 || rows <= 1)
1617 std::stack<run_t> runs;
1619 runs.push (run_t (0, 0, rows));
1621 while (! runs.empty ())
1629 T *lbuf = buf + ofs;
1630 const T *ldata = data + rows*col;
1635 lbuf[i] = ldata[lidx[i]];
1638 sort (lbuf, lidx, nel, comp);
1646 if (comp (lbuf[lst], lbuf[i]))
1649 runs.push (run_t (col+1, ofs + lst, i - lst));
1654 runs.push (run_t (col+1, ofs + lst, nel - lst));
1659 template <
typename T>
1664 #if defined (INLINE_ASCENDING_SORT)
1666 sort_rows (data, idx, rows, cols, std::less<T> ());
1669 #if defined (INLINE_DESCENDING_SORT)
1671 sort_rows (data, idx, rows, cols, std::greater<T> ());
1678 template <
typename T>
1679 template <
typename Comp>
1684 if (rows <= 1 || cols == 0)
1688 const T *lastrow = data + rows*(cols - 1);
1689 typedef std::pair<const T *, octave_idx_type> run_t;
1690 std::stack<run_t> runs;
1693 runs.push (run_t (data, rows));
1694 while (sorted && ! runs.empty ())
1696 const T *lo = runs.top ().first;
1703 const T *hi = lo +
n;
1705 for (lo++; lo < hi; lo++)
1707 if (comp (*lst, *lo))
1710 runs.push (run_t (lst + rows, lo - lst));
1713 else if (comp (*lo, *lst))
1720 runs.push (run_t (lst + rows, lo - lst));
1736 template <
typename T>
1743 #if defined (INLINE_ASCENDING_SORT)
1748 #if defined (INLINE_DESCENDING_SORT)
1761 template <
typename T>
1762 template <
typename Comp>
1765 const T& value, Comp comp)
1773 if (comp (value, data[mid]))
1782 template <
typename T>
1789 #if defined (INLINE_ASCENDING_SORT)
1794 #if defined (INLINE_DESCENDING_SORT)
1796 retval =
lookup (data, nel, value, std::greater<T> ());
1805 template <
typename T>
1806 template <
typename Comp>
1816 idx[j] =
lookup (data, nel, values[j], comp);
1819 template <
typename T>
1825 #if defined (INLINE_ASCENDING_SORT)
1827 lookup (data, nel, values, nvalues, idx, std::less<T> ());
1830 #if defined (INLINE_DESCENDING_SORT)
1832 lookup (data, nel, values, nvalues, idx, std::greater<T> ());
1839 template <
typename T>
1840 template <
typename Comp>
1851 if (nvalues > 0 && nel > 0)
1855 if (comp (values[j], data[i]))
1861 else if (++i == nel)
1874 if (nvalues > 0 && nel > 0)
1878 if (comp (values[j], data[i]))
1884 else if (++i == nel)
1889 for (; j != nvalues; j++)
1894 template <
typename T>
1900 #if defined (INLINE_ASCENDING_SORT)
1902 lookup_sorted (data, nel, values, nvalues, idx, rev, std::less<T> ());
1905 #if defined (INLINE_DESCENDING_SORT)
1907 lookup_sorted (data, nel, values, nvalues, idx, rev, std::greater<T> ());
1915 template <
typename T>
1916 template <
typename Comp>
1925 std::nth_element (data, data + lo, data + nel, comp);
1927 std::partial_sort (data, data + up, data + nel, comp);
1930 std::nth_element (data, data + lo, data + nel, comp);
1934 std::swap (data[lo+1],
1935 *std::min_element (data + lo + 1, data + nel, comp));
1938 std::partial_sort (data + lo + 1, data + up, data + nel, comp);
1942 template <
typename T>
1949 #if defined (INLINE_ASCENDING_SORT)
1954 #if defined (INLINE_DESCENDING_SORT)
1956 nth_element (data, nel, lo, up, std::greater<T> ());
1963 template <
typename T>
1971 template <
typename T>
charNDArray max(char d, const charNDArray &m)
static const int MERGESTATE_TEMP_SIZE
void set_compare(compare_fcn_type comp)
int merge_collapse(T *data, Comp comp)
void sort_rows(const T *data, octave_idx_type *idx, octave_idx_type rows, octave_idx_type cols)
octave_idx_type gallop_right(T key, T *a, octave_idx_type n, octave_idx_type hint, Comp comp)
int merge_hi(T *pa, octave_idx_type na, T *pb, octave_idx_type nb, Comp comp)
octave_idx_type count_run(T *lo, octave_idx_type n, bool &descending, Comp comp)
compare_fcn_type m_compare
octave_idx_type gallop_left(T key, T *a, octave_idx_type n, octave_idx_type hint, Comp comp)
static bool descending_compare(typename ref_param< T >::type, typename ref_param< T >::type)
bool issorted(const T *data, octave_idx_type nel)
static bool ascending_compare(typename ref_param< T >::type, typename ref_param< T >::type)
octave_idx_type lookup(const T *data, octave_idx_type nel, const T &value)
int merge_at(octave_idx_type i, T *data, Comp comp)
octave_idx_type merge_compute_minrun(octave_idx_type n)
void binarysort(T *data, octave_idx_type nel, octave_idx_type start, Comp comp)
void sort(T *data, octave_idx_type nel)
static const int MIN_GALLOP
void nth_element(T *data, octave_idx_type nel, octave_idx_type lo, octave_idx_type up=-1)
bool is_sorted_rows(const T *data, octave_idx_type rows, octave_idx_type cols)
static const int MAX_MERGE_PENDING
int merge_force_collapse(T *data, Comp comp)
int merge_lo(T *pa, octave_idx_type na, T *pb, octave_idx_type nb, Comp comp)
void lookup_sorted(const T *data, octave_idx_type nel, const T *values, octave_idx_type nvalues, octave_idx_type *idx, bool rev=false)
if_then_else< is_class_type< T >::no, T, T const & >::result type
F77_RET_T const F77_DBLE * x
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
static octave_idx_type roundupsize(size_t n)
octave_value::octave_value(const Array< char > &chm, char type) return retval
void getmem(octave_idx_type need)
struct s_slice m_pending[MAX_MERGE_PENDING]
octave_idx_type m_alloced
void getmemi(octave_idx_type need)
octave_idx_type m_min_gallop
sortrows_run_t(octave_idx_type c, octave_idx_type o, octave_idx_type n)