1 /* histogram/init.c 2 * 3 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 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 "gsl__config.h" 21 #include <stdlib.h> 22 #include "gsl_errno.h" 23 #include "gsl_histogram.h" 24 25 gsl_histogram * 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 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 * 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 * 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 137 gsl_histogram_free (gsl_histogram * h) 138 { 139 free (h->range); 140 free (h->bin); 141 free (h); 142 } 143 144 /* These initialization functions suggested by Achim Gaedke */ 145 146 int 147 gsl_histogram_set_ranges_uniform (gsl_histogram * h, double xmin, double xmax) 148 { 149 size_t i; 150 const size_t n = h->n; 151 152 if (xmin >= xmax) 153 { 154 GSL_ERROR ("xmin must be less than xmax", GSL_EINVAL); 155 } 156 157 /* initialize ranges */ 158 159 make_uniform (h->range, n, xmin, xmax); 160 161 /* clear contents */ 162 163 for (i = 0; i < n; i++) 164 { 165 h->bin[i] = 0; 166 } 167 168 return GSL_SUCCESS; 169 } 170 171 int 172 gsl_histogram_set_ranges (gsl_histogram * h, const double range[], size_t size) 173 { 174 size_t i; 175 const size_t n = h->n; 176 177 if (size != (n+1)) 178 { 179 GSL_ERROR ("size of range must match size of histogram", GSL_EINVAL); 180 } 181 182 /* initialize ranges */ 183 184 for (i = 0; i <= n; i++) 185 { 186 h->range[i] = range[i]; 187 } 188 189 /* clear contents */ 190 191 for (i = 0; i < n; i++) 192 { 193 h->bin[i] = 0; 194 } 195 196 return GSL_SUCCESS; 197 } 198 199