BRL-CAD
hist.c
Go to the documentation of this file.
1 /* H I S T . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1990-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 #include <stdio.h>
24 #include <math.h>
25 #include <string.h>
26 
27 #include "bu/hist.h"
28 #include "bu/log.h"
29 #include "bu/malloc.h"
30 
31 void
32 bu_hist_free(struct bu_hist *histp)
33 {
34  if (UNLIKELY((histp==(struct bu_hist *)NULL) ||
35  (histp && (histp->magic == 0 || histp->magic == (unsigned int)-1))))
36  {
37  return;
38  }
39 
40  BU_CK_HIST(histp);
41 
42  if (histp->hg_bins)
43  bu_free((char *)histp->hg_bins, "old bu_hist bins");
44  histp->hg_bins = NULL;
45  histp->hg_nbins = 0;
46  histp->magic = (unsigned int)-1; /* sanity */
47 }
48 
49 
50 void
51 bu_hist_init(struct bu_hist *histp, fastf_t min, fastf_t max, size_t nbins)
52 {
53 
54  if (max <= min)
55  max = min+1;
56  if (nbins < 1) {
57  nbins = 1; /* nbins=1 makes for a nice 2-bin binary histogram */
58  } else if (nbins > 10000) {
59  nbins = 10000; /* This is a lot of lines to print out */
60  }
61 
62  histp->hg_min = lrint(floor(min));
63  histp->hg_max = lrint(ceil(max));
64  histp->hg_nbins = nbins;
65 
66  histp->hg_clumpsize = ((max-min)/nbins);
67  if (histp->hg_clumpsize <= 0)
68  histp->hg_clumpsize = 1;
69 
70  histp->hg_nsamples = 0;
71  histp->hg_bins = (long *)bu_calloc(nbins+1, sizeof(long), "bu_hist bins");
72  histp->magic = BU_HIST_MAGIC;
73 }
74 
75 
76 void
77 bu_hist_range(register struct bu_hist *hp, fastf_t low, fastf_t high)
78 {
79  long a;
80  long b;
81  register int i;
82 
83  BU_CK_HIST(hp);
84  if (low <= hp->hg_min)
85  a = 0;
86  else
87  a = (low - hp->hg_min) / hp->hg_clumpsize;
88  if (high >= hp->hg_max)
89  b = hp->hg_nbins-1;
90  else
91  b = (high - hp->hg_min) / hp->hg_clumpsize;
92  if (b >= (long)hp->hg_nbins)
93  b = hp->hg_nbins-1;
94  if (b < 0)
95  b = 0;
96 
97  for (i=a; i <= b; i++) {
98  hp->hg_bins[i]++;
99  }
100  hp->hg_nsamples++;
101 }
102 
103 
104 /**
105  * Allows caller control over zero-suppression feature.
106  */
107 HIDDEN void
108 hist_pr_suppress(register const struct bu_hist *histp, const char *title, int zero_suppress)
109 {
110  long maxcount;
111  static const char marks[] = "################################################################";
112 #define NMARKS 50
113  char buf[256];
114  int percent;
115  unsigned int mark_count;
116  double val;
117  size_t i;
118  size_t nbins;
119 
120  BU_CK_HIST(histp);
121 
122  /* Find entry with highest count */
123  maxcount = 0L;
124  for (i=0; i<=histp->hg_nbins; i++) {
125  if (histp->hg_bins[i] > maxcount)
126  maxcount = histp->hg_bins[i];
127  }
128  if (maxcount < 1)
129  maxcount = 1;
130 
131  nbins = histp->hg_nbins;
132  if (zero_suppress) {
133  /* Suppress trailing bins with zero counts. nbins s/b >= 1 */
134  for (; nbins >= 1; nbins--) {
135  if (histp->hg_bins[nbins] > 0)
136  break;
137  }
138  }
139 
140  /* 12345678 12345678 123 .... */
141  bu_log("\nHistogram of %s\nmin=%g, max=%g, nbins=%zd, clumpsize=%g\n%ld samples collected, highest count was %ld\n\n Value Count Rel%%| Bar Graph\n",
142  title,
143  histp->hg_min, histp->hg_max,
144  histp->hg_nbins, histp->hg_clumpsize,
145  histp->hg_nsamples, maxcount);
146 
147  /* Print each bin. */
148  i = 0;
149  if (zero_suppress) {
150  /* Leading bins with zero counts are suppressed. */
151  for (; i <= nbins; i++) {
152  if (histp->hg_bins[i] > 0)
153  break;
154  }
155  }
156  for (; i <= nbins; i++) {
157  percent = (int)(((double)histp->hg_bins[i])*100.0/maxcount);
158  mark_count = percent*NMARKS/100;
159  if (mark_count <= 0 && histp->hg_bins[i] > 0)
160  mark_count = 1;
161  if (mark_count > NMARKS) {
162  bu_log("mark_count=%d, NMARKS=%d, hg_bins[%d]=%ld, maxcount=%ld\n",
163  mark_count, NMARKS, i, histp->hg_bins[i], maxcount);
164  bu_bomb("bu_hist_pr() bogus mark_count\n");
165  }
166  if (mark_count <= 0) {
167  buf[0] = '\0';
168  } else {
169  memcpy(buf, marks, mark_count);
170  buf[mark_count] = '\0';
171  }
172  val = histp->hg_min + i*histp->hg_clumpsize;
173  bu_log("%8g %8ld %3d |%s\n",
174  val, histp->hg_bins[i], percent, buf);
175  }
176 }
177 
178 
179 void
180 bu_hist_pr(register const struct bu_hist *histp, const char *title)
181 {
182  hist_pr_suppress(histp, title, 1);
183 }
184 
185 
186 /*
187  * Local Variables:
188  * mode: C
189  * tab-width: 8
190  * indent-tabs-mode: t
191  * c-file-style: "stroustrup"
192  * End:
193  * ex: shiftwidth=4 tabstop=8
194  */
Definition: db_flip.c:35
void bu_hist_pr(register const struct bu_hist *histp, const char *title)
Definition: hist.c:180
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
fastf_t hg_min
Definition: hist.h:55
HIDDEN void hist_pr_suppress(register const struct bu_hist *histp, const char *title, int zero_suppress)
Definition: hist.c:108
Definition: hist.h:53
void bu_hist_init(struct bu_hist *histp, fastf_t min, fastf_t max, size_t nbins)
Definition: hist.c:51
size_t hg_nbins
Definition: hist.h:59
Header file for the BRL-CAD common definitions.
#define HIDDEN
Definition: common.h:86
if(share_geom)
Definition: nmg_mod.c:3829
#define NMARKS
#define BU_CK_HIST(_p)
Definition: hist.h:68
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
fastf_t hg_clumpsize
Definition: hist.h:57
uint32_t magic
Definition: hist.h:54
#define BU_HIST_MAGIC
Definition: magic.h:53
void bu_hist_range(register struct bu_hist *hp, fastf_t low, fastf_t high)
Definition: hist.c:77
size_t hg_nsamples
Definition: hist.h:58
fastf_t hg_max
Definition: hist.h:56
void bu_hist_free(struct bu_hist *histp)
Definition: hist.c:32
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
long * hg_bins
Definition: hist.h:60
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
double fastf_t
Definition: defines.h:300
#define UNLIKELY(expression)
Definition: common.h:282