static void ssort1(string x[], int n, int depth) { int a, b, c, d, r, v; if (n <= 1) return; a = rand() % n; swap(0, a); v = i2c(0); a = b = 1; c = d = n-1; for (;;) { while (b <= c && (r = i2c(b)-v) <= 0) { if (r == 0) { swap(a, b); a++; } b++; } while (b <= c && (r = i2c(c)-v) >= 0) { if (r == 0) { swap(c, d); d--; } c--; } if (b > c) break; swap(b, c); b++; c--; } r = min(a, b-a); vecswap(0, b-r, r, x); r = min(d-c, n-d-1); vecswap(b, n-r, r, x); r = b-a; ssort1(x, r, depth); if (i2c(r) != 0) ssort1(x + r, a + n-d-1, depth+1); r = d-c; ssort1(x + n-r, r, depth); }
void ssort1(char *x[], int n, int depth,int* index) { int a, b, c, d, r, v; if (n <= 1) return; /// Choosing the pivot //a = rand() % n; a=0; /// ///////////////// swap(0, a); swapIndex(0,a); v = i2c(0); a = b = 1; c = d = n-1; for (;;) { while (b <= c && (r = i2c(b)-v) <= 0) { if (r == 0) { swap(a, b); swapIndex(a,b);a++; } b++; } while (b <= c && (r = i2c(c)-v) >= 0) { if (r == 0) { swap(c, d); swapIndex(c,d);d--; } c--; } if (b > c) break; swap(b, c); swapIndex(b,c); b++; c--; } r = min(a, b-a); vecswap(0, b-r, r, x); vecswapIndex(0, b-r, r, index); r = min(d-c, n-d-1); vecswap(b, n-r, r, x); vecswapIndex(b, n-r, r, index); r = b-a; ssort1(x, r, depth,index); if (i2c(r) != 0) ssort1(x + r, a + n-d-1, depth+1,index+r); r = d-c; ssort1(x + n-r, r, depth,index+ n-r); }
void rqsort(int *a, int n, double *x) { int *pa, *pb, *pc, *pd, *pl, *pm, *pn; int d, r; if (n < 7) { /* Insertion sort on small arrays */ for (pm = a + 1; pm < a + n; pm++) for (pl = pm; pl > a && cmp(pl-1, pl, x) > 0; pl--) swap(pl, pl-1); return; } pm = a + (n/2); if (n > 7) { pl = a; pn = a + (n-1); if (n > 40) { /* On big arrays, pseudomedian of 9 */ d = (n/8); pl = med3(pl, pl+d, pl+2*d, x); pm = med3(pm-d, pm, pm+d, x); pn = med3(pn-2*d, pn-d, pn, x); } pm = med3(pl, pm, pn, x); /* On mid arrays, med of 3 */ } swap(a, pm); /* On tiny arrays, partition around middle */ pa = pb = a + 1; pc = pd = a + (n-1); for (;;) { while (pb <= pc && (r = cmp(pb, a, x)) <= 0) { if (r == 0) { swap(pa, pb); pa++; } pb++; } while (pb <= pc && (r = cmp(pc, a, x)) >= 0) { if (r == 0) { swap(pc, pd); pd--; } pc--; } if (pb > pc) break; swap(pb, pc); pb++; pc--; } pn = a + n; r = minimum(pa-a, pb-pa); vecswap(a, pb-r, r); r = minimum(pd-pc, pn-pd-1); vecswap(pb, pn-r, r); if ((r = pb-pa) > 1) rqsort(a, r, x); if ((r = pd-pc) > 1) rqsort(pn-r, r, x); }
Uint * quickSortMultikey (void *space, void* toSort, Uint size, Uint (*cmp)(Uint, Uint, Uint, void *, void*), Uint sentinel, void *info) { Sint a, b, c, d, v, n, r; Uint *sorted = NULL, offset; Uint depth = 0; Stack stack; if (size == 0) return NULL; sorted = ALLOCMEMORY(space, NULL, Uint, size); if (size<=1) { sorted[0]=0; } for (r=0; r < size; r++) sorted[r]=r; initStack(space, &stack, 100); n = size; offset=0; while (1) { a = rand() % n; SWAPUINT(sorted, offset, a+offset); v = sorted[offset]; a = b = 1; c = d = n-1; for(;;) { while(b<=c&&((r=cmp(sorted[b+offset],v,depth,toSort,info))==2||r==0)) { if (r==0) { SWAPUINT(sorted, a+offset, b+offset); a++; } b++; } while(b<=c&&((r=cmp(sorted[c+offset],v,depth,toSort,info))==1||r==0)) { if (r==0) { SWAPUINT(sorted, c+offset, d+offset); d--; } c--; } if (b > c) break; SWAPUINT(sorted, b+offset, c+offset); b++; c--; } r = MIN(a, (b-a)); vecswap(offset, (b-r)+offset, r, sorted); r = MIN((d-c), (n-d-1)); vecswap(b+offset, (n-r)+offset, r, sorted); /*sort lesser*/ r = b-a; if (r > 1) { stackpush(space, &stack, offset); stackpush(space, &stack, r); stackpush(space, &stack, depth); } /*sort equal*/ if ((a+n-d-1) > 1 && cmp(sorted[r+offset], sentinel, depth, toSort, info) != 0) /*if (r > 1 && sorted[r+offset]!=sentinel)*/ { stackpush(space, &stack, r+offset); stackpush(space, &stack, (a+n-d-1)); stackpush(space, &stack, depth+1); } /*sort greater*/ r=d-c; if (r > 1) { stackpush(space, &stack, (n-r)+offset); stackpush(space, &stack, r); stackpush(space, &stack, depth); } if (!stackisempty(&stack)) { depth = stackpop(&stack); n = stackpop(&stack); offset = stackpop(&stack); } else { break; } } destructStack(space, &stack); return sorted; }
void recast_qsort(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp) { char *pa, *pb, *pc, *pd, *pl, *pm, *pn; int d, r, swaptype, swap_cnt; loop: SWAPINIT(a, es); swap_cnt = 0; if (n < 7) { for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; pl -= es) swap(pl, pl - es); return; } pm = (char *)a + (n / 2) * es; if (n > 7) { pl = (char *)a; pn = (char *)a + (n - 1) * es; if (n > 40) { d = (n / 8) * es; pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); pm = med3(pm - d, pm, pm + d, cmp, thunk); pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); } pm = med3(pl, pm, pn, cmp, thunk); } swap((char *)a, pm); pa = pb = (char *)a + es; pc = pd = (char *)a + (n - 1) * es; for (;;) { while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) { if (r == 0) { swap_cnt = 1; swap(pa, pb); pa += es; } pb += es; } while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) { if (r == 0) { swap_cnt = 1; swap(pc, pd); pd -= es; } pc -= es; } if (pb > pc) break; swap(pb, pc); swap_cnt = 1; pb += es; pc -= es; } if (swap_cnt == 0) { /* Switch to insertion sort */ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; pl -= es) swap(pl, pl - es); return; } pn = (char *)a + n * es; r = min(pa - (char *)a, pb - pa); vecswap((char *)a, pb - r, r); r = min(pd - pc, pn - pd - es); vecswap(pb, pn - r, r); if ((r = pb - pa) > es) recast_qsort(a, r / es, es, thunk, cmp); if ((r = pd - pc) > es) { /* Iterate rather than recurse to save stack space */ a = pn - r; n = r / es; goto loop; } }
/*--------------------------------------------------------------------------*/ void sciqsort(char *a, char *tab, int flag, int n, int es, int es1, int (*cmp)(), int (*swapcode)(), int (*lswapcodeind)()) { char *pa, *pb, *pc, *pd, *pl, *pm, *pn; char *taba, *tabb, *tabc, *tabd, *tabl, *tabm, *tabn; int d, dind, r, r1, swap_cnt; loop: swap_cnt = 0; if (n < 7) /* Insertion sort on smallest arrays */ { for (pm = a + es, tabm = tab + es1 ; pm < (char *) a + n * es; pm += es, tabm += es1 ) { for (pl = pm, tabl = tabm ; pl > (char *) a && cmp(pl - es, pl, tabl - es1, tabl, flag) > 0; pl -= es, tabl -= es1) { swapind(tabl, tabl - es1); swap(pl, pl - es); } } return; } /*Determine the pivot */ pm = a + (n / 2) * es;/* Small arrays, middle element */ tabm = tab + (n / 2) * es1 ; pn = a + (n - 1) * es; tabn = tab + (n - 1) * es1; if (n > 7) { pl = a; tabl = tab; if (n > 40) /* Big arrays, pseudomedian of 9 */ { dind = (n / 8) * es1; d = (n / 8) * es; med3(pl, tabl, pl, pl + d, pl + 2 * d, tabl, tabl + dind, tabl + 2 * dind, cmp); med3(pm, tabm, pm - d, pm, pm + d, tabm - dind, tabm, tabm + dind, cmp); med3(pn, tabn, pn - 2 * d, pn - d, pn, tabn - 2 * dind, tabn - dind, tabn, cmp); } med3(pm, tabm, pl, pm, pn, tabl, tabm, tabn, cmp); } /* Put it at the first position */ /* Partionning */ if (cmp(pn, a, tabn, tab, flag)) { swapind(tab, tabn); swap(a, pn); } /* pointers on data array */ pa = pb = a + es;/* pa and pb start from the beginning of the array */ pc = pd = a + (n - 1) * es;/* pc and pd start from the end of the array */ /* similar pointers for index array */ taba = tabb = tab + es1; tabc = tabd = tab + (n - 1) * es1; /* here we have |a |pa | pc| |a |pb | pd| |*a | ? | ? | */ for (;;) { /* increase the pointer pb while it points on values lesser than the pivot (pointer a) */ while (pb <= pc && (r = cmp(pb, a, tabb, tab, flag)) <= 0) { if (r == 0) /*The pivot and value pointed to by pb are equal */ { /* store the equal value at the location pa and increase pa */ swap_cnt = 1; swapind(taba, tabb); taba += es1; swap(pa, pb); pa += es; } pb += es;/* next number */ tabb += es1; } /* here pb points on a value greater than the pivot */ /* decrease the pointer pc while it points on a value greater than the pivot (pointer a) */ while (pb <= pc && (r = cmp(pc, a, tabc, tab, flag)) >= 0) { if (r == 0) /*The pivot and value pointed to by pc are equal */ { /* store the equal value at the location pd and decrease pd */ swap_cnt = 1; swapind(tabc, tabd); tabd -= es1; swap(pc, pd); pd -= es; } pc -= es; tabc -= es1; } /* here pc points on a value lesser than the pivot */ if (pb > pc) { /* here we have |a |pa |pc|pb pd| $| | =*a | <*a | >*a | =*a $| */ /* partition is done */ break; } /*here pc points on a value lesser than the pivot and pb points on a value greater than the pivot swap the values */ swapind(tabb, tabc); tabb += es1; tabc -= es1; swap(pb, pc); swap_cnt = 1; /* increase pb and decrease pc */ pb += es; pc -= es; /* here we have |a |pa |pb pc| pd| $| | =*a | <*a | ? | >*a | =*a $| */ } if (swap_cnt == 0) /* Switch to insertion sort */ { for (pm = a + es, tabm = tab + es1 ; pm < (char *) a + n * es; pm += es, tabm += es1) { for (pl = pm, tabl = tabm ; pl > (char *) a && cmp(pl - es, pl, tabl - es1, tabl, flag) > 0; pl -= es, tabl -= es1) { swapind(tabl, tabl - es1); swap(pl, pl - es); } } return; } /* put the equal values in the middle */ pn = a + n * es; r = (int)Min(pa - (char *)a, pb - pa); vecswap(a, pb - r, r); tabn = tab + n * es1 ; r1 = (int)Min(taba - (char *) tab, tabb - taba); vecswapind(tab, tabb - r1, r1); r = (int)Min(pd - pc, pn - pd - es); vecswap(pb, pn - r, r); r1 = (int)Min(tabd - tabc, tabn - tabd - es1 ); vecswapind(tabb, tabn - r1, r1); if ((r = (int)(pb - pa)) > es ) /* recall sciqsort for the lower part */ { sciqsort(a, tab, flag, r / es, es, es1, cmp, swapcode, lswapcodeind); } if ((r = (int)(pd - pc)) > es) { /* Iterate rather than recurse to save stack space */ a = pn - r; tab = tabn - (tabd - tabc); n = r / es; goto loop; } }
void yaffs_qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *)) { char *pa, *pb, *pc, *pd, *pl, *pm, *pn; int d, r, swaptype, swap_cnt; register char *a = aa; loop: SWAPINIT(a, es); swap_cnt = 0; if (n < 7) { for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es) for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; pl -= es) yswap(pl, pl - es); return; } pm = (char *)a + (n / 2) * es; if (n > 7) { pl = (char *)a; pn = (char *)a + (n - 1) * es; if (n > 40) { d = (n / 8) * es; pl = med3(pl, pl + d, pl + 2 * d, cmp); pm = med3(pm - d, pm, pm + d, cmp); pn = med3(pn - 2 * d, pn - d, pn, cmp); } pm = med3(pl, pm, pn, cmp); } yswap(a, pm); pa = pb = (char *)a + es; pc = pd = (char *)a + (n - 1) * es; for (;;) { while (pb <= pc && (r = cmp(pb, a)) <= 0) { if (r == 0) { swap_cnt = 1; yswap(pa, pb); pa += es; } pb += es; } while (pb <= pc && (r = cmp(pc, a)) >= 0) { if (r == 0) { swap_cnt = 1; yswap(pc, pd); pd -= es; } pc -= es; } if (pb > pc) break; yswap(pb, pc); swap_cnt = 1; pb += es; pc -= es; } if (swap_cnt == 0) { /* Switch to insertion sort */ for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; pl -= es) yswap(pl, pl - es); return; } pn = (char *)a + n * es; r = min(pa - (char *)a, pb - pa); vecswap(a, pb - r, r); r = min((long)(pd - pc), (long)(pn - pd - es)); vecswap(pb, pn - r, r); r = pb - pa; if (r > es) yaffs_qsort(a, r / es, es, cmp); r = pd - pc; if (r > es) { /* Iterate rather than recurse to save stack space */ a = pn - r; n = r / es; goto loop; } /* yaffs_qsort(pn - r, r / es, es, cmp);*/ }
void qsort ( /* SYNOPSIS */ void * a, size_t n, size_t es, int (* cmp)(const void *, const void *)) /* FUNCTION Sort the array a. It contains n elements of the size es. Elements are compares using the function cmp(). INPUTS a - The array to sort n - The number of elements in the array es - The size of a single element in the array cmp - The function which is called when two elements must be compared. The function gets the addresses of two elements of the array and must return 0 is both are equal, < 0 if the first element is less than the second and > 0 otherwise. RESULT None. NOTES EXAMPLE // Use this function to compare to stringpointers int cmp_strptr (const char ** sptr1, const char ** sptr2) { return strcmp (*sptr1, *sptr2); } // Sort an array of strings char ** strings; // fill the array strings = malloc (sizeof (char *)*4); strings[0] = strdup ("h"); strings[1] = strdup ("a"); strings[2] = strdup ("f"); strings[3] = strdup ("d"); // Sort it qsort (strings, sizeof (char *), 4, (void *)cmp_strptr); BUGS SEE ALSO strcmp(), strncmp(), memcmp(), strcasecmp(), strncasecmp() INTERNALS ******************************************************************************/ { char *pa, *pb, *pc, *pd, *pl, *pm, *pn; int d, r, swaptype, swap_cnt; loop: SWAPINIT(a, es); swap_cnt = 0; if (n < 7) { for (pm = a + es; pm < (char *) a + n * es; pm += es) for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; pl -= es) swap(pl, pl - es); return; } pm = a + (n / 2) * es; if (n > 7) { pl = a; pn = a + (n - 1) * es; if (n > 40) { d = (n / 8) * es; pl = (char *)med3(pl, pl + d, pl + 2 * d, cmp); pm = (char *)med3(pm - d, pm, pm + d, cmp); pn = (char *)med3(pn - 2 * d, pn - d, pn, cmp); } pm = (char *)med3(pl, pm, pn, cmp); } swap(a, pm); pa = pb = a + es; pc = pd = a + (n - 1) * es; for (;;) { while (pb <= pc && (r = cmp(pb, a)) <= 0) { if (r == 0) { swap_cnt = 1; swap(pa, pb); pa += es; } pb += es; } while (pb <= pc && (r = cmp(pc, a)) >= 0) { if (r == 0) { swap_cnt = 1; swap(pc, pd); pd -= es; } pc -= es; } if (pb > pc) break; swap(pb, pc); swap_cnt = 1; pb += es; pc -= es; } if (swap_cnt == 0) { /* Switch to insertion sort */ for (pm = a + es; pm < (char *) a + n * es; pm += es) for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; pl -= es) swap(pl, pl - es); return; } pn = a + n * es; r = min(pa - (char *)a, pb - pa); vecswap(a, pb - r, r); r = min(pd - pc, pn - pd - es); vecswap(pb, pn - r, r); if ((r = pb - pa) > es) qsort(a, r / es, es, cmp); if ((r = pd - pc) > es) { /* Iterate rather than recurse to save stack space */ a = pn - r; n = r / es; goto loop; } /* qsort(pn - r, r / es, es, cmp);*/ }
void qsort_arg(void *a, size_t n, size_t es, qsort_arg_comparator cmp, void *arg) { char *pa, *pb, *pc, *pd, *pl, *pm, *pn; int d, r, swaptype, presorted; loop:SWAPINIT(a, es); if (n < 7) { for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) for (pl = pm; pl > (char *) a && cmp(pl - es, pl, arg) > 0; pl -= es) swap(pl, pl - es); return; } presorted = 1; for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) { if (cmp(pm - es, pm, arg) > 0) { presorted = 0; break; } } if (presorted) return; pm = (char *) a + (n / 2) * es; if (n > 7) { pl = (char *) a; pn = (char *) a + (n - 1) * es; if (n > 40) { d = (n / 8) * es; pl = med3(pl, pl + d, pl + 2 * d, cmp, arg); pm = med3(pm - d, pm, pm + d, cmp, arg); pn = med3(pn - 2 * d, pn - d, pn, cmp, arg); } pm = med3(pl, pm, pn, cmp, arg); } swap(static_cast<char *>(a), pm); pa = pb = (char *) a + es; pc = pd = (char *) a + (n - 1) * es; for (;;) { while (pb <= pc && (r = cmp(pb, a, arg)) <= 0) { if (r == 0) { swap(pa, pb); pa += es; } pb += es; } while (pb <= pc && (r = cmp(pc, a, arg)) >= 0) { if (r == 0) { swap(pc, pd); pd -= es; } pc -= es; } if (pb > pc) break; swap(pb, pc); pb += es; pc -= es; } pn = (char *) a + n * es; r = Min(pa - (char *) a, pb - pa); vecswap(static_cast<char *>(a), pb - r, r); r = Min(pd - pc, pn - pd - es); vecswap(pb, pn - r, r); if ((r = pb - pa) > es) qsort_arg(a, r / es, es, cmp, arg); if ((r = pd - pc) > es) { /* Iterate rather than recurse to save stack space */ a = pn - r; n = r / es; goto loop; } /* qsort_arg(pn - r, r / es, es, cmp, arg);*/ }
Uint * quickSortMultikey (void *space, void* toSort, Uint size, Uint (*cmp)(Uint, Uint, Uint, void *, void*), Uint sentinel, void *info) { Sint a, b, c, d, v, n, r; TripleSint ins; Uint *sorted = NULL, offset; Uint depth = 0; VStack vstack; if (size == 0) return NULL; sorted = ALLOCMEMORY(space, NULL, Uint, size); if (size<=1) { sorted[0]=0; } for (r=0; r < size; r++) sorted[r]=r; bl_vstackInit(&vstack, 100, sizeof(TripleSint)); n = size; offset=0; while (1) { a = rand() % n; SWAPUINT(sorted, offset, a+offset); v = sorted[offset]; a = b = 1; c = d = n-1; for(;;) { while(b<=c&&((r=cmp(sorted[b+offset],v,depth,toSort,info))==2||r==0)) { if (r==0) { SWAPUINT(sorted, a+offset, b+offset); a++; } b++; } while(b<=c&&((r=cmp(sorted[c+offset],v,depth,toSort,info))==1||r==0)) { if (r==0) { SWAPUINT(sorted, c+offset, d+offset); d--; } c--; } if (b > c) break; SWAPUINT(sorted, b+offset, c+offset); b++; c--; } r = MIN(a, (b-a)); vecswap(offset, (b-r)+offset, r, sorted); r = MIN((d-c), (n-d-1)); vecswap(b+offset, (n-r)+offset, r, sorted); /*sort lesser*/ r = b-a; if (r > 1) { ins.a = offset; ins.b = r; ins.c = depth; bl_vstackPush(&vstack, &ins); } /*sort equal*/ if ((a+n-d-1) > 1 && cmp(sorted[r+offset], sentinel, depth, toSort, info) != 0) /*if (r > 1 && sorted[r+offset]!=sentinel)*/ { ins.a = r+offset; ins.b = (a+n-d-1); ins.c = depth+1; bl_vstackPush(&vstack, &ins); } /*sort greater*/ r=d-c; if (r > 1) { ins.a = (n-r)+offset; ins.b = r; ins.c = depth; bl_vstackPush(&vstack, &ins); } if (!bl_vstackIsEmpty(&vstack)){ ins = *((TripleSint *) bl_vstackPop(&vstack, NULL)); offset = ins.a; r = ins.b; depth = ins.c; } else { break; } } bl_vstackDestruct(&vstack, NULL); return sorted; }
void qsort(void *a, size_t n, size_t es, cmp_t *cmp) #endif { char *pa, *pb, *pc, *pd, *pl, *pm, *pn; size_t d, r; int cmp_result; int swaptype, swap_cnt; loop: SWAPINIT(a, es); swap_cnt = 0; if (n < 7) { for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; pl -= es) swap(pl, pl - es); return; } pm = (char *)a + (n / 2) * es; if (n > 7) { pl = (char *)a; pn = (char *)a + (n - 1) * es; if (n > 40) { d = (n / 8) * es; pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk); pm = med3(pm - d, pm, pm + d, cmp, thunk); pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk); } pm = med3(pl, pm, pn, cmp, thunk); } swap(a, pm); pa = pb = (char *)a + es; pc = pd = (char *)a + (n - 1) * es; for (;;) { while (pb <= pc && (cmp_result = CMP(thunk, pb, a)) <= 0) { if (cmp_result == 0) { swap_cnt = 1; swap(pa, pb); pa += es; } pb += es; } while (pb <= pc && (cmp_result = CMP(thunk, pc, a)) >= 0) { if (cmp_result == 0) { swap_cnt = 1; swap(pc, pd); pd -= es; } pc -= es; } if (pb > pc) break; swap(pb, pc); swap_cnt = 1; pb += es; pc -= es; } if (swap_cnt == 0) { /* Switch to insertion sort */ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) for (pl = pm; pl > (char *)a && CMP(thunk, pl - es, pl) > 0; pl -= es) swap(pl, pl - es); return; } pn = (char *)a + n * es; r = min(pa - (char *)a, pb - pa); vecswap((char*)a, (char *)(pb - r), r); // !!! Ren/C: pn - pd - es => (long)(pn - pd - ps) for -Wsign-compare r = min(pd - pc, (long)(pn - pd - es)); vecswap(pb, pn - r, r); if ((r = pb - pa) > es) #ifdef I_AM_QSORT_R qsort_r(a, r / es, es, thunk, cmp); #else qsort(a, r / es, es, cmp); #endif if ((r = pd - pc) > es) { /* Iterate rather than recurse to save stack space */ a = pn - r; n = r / es; goto loop; } /* qsort(pn - r, r / es, es, cmp);*/ }
//Stable sort of sequences void SArrayIndex::sort(quint32* x, int off, int len) { // Insertion sort on smallest arrays if (len < 7) { for (int i=off; i<len+off; i++){ for (int j=i; j > off && compare(x[j-1],x[j])>0; j--) { qSwap(x[j], x[j-1]); } } return; } // Choose a partition element, v quint32 m = off + len / 2; // Small arrays, middle element if (len > 7) { quint32 l = off; quint32 n = off + len - 1; if (len > 40) { // Big arrays, pseudo median of 9 quint32 s = len / 8; l = med3(x, l, l+s, l+2*s); m = med3(x, m-s, m, m+s); n = med3(x, n-2*s, n-s, n); } m = med3(x, l, m, n); // Mid-size, med of 3 } quint32 v = x[m]; // Establish Invariant: v* (<v)* (>v)* v* int a = off, b = off, c = off + len - 1, d = c; while(true) { int cr; while (b <= c && (cr = compare(v, x[b])) >= 0) { if (cr == 0) { qSwap(x[a],x[b]); a++; } b++; } while (c >= b && (cr = compare(x[c], v)) >=0 ) { if (cr == 0) { qSwap(x[c],x[d]); d--; } c--; } if (b > c) { break; } qSwap(x[b], x[c]); b++; c--; } // Swap partition elements back to middle int s, n = off + len; s = qMin(a-off, b-a ); vecswap(x, off, b-s, s); s = qMin(d-c, n-d-1); vecswap(x, b, n-s, s); // Recursively sort non-partition-elements if ((s = b-a) > 1) { sort(x, off, s); } if ((s = d-c) > 1) { sort(x, n-s, s); } }
static void ssort1(char ** x, int n, int depth, int * oi) { int a,b,c,d,r,v; if (n <= 1) return; a = rand() % n; SWAP(x[0], x[a]); if (oi) SWAP(oi[0], oi[a]); v = x[0][depth]; a = b = 1; c = d = n-1; while (1) { while (b <= c && (r = x[b][depth]-v) <= 0) { if (r == 0) { SWAP(x[a], x[b]); if (oi) SWAP(oi[a], oi[b]); ++a; } ++b; } while (b <= c && (r = x[c][depth]-v) >= 0) { if (r == 0) { SWAP(x[c], x[d]); if (oi) SWAP(oi[c], oi[d]); --d; } --c; } if (b > c) break; SWAP(x[b], x[c]); if (oi) SWAP(oi[b], oi[c]); ++b; --c; } r = MIN(a,b-a); vecswap(0,b-r,r,x,oi); r = MIN(d-c,n-d-1); vecswap(b,n-r,r,x,oi); r = b-a; ssort1(x,r,depth,oi); if (x[r][depth] != 0) { if (oi) ssort1 (x + r, a + n - d - 1, depth + 1, oi + r); else ssort1 (x + r, a + n - d - 1, depth + 1, NULL); } r = d - c; if (oi) ssort1(x+n-r,r,depth,oi+n-r); else ssort1(x+n-r,r,depth,NULL); }
int cg( int n, double* x, double* pfx, lbfgs_evaluate_t evaluate, lbfgs_progress_t progress, void* instance, const lbfgs_parameter_t* _param ) { static const double RHO = 0.01; static const double SIG = 0.5; static const double INT = 0.1; static const double EXT = 3.0; static const double RATIO = 100.0; int ret; int k, ls_count, ls_success, ls_failed = 0, n_evaluate = 0; lbfgs_parameter_t param = (_param) ? (*_param) : default_param; double f0, f1, f2 = 0.0, f3, d1, d2, d3, z1, z2 = 0.0, z3, limit, A, B, C; double xnorm, gnorm, rate; double* df0, *df1, *df2, *s, *x0; double* pf = 0; if (progress == 0) { progress = default_lbfgs_progress; } if (n <= 0) { return LBFGSERR_INVALID_N; } if (param.epsilon < 0.0) { return LBFGSERR_INVALID_EPSILON; } if (param.past < 0) { return LBFGSERR_INVALID_TESTPERIOD; } if (param.delta < 0.0) { return LBFGSERR_INVALID_DELTA; } if (param.max_linesearch <= 0) { return LBFGSERR_INVALID_MAXLINESEARCH; } df0 = vecalloc(n); df1 = vecalloc(n); df2 = vecalloc(n); s = vecalloc(n); x0 = vecalloc(n); if (param.past > 0) { pf = vecalloc((size_t)param.past); } f1 = evaluate(instance, n, x, df1, 0); n_evaluate++; if (pf) { pf[0] = f1; } vec2norm(&xnorm, x, n); vec2norm(&gnorm, df1, n); if (xnorm < 1.0) { xnorm = 1.0; } if (gnorm / xnorm <= param.epsilon) { ret = LBFGS_ALREADY_MINIMIZED; goto cg_exit; } vecncpy(s, df1, n); vecdot(&d1, s, s, n); d1 = -d1; /** * Compute the initial step z1: */ z1 = 1.0 / (1.0 - d1); k = 1; for (;;) { /* Store the current position and gradient vectors. */ f0 = f1; veccpy(x0, x, n); veccpy(df0, df1, n); /* update x using current step: x=x+z1*s */ vecadd(x, s, z1, n); f2 = evaluate(instance, n, x, df2, 0); n_evaluate++; vecdot(&d2, df2, s, n); /* set point 3 equal to point 1 */ f3 = f1; d3 = d1; z3 = -z1; /* begin line search */ ls_success = 0; ls_count = 0; limit = -1.0; for (;;) { while (f2 > f1 + RHO * z1 * d1 || d2 > -SIG * d1) { limit = z1; if (f2 > f1) { /* quadratic fit */ z2 = z3 - (0.5 * d3 * z3 * z3) / (d3 * z3 + f2 - f3); } else { /* cubic fit */ A = 6 * (f2 - f3) / z3 + 3 * (d2 + d3); B = 3 * (f3 - f2) - z3 * (d3 + 2 * d2); z2 = (sqrt(B * B - A * d2 * z3 * z3) - B) / A; } if (isinf(z2) || isnan(z2)) { /* if we had a numerical problem then bisect */ z2 = z3 / 2.0; } /* don't accept too close to limits */ z2 = max2(min2(z2, INT* z3), (1.0 - INT) * z3); /* update step and x */ z1 = z1 + z2; vecadd(x, s, z2, n); f2 = evaluate(instance, n, x, df2, 0); n_evaluate++; ls_count++; vecdot(&d2, df2, s, n); z3 = z3 - z2; } if (f2 > f1 + z1 * RHO * d1 || d2 > -SIG * d1) { /* a line search failure */ break; } else if (d2 > SIG * d1) { /* a line search success */ ls_success = 1; break; } else if (ls_count >= param.max_linesearch) { ret = LBFGSERR_MAXIMUMLINESEARCH; goto cg_exit; } /* cubic extrapolation */ A = 6.0 * (f2 - f3) / z3 + 3.0 * (d2 + d3); B = 3.0 * (f3 - f2) - z3 * (d3 + 2 * d2); z2 = -d2 * z3 * z3 / (B + sqrt(B * B - A * d2 * z3 * z3)); /* adjust current step z2 for many cases */ if (isnan(z2) || isinf(z2) || z2 < 0.0) { if (limit < -0.5) { z2 = z1 * (EXT - 1.0); } else { z2 = (limit - z1) / 2.0; } } else if (limit > -0.5 && z2 + z1 > limit) { z2 = (limit - z1) / 2.0; } else if (limit < -0.5 && z2 + z1 > z1 * EXT) { z2 = z1 * (EXT - 1.0); } else if (z2 < -z3 * INT) { z2 = -z3 * INT; } else if (limit > -0.5 && z2 < (limit - z1) * (1.0 - INT)) { z2 = (limit - z1) * (1.0 - INT); } /* set point 3 equal to point 2 */ f3 = f2; d3 = d2; z3 = -z2; z1 = z1 + z2; vecadd(x, s, z2, n); f2 = evaluate(instance, n, x, df2, 0); n_evaluate++; ls_count++; vecdot(&d2, df2, s, n); } if (ls_success) { vec2norm(&xnorm, x, n); vec2norm(&gnorm, df2, n); if ((ret = progress(instance, n, x, df2, f2, xnorm, gnorm, z2, k, n_evaluate)) != 0) { ret = LBFGSERR_CANCELED; break; } if (xnorm < 1.0) { xnorm = 1.0; } if (gnorm / xnorm <= param.epsilon) { ret = LBFGS_CONVERGENCE; break; } if (pf) { if (param.past <= k) { rate = (pf[k % param.past] - f2) / f2; if (rate < param.delta) { ret = LBFGS_CONVERGENCE_DELTA; break; } } pf[k % param.past] = f2; } if (param.max_iterations != 0 && param.max_iterations < k + 1) { ret = LBFGSERR_MAXIMUMITERATION; break; } k++; f1 = f2; /** * Polack-Ribiere direction * s = (df2'*df2-df1'*df2)/(df1'*df1)*s - df2 */ vecdot(&A, df2, df2, n); vecdot(&B, df1, df2, n); vecdot(&C, df1, df1, n); vecscale(s, (A - B) / C, n); vecadd(s, df2, -1.0, n); vecswap(df1, df2, n); vecdot(&d2, df1, s, n); if (d2 > 0) { vecncpy(s, df1, n); vecdot(&d2, s, s, n); d2 = -d2; } z1 = z1 * min2(RATIO, d1 / (d2 - DBL_MIN)); d1 = d2; ls_failed = 0; } else { /* restore previous point */ f1 = f0; veccpy(x, x0, n); veccpy(df1, df0, n); if (ls_failed) { /* line search failed twice */ ret = LBFGSERR_LINE_SEARCH_FAILED; break; } vecswap(df1, df2, n); vecncpy(s, df1, n);/* try steepest */ vecdot(&d1, s, s, n); d1 = -d1; z1 = 1.0 / (1.0 - d1); ls_failed = 1; } } cg_exit: if (pfx) { *pfx = f2; } vecfree(pf); vecfree(x0); vecfree(s); vecfree(df2); vecfree(df1); vecfree(df0); return ret; }
void NS_QuickSort ( void *a, unsigned int n, unsigned int es, cmp_t *cmp, void *data ) { char *pa, *pb, *pc, *pd, *pl, *pm, *pn; int d, r, swaptype; loop: SWAPINIT(a, es); /* Use insertion sort when input is small */ if (n < 7) { for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) for (pl = pm; pl > (char *)a && cmp(pl - es, pl, data) > 0; pl -= es) swap(pl, pl - es); return; } /* Choose pivot */ pm = (char *)a + (n / 2) * es; if (n > 7) { pl = (char *)a; pn = (char *)a + (n - 1) * es; if (n > 40) { d = (n / 8) * es; pl = med3(pl, pl + d, pl + 2 * d, cmp, data); pm = med3(pm - d, pm, pm + d, cmp, data); pn = med3(pn - 2 * d, pn - d, pn, cmp, data); } pm = med3(pl, pm, pn, cmp, data); } swap(a, pm); pa = pb = (char *)a + es; pc = pd = (char *)a + (n - 1) * es; /* loop invariants: * [a, pa) = pivot * [pa, pb) < pivot * [pb, pc + es) unprocessed * [pc + es, pd + es) > pivot * [pd + es, pn) = pivot */ for (;;) { while (pb <= pc && (r = cmp(pb, a, data)) <= 0) { if (r == 0) { swap(pa, pb); pa += es; } pb += es; } while (pb <= pc && (r = cmp(pc, a, data)) >= 0) { if (r == 0) { swap(pc, pd); pd -= es; } pc -= es; } if (pb > pc) break; swap(pb, pc); pb += es; pc -= es; } /* Move pivot values */ pn = (char *)a + n * es; r = XPCOM_MIN(pa - (char *)a, pb - pa); vecswap(a, pb - r, r); r = XPCOM_MIN<size_t>(pd - pc, pn - pd - es); vecswap(pb, pn - r, r); /* Recursively process partitioned items */ if ((r = pb - pa) > (int)es) NS_QuickSort(a, r / es, es, cmp, data); if ((r = pd - pc) > (int)es) { /* Iterate rather than recurse to save stack space */ a = pn - r; n = r / es; goto loop; } /* NS_QuickSort(pn - r, r / es, es, cmp, data);*/ }
static void _pqsort(void *a, size_t n, size_t es, int (*cmp) (const void *, const void *), void *lrange, void *rrange) { char *pa, *pb, *pc, *pd, *pl, *pm, *pn; size_t d, r; int swaptype, cmp_result; loop: SWAPINIT(a, es); if (n < 7) { for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; pl -= es) swap(pl, pl - es); return; } pm = (char *) a + (n / 2) * es; if (n > 7) { pl = (char *) a; pn = (char *) a + (n - 1) * es; if (n > 40) { d = (n / 8) * es; pl = med3(pl, pl + d, pl + 2 * d, cmp); pm = med3(pm - d, pm, pm + d, cmp); pn = med3(pn - 2 * d, pn - d, pn, cmp); } pm = med3(pl, pm, pn, cmp); } swap(a, pm); pa = pb = (char *) a + es; pc = pd = (char *) a + (n - 1) * es; for (;;) { while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) { if (cmp_result == 0) { swap(pa, pb); pa += es; } pb += es; } while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) { if (cmp_result == 0) { swap(pc, pd); pd -= es; } pc -= es; } if (pb > pc) break; swap(pb, pc); pb += es; pc -= es; } pn = (char *) a + n * es; r = min(pa - (char *) a, pb - pa); vecswap(a, pb - r, r); r = min((size_t)(pd - pc), pn - pd - es); vecswap(pb, pn - r, r); if ((r = pb - pa) > es) { void *_l = a, *_r = ((unsigned char*)a)+r-1; if (!((lrange < _l && rrange < _l) || (lrange > _r && rrange > _r))) _pqsort(a, r / es, es, cmp, lrange, rrange); } if ((r = pd - pc) > es) { void *_l, *_r; /* Iterate rather than recurse to save stack space */ a = pn - r; n = r / es; _l = a; _r = ((unsigned char*)a)+r-1; if (!((lrange < _l && rrange < _l) || (lrange > _r && rrange > _r))) goto loop; } /* qsort(pn - r, r / es, es, cmp);*/ }