expressions: Merge all the little generator programs into generate.pl.
[pspp.git] / src / math / extrema.c
blob7b82a5c4a0e4914d04c35d8c726209adadaaf9c9
1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2008, 2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 #include <config.h>
19 #include "math/extrema.h"
21 #include <stdlib.h>
23 #include "data/case.h"
24 #include "data/val-type.h"
25 #include "libpspp/compiler.h"
26 #include "libpspp/ll.h"
28 #include "gl/xalloc.h"
30 struct extrema
32 size_t capacity;
33 size_t n;
34 struct ll_list list;
36 ll_compare_func *cmp_func;
40 static int
41 cmp_descending (const struct ll *a_, const struct ll *b_, void *aux UNUSED)
43 const struct extremum *a = ll_data (a_, struct extremum, ll);
44 const struct extremum *b = ll_data (b_, struct extremum, ll);
46 if ( a->value > b->value) return -1;
48 return (a->value < b->value);
51 static int
52 cmp_ascending (const struct ll *a_, const struct ll *b_, void *aux UNUSED)
54 const struct extremum *a = ll_data (a_, struct extremum, ll);
55 const struct extremum *b = ll_data (b_, struct extremum, ll);
57 if ( a->value < b->value) return -1;
59 return (a->value > b->value);
63 struct extrema *
64 extrema_create (size_t n, enum extreme_end end)
66 struct extrema *extrema = xzalloc (sizeof *extrema);
67 extrema->capacity = n;
69 if ( end == EXTREME_MAXIMA )
70 extrema->cmp_func = cmp_descending;
71 else
72 extrema->cmp_func = cmp_ascending;
74 ll_init (&extrema->list);
76 return extrema;
79 void
80 extrema_destroy (struct extrema *extrema)
82 struct ll *ll = ll_head (&extrema->list);
84 while (ll != ll_null (&extrema->list))
86 struct extremum *e = ll_data (ll, struct extremum, ll);
88 ll = ll_next (ll);
89 free (e);
92 free (extrema);
96 void
97 extrema_add (struct extrema *extrema, double val,
98 double weight,
99 casenumber location)
101 struct extremum *e = xzalloc (sizeof *e) ;
102 e->value = val;
103 e->location = location;
104 e->weight = weight;
106 if ( val == SYSMIS)
108 free (e);
109 return;
112 ll_insert_ordered (ll_head (&extrema->list), ll_null (&extrema->list),
113 &e->ll, extrema->cmp_func, NULL);
115 if ( extrema->n++ > extrema->capacity)
117 struct ll *tail = ll_tail (&extrema->list);
118 struct extremum *et = ll_data (tail, struct extremum, ll);
120 ll_remove (tail);
122 free (et);
127 const struct ll_list *
128 extrema_list (const struct extrema *ex)
130 return &ex->list;
134 bool
135 extrema_top (const struct extrema *ex, double *v)
137 const struct extremum *top;
139 if ( ll_is_empty (&ex->list))
140 return false;
142 top = (const struct extremum *)
143 ll_data (ll_head(&ex->list), struct extremum, ll);
145 *v = top->value;
147 return true;