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