29 #include <list_void.h>
82 int current_p1, current_p2;
92 static void *(*list_malloc)(size_t) = malloc;
93 static void *(*list_calloc)(size_t, size_t) = calloc;
94 static void *(*list_realloc)(
void *, size_t) = realloc;
95 static void (*list_free)(
const void *) = (
void (*)(
const void *))free;
101 #define assure(EXPR) assert(EXPR)
133 dupl->elements =
list_malloc((l->size+l->back) *
sizeof(*dupl->elements));
134 dupl->size = l->size;
135 dupl->back = l->back;
136 dupl->current = l->current;
137 dupl->current_p1 = l->current_p1;
138 dupl->current_p2 = l->current_p2;
142 for (i = 0; i < l->size; i++) {
143 if (duplicate != NULL) {
144 dupl->elements[i] = duplicate(l->elements[i]);
147 dupl->elements[i] = l->elements[i];
163 list_delete_const(
const list **l,
void (*ldelete)(
void **))
165 if (l != NULL && *l != NULL) {
167 if (ldelete != NULL) {
170 for (i = 0; i < (*l)->size; i++) {
171 ldelete(&((*l)->elements[i]));
174 list_free((*l)->elements);
175 list_free((*l)); *l = NULL;
181 list_delete(
list **l,
void (*ldelete)(
void **))
183 list_delete_const((
const list **)l, ldelete);
195 list_size(
const list *l)
211 list_insert(
list *l,
void *e)
216 l->back = l->size + 1;
217 l->elements = list_realloc(l->elements, (l->size + l->back) *
sizeof(*l->elements));
222 l->elements[l->size - 1] = e;
246 list_remove_const(
list *l,
const void *e)
254 for (i = l->size - 1; i >= 0 && indx < 0; i--) {
255 if (l->elements[i] == e) {
262 for (i = indx; i < l->size-1; i++) {
263 l->elements[i] = l->elements[i+1];
270 if (l->back > 4 * l->size) {
273 l->elements = list_realloc(l->elements,
274 (l->size + l->back) *
sizeof(*l->elements));
281 list_remove(
list *l,
void *e)
283 return (
void *)list_remove_const(l, e);
294 list_reverse(
list *l)
300 for (i = 0, k = l->size-1; i < k; i++, k--)
303 tmp = l->elements[i];
304 l->elements[i] = l->elements[k];
305 l->elements[k] = tmp;
330 list_first_const(
const list *l)
334 if (l->size == 0)
return NULL;
339 ((
list *)l)->current = l->size - 1;
340 return l->elements[l->current];
346 return (
void *)list_first_const(l);
359 list_next_const(
const list *l)
363 if (l->size == 0)
return NULL;
365 ((
list *)l)->current -= 1;
367 if (l->current < 0)
return NULL;
368 else return l->elements[l->current];
374 return (
void *)list_next_const(l);
406 list_first_pair_const(
const list *l,
420 ((
list *)l)->current_p1 = l->size - 1;
421 ((
list *)l)->current_p2 = l->size - 2;
423 *e1 = l->elements[l->current_p1];
424 *e2 = l->elements[l->current_p2];
430 list_first_pair(
list *l,
434 list_first_pair_const(l,
452 list_next_pair_const(
const list *l,
466 ((
list *)l)->current_p2 -= 1;
468 if (l->current_p2 < 0) {
469 ((
list *)l)->current_p1 -= 1;
470 ((
list *)l)->current_p2 = l->current_p1 - 1;
471 if (l->current_p2 < 0) {
476 *e1 = l->elements[l->current_p1];
477 *e2 = l->elements[l->current_p2];
481 *e2 = l->elements[l->current_p2];
486 list_next_pair(
list *l,
490 list_next_pair_const(l, (
const void **)e1, (
const void **)e2);
508 void *(*duplicate)(
const void *),
509 bool (*predicate)(
const void *,
void *),
513 assure( duplicate != NULL);
514 assure( predicate != NULL);
520 for (i = 0; i < l->size; i++) {
521 if (predicate(l->elements[i], data)) {
522 list_insert(ex, duplicate(l->elements[i]));
544 list_min(
list *l, list_func_lt less_than,
void *data)
547 assure( less_than != NULL);
548 assure( list_size(l) > 0);
553 for (i = 1; i < l->size; i++) {
554 if (less_than(l->elements[i], l->elements[minindex], data))
558 return l->elements[minindex];
572 list_min_val(
list *l, list_func_eval eval,
void *data)
576 assure( list_size(l) > 0);
580 double minval = eval(l->elements[0], data);
583 for (i = 1; i < l->size; i++) {
584 double val = eval(l->elements[i], data);
591 return l->elements[minindex];
605 list_max_val(
list *l, list_func_eval eval,
void *data)
609 assure( list_size(l) > 0);
613 double maxval = eval(l->elements[0], data);
616 for (i = 1; i < l->size; i++) {
617 double val = eval(l->elements[i], data);
624 return l->elements[maxindex];
638 list_max_const(
const list *l, list_func_lt less_than,
void *data)
641 assure( less_than != NULL);
642 assure( list_size(l) > 0);
647 for (i = 1; i < l->size; i++) {
648 if (!less_than(l->elements[i], l->elements[maxindex], data))
652 return l->elements[maxindex];
657 list_max(
list *l, list_func_lt less_than,
void *data)
659 return (
void *)list_max_const(l, less_than, data);
678 kth(
const void *a[],
int k,
int n, list_func_lt less_than,
void *data)
687 const void *pivot = a[k];
691 while (less_than(a[i], pivot, data)) i++;
692 while (less_than(pivot, a[j], data)) {
696 const void *tmp = a[i];
709 list_kth_const(
const list *l,
int k,
710 list_func_lt less_than,
void *data)
717 assure( 1 <= k && k <= l->size );
720 len = l->size *
sizeof(*l->elements);
722 memcpy(elemcpy, l->elements, len);
724 kp = (
void*)kth((
const void **)elemcpy, k, l->size, less_than, data);
732 list_kth(
list *l,
int k,
733 list_func_lt less_than,
736 return (
void *)list_kth_const(l, k, less_than, data);
748 bool val_less_than(
const void *e1,
const void *e2,
void *data)
766 if (e1 == e2)
return false;
784 return (d->f(e1, d->aux_data) < d->f(e2, d->aux_data));
796 list_kth_val_const(
const list *l,
int k, list_func_eval eval,
void *data)
799 assure( 1 <= k && k <= l->size );
809 return list_kth_const(l, k, val_less_than, &d);
812 list_kth_val(
list *l,
int k, list_func_eval eval,
void *data)
814 return (
void *) list_kth_val_const(l, k, eval, data);
830 list_median(
const list *l, list_func_eval eval,
void *data)
836 const void *median_element = list_kth_val_const(l, (l->size+1)/2, eval, data);
838 double median_val = eval(median_element, data);
840 if (list_size(l) && 2 == 0)
842 const void *other_median_element =
843 list_kth_val_const(l, (l->size+2)/2, eval, data);
845 median_val = (median_val + eval(other_median_element, data) ) / 2.0;
861 list_mean(
const list *l, list_func_eval eval,
void *data)
867 double result = eval(l->elements[0], data);
870 for (i = 1; i < l->size; i++) {
871 result += eval(l->elements[i], data);
899 list_mean_optimal(
const list *l,
900 list_func_eval eval,
void *data_eval,
901 list_func_eval eval_err,
void *data_err,
907 assure( red_chisq == NULL || l->size >= 2 );
909 assure( eval_err != NULL );
912 double sum_weights = 0;
913 double opt_average = 0;
916 for (i = 0; i < l->size; i++) {
917 void *e = l->elements[i];
918 double sigma = eval_err(e, data_err);
922 double weight = 1/(sigma*sigma);
924 opt_average += eval(e, data_eval) * weight;
925 sum_weights += weight;
927 opt_average /= sum_weights;
928 *err = 1 / sqrt(sum_weights);
930 if (red_chisq != NULL) {
932 for (i = 0; i < l->size; i++) {
933 void *e = l->elements[i];
934 double residual = ((eval(e, data_eval) - opt_average)) / eval_err(e, data_err);
935 *red_chisq += residual * residual;
937 *red_chisq /= (l->size - 1);
953 abs_dev(
const void *e1,
void *data)
962 return fabs(d->f(e1, d->aux_data) - d->ref);
975 list_mad(
list *l, list_func_eval eval,
void *data)
980 double median = list_median(l, eval, data);
992 return list_median(l, abs_dev, &d);
list * list_duplicate(const list *l, void *(*duplicate)(const void *))
Copy constructor.
list * list_extract(const list *l, void *(*duplicate)(const void *), bool(*predicate)(const void *, void *), void *data)
Extract elements.
list * list_new(void)
Constructor.
static void *(* list_malloc)(size_t)