1 /* histogram/init.c
2 *
3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007, 2009 Brian Gough
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or (at
8 * your option) any later version.
9 *
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.
14 *
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 02110-1301, USA.
18 */
19
20 #include <config.h>
21 #include <stdlib.h>
22 #include <gsl/gsl_errno.h>
23 #include <gsl/gsl_histogram.h>
24
25 gsl_histogram *
gsl_histogram_alloc(size_t n)26 gsl_histogram_alloc (size_t n)
27 {
28 gsl_histogram *h;
29
30 if (n == 0)
31 {
32 GSL_ERROR_VAL ("histogram length n must be positive integer",
33 GSL_EDOM, 0);
34 }
35
36 h = (gsl_histogram *) malloc (sizeof (gsl_histogram));
37
38 if (h == 0)
39 {
40 GSL_ERROR_VAL ("failed to allocate space for histogram struct",
41 GSL_ENOMEM, 0);
42 }
43
44 h->range = (double *) malloc ((n + 1) * sizeof (double));
45
46 if (h->range == 0)
47 {
48 free (h); /* exception in constructor, avoid memory leak */
49
50 GSL_ERROR_VAL ("failed to allocate space for histogram ranges",
51 GSL_ENOMEM, 0);
52 }
53
54 h->bin = (double *) malloc (n * sizeof (double));
55
56 if (h->bin == 0)
57 {
58 free (h->range);
59 free (h); /* exception in constructor, avoid memory leak */
60
61 GSL_ERROR_VAL ("failed to allocate space for histogram bins",
62 GSL_ENOMEM, 0);
63 }
64
65 h->n = n;
66
67 return h;
68 }
69
70 static void
make_uniform(double range[],size_t n,double xmin,double xmax)71 make_uniform (double range[], size_t n, double xmin, double xmax)
72 {
73 size_t i;
74
75 for (i = 0; i <= n; i++)
76 {
77 double f1 = ((double) (n-i) / (double) n);
78 double f2 = ((double) i / (double) n);
79 range[i] = f1 * xmin + f2 * xmax;
80 }
81 }
82
83 gsl_histogram *
gsl_histogram_calloc_uniform(const size_t n,const double xmin,const double xmax)84 gsl_histogram_calloc_uniform (const size_t n, const double xmin,
85 const double xmax)
86 {
87 gsl_histogram *h;
88
89 if (xmin >= xmax)
90 {
91 GSL_ERROR_VAL ("xmin must be less than xmax", GSL_EINVAL, 0);
92 }
93
94 h = gsl_histogram_calloc (n);
95
96 if (h == 0)
97 {
98 return h;
99 }
100
101 make_uniform (h->range, n, xmin, xmax);
102
103 return h;
104 }
105
106 gsl_histogram *
gsl_histogram_calloc(size_t n)107 gsl_histogram_calloc (size_t n)
108 {
109 gsl_histogram * h = gsl_histogram_alloc (n);
110
111 if (h == 0)
112 {
113 return h;
114 }
115
116 {
117 size_t i;
118
119 for (i = 0; i < n + 1; i++)
120 {
121 h->range[i] = i;
122 }
123
124 for (i = 0; i < n; i++)
125 {
126 h->bin[i] = 0;
127 }
128 }
129
130 h->n = n;
131
132 return h;
133 }
134
135
136 void
gsl_histogram_free(gsl_histogram * h)137 gsl_histogram_free (gsl_histogram * h)
138 {
139 RETURN_IF_NULL (h);
140 free (h->range);
141 free (h->bin);
142 free (h);
143 }
144
145 /* These initialization functions suggested by Achim Gaedke */
146
147 int
gsl_histogram_set_ranges_uniform(gsl_histogram * h,double xmin,double xmax)148 gsl_histogram_set_ranges_uniform (gsl_histogram * h, double xmin, double xmax)
149 {
150 size_t i;
151 const size_t n = h->n;
152
153 if (xmin >= xmax)
154 {
155 GSL_ERROR ("xmin must be less than xmax", GSL_EINVAL);
156 }
157
158 /* initialize ranges */
159
160 make_uniform (h->range, n, xmin, xmax);
161
162 /* clear contents */
163
164 for (i = 0; i < n; i++)
165 {
166 h->bin[i] = 0;
167 }
168
169 return GSL_SUCCESS;
170 }
171
172 int
gsl_histogram_set_ranges(gsl_histogram * h,const double range[],size_t size)173 gsl_histogram_set_ranges (gsl_histogram * h, const double range[], size_t size)
174 {
175 size_t i;
176 const size_t n = h->n;
177
178 if (size != (n+1))
179 {
180 GSL_ERROR ("size of range must match size of histogram", GSL_EINVAL);
181 }
182
183 /* initialize ranges */
184
185 for (i = 0; i <= n; i++)
186 {
187 h->range[i] = range[i];
188 }
189
190 /* clear contents */
191
192 for (i = 0; i < n; i++)
193 {
194 h->bin[i] = 0;
195 }
196
197 return GSL_SUCCESS;
198 }
199
200