1 /* PSPP - computes sample statistics.
2 Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
3 Written by Ben Pfaff <blp@gnu.org>.
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 /* Copyright (C) 2001 Free Software Foundation, Inc.
22 This file is part of the GNU ISO C++ Library. This library is free
23 software; you can redistribute it and/or modify it under the
24 terms of the GNU General Public License as published by the
25 Free Software Foundation; either version 2, or (at your option)
28 This library is distributed in the hope that it will be useful,
29 but WITHOUT ANY WARRANTY; without even the implied warranty of
30 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 GNU General Public License for more details.
33 You should have received a copy of the GNU General Public License along
34 with this library; see the file COPYING. If not, write to the Free
35 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
38 As a special exception, you may use this file as part of a free software
39 library without restriction. Specifically, if other files instantiate
40 templates or use macros or inline functions from this file, or you compile
41 this file and link it with other files to produce an executable, this
42 file does not by itself cause the resulting executable to be covered by
43 the GNU General Public License. This exception does not however
44 invalidate any other reasons why the executable file might be covered by
45 the GNU General Public License. */
50 * Hewlett-Packard Company
52 * Permission to use, copy, modify, distribute and sell this software
53 * and its documentation for any purpose is hereby granted without fee,
54 * provided that the above copyright notice appear in all copies and
55 * that both that copyright notice and this permission notice appear
56 * in supporting documentation. Hewlett-Packard Company makes no
57 * representations about the suitability of this software for any
58 * purpose. It is provided "as is" without express or implied warranty.
62 * Silicon Graphics Computer Systems, Inc.
64 * Permission to use, copy, modify, distribute and sell this software
65 * and its documentation for any purpose is hereby granted without fee,
66 * provided that the above copyright notice appear in all copies and
67 * that both that copyright notice and this permission notice appear
68 * in supporting documentation. Silicon Graphics makes no
69 * representations about the suitability of this software for any
70 * purpose. It is provided "as is" without express or implied warranty.
73 /* Copyright (C) 1991, 1992, 1996, 1997, 1999 Free Software Foundation, Inc.
74 This file is part of the GNU C Library.
75 Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
77 The GNU C Library is free software; you can redistribute it and/or
78 modify it under the terms of the GNU Lesser General Public
79 License as published by the Free Software Foundation; either
80 version 2.1 of the License, or (at your option) any later version.
82 The GNU C Library is distributed in the hope that it will be useful,
83 but WITHOUT ANY WARRANTY; without even the implied warranty of
84 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
85 Lesser General Public License for more details.
87 You should have received a copy of the GNU Lesser General Public
88 License along with the GNU C Library; if not, write to the Free
89 Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
93 #include "algorithm.h"
94 #include <gsl/gsl_rng.h>
101 /* Some of the assertions in this file are very expensive. We
102 don't use them by default. */
104 #define expensive_assert(X) assert(X)
106 #define expensive_assert(X) ((void) 0)
110 /* Finds an element in ARRAY, which contains COUNT elements of
111 SIZE bytes each, using COMPARE for comparisons. Returns the
112 first element in ARRAY that matches TARGET, or a null pointer
113 on failure. AUX is passed to each comparison as auxiliary
116 find (const void *array, size_t count, size_t size,
118 algo_compare_func *compare, void *aux)
120 const unsigned char *element = array;
124 if (compare (target, element, aux) == 0)
125 return (void *) element;
133 /* Counts and return the number of elements in ARRAY, which
134 contains COUNT elements of SIZE bytes each, which are equal to
135 ELEMENT as compared with COMPARE. AUX is passed as auxiliary
138 count_equal (const void *array, size_t count, size_t size,
140 algo_compare_func *compare, void *aux)
142 const unsigned char *first = array;
143 size_t equal_cnt = 0;
147 if (compare (element, first, aux) == 0)
156 /* Counts and return the number of elements in ARRAY, which
157 contains COUNT elements of SIZE bytes each, for which
158 PREDICATE returns nonzero. AUX is passed as auxiliary data to
161 count_if (const void *array, size_t count, size_t size,
162 algo_predicate_func *predicate, void *aux)
164 const unsigned char *first = array;
165 size_t nonzero_cnt = 0;
169 if (predicate (first, aux) != 0)
178 /* Byte-wise swap two items of size SIZE. */
179 #define SWAP(a, b, size) \
182 register size_t __size = (size); \
183 register char *__a = (a), *__b = (b); \
189 } while (--__size > 0); \
192 /* Makes the elements in ARRAY unique, by moving up duplicates,
193 and returns the new number of elements in the array. Sorted
194 arrays only. Arguments same as for sort() above. */
196 unique (void *array, size_t count, size_t size,
197 algo_compare_func *compare, void *aux)
200 char *last = first + size * count;
201 char *result = array;
208 assert (adjacent_find_equal (array, count,
209 size, compare, aux) == NULL);
213 if (compare (result, first, aux))
217 memcpy (result, first, size);
224 /* Helper function that calls sort(), then unique(). */
226 sort_unique (void *array, size_t count, size_t size,
227 algo_compare_func *compare, void *aux)
229 sort (array, count, size, compare, aux);
230 return unique (array, count, size, compare, aux);
233 /* Reorders ARRAY, which contains COUNT elements of SIZE bytes
234 each, so that the elements for which PREDICATE returns nonzero
235 precede those for which PREDICATE returns zero. AUX is
236 passed to each predicate as auxiliary data. Returns the
237 number of elements for which PREDICATE returns nonzero. Not
240 partition (void *array, size_t count, size_t size,
241 algo_predicate_func *predicate, void *aux)
243 size_t nonzero_cnt = count;
245 char *last = first + nonzero_cnt * size;
249 /* Move FIRST forward to point to first element that fails
255 else if (!predicate (first, aux))
262 /* Move LAST backward to point to last element that passes
270 else if (predicate (last, aux))
276 /* By swapping FIRST and LAST we extend the starting and
277 ending sequences that pass and fail, respectively,
279 SWAP (first, last, size);
284 assert (is_partitioned (array, count, size, nonzero_cnt, predicate, aux));
288 /* Checks whether ARRAY, which contains COUNT elements of SIZE
289 bytes each, is partitioned such that PREDICATE returns nonzero
290 for the first NONZERO_CNT elements and zero for the remaining
291 elements. AUX is passed as auxiliary data to PREDICATE. */
293 is_partitioned (const void *array, size_t count, size_t size,
295 algo_predicate_func *predicate, void *aux)
297 const unsigned char *first = array;
300 assert (nonzero_cnt <= count);
301 for (idx = 0; idx < nonzero_cnt; idx++)
302 if (predicate (first + idx * size, aux) == 0)
304 for (idx = nonzero_cnt; idx < count; idx++)
305 if (predicate (first + idx * size, aux) != 0)
310 /* A algo_random_func that uses random.h. */
312 algo_default_random (unsigned max, void *aux UNUSED)
314 unsigned long r_min = gsl_rng_min (get_rng ());
315 return (gsl_rng_get (get_rng ()) - r_min) % max;
318 /* Randomly reorders ARRAY, which contains COUNT elements of SIZE
319 bytes each. Uses RANDOM as a source of random data, passing
320 AUX as the auxiliary data. RANDOM may be null to use a
321 default random source. */
323 random_shuffle (void *array_, size_t count, size_t size,
324 algo_random_func *random, void *aux)
326 unsigned char *array = array_;
330 random = algo_default_random;
332 for (i = 1; i < count; i++)
333 SWAP (array + i * size, array + random (i + 1, aux) * size, size);
336 /* Copies the COUNT elements of SIZE bytes each from ARRAY to
337 RESULT, except that elements for which PREDICATE is false are
338 not copied. Returns the number of elements copied. AUX is
339 passed to PREDICATE as auxiliary data. */
341 copy_if (const void *array, size_t count, size_t size,
343 algo_predicate_func *predicate, void *aux)
345 const unsigned char *input = array;
346 const unsigned char *last = input + size * count;
347 unsigned char *output = result;
348 size_t nonzero_cnt = 0;
352 if (predicate (input, aux))
354 memcpy (output, input, size);
362 assert (nonzero_cnt == count_if (array, count, size, predicate, aux));
363 assert (nonzero_cnt == count_if (result, nonzero_cnt, size, predicate, aux));
368 /* Removes N elements starting at IDX from ARRAY, which consists
369 of COUNT elements of SIZE bytes each, by shifting the elements
370 following them, if any, into its position. */
372 remove_range (void *array_, size_t count, size_t size,
373 size_t idx, size_t n)
375 char *array = array_;
377 assert (array != NULL);
378 assert (idx <= count);
379 assert (idx + n <= count);
382 memmove (array + idx * size, array + (idx + n) * size,
383 size * (count - idx - n));
386 /* Removes element IDX from ARRAY, which consists of COUNT
387 elements of SIZE bytes each, by shifting the elements
388 following it, if any, into its position. */
390 remove_element (void *array, size_t count, size_t size,
393 remove_range (array, count, size, idx, 1);
396 /* Moves an element in ARRAY, which consists of COUNT elements of
397 SIZE bytes each, from OLD_IDX to NEW_IDX, shifting around
398 other elements as needed. Runs in O(abs(OLD_IDX - NEW_IDX))
401 move_element (void *array_, size_t count, size_t size,
402 size_t old_idx, size_t new_idx)
404 assert (array_ != NULL || count == 0);
405 assert (old_idx < count);
406 assert (new_idx < count);
408 if (old_idx != new_idx)
410 char *array = array_;
411 char *element = xmalloc (size);
412 char *new = array + new_idx * size;
413 char *old = array + old_idx * size;
415 memcpy (element, old, size);
417 memmove (new + size, new, (old_idx - new_idx) * size);
419 memmove (old, old + size, (new_idx - old_idx) * size);
420 memcpy (new, element, size);
426 /* A predicate and its auxiliary data. */
429 algo_predicate_func *predicate;
434 not (const void *data, void *pred_aux_)
436 const struct pred_aux *pred_aux = pred_aux_;
438 return !pred_aux->predicate (data, pred_aux->aux);
441 /* Removes elements equal to ELEMENT from ARRAY, which consists
442 of COUNT elements of SIZE bytes each. Returns the number of
443 remaining elements. AUX is passed to COMPARE as auxiliary
446 remove_equal (void *array, size_t count, size_t size,
448 algo_compare_func *compare, void *aux)
450 unsigned char *first = array;
451 unsigned char *last = first + count * size;
452 unsigned char *result;
458 if (compare (first, element, aux) == 0)
472 if (compare (first, element, aux) == 0)
478 memcpy (result, first, size);
483 assert (count_equal (array, count, size, element, compare, aux) == 0);
487 /* Copies the COUNT elements of SIZE bytes each from ARRAY to
488 RESULT, except that elements for which PREDICATE is true are
489 not copied. Returns the number of elements copied. AUX is
490 passed to PREDICATE as auxiliary data. */
492 remove_copy_if (const void *array, size_t count, size_t size,
494 algo_predicate_func *predicate, void *aux)
496 struct pred_aux pred_aux;
497 pred_aux.predicate = predicate;
499 return copy_if (array, count, size, result, not, &pred_aux);
502 /* Searches ARRAY, which contains COUNT of SIZE bytes each, using
503 a binary search. Returns any element that equals VALUE, if
504 one exists, or a null pointer otherwise. ARRAY must ordered
505 according to COMPARE. AUX is passed to COMPARE as auxiliary
508 binary_search (const void *array, size_t count, size_t size,
510 algo_compare_func *compare, void *aux)
512 assert (array != NULL);
513 assert (count <= INT_MAX);
514 assert (compare != NULL);
518 const unsigned char *first = array;
520 int high = count - 1;
524 int middle = (low + high) / 2;
525 const unsigned char *element = first + middle * size;
526 int cmp = compare (value, element, aux);
533 return (void *) element;
537 expensive_assert (find (array, count, size, value, compare, aux) == NULL);
541 /* Lexicographically compares ARRAY1, which contains COUNT1
542 elements of SIZE bytes each, to ARRAY2, which contains COUNT2
543 elements of SIZE bytes, according to COMPARE. Returns a
544 strcmp()-type result. AUX is passed to COMPARE as auxiliary
547 lexicographical_compare_3way (const void *array1, size_t count1,
548 const void *array2, size_t count2,
550 algo_compare_func *compare, void *aux)
552 const unsigned char *first1 = array1;
553 const unsigned char *first2 = array2;
554 size_t min_count = count1 < count2 ? count1 : count2;
556 while (min_count > 0)
558 int cmp = compare (first1, first2, aux);
567 return count1 < count2 ? -1 : count1 > count2;
570 /* If you consider tuning this algorithm, you should consult first:
571 Engineering a sort function; Jon Bentley and M. Douglas McIlroy;
572 Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */
578 /* Discontinue quicksort algorithm when partition gets below this size.
579 This particular magic number was chosen to work best on a Sun 4/260. */
582 /* Stack node declarations used to store unfulfilled partition obligations. */
589 /* The next 4 #defines implement a very fast in-line stack abstraction. */
590 /* The stack needs log (total_elements) entries (we could even subtract
591 log(MAX_THRESH)). Since total_elements has type size_t, we get as
592 upper bound for log (total_elements):
593 bits per byte (CHAR_BIT) * sizeof(size_t). */
594 #define STACK_SIZE (CHAR_BIT * sizeof(size_t))
595 #define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
596 #define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi)))
597 #define STACK_NOT_EMPTY (stack < top)
600 /* Order size using quicksort. This implementation incorporates
601 four optimizations discussed in Sedgewick:
603 1. Non-recursive, using an explicit stack of pointer that store the
604 next array partition to sort. To save time, this maximum amount
605 of space required to store an array of SIZE_MAX is allocated on the
606 stack. Assuming a 32-bit (64 bit) integer for size_t, this needs
607 only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes).
608 Pretty cheap, actually.
610 2. Chose the pivot element using a median-of-three decision tree.
611 This reduces the probability of selecting a bad pivot value and
612 eliminates certain extraneous comparisons.
614 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
615 insertion sort to order the MAX_THRESH items within each partition.
616 This is a big win, since insertion sort is faster for small, mostly
617 sorted array segments.
619 4. The larger of the two sub-partitions is always pushed onto the
620 stack first, with the algorithm then concentrating on the
621 smaller partition. This *guarantees* no more than log (total_elems)
622 stack size is needed (actually O(1) in this case)! */
625 sort (void *array, size_t count, size_t size,
626 algo_compare_func *compare, void *aux)
628 char *const first = array;
629 const size_t max_thresh = MAX_THRESH * size;
632 /* Avoid lossage with unsigned arithmetic below. */
635 if (count > MAX_THRESH)
638 char *hi = &lo[size * (count - 1)];
639 stack_node stack[STACK_SIZE];
640 stack_node *top = stack + 1;
642 while (STACK_NOT_EMPTY)
647 /* Select median value from among LO, MID, and HI. Rearrange
648 LO and HI so the three values are sorted. This lowers the
649 probability of picking a pathological pivot value and
650 skips a comparison for both the LEFT_PTR and RIGHT_PTR in
653 char *mid = lo + size * ((hi - lo) / size >> 1);
655 if (compare (mid, lo, aux) < 0)
656 SWAP (mid, lo, size);
657 if (compare (hi, mid, aux) < 0)
658 SWAP (mid, hi, size);
661 if (compare (mid, lo, aux) < 0)
662 SWAP (mid, lo, size);
665 left_ptr = lo + size;
666 right_ptr = hi - size;
668 /* Here's the famous ``collapse the walls'' section of quicksort.
669 Gotta like those tight inner loops! They are the main reason
670 that this algorithm runs much faster than others. */
673 while (compare (left_ptr, mid, aux) < 0)
676 while (compare (mid, right_ptr, aux) < 0)
679 if (left_ptr < right_ptr)
681 SWAP (left_ptr, right_ptr, size);
684 else if (mid == right_ptr)
689 else if (left_ptr == right_ptr)
696 while (left_ptr <= right_ptr);
698 /* Set up pointers for next iteration. First determine whether
699 left and right partitions are below the threshold size. If so,
700 ignore one or both. Otherwise, push the larger partition's
701 bounds on the stack and continue sorting the smaller one. */
703 if ((size_t) (right_ptr - lo) <= max_thresh)
705 if ((size_t) (hi - left_ptr) <= max_thresh)
706 /* Ignore both small partitions. */
709 /* Ignore small left partition. */
712 else if ((size_t) (hi - left_ptr) <= max_thresh)
713 /* Ignore small right partition. */
715 else if ((right_ptr - lo) > (hi - left_ptr))
717 /* Push larger left partition indices. */
718 PUSH (lo, right_ptr);
723 /* Push larger right partition indices. */
730 /* Once the FIRST array is partially sorted by quicksort the rest
731 is completely sorted using insertion sort, since this is efficient
732 for partitions below MAX_THRESH size. FIRST points to the beginning
733 of the array to sort, and END_PTR points at the very last element in
734 the array (*not* one beyond it!). */
736 #define min(x, y) ((x) < (y) ? (x) : (y))
739 char *const end_ptr = &first[size * (count - 1)];
740 char *tmp_ptr = first;
741 char *thresh = min(end_ptr, first + max_thresh);
742 register char *run_ptr;
744 /* Find smallest element in first threshold and place it at the
745 array's beginning. This is the smallest array element,
746 and the operation speeds up insertion sort's inner loop. */
748 for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
749 if (compare (run_ptr, tmp_ptr, aux) < 0)
752 if (tmp_ptr != first)
753 SWAP (tmp_ptr, first, size);
755 /* Insertion sort, running from left-hand-side up to right-hand-side. */
757 run_ptr = first + size;
758 while ((run_ptr += size) <= end_ptr)
760 tmp_ptr = run_ptr - size;
761 while (compare (run_ptr, tmp_ptr, aux) < 0)
765 if (tmp_ptr != run_ptr)
769 trav = run_ptr + size;
770 while (--trav >= run_ptr)
775 for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)
783 assert (is_sorted (array, count, size, compare, aux));
786 /* Tests whether ARRAY, which contains COUNT elements of SIZE
787 bytes each, is sorted in order according to COMPARE. AUX is
788 passed to COMPARE as auxiliary data. */
790 is_sorted (const void *array, size_t count, size_t size,
791 algo_compare_func *compare, void *aux)
793 const unsigned char *first = array;
796 for (idx = 0; idx + 1 < count; idx++)
797 if (compare (first + idx * size, first + (idx + 1) * size, aux) > 0)
803 /* Computes the generalized set difference, ARRAY1 minus ARRAY2,
804 into RESULT, and returns the number of elements written to
805 RESULT. If a value appears M times in ARRAY1 and N times in
806 ARRAY2, then it will appear max(M - N, 0) in RESULT. ARRAY1
807 and ARRAY2 must be sorted, and RESULT is sorted and stable.
808 ARRAY1 consists of COUNT1 elements, ARRAY2 of COUNT2 elements,
809 each SIZE bytes. AUX is passed to COMPARE as auxiliary
811 size_t set_difference (const void *array1, size_t count1,
812 const void *array2, size_t count2,
815 algo_compare_func *compare, void *aux)
817 const unsigned char *first1 = array1;
818 const unsigned char *last1 = first1 + count1 * size;
819 const unsigned char *first2 = array2;
820 const unsigned char *last2 = first2 + count2 * size;
821 unsigned char *result = result_;
822 size_t result_count = 0;
824 while (first1 != last1 && first2 != last2)
826 int cmp = compare (first1, first2, aux);
829 memcpy (result, first1, size);
843 while (first1 != last1)
845 memcpy (result, first1, size);
854 /* Finds the first pair of adjacent equal elements in ARRAY,
855 which has COUNT elements of SIZE bytes. Returns the first
856 element in ARRAY such that COMPARE returns zero when it and
857 its successor element are compared, or a null pointer if no
858 such element exists. AUX is passed to COMPARE as auxiliary
861 adjacent_find_equal (const void *array, size_t count, size_t size,
862 algo_compare_func *compare, void *aux)
864 const unsigned char *first = array;
865 const unsigned char *last = first + count * size;
867 while (first < last && first + size < last)
869 if (compare (first, first + size, aux) == 0)
870 return (void *) first;
877 /* ARRAY contains COUNT elements of SIZE bytes each. Initially
878 the first COUNT - 1 elements of these form a heap, followed by
879 a single element not part of the heap. This function adds the
880 final element, forming a heap of COUNT elements in ARRAY.
881 Uses COMPARE to compare elements, passing AUX as auxiliary
884 push_heap (void *array, size_t count, size_t size,
885 algo_compare_func *compare, void *aux)
887 unsigned char *first = array;
890 expensive_assert (count < 1 || is_heap (array, count - 1,
891 size, compare, aux));
892 for (i = count; i > 1; i /= 2)
894 unsigned char *parent = first + (i / 2 - 1) * size;
895 unsigned char *element = first + (i - 1) * size;
896 if (compare (parent, element, aux) < 0)
897 SWAP (parent, element, size);
901 expensive_assert (is_heap (array, count, size, compare, aux));
904 /* ARRAY contains COUNT elements of SIZE bytes each. Initially
905 the children of ARRAY[idx - 1] are heaps, but ARRAY[idx - 1]
906 may be smaller than its children. This function fixes that,
907 so that ARRAY[idx - 1] itself is a heap. Uses COMPARE to
908 compare elements, passing AUX as auxiliary data. */
910 heapify (void *array, size_t count, size_t size,
912 algo_compare_func *compare, void *aux)
914 unsigned char *first = array;
918 size_t left = 2 * idx;
919 size_t right = left + 1;
920 size_t largest = idx;
923 && compare (first + size * (left - 1),
924 first + size * (idx - 1), aux) > 0)
928 && compare (first + size * (right - 1),
929 first + size * (largest - 1), aux) > 0)
935 SWAP (first + size * (idx - 1), first + size * (largest - 1), size);
940 /* ARRAY contains COUNT elements of SIZE bytes each. Initially
941 all COUNT elements form a heap. This function moves the
942 largest element in the heap to the final position in ARRAY and
943 reforms a heap of the remaining COUNT - 1 elements at the
944 beginning of ARRAY. Uses COMPARE to compare elements, passing
945 AUX as auxiliary data. */
947 pop_heap (void *array, size_t count, size_t size,
948 algo_compare_func *compare, void *aux)
950 unsigned char *first = array;
952 expensive_assert (is_heap (array, count, size, compare, aux));
953 SWAP (first, first + (count - 1) * size, size);
954 heapify (first, count - 1, size, 1, compare, aux);
955 expensive_assert (count < 1 || is_heap (array, count - 1,
956 size, compare, aux));
959 /* Turns ARRAY, which contains COUNT elements of SIZE bytes, into
960 a heap. Uses COMPARE to compare elements, passing AUX as
963 make_heap (void *array, size_t count, size_t size,
964 algo_compare_func *compare, void *aux)
968 for (idx = count / 2; idx >= 1; idx--)
969 heapify (array, count, size, idx, compare, aux);
970 expensive_assert (count < 1 || is_heap (array, count, size, compare, aux));
973 /* ARRAY contains COUNT elements of SIZE bytes each. Initially
974 all COUNT elements form a heap. This function turns the heap
975 into a fully sorted array. Uses COMPARE to compare elements,
976 passing AUX as auxiliary data. */
978 sort_heap (void *array, size_t count, size_t size,
979 algo_compare_func *compare, void *aux)
981 unsigned char *first = array;
984 expensive_assert (is_heap (array, count, size, compare, aux));
985 for (idx = count; idx >= 2; idx--)
987 SWAP (first, first + (idx - 1) * size, size);
988 heapify (array, idx - 1, size, 1, compare, aux);
990 expensive_assert (is_sorted (array, count, size, compare, aux));
993 /* ARRAY contains COUNT elements of SIZE bytes each. This
994 function tests whether ARRAY is a heap and returns 1 if so, 0
995 otherwise. Uses COMPARE to compare elements, passing AUX as
998 is_heap (const void *array, size_t count, size_t size,
999 algo_compare_func *compare, void *aux)
1001 const unsigned char *first = array;
1004 for (child = 2; child <= count; child++)
1006 size_t parent = child / 2;
1007 if (compare (first + (parent - 1) * size,
1008 first + (child - 1) * size, aux) < 0)