004b72a86c7fad684be7821df3123c68c573c548 kent Mon Dec 23 15:50:56 2013 -0800 Adding slListRandomReduce and slListRandomSample for making samples of larger lists. diff --git src/lib/obscure.c src/lib/obscure.c index feaa622..990211a 100644 --- src/lib/obscure.c +++ src/lib/obscure.c @@ -667,30 +667,72 @@ array[i] = el; for (i=0; i<4; ++i) shuffleArrayOfPointers(array, count); list = NULL; for (i=0; inext = list; list = array[i]; } freeMem(array); slReverse(&list); *pL = list; } } +void *slListRandomReduce(void *list, double reduceRatio) +/* Reduce list to approximately reduceRatio times original size. Destroys original list. */ +{ +if (reduceRatio >= 1.0) + return list; +int threshold = RAND_MAX * reduceRatio; +struct slList *newList = NULL, *next, *el; +for (el = list; el != NULL; el = next) + { + next = el->next; + if (rand() <= threshold) + { + slAddHead(&newList, el); + } + } +return newList; +} + +void *slListRandomSample(void *list, int maxCount) +/* Return a sublist of list with at most maxCount. Destroy list in process */ +{ +if (list == NULL) + return list; +int initialCount = slCount(list); +if (initialCount <= maxCount) + return list; +double reduceRatio = (double)maxCount/initialCount; +if (reduceRatio < 0.9) + { + double conservativeReduceRatio = reduceRatio * 1.05; + list = slListRandomReduce(list, conservativeReduceRatio); + } +int midCount = slCount(list); +if (midCount <= maxCount) + return list; +shuffleList(list); +struct slList *lastEl = slElementFromIx(list, maxCount-1); +lastEl->next = NULL; +return list; +} + + char *stripCommas(char *position) /* make a new string with commas stripped out */ { char *newPos = cloneString(position); char *nPtr = newPos; if (position == NULL) return NULL; while((*nPtr = *position++)) if (*nPtr != ',') nPtr++; return newPos; }