SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
makeHistogram.c
Go to the documentation of this file.
1/**
2 * @file makeHistogram.c
3 * @brief Compiles histograms from data points.
4 *
5 * This file contains functions to compile histograms from data points. It provides both standard and weighted histogram functions,
6 * as well as a function to compute the mode of a dataset.
7 *
8 * @copyright
9 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
10 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
11 *
12 * @license
13 * This file is distributed under the terms of the Software License Agreement
14 * found in the file LICENSE included with this distribution.
15 *
16 * @author M. Borland, C. Saunders, R. Soliday
17 */
18
19#include "mdb.h"
20
21/**
22 * @brief Compiles a histogram from data points.
23 *
24 * @param hist Pointer to the histogram array to be filled.
25 * @param n_bins Number of bins in the histogram.
26 * @param lo Lower bound of the histogram range.
27 * @param hi Upper bound of the histogram range.
28 * @param data Pointer to the data array.
29 * @param n_pts Number of data points.
30 * @param new_start Flag indicating whether to initialize the histogram (1 to initialize, 0 to accumulate).
31 * @return Returns the total number of points binned.
32 */
34 double *hist, long n_bins, double lo, double hi, double *data,
35 int64_t n_pts, long new_start) {
36 static long bin;
37 static int64_t i;
38 static double bin_size, dbin;
39
40 if (new_start) {
41 bin_size = (hi - lo) / n_bins;
42 for (i = 0; i < n_bins; i++)
43 hist[i] = 0;
44 }
45
46 for (i = 0; i < n_pts; i++) {
47 bin = (dbin = (data[i] - lo) / bin_size);
48 if (dbin < 0)
49 continue;
50 if (bin < 0 || bin >= n_bins)
51 continue;
52 hist[bin] += 1;
53 }
54
55 for (i = bin = 0; i < n_bins; i++)
56 bin += hist[i];
57
58 return (bin);
59}
60
61/**
62 * @brief Compiles a weighted histogram from data points.
63 *
64 * @param hist Pointer to the histogram array to be filled.
65 * @param n_bins Number of bins in the histogram.
66 * @param lo Lower bound of the histogram range.
67 * @param hi Upper bound of the histogram range.
68 * @param data Pointer to the data array.
69 * @param n_pts Number of data points.
70 * @param new_start Flag indicating whether to initialize the histogram (1 to initialize, 0 to accumulate).
71 * @param weight Pointer to the weights array corresponding to each data point.
72 * @return Returns the total number of points binned.
73 */
75 double *hist, long n_bins, double lo, double hi, double *data,
76 long n_pts, long new_start, double *weight) {
77 static long bin, i, count;
78 static double bin_size, dbin;
79
80 if (new_start) {
81 count = 0;
82 bin_size = (hi - lo) / n_bins;
83 for (i = 0; i < n_bins; i++)
84 hist[i] = 0;
85 }
86
87 for (i = 0; i < n_pts; i++) {
88 bin = (dbin = (data[i] - lo) / bin_size);
89 if (dbin < 0)
90 continue;
91 if (bin < 0 || bin >= n_bins)
92 continue;
93 hist[bin] += weight[i];
94 count++;
95 }
96
97 return (count);
98}
99
100/**
101 * @brief Computes the mode of a dataset using histogram binning.
102 *
103 * @param result Pointer to store the computed mode value.
104 * @param data Pointer to the data array.
105 * @param pts Number of data points.
106 * @param binSize Size of each histogram bin. If greater than 0, determines the bin size; otherwise, the number of bins is used.
107 * @param bins Number of bins in the histogram.
108 * @return
109 * @return 1 on success,
110 * @return -1 if invalid binSize and bins parameters,
111 * @return -2 if pts <= 0,
112 * @return -3 if data is NULL,
113 * @return -4 if result is NULL.
114 */
115long computeMode(double *result, double *data, long pts, double binSize, long bins) {
116 double min, max;
117 int64_t imin, imax;
118 double *histogram;
119
120 if ((binSize <= 0 && bins <= 2) || (binSize > 0 && bins > 2))
121 return -1;
122 if (pts <= 0)
123 return -2;
124 if (!data)
125 return -3;
126 if (!result)
127 return -4;
128 if (pts == 1) {
129 *result = data[0];
130 return 1;
131 }
132 find_min_max(&min, &max, data, pts);
133 /* add buffer bins and compute bin size or number of bins */
134 if (binSize > 0) {
135 max += binSize;
136 min -= binSize;
137 bins = (max - min) / binSize + 0.5;
138 } else {
139 binSize = (max - min) / bins;
140 max += binSize;
141 min -= binSize;
142 bins += 2;
143 binSize = (max - min) / bins;
144 }
145 if (!(histogram = malloc(sizeof(*histogram) * bins)))
146 bomb("memory allocation failure (computeMode)", NULL);
147 make_histogram(histogram, bins, min, max, data, pts, 1);
148 index_min_max(&imin, &imax, histogram, bins);
149 free(histogram);
150 *result = (imax + 0.5) * binSize + min;
151 return 1;
152}
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
int index_min_max(int64_t *imin, int64_t *imax, double *list, int64_t n)
Finds the indices of the minimum and maximum values in a list of doubles.
Definition findMinMax.c:116
int find_min_max(double *min, double *max, double *list, int64_t n)
Finds the minimum and maximum values in a list of doubles.
Definition findMinMax.c:33
long make_histogram_weighted(double *hist, long n_bins, double lo, double hi, double *data, long n_pts, long new_start, double *weight)
Compiles a weighted histogram from data points.
long computeMode(double *result, double *data, long pts, double binSize, long bins)
Computes the mode of a dataset using histogram binning.
long make_histogram(double *hist, long n_bins, double lo, double hi, double *data, int64_t n_pts, long new_start)
Compiles a histogram from data points.