xref: /petsc/src/sys/classes/draw/utils/hists.c (revision a197972ac2354be954b7aae623d40f6de50a3e72) !
1 
2 /*
3   Contains the data structure for plotting a histogram in a window with an axis.
4 */
5 #include <petscdraw.h>         /*I "petscdraw.h" I*/
6 #include <petsc-private/petscimpl.h>         /*I "petscsys.h" I*/
7 #include <petscviewer.h>         /*I "petscviewer.h" I*/
8 
9 PetscClassId PETSC_DRAWHG_CLASSID = 0;
10 
11 struct _p_PetscDrawHG {
12   PETSCHEADER(int);
13   PetscErrorCode (*destroy)(PetscDrawSP);
14   PetscErrorCode (*view)(PetscDrawSP,PetscViewer);
15   PetscDraw      win;
16   PetscDrawAxis  axis;
17   PetscReal      xmin,xmax;
18   PetscReal      ymin,ymax;
19   int            numBins;
20   int            maxBins;
21   PetscReal      *bins;
22   int            numValues;
23   int            maxValues;
24   PetscReal      *values;
25   int            color;
26   PetscBool      calcStats;
27   PetscBool      integerBins;
28 };
29 
30 #define CHUNKSIZE 100
31 
32 #undef __FUNCT__
33 #define __FUNCT__ "PetscDrawHGCreate"
34 /*@C
35    PetscDrawHGCreate - Creates a histogram data structure.
36 
37    Collective over PetscDraw
38 
39    Input Parameters:
40 +  draw  - The window where the graph will be made
41 -  bins - The number of bins to use
42 
43    Output Parameters:
44 .  hist - The histogram context
45 
46    Level: intermediate
47 
48    Concepts: histogram^creating
49 
50 .seealso: PetscDrawHGDestroy()
51 
52 @*/
53 PetscErrorCode  PetscDrawHGCreate(PetscDraw draw, int bins, PetscDrawHG *hist)
54 {
55   PetscDrawHG    h;
56   MPI_Comm       comm;
57   PetscBool      isnull;
58   PetscErrorCode ierr;
59 
60   PetscFunctionBegin;
61   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID,1);
62   PetscValidPointer(hist,3);
63   ierr = PetscObjectGetComm((PetscObject) draw, &comm);CHKERRQ(ierr);
64   ierr = PetscHeaderCreate(h, _p_PetscDrawHG, int, PETSC_DRAWHG_CLASSID,  "PetscDrawHG", "Histogram", "Draw", comm, PetscDrawHGDestroy, NULL);CHKERRQ(ierr);
65 
66   h->view        = NULL;
67   h->destroy     = NULL;
68   h->win         = draw;
69 
70   ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr);
71 
72   h->color       = PETSC_DRAW_GREEN;
73   h->xmin        = PETSC_MAX_REAL;
74   h->xmax        = PETSC_MIN_REAL;
75   h->ymin        = 0.;
76   h->ymax        = 1.;
77   h->numBins     = bins;
78   h->maxBins     = bins;
79 
80   ierr = PetscMalloc1(h->maxBins, &h->bins);CHKERRQ(ierr);
81 
82   h->numValues   = 0;
83   h->maxValues   = CHUNKSIZE;
84   h->calcStats   = PETSC_FALSE;
85   h->integerBins = PETSC_FALSE;
86 
87   ierr = PetscMalloc1(h->maxValues, &h->values);CHKERRQ(ierr);
88   ierr = PetscLogObjectMemory((PetscObject)h, (h->maxBins + h->maxValues)*sizeof(PetscReal));CHKERRQ(ierr);
89   ierr = PetscObjectTypeCompare((PetscObject) draw, PETSC_DRAW_NULL, &isnull);CHKERRQ(ierr);
90 
91   if (!isnull) {
92     ierr = PetscDrawAxisCreate(draw, &h->axis);CHKERRQ(ierr);
93     ierr = PetscLogObjectParent((PetscObject)h, (PetscObject)h->axis);CHKERRQ(ierr);
94   } else h->axis = NULL;
95   *hist = h;
96   PetscFunctionReturn(0);
97 }
98 
99 #undef __FUNCT__
100 #define __FUNCT__ "PetscDrawHGSetNumberBins"
101 /*@
102    PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn.
103 
104    Not Collective (ignored except on processor 0 of PetscDrawHG)
105 
106    Input Parameter:
107 +  hist - The histogram context.
108 -  dim  - The number of curves.
109 
110    Level: intermediate
111 
112    Concepts: histogram^setting number of bins
113 
114 @*/
115 PetscErrorCode  PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins)
116 {
117   PetscErrorCode ierr;
118 
119   PetscFunctionBegin;
120   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
121   if (hist->maxBins < bins) {
122     ierr = PetscFree(hist->bins);CHKERRQ(ierr);
123     ierr = PetscMalloc1(bins, &hist->bins);CHKERRQ(ierr);
124     ierr = PetscLogObjectMemory((PetscObject)hist, (bins - hist->maxBins) * sizeof(PetscReal));CHKERRQ(ierr);
125 
126     hist->maxBins = bins;
127   }
128   hist->numBins = bins;
129   PetscFunctionReturn(0);
130 }
131 
132 #undef __FUNCT__
133 #define __FUNCT__ "PetscDrawHGReset"
134 /*@
135   PetscDrawHGReset - Clears histogram to allow for reuse with new data.
136 
137   Not Collective (ignored except on processor 0 of PetscDrawHG)
138 
139   Input Parameter:
140 . hist - The histogram context.
141 
142   Level: intermediate
143 
144   Concepts: histogram^resetting
145 @*/
146 PetscErrorCode  PetscDrawHGReset(PetscDrawHG hist)
147 {
148   PetscFunctionBegin;
149   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
150   hist->xmin      = PETSC_MAX_REAL;
151   hist->xmax      = PETSC_MIN_REAL;
152   hist->ymin      = 0.0;
153   hist->ymax      = 0.0;
154   hist->numValues = 0;
155   PetscFunctionReturn(0);
156 }
157 
158 #undef __FUNCT__
159 #define __FUNCT__ "PetscDrawHGDestroy"
160 /*@C
161   PetscDrawHGDestroy - Frees all space taken up by histogram data structure.
162 
163   Collective over PetscDrawHG
164 
165   Input Parameter:
166 . hist - The histogram context
167 
168   Level: intermediate
169 
170 .seealso:  PetscDrawHGCreate()
171 @*/
172 PetscErrorCode  PetscDrawHGDestroy(PetscDrawHG *hist)
173 {
174   PetscErrorCode ierr;
175 
176   PetscFunctionBegin;
177   if (!*hist) PetscFunctionReturn(0);
178   PetscValidHeader(*hist,1);
179 
180   if (--((PetscObject)(*hist))->refct > 0) PetscFunctionReturn(0);
181   ierr = PetscDrawAxisDestroy(&(*hist)->axis);CHKERRQ(ierr);
182   ierr = PetscDrawDestroy(&(*hist)->win);CHKERRQ(ierr);
183   ierr = PetscFree((*hist)->bins);CHKERRQ(ierr);
184   ierr = PetscFree((*hist)->values);CHKERRQ(ierr);
185   ierr = PetscHeaderDestroy(hist);CHKERRQ(ierr);
186   PetscFunctionReturn(0);
187 }
188 
189 #undef __FUNCT__
190 #define __FUNCT__ "PetscDrawHGAddValue"
191 /*@
192   PetscDrawHGAddValue - Adds another value to the histogram.
193 
194   Not Collective (ignored except on processor 0 of PetscDrawHG)
195 
196   Input Parameters:
197 + hist  - The histogram
198 - value - The value
199 
200   Level: intermediate
201 
202   Concepts: histogram^adding values
203 
204 .seealso: PetscDrawHGAddValues()
205 @*/
206 PetscErrorCode  PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value)
207 {
208   PetscFunctionBegin;
209   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
210   /* Allocate more memory if necessary */
211   if (hist->numValues >= hist->maxValues) {
212     PetscReal      *tmp;
213     PetscErrorCode ierr;
214 
215     ierr = PetscMalloc1(hist->maxValues+CHUNKSIZE, &tmp);CHKERRQ(ierr);
216     ierr = PetscLogObjectMemory((PetscObject)hist, CHUNKSIZE * sizeof(PetscReal));CHKERRQ(ierr);
217     ierr = PetscMemcpy(tmp, hist->values, hist->maxValues * sizeof(PetscReal));CHKERRQ(ierr);
218     ierr = PetscFree(hist->values);CHKERRQ(ierr);
219 
220     hist->values     = tmp;
221     hist->maxValues += CHUNKSIZE;
222   }
223   /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the
224      stated convention of using half-open intervals (always the way to go) */
225   if (!hist->numValues) {
226     hist->xmin = value;
227     hist->xmax = value;
228 #if 1
229   } else {
230     /* Update limits */
231     if (value > hist->xmax) hist->xmax = value;
232     if (value < hist->xmin) hist->xmin = value;
233 #else
234   } else if (hist->numValues == 1) {
235     /* Update limits -- We need to overshoot the largest value somewhat */
236     if (value > hist->xmax) hist->xmax = value + 0.001*(value - hist->xmin)/hist->numBins;
237     if (value < hist->xmin) {
238       hist->xmin = value;
239       hist->xmax = hist->xmax + 0.001*(hist->xmax - hist->xmin)/hist->numBins;
240     }
241   } else {
242     /* Update limits -- We need to overshoot the largest value somewhat */
243     if (value > hist->xmax) hist->xmax = value + 0.001*(hist->xmax - hist->xmin)/hist->numBins;
244     if (value < hist->xmin) hist->xmin = value;
245 #endif
246   }
247 
248   hist->values[hist->numValues++] = value;
249   PetscFunctionReturn(0);
250 }
251 
252 #undef __FUNCT__
253 #define __FUNCT__ "PetscDrawHGDraw"
254 /*@
255   PetscDrawHGDraw - Redraws a histogram.
256 
257   Not Collective (ignored except on processor 0 of PetscDrawHG)
258 
259   Input Parameter:
260 . hist - The histogram context
261 
262   Level: intermediate
263 
264 @*/
265 PetscErrorCode  PetscDrawHGDraw(PetscDrawHG hist)
266 {
267   PetscDraw      draw = hist->win;
268   PetscBool      isnull;
269   PetscReal      xmin,xmax,ymin,ymax,*bins,*values,binSize,binLeft,binRight,maxHeight,mean,var;
270   char           title[256];
271   char           xlabel[256];
272   PetscInt       numBins,numBinsOld,numValues,initSize,i,p,bcolor,color;
273   PetscErrorCode ierr;
274 
275   PetscFunctionBegin;
276   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
277   ierr = PetscObjectTypeCompare((PetscObject) draw, PETSC_DRAW_NULL, &isnull);CHKERRQ(ierr);
278   if (isnull) PetscFunctionReturn(0);
279   if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0);
280   if (hist->numValues < 1) PetscFunctionReturn(0);
281 
282 #if 0
283   ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)hist),&rank);CHKERRQ(ierr);
284   if (rank) PetscFunctionReturn(0);
285 #endif
286 
287   color = hist->color;
288   if (color == PETSC_DRAW_ROTATE) bcolor = 2;
289   else bcolor = color;
290 
291   xmin      = hist->xmin;
292   xmax      = hist->xmax;
293   ymin      = hist->ymin;
294   ymax      = hist->ymax;
295   numValues = hist->numValues;
296   values    = hist->values;
297   mean      = 0.0;
298   var       = 0.0;
299 
300   ierr = PetscDrawClear(draw);CHKERRQ(ierr);
301   if (xmin == xmax) {
302     /* Calculate number of points in each bin */
303     bins    = hist->bins;
304     bins[0] = 0.;
305     for (p = 0; p < numValues; p++) {
306       if (values[p] == xmin) bins[0]++;
307       mean += values[p];
308       var  += values[p]*values[p];
309     }
310     maxHeight = bins[0];
311     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
312     xmax = xmin + 1;
313     ierr = PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);CHKERRQ(ierr);
314     if (hist->calcStats) {
315       mean /= numValues;
316       if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
317       else var = 0.0;
318       ierr = PetscSNPrintf(title, 256, "Mean: %g  Var: %g", (double)mean, (double)var);CHKERRQ(ierr);
319       ierr = PetscSNPrintf(xlabel,256, "Total: %D", numValues);CHKERRQ(ierr);
320       ierr = PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL);CHKERRQ(ierr);
321     }
322     ierr = PetscDrawAxisDraw(hist->axis);CHKERRQ(ierr);
323     /* Draw bins */
324     binLeft  = xmin;
325     binRight = xmax;
326     ierr = PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[0],bcolor,bcolor,bcolor,bcolor);CHKERRQ(ierr);
327 
328     if (color == PETSC_DRAW_ROTATE && bins[0] != 0.0) bcolor++;
329     if (bcolor > 31) bcolor = 2;
330 
331     ierr = PetscDrawLine(draw,binLeft,ymin,binLeft,bins[0],PETSC_DRAW_BLACK);CHKERRQ(ierr);
332     ierr = PetscDrawLine(draw,binRight,ymin,binRight,bins[0],PETSC_DRAW_BLACK);CHKERRQ(ierr);
333     ierr = PetscDrawLine(draw,binLeft,bins[0],binRight,bins[0],PETSC_DRAW_BLACK);CHKERRQ(ierr);
334   } else {
335     numBins    = hist->numBins;
336     numBinsOld = hist->numBins;
337     if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) {
338       initSize = (int) ((int) xmax - xmin)/numBins;
339       while (initSize*numBins != (int) xmax - xmin) {
340         initSize = PetscMax(initSize - 1, 1);
341         numBins  = (int) ((int) xmax - xmin)/initSize;
342         ierr     = PetscDrawHGSetNumberBins(hist, numBins);CHKERRQ(ierr);
343       }
344     }
345     binSize = (xmax - xmin)/numBins;
346     bins    = hist->bins;
347 
348     ierr = PetscMemzero(bins, numBins * sizeof(PetscReal));CHKERRQ(ierr);
349 
350     maxHeight = 0.0;
351     for (i = 0; i < numBins; i++) {
352       binLeft  = xmin + binSize*i;
353       binRight = xmin + binSize*(i+1);
354       for (p = 0; p < numValues; p++) {
355         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
356         /* Handle last bin separately */
357         if ((i == numBins-1) && (values[p] == binRight)) bins[i]++;
358         if (!i) {
359           mean += values[p];
360           var  += values[p]*values[p];
361         }
362       }
363       maxHeight = PetscMax(maxHeight, bins[i]);
364     }
365     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
366 
367     ierr = PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);CHKERRQ(ierr);
368     if (hist->calcStats) {
369       mean /= numValues;
370       if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
371       else var = 0.0;
372 
373       ierr = PetscSNPrintf(title, 256,"Mean: %g  Var: %g", (double)mean, (double)var);CHKERRQ(ierr);
374       ierr = PetscSNPrintf(xlabel,256, "Total: %D", numValues);CHKERRQ(ierr);
375       ierr = PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL);CHKERRQ(ierr);
376     }
377     ierr = PetscDrawAxisDraw(hist->axis);CHKERRQ(ierr);
378     /* Draw bins */
379     for (i = 0; i < numBins; i++) {
380       binLeft  = xmin + binSize*i;
381       binRight = xmin + binSize*(i+1);
382       ierr = PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[i],bcolor,bcolor,bcolor,bcolor);CHKERRQ(ierr);
383       if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++;
384       if (bcolor > 31) bcolor = 2;
385       ierr = PetscDrawLine(draw,binLeft,ymin,binLeft,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
386       ierr = PetscDrawLine(draw,binRight,ymin,binRight,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
387       ierr = PetscDrawLine(draw,binLeft,bins[i],binRight,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr);
388     }
389     ierr = PetscDrawHGSetNumberBins(hist, numBinsOld);CHKERRQ(ierr);
390   }
391   ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr);
392   ierr = PetscDrawPause(draw);CHKERRQ(ierr);
393   PetscFunctionReturn(0);
394 }
395 
396 #undef __FUNCT__
397 #define __FUNCT__ "PetscDrawHGView"
398 /*@
399   PetscDrawHGView - Prints the histogram information.
400 
401   Not collective
402 
403   Input Parameter:
404 . hist - The histogram context
405 
406   Level: beginner
407 
408 .keywords:  draw, histogram
409 @*/
410 PetscErrorCode  PetscDrawHGView(PetscDrawHG hist,PetscViewer viewer)
411 {
412   PetscReal      xmax,xmin,*bins,*values,binSize,binLeft,binRight,mean,var;
413   PetscErrorCode ierr;
414   PetscInt       numBins,numBinsOld,numValues,initSize,i,p;
415 
416   PetscFunctionBegin;
417   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
418   if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0);
419   if (hist->numValues < 1) PetscFunctionReturn(0);
420 
421   if (!viewer){
422     ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist),&viewer);CHKERRQ(ierr);
423   }
424   ierr = PetscObjectPrintClassNamePrefixType((PetscObject)hist,viewer);CHKERRQ(ierr);
425   xmax      = hist->xmax;
426   xmin      = hist->xmin;
427   numValues = hist->numValues;
428   values    = hist->values;
429   mean      = 0.0;
430   var       = 0.0;
431   if (xmax == xmin) {
432     /* Calculate number of points in the bin */
433     bins    = hist->bins;
434     bins[0] = 0.;
435     for (p = 0; p < numValues; p++) {
436       if (values[p] == xmin) bins[0]++;
437       mean += values[p];
438       var  += values[p]*values[p];
439     }
440     /* Draw bins */
441     ierr = PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0]);CHKERRQ(ierr);
442   } else {
443     numBins    = hist->numBins;
444     numBinsOld = hist->numBins;
445     if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) {
446       initSize = (int) ((int) xmax - xmin)/numBins;
447       while (initSize*numBins != (int) xmax - xmin) {
448         initSize = PetscMax(initSize - 1, 1);
449         numBins  = (int) ((int) xmax - xmin)/initSize;
450         ierr     = PetscDrawHGSetNumberBins(hist, numBins);CHKERRQ(ierr);
451       }
452     }
453     binSize = (xmax - xmin)/numBins;
454     bins    = hist->bins;
455 
456     /* Calculate number of points in each bin */
457     ierr = PetscMemzero(bins, numBins * sizeof(PetscReal));CHKERRQ(ierr);
458     for (i = 0; i < numBins; i++) {
459       binLeft  = xmin + binSize*i;
460       binRight = xmin + binSize*(i+1);
461       for (p = 0; p < numValues; p++) {
462         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
463         /* Handle last bin separately */
464         if ((i == numBins-1) && (values[p] == binRight)) bins[i]++;
465         if (!i) {
466           mean += values[p];
467           var  += values[p]*values[p];
468         }
469       }
470     }
471     /* Draw bins */
472     for (i = 0; i < numBins; i++) {
473       binLeft  = xmin + binSize*i;
474       binRight = xmin + binSize*(i+1);
475       ierr = PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i]);CHKERRQ(ierr);
476     }
477     ierr = PetscDrawHGSetNumberBins(hist, numBinsOld);CHKERRQ(ierr);
478   }
479 
480   if (hist->calcStats) {
481     mean /= numValues;
482     if (numValues > 1) var = (var - numValues*mean*mean) / (numValues-1);
483     else var = 0.0;
484     ierr = PetscViewerASCIIPrintf(viewer, "Mean: %g  Var: %g\n", (double)mean, (double)var);CHKERRQ(ierr);
485     ierr = PetscViewerASCIIPrintf(viewer, "Total: %D\n", numValues);CHKERRQ(ierr);
486   }
487   PetscFunctionReturn(0);
488 }
489 
490 #undef __FUNCT__
491 #define __FUNCT__ "PetscDrawHGSetColor"
492 /*@
493   PetscDrawHGSetColor - Sets the color the bars will be drawn with.
494 
495   Not Collective (ignored except on processor 0 of PetscDrawHG)
496 
497   Input Parameters:
498 + hist - The histogram context
499 - color - one of the colors defined in petscdraw.h or PETSC_DRAW_ROTATE to make each bar a
500           different color
501 
502   Level: intermediate
503 
504 @*/
505 PetscErrorCode  PetscDrawHGSetColor(PetscDrawHG hist, int color)
506 {
507   PetscFunctionBegin;
508   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
509   hist->color = color;
510   PetscFunctionReturn(0);
511 }
512 
513 #undef __FUNCT__
514 #define __FUNCT__ "PetscDrawHGSetLimits"
515 /*@
516   PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
517   points are added after this call, the limits will be adjusted to
518   include those additional points.
519 
520   Not Collective (ignored except on processor 0 of PetscDrawHG)
521 
522   Input Parameters:
523 + hist - The histogram context
524 - x_min,x_max,y_min,y_max - The limits
525 
526   Level: intermediate
527 
528   Concepts: histogram^setting axis
529 @*/
530 PetscErrorCode  PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max)
531 {
532   PetscFunctionBegin;
533   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
534   hist->xmin = x_min;
535   hist->xmax = x_max;
536   hist->ymin = y_min;
537   hist->ymax = y_max;
538   PetscFunctionReturn(0);
539 }
540 
541 #undef __FUNCT__
542 #define __FUNCT__ "PetscDrawHGCalcStats"
543 /*@
544   PetscDrawHGCalcStats - Turns on calculation of descriptive statistics
545 
546   Not collective
547 
548   Input Parameters:
549 + hist - The histogram context
550 - calc - Flag for calculation
551 
552   Level: intermediate
553 
554 .keywords:  draw, histogram, statistics
555 
556 @*/
557 PetscErrorCode  PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc)
558 {
559   PetscFunctionBegin;
560   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
561   hist->calcStats = calc;
562   PetscFunctionReturn(0);
563 }
564 
565 #undef __FUNCT__
566 #define __FUNCT__ "PetscDrawHGIntegerBins"
567 /*@
568   PetscDrawHGIntegerBins - Turns on integer width bins
569 
570   Not collective
571 
572   Input Parameters:
573 + hist - The histogram context
574 - ints - Flag for integer width bins
575 
576   Level: intermediate
577 
578 .keywords:  draw, histogram, statistics
579 @*/
580 PetscErrorCode  PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints)
581 {
582   PetscFunctionBegin;
583   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
584   hist->integerBins = ints;
585   PetscFunctionReturn(0);
586 }
587 
588 #undef __FUNCT__
589 #define __FUNCT__ "PetscDrawHGGetAxis"
590 /*@C
591   PetscDrawHGGetAxis - Gets the axis context associated with a histogram.
592   This is useful if one wants to change some axis property, such as
593   labels, color, etc. The axis context should not be destroyed by the
594   application code.
595 
596   Not Collective (ignored except on processor 0 of PetscDrawHG)
597 
598   Input Parameter:
599 . hist - The histogram context
600 
601   Output Parameter:
602 . axis - The axis context
603 
604   Level: intermediate
605 
606 @*/
607 PetscErrorCode  PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis)
608 {
609   PetscFunctionBegin;
610   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
611   PetscValidPointer(axis,2);
612   *axis = hist->axis;
613   PetscFunctionReturn(0);
614 }
615 
616 #undef __FUNCT__
617 #define __FUNCT__ "PetscDrawHGGetDraw"
618 /*@C
619   PetscDrawHGGetDraw - Gets the draw context associated with a histogram.
620 
621   Not Collective, PetscDraw is parallel if PetscDrawHG is parallel
622 
623   Input Parameter:
624 . hist - The histogram context
625 
626   Output Parameter:
627 . win  - The draw context
628 
629   Level: intermediate
630 
631 @*/
632 PetscErrorCode  PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *win)
633 {
634   PetscFunctionBegin;
635   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1);
636   PetscValidPointer(win,2);
637   *win = hist->win;
638   PetscFunctionReturn(0);
639 }
640 
641