121 template <
typename T>
123 m_compare (ascending_compare), m_ms (nullptr)
126 template <
typename T>
128 : m_compare (comp), m_ms (nullptr)
131 template <
typename T>
137 template <
typename T>
142 m_compare = ascending_compare;
144 m_compare = descending_compare;
149 template <
typename T>
150 template <
typename Comp>
158 for (; start < nel; ++start)
163 T pivot = data[start];
172 if (comp (pivot, data[p]))
187 std::swap (pivot, data[p]);
194 template <
typename T>
195 template <
typename Comp>
203 for (; start < nel; ++start)
208 T pivot = data[start];
217 if (comp (pivot, data[p]))
232 std::swap (pivot, data[p]);
236 std::swap (ipivot, idx[p]);
261 template <
typename T>
262 template <
typename Comp>
277 if (comp (*lo, *(lo-1)))
280 for (lo = lo+1; lo < hi; ++lo, ++
n)
282 if (comp (*lo, *(lo-1)))
290 for (lo = lo+1; lo < hi; ++lo, ++
n)
292 if (comp (*lo, *(lo-1)))
321 template <
typename T>
322 template <
typename Comp>
343 if (comp (a[ofs], key))
346 ofs = (ofs << 1) + 1;
367 if (comp (*(a-ofs), key))
371 ofs = (ofs << 1) + 1;
379 lastofs = hint - ofs;
389 while (lastofs < ofs)
393 if (comp (a[
m], key))
416 template <
typename T>
417 template <
typename Comp>
438 if (comp (key, *(a-ofs)))
441 ofs = (ofs << 1) + 1;
452 lastofs = hint - ofs;
463 if (comp (key, a[ofs]))
467 ofs = (ofs << 1) + 1;
484 while (lastofs < ofs)
488 if (comp (key, a[
m]))
498 roundupsize (std::size_t
n)
500 unsigned int nbits = 3;
501 std::size_t n2 =
n >> 8;
531 std::size_t new_size = ((
n >> nbits) + 1) << nbits;
536 (*current_liboctave_error_handler)
537 (
"unable to allocate sufficient memory for sort");
545 template <
typename T>
549 if (need <= m_alloced)
552 need = roundupsize (need);
563 template <
typename T>
567 if (m_ia && need <= m_alloced)
570 need = roundupsize (need);
588 template <
typename T>
589 template <
typename Comp>
602 std::copy (pa, pa + na, m_ms->m_a);
635 if (bcount >= min_gallop)
646 if (acount >= min_gallop)
659 min_gallop -= (min_gallop > 1);
660 m_ms->m_min_gallop = min_gallop;
661 k = gallop_right (*pb, pa, na, 0, comp);
667 dest = std::copy (pa, pa + k, dest);
684 k = gallop_left (*pa, pb, nb, 0, comp);
690 dest = std::copy (pb, pb + k, dest);
701 while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
704 m_ms->m_min_gallop = min_gallop;
712 std::copy (pa, pa + na, dest);
717 std::copy (pb, pb + nb, dest);
723 template <
typename T>
724 template <
typename Comp>
738 std::copy (pa, pa + na, m_ms->m_a);
739 std::copy (ipa, ipa + na, m_ms->m_ia);
740 dest = pa; idest = ipa;
741 pa = m_ms->m_a; ipa = m_ms->m_ia;
743 *dest++ = *pb++; *idest++ = *ipb++;
763 *dest++ = *pb++; *idest++ = *ipb++;
769 if (bcount >= min_gallop)
774 *dest++ = *pa++; *idest++ = *ipa++;
780 if (acount >= min_gallop)
793 min_gallop -= (min_gallop > 1);
794 m_ms->m_min_gallop = min_gallop;
795 k = gallop_right (*pb, pa, na, 0, comp);
801 dest = std::copy (pa, pa + k, dest);
802 idest = std::copy (ipa, ipa + k, idest);
814 *dest++ = *pb++; *idest++ = *ipb++;
819 k = gallop_left (*pa, pb, nb, 0, comp);
825 dest = std::copy (pb, pb + k, dest);
826 idest = std::copy (ipb, ipb + k, idest);
832 *dest++ = *pa++; *idest++ = *ipa++;
837 while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
840 m_ms->m_min_gallop = min_gallop;
849 std::copy (pa, pa + na, dest);
850 std::copy (ipa, ipa + na, idest);
856 std::copy (pb, pb + nb, dest);
857 std::copy (ipb, ipb + nb, idest);
870 template <
typename T>
871 template <
typename Comp>
886 std::copy (pb, pb + nb, m_ms->m_a);
889 pb = m_ms->m_a + nb - 1;
917 if (acount >= min_gallop)
928 if (bcount >= min_gallop)
941 min_gallop -= (min_gallop > 1);
942 m_ms->m_min_gallop = min_gallop;
943 k = gallop_right (*pb, basea, na, na-1, comp);
950 dest = std::copy_backward (pa+1 - k, pa+1, dest+1) - 1;
961 k = gallop_left (*pa, baseb, nb, nb-1, comp);
970 std::copy (pb+1, pb+1 + k, dest+1);
986 while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
988 m_ms->m_min_gallop = min_gallop;
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);
1030 baseb = m_ms->m_a; ibaseb = m_ms->m_ia;
1031 pb = m_ms->m_a + nb - 1; ipb = m_ms->m_ia + nb - 1;
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);
1084 m_ms->m_min_gallop = min_gallop;
1085 k = gallop_right (*pb, basea, na, na-1, comp);
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--;
1104 k = gallop_left (*pa, baseb, nb, nb-1, comp);
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--;
1130 while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
1132 m_ms->m_min_gallop = min_gallop;
1141 std::copy (baseb, baseb + nb, dest-(nb-1));
1142 std::copy (ibaseb, ibaseb + nb, idest-(nb-1));
1148 dest = std::copy_backward (pa+1 - na, pa+1, dest+1) - 1;
1149 idest = std::copy_backward (ipa+1 - na, ipa+1, idest+1) - 1;
1150 pa -= na; ipa -= na;
1151 *dest = *pb; *idest = *ipb;
1159 template <
typename T>
1160 template <
typename Comp>
1169 pa = data + m_ms->m_pending[i].m_base;
1170 na = m_ms->m_pending[i].m_len;
1171 pb = data + m_ms->m_pending[i+1].m_base;
1172 nb = m_ms->m_pending[i+1].m_len;
1178 m_ms->m_pending[i].m_len = na + nb;
1179 if (i == m_ms->m_n - 3)
1180 m_ms->m_pending[i+1] = m_ms->m_pending[i+2];
1186 k = gallop_right (*pb, pa, na, 0, comp);
1197 nb = gallop_left (pa[na-1], pb, nb, nb-1, comp);
1205 return merge_lo (pa, na, pb, nb, comp);
1207 return merge_hi (pa, na, pb, nb, comp);
1210 template <
typename T>
1211 template <
typename Comp>
1221 pa = data + m_ms->m_pending[i].m_base;
1222 ipa = idx + m_ms->m_pending[i].m_base;
1223 na = m_ms->m_pending[i].m_len;
1224 pb = data + m_ms->m_pending[i+1].m_base;
1225 ipb = idx + m_ms->m_pending[i+1].m_base;
1226 nb = m_ms->m_pending[i+1].m_len;
1232 m_ms->m_pending[i].m_len = na + nb;
1233 if (i == m_ms->m_n - 3)
1234 m_ms->m_pending[i+1] = m_ms->m_pending[i+2];
1240 k = gallop_right (*pb, pa, na, 0, comp);
1251 nb = gallop_left (pa[na-1], pb, nb, nb-1, comp);
1259 return merge_lo (pa, ipa, na, pb, ipb, nb, comp);
1261 return merge_hi (pa, ipa, na, pb, ipb, nb, comp);
1274 template <
typename T>
1275 template <
typename Comp>
1279 struct s_slice *p = m_ms->m_pending;
1281 while (m_ms->m_n > 1)
1284 if (
n > 0 && p[
n-1].m_len <= p[
n].m_len + p[
n+1].m_len)
1286 if (p[
n-1].m_len < p[
n+1].m_len)
1288 if (merge_at (
n, data, comp) < 0)
1291 else if (p[
n].m_len <= p[
n+1].m_len)
1293 if (merge_at (
n, data, comp) < 0)
1303 template <
typename T>
1304 template <
typename Comp>
1308 struct s_slice *p = m_ms->m_pending;
1310 while (m_ms->m_n > 1)
1313 if (
n > 0 && p[
n-1].m_len <= p[
n].m_len + p[
n+1].m_len)
1315 if (p[
n-1].m_len < p[
n+1].m_len)
1317 if (merge_at (
n, data, idx, comp) < 0)
1320 else if (p[
n].m_len <= p[
n+1].m_len)
1322 if (merge_at (
n, data, idx, comp) < 0)
1337 template <
typename T>
1338 template <
typename Comp>
1342 struct s_slice *p = m_ms->m_pending;
1344 while (m_ms->m_n > 1)
1347 if (
n > 0 && p[
n-1].m_len < p[
n+1].m_len)
1349 if (merge_at (
n, data, comp) < 0)
1356 template <
typename T>
1357 template <
typename Comp>
1361 struct s_slice *p = m_ms->m_pending;
1363 while (m_ms->m_n > 1)
1366 if (
n > 0 && p[
n-1].m_len < p[
n+1].m_len)
1368 if (merge_at (
n, data, idx, comp) < 0)
1385 template <
typename T>
1400 template <
typename T>
1401 template <
typename Comp>
1406 if (! m_ms) m_ms =
new MergeState;
1409 m_ms->getmem (MERGESTATE_TEMP_SIZE);
1426 n = count_run (data + lo, nremaining, descending, comp);
1430 std::reverse (data + lo, data + lo +
n);
1436 binarysort (data + lo, force,
n, comp);
1440 assert (m_ms->m_n < MAX_MERGE_PENDING);
1441 m_ms->m_pending[m_ms->m_n].m_base = lo;
1442 m_ms->m_pending[m_ms->m_n].m_len =
n;
1444 if (merge_collapse (data, comp) < 0)
1452 merge_force_collapse (data, comp);
1456 template <
typename T>
1457 template <
typename Comp>
1463 if (! m_ms) m_ms =
new MergeState;
1466 m_ms->getmemi (MERGESTATE_TEMP_SIZE);
1483 n = count_run (data + lo, nremaining, descending, comp);
1488 std::reverse (data + lo, data + lo +
n);
1489 std::reverse (idx + lo, idx + lo +
n);
1496 binarysort (data + lo, idx + lo, force,
n, comp);
1500 assert (m_ms->m_n < MAX_MERGE_PENDING);
1501 m_ms->m_pending[m_ms->m_n].m_base = lo;
1502 m_ms->m_pending[m_ms->m_n].m_len =
n;
1504 if (merge_collapse (data, idx, comp) < 0)
1512 merge_force_collapse (data, idx, comp);
1516 template <
typename T>
1520 template <
typename T>
1524 #if defined (INLINE_ASCENDING_SORT)
1526 sort (data, nel, std::less<T> ());
1529 #if defined (INLINE_DESCENDING_SORT)
1531 sort (data, nel, std::greater<T> ());
1535 sort (data, nel, m_compare);
1538 template <
typename T>
1542 #if defined (INLINE_ASCENDING_SORT)
1544 sort (data, idx, nel, std::less<T> ());
1547 #if defined (INLINE_DESCENDING_SORT)
1549 sort (data, idx, nel, std::greater<T> ());
1553 sort (data, idx, nel, m_compare);
1556 template <
typename T>
1557 template <
typename Comp>
1561 const T *end = data + nel;
1564 const T *next = data;
1565 while (++next != end)
1567 if (comp (*next, *data))
1577 template <
typename T>
1581 bool retval =
false;
1582 #if defined (INLINE_ASCENDING_SORT)
1584 retval = issorted (data, nel, std::less<T> ());
1587 #if defined (INLINE_DESCENDING_SORT)
1589 retval = issorted (data, nel, std::greater<T> ());
1593 retval = issorted (data, nel, m_compare);
1598 struct sortrows_run_t
1602 : col (c), ofs (o), nel (
n) { }
1607 template <
typename T>
1608 template <
typename Comp>
1618 if (cols == 0 || rows <= 1)
1622 typedef sortrows_run_t run_t;
1623 std::stack<run_t> runs;
1625 runs.push (run_t (0, 0, rows));
1627 while (! runs.empty ())
1635 T *lbuf = buf + ofs;
1636 const T *ldata = data + rows*col;
1641 lbuf[i] = ldata[lidx[i]];
1644 sort (lbuf, lidx, nel, comp);
1652 if (comp (lbuf[lst], lbuf[i]))
1655 runs.push (run_t (col+1, ofs + lst, i - lst));
1660 runs.push (run_t (col+1, ofs + lst, nel - lst));
1665 template <
typename T>
1670 #if defined (INLINE_ASCENDING_SORT)
1672 sort_rows (data, idx, rows, cols, std::less<T> ());
1675 #if defined (INLINE_DESCENDING_SORT)
1677 sort_rows (data, idx, rows, cols, std::greater<T> ());
1681 sort_rows (data, idx, rows, cols, m_compare);
1684 template <
typename T>
1685 template <
typename Comp>
1690 if (rows <= 1 || cols == 0)
1694 const T *lastrow = data + rows*(cols - 1);
1695 typedef std::pair<const T *, octave_idx_type> run_t;
1696 std::stack<run_t> runs;
1699 runs.push (run_t (data, rows));
1700 while (sorted && ! runs.empty ())
1702 const T *lo = runs.top ().first;
1709 const T *hi = lo +
n;
1711 for (lo++; lo < hi; lo++)
1713 if (comp (*lst, *lo))
1716 runs.push (run_t (lst + rows, lo - lst));
1719 else if (comp (*lo, *lst))
1726 runs.push (run_t (lst + rows, lo - lst));
1736 sorted = issorted (lo,
n, comp);
1742 template <
typename T>
1747 bool retval =
false;
1748 #if defined (INLINE_ASCENDING_SORT)
1750 retval = is_sorted_rows (data, rows, cols, std::less<T> ());
1753 #if defined (INLINE_DESCENDING_SORT)
1755 retval = is_sorted_rows (data, rows, cols, std::greater<T> ());
1759 retval = is_sorted_rows (data, rows, cols, m_compare);
1766 template <
typename T>
1767 template <
typename Comp>
1770 const T& value, Comp comp)
1778 if (comp (value, data[mid]))
1787 template <
typename T>
1793 #if defined (INLINE_ASCENDING_SORT)
1795 retval =
lookup (data, nel, value, std::less<T> ());
1798 #if defined (INLINE_DESCENDING_SORT)
1800 retval =
lookup (data, nel, value, std::greater<T> ());
1804 retval =
lookup (data, nel, value, m_compare);
1809 template <
typename T>
1810 template <
typename Comp>
1820 idx[j] =
lookup (data, nel, values[j], comp);
1823 template <
typename T>
1829 #if defined (INLINE_ASCENDING_SORT)
1831 lookup (data, nel, values, nvalues, idx, std::less<T> ());
1834 #if defined (INLINE_DESCENDING_SORT)
1836 lookup (data, nel, values, nvalues, idx, std::greater<T> ());
1840 lookup (data, nel, values, nvalues, idx, m_compare);
1843 template <
typename T>
1844 template <
typename Comp>
1855 if (nvalues > 0 && nel > 0)
1859 if (comp (values[j], data[i]))
1865 else if (++i == nel)
1878 if (nvalues > 0 && nel > 0)
1882 if (comp (values[j], data[i]))
1888 else if (++i == nel)
1893 for (; j != nvalues; j++)
1898 template <
typename T>
1904 #if defined (INLINE_ASCENDING_SORT)
1906 lookup_sorted (data, nel, values, nvalues, idx, rev, std::less<T> ());
1909 #if defined (INLINE_DESCENDING_SORT)
1911 lookup_sorted (data, nel, values, nvalues, idx, rev, std::greater<T> ());
1915 lookup_sorted (data, nel, values, nvalues, idx, rev, m_compare);
1918 template <
typename T>
1919 template <
typename Comp>
1928 std::nth_element (data, data + lo, data + nel, comp);
1930 std::partial_sort (data, data + up, data + nel, comp);
1933 std::nth_element (data, data + lo, data + nel, comp);
1937 std::swap (data[lo+1],
1938 *std::min_element (data + lo + 1, data + nel, comp));
1941 std::partial_sort (data + lo + 1, data + up, data + nel, comp);
1945 template <
typename T>
1953 #if defined (INLINE_ASCENDING_SORT)
1955 nth_element (data, nel, lo, up, std::less<T> ());
1958 #if defined (INLINE_DESCENDING_SORT)
1960 nth_element (data, nel, lo, up, std::greater<T> ());
1964 nth_element (data, nel, lo, up, m_compare);
1967 template <
typename T>
1975 template <
typename T>
octave_idx_type lookup(const T *x, octave_idx_type n, T y)
charNDArray max(char d, const charNDArray &m)
void set_compare(const compare_fcn_type &comp)
void sort_rows(const T *data, octave_idx_type *idx, octave_idx_type rows, octave_idx_type cols)
static bool descending_compare(typename ref_param< T >::type, typename ref_param< T >::type)
bool issorted(const T *data, octave_idx_type nel)
std::function< bool(typename ref_param< T >::type, typename ref_param< T >::type)> compare_fcn_type
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)
void sort(T *data, octave_idx_type nel)
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)
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)
bool(*)(typename ref_param< T >::type, typename ref_param< T >::type) compare_fcn_ptr