xref: /petsc/src/sys/classes/draw/utils/hists.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
15c6c1daeSBarry Smith 
25c6c1daeSBarry Smith /*
35c6c1daeSBarry Smith   Contains the data structure for plotting a histogram in a window with an axis.
45c6c1daeSBarry Smith */
59804daf3SBarry Smith #include <petscdraw.h>               /*I "petscdraw.h" I*/
6af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/
734a5a0e3SBarry Smith #include <petscviewer.h>             /*I "petscviewer.h" I*/
85c6c1daeSBarry Smith 
95c6c1daeSBarry Smith PetscClassId PETSC_DRAWHG_CLASSID = 0;
105c6c1daeSBarry Smith 
115c6c1daeSBarry Smith struct _p_PetscDrawHG {
125c6c1daeSBarry Smith   PETSCHEADER(int);
135c6c1daeSBarry Smith   PetscErrorCode (*destroy)(PetscDrawSP);
145c6c1daeSBarry Smith   PetscErrorCode (*view)(PetscDrawSP, PetscViewer);
155c6c1daeSBarry Smith   PetscDraw     win;
165c6c1daeSBarry Smith   PetscDrawAxis axis;
175c6c1daeSBarry Smith   PetscReal     xmin, xmax;
185c6c1daeSBarry Smith   PetscReal     ymin, ymax;
195c6c1daeSBarry Smith   int           numBins;
205c6c1daeSBarry Smith   int           maxBins;
215c6c1daeSBarry Smith   PetscReal    *bins;
225c6c1daeSBarry Smith   int           numValues;
235c6c1daeSBarry Smith   int           maxValues;
245c6c1daeSBarry Smith   PetscReal    *values;
255c6c1daeSBarry Smith   int           color;
265c6c1daeSBarry Smith   PetscBool     calcStats;
275c6c1daeSBarry Smith   PetscBool     integerBins;
285c6c1daeSBarry Smith };
295c6c1daeSBarry Smith 
305c6c1daeSBarry Smith #define CHUNKSIZE 100
315c6c1daeSBarry Smith 
325c6c1daeSBarry Smith /*@C
335c6c1daeSBarry Smith    PetscDrawHGCreate - Creates a histogram data structure.
345c6c1daeSBarry Smith 
355b399a63SLisandro Dalcin    Collective on PetscDraw
365c6c1daeSBarry Smith 
375c6c1daeSBarry Smith    Input Parameters:
385c6c1daeSBarry Smith +  draw  - The window where the graph will be made
395c6c1daeSBarry Smith -  bins - The number of bins to use
405c6c1daeSBarry Smith 
415c6c1daeSBarry Smith    Output Parameters:
425c6c1daeSBarry Smith .  hist - The histogram context
435c6c1daeSBarry Smith 
4495452b02SPatrick Sanan    Notes:
45a8d69d7bSBarry Smith     The difference between a bar chart, PetscDrawBar, and a histogram, PetscDrawHG, is explained here https://stattrek.com/statistics/charts/histogram.aspx?Tutorial=AP
460afdd333SBarry Smith 
470afdd333SBarry Smith    The histogram is only displayed when PetscDrawHGDraw() is called.
480afdd333SBarry Smith 
497e25d57eSBarry Smith    The MPI communicator that owns the PetscDraw owns this PetscDrawHG, but the calls to set options and add data are ignored on all processes except the
507e25d57eSBarry Smith    zeroth MPI process in the communicator. All MPI processes in the communicator must call PetscDrawHGDraw() to display the updated graph.
517e25d57eSBarry Smith 
525c6c1daeSBarry Smith    Level: intermediate
535c6c1daeSBarry Smith 
54db781477SPatrick Sanan .seealso: `PetscDrawHGDestroy()`, `PetscDrawHG`, `PetscDrawBarCreate()`, `PetscDrawBar`, `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawSPCreate()`, `PetscDrawSP`,
55db781477SPatrick Sanan           `PetscDrawHGSetNumberBins()`, `PetscDrawHGReset()`, `PetscDrawHGAddValue()`, `PetscDrawHGDraw()`, `PetscDrawHGSave()`, `PetscDrawHGView()`, `PetscDrawHGSetColor()`,
56db781477SPatrick Sanan           `PetscDrawHGSetLimits()`, `PetscDrawHGCalcStats()`, `PetscDrawHGIntegerBins()`, `PetscDrawHGGetAxis()`, `PetscDrawAxis`, `PetscDrawHGGetDraw()`
575c6c1daeSBarry Smith 
585c6c1daeSBarry Smith @*/
599371c9d4SSatish Balay PetscErrorCode PetscDrawHGCreate(PetscDraw draw, int bins, PetscDrawHG *hist) {
60e118a51fSLisandro Dalcin   PetscDrawHG h;
615c6c1daeSBarry Smith 
625c6c1daeSBarry Smith   PetscFunctionBegin;
635c6c1daeSBarry Smith   PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1);
64e118a51fSLisandro Dalcin   PetscValidLogicalCollectiveInt(draw, bins, 2);
655c6c1daeSBarry Smith   PetscValidPointer(hist, 3);
66e118a51fSLisandro Dalcin 
679566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(h, PETSC_DRAWHG_CLASSID, "DrawHG", "Histogram", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawHGDestroy, NULL));
689566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject)draw, (PetscObject)h));
69e118a51fSLisandro Dalcin 
709566063dSJacob Faibussowitsch   PetscCall(PetscObjectReference((PetscObject)draw));
71e118a51fSLisandro Dalcin   h->win = draw;
72a297a907SKarl Rupp 
730298fd71SBarry Smith   h->view    = NULL;
740298fd71SBarry Smith   h->destroy = NULL;
755c6c1daeSBarry Smith   h->color   = PETSC_DRAW_GREEN;
765c6c1daeSBarry Smith   h->xmin    = PETSC_MAX_REAL;
775c6c1daeSBarry Smith   h->xmax    = PETSC_MIN_REAL;
785c6c1daeSBarry Smith   h->ymin    = 0.;
795c6c1daeSBarry Smith   h->ymax    = 1.;
805c6c1daeSBarry Smith   h->numBins = bins;
815c6c1daeSBarry Smith   h->maxBins = bins;
82a297a907SKarl Rupp 
839566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(h->maxBins, &h->bins));
84a297a907SKarl Rupp 
855c6c1daeSBarry Smith   h->numValues   = 0;
865c6c1daeSBarry Smith   h->maxValues   = CHUNKSIZE;
875c6c1daeSBarry Smith   h->calcStats   = PETSC_FALSE;
885c6c1daeSBarry Smith   h->integerBins = PETSC_FALSE;
89a297a907SKarl Rupp 
909566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(h->maxValues, &h->values));
919566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectMemory((PetscObject)h, (h->maxBins + h->maxValues) * sizeof(PetscReal)));
92a297a907SKarl Rupp 
939566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisCreate(draw, &h->axis));
949566063dSJacob Faibussowitsch   PetscCall(PetscLogObjectParent((PetscObject)h, (PetscObject)h->axis));
95e118a51fSLisandro Dalcin 
965c6c1daeSBarry Smith   *hist = h;
975c6c1daeSBarry Smith   PetscFunctionReturn(0);
985c6c1daeSBarry Smith }
995c6c1daeSBarry Smith 
1005c6c1daeSBarry Smith /*@
1015c6c1daeSBarry Smith    PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn.
1025c6c1daeSBarry Smith 
1035b399a63SLisandro Dalcin    Logically Collective on PetscDrawHG
1045c6c1daeSBarry Smith 
105d8d19677SJose E. Roman    Input Parameters:
1065c6c1daeSBarry Smith +  hist - The histogram context.
107e118a51fSLisandro Dalcin -  bins  - The number of bins.
1085c6c1daeSBarry Smith 
1095c6c1daeSBarry Smith    Level: intermediate
1105c6c1daeSBarry Smith 
111db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGIntegerBins()`
1120afdd333SBarry Smith 
1135c6c1daeSBarry Smith @*/
1149371c9d4SSatish Balay PetscErrorCode PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins) {
1155c6c1daeSBarry Smith   PetscFunctionBegin;
1165c6c1daeSBarry Smith   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
117e118a51fSLisandro Dalcin   PetscValidLogicalCollectiveInt(hist, bins, 2);
118e118a51fSLisandro Dalcin 
1195c6c1daeSBarry Smith   if (hist->maxBins < bins) {
1209566063dSJacob Faibussowitsch     PetscCall(PetscFree(hist->bins));
1219566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(bins, &hist->bins));
1229566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)hist, (bins - hist->maxBins) * sizeof(PetscReal)));
1235c6c1daeSBarry Smith     hist->maxBins = bins;
1245c6c1daeSBarry Smith   }
1255c6c1daeSBarry Smith   hist->numBins = bins;
1265c6c1daeSBarry Smith   PetscFunctionReturn(0);
1275c6c1daeSBarry Smith }
1285c6c1daeSBarry Smith 
1295c6c1daeSBarry Smith /*@
1305c6c1daeSBarry Smith   PetscDrawHGReset - Clears histogram to allow for reuse with new data.
1315c6c1daeSBarry Smith 
1325b399a63SLisandro Dalcin   Logically Collective on PetscDrawHG
1335c6c1daeSBarry Smith 
1345c6c1daeSBarry Smith   Input Parameter:
1355c6c1daeSBarry Smith . hist - The histogram context.
1365c6c1daeSBarry Smith 
1375c6c1daeSBarry Smith   Level: intermediate
1385c6c1daeSBarry Smith 
139db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`
1400afdd333SBarry Smith 
1415c6c1daeSBarry Smith @*/
1429371c9d4SSatish Balay PetscErrorCode PetscDrawHGReset(PetscDrawHG hist) {
1435c6c1daeSBarry Smith   PetscFunctionBegin;
1445c6c1daeSBarry Smith   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
145e118a51fSLisandro Dalcin 
1465c6c1daeSBarry Smith   hist->xmin      = PETSC_MAX_REAL;
1475c6c1daeSBarry Smith   hist->xmax      = PETSC_MIN_REAL;
1485c6c1daeSBarry Smith   hist->ymin      = 0.0;
1495c6c1daeSBarry Smith   hist->ymax      = 0.0;
1505c6c1daeSBarry Smith   hist->numValues = 0;
1515c6c1daeSBarry Smith   PetscFunctionReturn(0);
1525c6c1daeSBarry Smith }
1535c6c1daeSBarry Smith 
1545c6c1daeSBarry Smith /*@C
1555c6c1daeSBarry Smith   PetscDrawHGDestroy - Frees all space taken up by histogram data structure.
1565c6c1daeSBarry Smith 
1575b399a63SLisandro Dalcin   Collective on PetscDrawHG
1585c6c1daeSBarry Smith 
1595c6c1daeSBarry Smith   Input Parameter:
1605c6c1daeSBarry Smith . hist - The histogram context
1615c6c1daeSBarry Smith 
1625c6c1daeSBarry Smith   Level: intermediate
1635c6c1daeSBarry Smith 
164db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`
1655c6c1daeSBarry Smith @*/
1669371c9d4SSatish Balay PetscErrorCode PetscDrawHGDestroy(PetscDrawHG *hist) {
1675c6c1daeSBarry Smith   PetscFunctionBegin;
1685c6c1daeSBarry Smith   if (!*hist) PetscFunctionReturn(0);
169e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(*hist, PETSC_DRAWHG_CLASSID, 1);
1709371c9d4SSatish Balay   if (--((PetscObject)(*hist))->refct > 0) {
1719371c9d4SSatish Balay     *hist = NULL;
1729371c9d4SSatish Balay     PetscFunctionReturn(0);
1739371c9d4SSatish Balay   }
1745c6c1daeSBarry Smith 
1759566063dSJacob Faibussowitsch   PetscCall(PetscFree((*hist)->bins));
1769566063dSJacob Faibussowitsch   PetscCall(PetscFree((*hist)->values));
1779566063dSJacob Faibussowitsch   PetscCall(PetscDrawAxisDestroy(&(*hist)->axis));
1789566063dSJacob Faibussowitsch   PetscCall(PetscDrawDestroy(&(*hist)->win));
1799566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(hist));
1805c6c1daeSBarry Smith   PetscFunctionReturn(0);
1815c6c1daeSBarry Smith }
1825c6c1daeSBarry Smith 
1835c6c1daeSBarry Smith /*@
1845c6c1daeSBarry Smith   PetscDrawHGAddValue - Adds another value to the histogram.
1855c6c1daeSBarry Smith 
1865b399a63SLisandro Dalcin   Logically Collective on PetscDrawHG
1875c6c1daeSBarry Smith 
1885c6c1daeSBarry Smith   Input Parameters:
1895c6c1daeSBarry Smith + hist  - The histogram
1905c6c1daeSBarry Smith - value - The value
1915c6c1daeSBarry Smith 
1925c6c1daeSBarry Smith   Level: intermediate
1935c6c1daeSBarry Smith 
194db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()`
1955c6c1daeSBarry Smith @*/
1969371c9d4SSatish Balay PetscErrorCode PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value) {
1975c6c1daeSBarry Smith   PetscFunctionBegin;
1985c6c1daeSBarry Smith   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
199e118a51fSLisandro Dalcin 
2005c6c1daeSBarry Smith   /* Allocate more memory if necessary */
2015c6c1daeSBarry Smith   if (hist->numValues >= hist->maxValues) {
2025c6c1daeSBarry Smith     PetscReal *tmp;
2035c6c1daeSBarry Smith 
2049566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(hist->maxValues + CHUNKSIZE, &tmp));
2059566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)hist, CHUNKSIZE * sizeof(PetscReal)));
2069566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(tmp, hist->values, hist->maxValues));
2079566063dSJacob Faibussowitsch     PetscCall(PetscFree(hist->values));
208a297a907SKarl Rupp 
2095c6c1daeSBarry Smith     hist->values = tmp;
2105c6c1daeSBarry Smith     hist->maxValues += CHUNKSIZE;
2115c6c1daeSBarry Smith   }
2125c6c1daeSBarry Smith   /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the
2135c6c1daeSBarry Smith      stated convention of using half-open intervals (always the way to go) */
214d0c080abSJoseph Pusztay   if (!hist->numValues && (hist->xmin == PETSC_MAX_REAL) && (hist->xmax == PETSC_MIN_REAL)) {
2155c6c1daeSBarry Smith     hist->xmin = value;
2165c6c1daeSBarry Smith     hist->xmax = value;
2175c6c1daeSBarry Smith #if 1
2185c6c1daeSBarry Smith   } else {
2195c6c1daeSBarry Smith     /* Update limits */
220a297a907SKarl Rupp     if (value > hist->xmax) hist->xmax = value;
221a297a907SKarl Rupp     if (value < hist->xmin) hist->xmin = value;
2225c6c1daeSBarry Smith #else
2235c6c1daeSBarry Smith   } else if (hist->numValues == 1) {
2245c6c1daeSBarry Smith     /* Update limits -- We need to overshoot the largest value somewhat */
225a297a907SKarl Rupp     if (value > hist->xmax) hist->xmax = value + 0.001 * (value - hist->xmin) / hist->numBins;
2265c6c1daeSBarry Smith     if (value < hist->xmin) {
2275c6c1daeSBarry Smith       hist->xmin = value;
2285c6c1daeSBarry Smith       hist->xmax = hist->xmax + 0.001 * (hist->xmax - hist->xmin) / hist->numBins;
2295c6c1daeSBarry Smith     }
2305c6c1daeSBarry Smith   } else {
2315c6c1daeSBarry Smith     /* Update limits -- We need to overshoot the largest value somewhat */
232a297a907SKarl Rupp     if (value > hist->xmax) hist->xmax = value + 0.001 * (hist->xmax - hist->xmin) / hist->numBins;
233a297a907SKarl Rupp     if (value < hist->xmin) hist->xmin = value;
2345c6c1daeSBarry Smith #endif
2355c6c1daeSBarry Smith   }
2365c6c1daeSBarry Smith 
2375c6c1daeSBarry Smith   hist->values[hist->numValues++] = value;
2385c6c1daeSBarry Smith   PetscFunctionReturn(0);
2395c6c1daeSBarry Smith }
2405c6c1daeSBarry Smith 
2415c6c1daeSBarry Smith /*@
2425c6c1daeSBarry Smith   PetscDrawHGDraw - Redraws a histogram.
2435c6c1daeSBarry Smith 
2445b399a63SLisandro Dalcin   Collective on PetscDrawHG
2455c6c1daeSBarry Smith 
2465c6c1daeSBarry Smith   Input Parameter:
2475c6c1daeSBarry Smith . hist - The histogram context
2485c6c1daeSBarry Smith 
2495c6c1daeSBarry Smith   Level: intermediate
2505c6c1daeSBarry Smith 
251db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()`
2520afdd333SBarry Smith 
2535c6c1daeSBarry Smith @*/
2549371c9d4SSatish Balay PetscErrorCode PetscDrawHGDraw(PetscDrawHG hist) {
255e118a51fSLisandro Dalcin   PetscDraw   draw;
2565c6c1daeSBarry Smith   PetscBool   isnull;
2575c6c1daeSBarry Smith   PetscReal   xmin, xmax, ymin, ymax, *bins, *values, binSize, binLeft, binRight, maxHeight, mean, var;
2585c6c1daeSBarry Smith   char        title[256];
2595c6c1daeSBarry Smith   char        xlabel[256];
2605c6c1daeSBarry Smith   PetscInt    numBins, numBinsOld, numValues, initSize, i, p, bcolor, color;
261e118a51fSLisandro Dalcin   PetscMPIInt rank;
2625c6c1daeSBarry Smith 
2635c6c1daeSBarry Smith   PetscFunctionBegin;
2645c6c1daeSBarry Smith   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
2659566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(hist->win, &isnull));
2668f69470aSLisandro Dalcin   if (isnull) PetscFunctionReturn(0);
2679566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)hist), &rank));
268e118a51fSLisandro Dalcin 
2695c6c1daeSBarry Smith   if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0);
2705c6c1daeSBarry Smith   if (hist->numValues < 1) PetscFunctionReturn(0);
2715c6c1daeSBarry Smith 
2725c6c1daeSBarry Smith   color = hist->color;
27371917b75SLisandro Dalcin   if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK + 1;
274a297a907SKarl Rupp   else bcolor = color;
275a297a907SKarl Rupp 
2765c6c1daeSBarry Smith   xmin      = hist->xmin;
2775c6c1daeSBarry Smith   xmax      = hist->xmax;
2785c6c1daeSBarry Smith   ymin      = hist->ymin;
2795c6c1daeSBarry Smith   ymax      = hist->ymax;
2805c6c1daeSBarry Smith   numValues = hist->numValues;
2815c6c1daeSBarry Smith   values    = hist->values;
2825c6c1daeSBarry Smith   mean      = 0.0;
2835c6c1daeSBarry Smith   var       = 0.0;
2845c6c1daeSBarry Smith 
2855b399a63SLisandro Dalcin   draw = hist->win;
2869566063dSJacob Faibussowitsch   PetscCall(PetscDrawCheckResizedWindow(draw));
2879566063dSJacob Faibussowitsch   PetscCall(PetscDrawClear(draw));
288e118a51fSLisandro Dalcin 
2895c6c1daeSBarry Smith   if (xmin == xmax) {
2905c6c1daeSBarry Smith     /* Calculate number of points in each bin */
2915c6c1daeSBarry Smith     bins    = hist->bins;
2925c6c1daeSBarry Smith     bins[0] = 0.;
2935c6c1daeSBarry Smith     for (p = 0; p < numValues; p++) {
2945c6c1daeSBarry Smith       if (values[p] == xmin) bins[0]++;
2955c6c1daeSBarry Smith       mean += values[p];
2965c6c1daeSBarry Smith       var += values[p] * values[p];
2975c6c1daeSBarry Smith     }
2985c6c1daeSBarry Smith     maxHeight = bins[0];
2995c6c1daeSBarry Smith     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
3005c6c1daeSBarry Smith     xmax = xmin + 1;
3019566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax));
3025c6c1daeSBarry Smith     if (hist->calcStats) {
3035c6c1daeSBarry Smith       mean /= numValues;
304a297a907SKarl Rupp       if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
305a297a907SKarl Rupp       else var = 0.0;
3069566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(title, 256, "Mean: %g  Var: %g", (double)mean, (double)var));
3079566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues));
3089566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL));
3095c6c1daeSBarry Smith     }
3109566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(hist->axis));
311d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
312dd400576SPatrick Sanan     if (rank == 0) { /* Draw bins */
3135c6c1daeSBarry Smith       binLeft  = xmin;
3145c6c1daeSBarry Smith       binRight = xmax;
3159566063dSJacob Faibussowitsch       PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[0], bcolor, bcolor, bcolor, bcolor));
3169566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[0], PETSC_DRAW_BLACK));
3179566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[0], PETSC_DRAW_BLACK));
3189566063dSJacob Faibussowitsch       PetscCall(PetscDrawLine(draw, binLeft, bins[0], binRight, bins[0], PETSC_DRAW_BLACK));
319e118a51fSLisandro Dalcin     }
320d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
3215c6c1daeSBarry Smith   } else {
3225c6c1daeSBarry Smith     numBins    = hist->numBins;
3235c6c1daeSBarry Smith     numBinsOld = hist->numBins;
3245c6c1daeSBarry Smith     if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) {
3255c6c1daeSBarry Smith       initSize = (int)((int)xmax - xmin) / numBins;
3265c6c1daeSBarry Smith       while (initSize * numBins != (int)xmax - xmin) {
3275c6c1daeSBarry Smith         initSize = PetscMax(initSize - 1, 1);
3285c6c1daeSBarry Smith         numBins  = (int)((int)xmax - xmin) / initSize;
3299566063dSJacob Faibussowitsch         PetscCall(PetscDrawHGSetNumberBins(hist, numBins));
3305c6c1daeSBarry Smith       }
3315c6c1daeSBarry Smith     }
3325c6c1daeSBarry Smith     binSize = (xmax - xmin) / numBins;
3335c6c1daeSBarry Smith     bins    = hist->bins;
3345c6c1daeSBarry Smith 
3359566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(bins, numBins));
336a297a907SKarl Rupp 
3375c6c1daeSBarry Smith     maxHeight = 0.0;
3385c6c1daeSBarry Smith     for (i = 0; i < numBins; i++) {
3395c6c1daeSBarry Smith       binLeft  = xmin + binSize * i;
3405c6c1daeSBarry Smith       binRight = xmin + binSize * (i + 1);
3415c6c1daeSBarry Smith       for (p = 0; p < numValues; p++) {
3425c6c1daeSBarry Smith         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
3435c6c1daeSBarry Smith         /* Handle last bin separately */
3445c6c1daeSBarry Smith         if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++;
3455c6c1daeSBarry Smith         if (!i) {
3465c6c1daeSBarry Smith           mean += values[p];
3475c6c1daeSBarry Smith           var += values[p] * values[p];
3485c6c1daeSBarry Smith         }
3495c6c1daeSBarry Smith       }
3505c6c1daeSBarry Smith       maxHeight = PetscMax(maxHeight, bins[i]);
3515c6c1daeSBarry Smith     }
3525c6c1daeSBarry Smith     if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
3535c6c1daeSBarry Smith 
3549566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax));
3555c6c1daeSBarry Smith     if (hist->calcStats) {
3565c6c1daeSBarry Smith       mean /= numValues;
357a297a907SKarl Rupp       if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
358a297a907SKarl Rupp       else var = 0.0;
3599566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(title, 256, "Mean: %g  Var: %g", (double)mean, (double)var));
3609566063dSJacob Faibussowitsch       PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues));
3619566063dSJacob Faibussowitsch       PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL));
3625c6c1daeSBarry Smith     }
3639566063dSJacob Faibussowitsch     PetscCall(PetscDrawAxisDraw(hist->axis));
364d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
365dd400576SPatrick Sanan     if (rank == 0) { /* Draw bins */
3665c6c1daeSBarry Smith       for (i = 0; i < numBins; i++) {
3675c6c1daeSBarry Smith         binLeft  = xmin + binSize * i;
3685c6c1daeSBarry Smith         binRight = xmin + binSize * (i + 1);
3699566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[i], bcolor, bcolor, bcolor, bcolor));
3709566063dSJacob Faibussowitsch         PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[i], PETSC_DRAW_BLACK));
3719566063dSJacob Faibussowitsch         PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[i], PETSC_DRAW_BLACK));
3729566063dSJacob Faibussowitsch         PetscCall(PetscDrawLine(draw, binLeft, bins[i], binRight, bins[i], PETSC_DRAW_BLACK));
373e118a51fSLisandro Dalcin         if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++;
37471917b75SLisandro Dalcin         if (bcolor > PETSC_DRAW_BASIC_COLORS - 1) bcolor = PETSC_DRAW_BLACK + 1;
375e118a51fSLisandro Dalcin       }
3765c6c1daeSBarry Smith     }
377d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
3789566063dSJacob Faibussowitsch     PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld));
3795c6c1daeSBarry Smith   }
380e118a51fSLisandro Dalcin 
3819566063dSJacob Faibussowitsch   PetscCall(PetscDrawFlush(draw));
3829566063dSJacob Faibussowitsch   PetscCall(PetscDrawPause(draw));
3835c6c1daeSBarry Smith   PetscFunctionReturn(0);
3845c6c1daeSBarry Smith }
3855c6c1daeSBarry Smith 
38657fd6651SLisandro Dalcin /*@
38757fd6651SLisandro Dalcin   PetscDrawHGSave - Saves a drawn image
38857fd6651SLisandro Dalcin 
38957fd6651SLisandro Dalcin   Collective on PetscDrawHG
39057fd6651SLisandro Dalcin 
39157fd6651SLisandro Dalcin   Input Parameter:
39257fd6651SLisandro Dalcin . hist - The histogram context
39357fd6651SLisandro Dalcin 
39457fd6651SLisandro Dalcin   Level: intermediate
39557fd6651SLisandro Dalcin 
396db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`
39757fd6651SLisandro Dalcin @*/
3989371c9d4SSatish Balay PetscErrorCode PetscDrawHGSave(PetscDrawHG hg) {
39957fd6651SLisandro Dalcin   PetscFunctionBegin;
40057fd6651SLisandro Dalcin   PetscValidHeaderSpecific(hg, PETSC_DRAWHG_CLASSID, 1);
4019566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(hg->win));
40257fd6651SLisandro Dalcin   PetscFunctionReturn(0);
40357fd6651SLisandro Dalcin }
40457fd6651SLisandro Dalcin 
4055c6c1daeSBarry Smith /*@
40634a5a0e3SBarry Smith   PetscDrawHGView - Prints the histogram information.
4075c6c1daeSBarry Smith 
4085c6c1daeSBarry Smith   Not collective
4095c6c1daeSBarry Smith 
4105c6c1daeSBarry Smith   Input Parameter:
4115c6c1daeSBarry Smith . hist - The histogram context
4125c6c1daeSBarry Smith 
4135c6c1daeSBarry Smith   Level: beginner
4145c6c1daeSBarry Smith 
415db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`
4160afdd333SBarry Smith 
4175c6c1daeSBarry Smith @*/
4189371c9d4SSatish Balay PetscErrorCode PetscDrawHGView(PetscDrawHG hist, PetscViewer viewer) {
4195c6c1daeSBarry Smith   PetscReal xmax, xmin, *bins, *values, binSize, binLeft, binRight, mean, var;
4205c6c1daeSBarry Smith   PetscInt  numBins, numBinsOld, numValues, initSize, i, p;
4215c6c1daeSBarry Smith 
4225c6c1daeSBarry Smith   PetscFunctionBegin;
4235c6c1daeSBarry Smith   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
424e118a51fSLisandro Dalcin 
4255c6c1daeSBarry Smith   if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0);
4265c6c1daeSBarry Smith   if (hist->numValues < 1) PetscFunctionReturn(0);
4275c6c1daeSBarry Smith 
428*48a46eb9SPierre Jolivet   if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist), &viewer));
4299566063dSJacob Faibussowitsch   PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)hist, viewer));
4305c6c1daeSBarry Smith   xmax      = hist->xmax;
4315c6c1daeSBarry Smith   xmin      = hist->xmin;
4325c6c1daeSBarry Smith   numValues = hist->numValues;
4335c6c1daeSBarry Smith   values    = hist->values;
4345c6c1daeSBarry Smith   mean      = 0.0;
4355c6c1daeSBarry Smith   var       = 0.0;
4365c6c1daeSBarry Smith   if (xmax == xmin) {
4375c6c1daeSBarry Smith     /* Calculate number of points in the bin */
4385c6c1daeSBarry Smith     bins    = hist->bins;
4395c6c1daeSBarry Smith     bins[0] = 0.;
4405c6c1daeSBarry Smith     for (p = 0; p < numValues; p++) {
4415c6c1daeSBarry Smith       if (values[p] == xmin) bins[0]++;
4425c6c1daeSBarry Smith       mean += values[p];
4435c6c1daeSBarry Smith       var += values[p] * values[p];
4445c6c1daeSBarry Smith     }
4455c6c1daeSBarry Smith     /* Draw bins */
4469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0]));
4475c6c1daeSBarry Smith   } else {
4485c6c1daeSBarry Smith     numBins    = hist->numBins;
4495c6c1daeSBarry Smith     numBinsOld = hist->numBins;
4505c6c1daeSBarry Smith     if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) {
4515c6c1daeSBarry Smith       initSize = (int)((int)xmax - xmin) / numBins;
4525c6c1daeSBarry Smith       while (initSize * numBins != (int)xmax - xmin) {
4535c6c1daeSBarry Smith         initSize = PetscMax(initSize - 1, 1);
4545c6c1daeSBarry Smith         numBins  = (int)((int)xmax - xmin) / initSize;
4559566063dSJacob Faibussowitsch         PetscCall(PetscDrawHGSetNumberBins(hist, numBins));
4565c6c1daeSBarry Smith       }
4575c6c1daeSBarry Smith     }
4585c6c1daeSBarry Smith     binSize = (xmax - xmin) / numBins;
4595c6c1daeSBarry Smith     bins    = hist->bins;
4605c6c1daeSBarry Smith 
4615c6c1daeSBarry Smith     /* Calculate number of points in each bin */
4629566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(bins, numBins));
4635c6c1daeSBarry Smith     for (i = 0; i < numBins; i++) {
4645c6c1daeSBarry Smith       binLeft  = xmin + binSize * i;
4655c6c1daeSBarry Smith       binRight = xmin + binSize * (i + 1);
4665c6c1daeSBarry Smith       for (p = 0; p < numValues; p++) {
4675c6c1daeSBarry Smith         if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
4685c6c1daeSBarry Smith         /* Handle last bin separately */
4695c6c1daeSBarry Smith         if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++;
4705c6c1daeSBarry Smith         if (!i) {
4715c6c1daeSBarry Smith           mean += values[p];
4725c6c1daeSBarry Smith           var += values[p] * values[p];
4735c6c1daeSBarry Smith         }
4745c6c1daeSBarry Smith       }
4755c6c1daeSBarry Smith     }
4765c6c1daeSBarry Smith     /* Draw bins */
4775c6c1daeSBarry Smith     for (i = 0; i < numBins; i++) {
4785c6c1daeSBarry Smith       binLeft  = xmin + binSize * i;
4795c6c1daeSBarry Smith       binRight = xmin + binSize * (i + 1);
4809566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i]));
4815c6c1daeSBarry Smith     }
4829566063dSJacob Faibussowitsch     PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld));
4835c6c1daeSBarry Smith   }
4845c6c1daeSBarry Smith 
4855c6c1daeSBarry Smith   if (hist->calcStats) {
4865c6c1daeSBarry Smith     mean /= numValues;
487a297a907SKarl Rupp     if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1);
488a297a907SKarl Rupp     else var = 0.0;
4899566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Mean: %g  Var: %g\n", (double)mean, (double)var));
4909566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "Total: %" PetscInt_FMT "\n", numValues));
4915c6c1daeSBarry Smith   }
4925c6c1daeSBarry Smith   PetscFunctionReturn(0);
4935c6c1daeSBarry Smith }
4945c6c1daeSBarry Smith 
4955c6c1daeSBarry Smith /*@
4965c6c1daeSBarry Smith   PetscDrawHGSetColor - Sets the color the bars will be drawn with.
4975c6c1daeSBarry Smith 
4985b399a63SLisandro Dalcin   Logically Collective on PetscDrawHG
4995c6c1daeSBarry Smith 
5005c6c1daeSBarry Smith   Input Parameters:
5015c6c1daeSBarry Smith + hist - The histogram context
5025c6c1daeSBarry Smith - color - one of the colors defined in petscdraw.h or PETSC_DRAW_ROTATE to make each bar a
5035c6c1daeSBarry Smith           different color
5045c6c1daeSBarry Smith 
5055c6c1daeSBarry Smith   Level: intermediate
5065c6c1daeSBarry Smith 
507db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
5080afdd333SBarry Smith 
5095c6c1daeSBarry Smith @*/
5109371c9d4SSatish Balay PetscErrorCode PetscDrawHGSetColor(PetscDrawHG hist, int color) {
5115c6c1daeSBarry Smith   PetscFunctionBegin;
5125c6c1daeSBarry Smith   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
513e118a51fSLisandro Dalcin 
5145c6c1daeSBarry Smith   hist->color = color;
5155c6c1daeSBarry Smith   PetscFunctionReturn(0);
5165c6c1daeSBarry Smith }
5175c6c1daeSBarry Smith 
5185c6c1daeSBarry Smith /*@
5195c6c1daeSBarry Smith   PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
5205c6c1daeSBarry Smith   points are added after this call, the limits will be adjusted to
5215c6c1daeSBarry Smith   include those additional points.
5225c6c1daeSBarry Smith 
5235b399a63SLisandro Dalcin   Logically Collective on PetscDrawHG
5245c6c1daeSBarry Smith 
5255c6c1daeSBarry Smith   Input Parameters:
5265c6c1daeSBarry Smith + hist - The histogram context
5275c6c1daeSBarry Smith - x_min,x_max,y_min,y_max - The limits
5285c6c1daeSBarry Smith 
5295c6c1daeSBarry Smith   Level: intermediate
5305c6c1daeSBarry Smith 
531db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()`
5320afdd333SBarry Smith 
5335c6c1daeSBarry Smith @*/
5349371c9d4SSatish Balay PetscErrorCode PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max) {
5355c6c1daeSBarry Smith   PetscFunctionBegin;
5365c6c1daeSBarry Smith   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
537e118a51fSLisandro Dalcin 
5385c6c1daeSBarry Smith   hist->xmin = x_min;
5395c6c1daeSBarry Smith   hist->xmax = x_max;
5405c6c1daeSBarry Smith   hist->ymin = y_min;
5415c6c1daeSBarry Smith   hist->ymax = y_max;
5425c6c1daeSBarry Smith   PetscFunctionReturn(0);
5435c6c1daeSBarry Smith }
5445c6c1daeSBarry Smith 
5455c6c1daeSBarry Smith /*@
5465c6c1daeSBarry Smith   PetscDrawHGCalcStats - Turns on calculation of descriptive statistics
5475c6c1daeSBarry Smith 
5485c6c1daeSBarry Smith   Not collective
5495c6c1daeSBarry Smith 
5505c6c1daeSBarry Smith   Input Parameters:
5515c6c1daeSBarry Smith + hist - The histogram context
5525c6c1daeSBarry Smith - calc - Flag for calculation
5535c6c1daeSBarry Smith 
5545c6c1daeSBarry Smith   Level: intermediate
5555c6c1daeSBarry Smith 
556db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`
5570afdd333SBarry Smith 
5585c6c1daeSBarry Smith @*/
5599371c9d4SSatish Balay PetscErrorCode PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc) {
5605c6c1daeSBarry Smith   PetscFunctionBegin;
5615c6c1daeSBarry Smith   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
562e118a51fSLisandro Dalcin 
5635c6c1daeSBarry Smith   hist->calcStats = calc;
5645c6c1daeSBarry Smith   PetscFunctionReturn(0);
5655c6c1daeSBarry Smith }
5665c6c1daeSBarry Smith 
5675c6c1daeSBarry Smith /*@
5685c6c1daeSBarry Smith   PetscDrawHGIntegerBins - Turns on integer width bins
5695c6c1daeSBarry Smith 
5705c6c1daeSBarry Smith   Not collective
5715c6c1daeSBarry Smith 
5725c6c1daeSBarry Smith   Input Parameters:
5735c6c1daeSBarry Smith + hist - The histogram context
5745c6c1daeSBarry Smith - ints - Flag for integer width bins
5755c6c1daeSBarry Smith 
5765c6c1daeSBarry Smith   Level: intermediate
5775c6c1daeSBarry Smith 
578db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`
5790afdd333SBarry Smith 
5805c6c1daeSBarry Smith @*/
5819371c9d4SSatish Balay PetscErrorCode PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints) {
5825c6c1daeSBarry Smith   PetscFunctionBegin;
5835c6c1daeSBarry Smith   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
584e118a51fSLisandro Dalcin 
5855c6c1daeSBarry Smith   hist->integerBins = ints;
5865c6c1daeSBarry Smith   PetscFunctionReturn(0);
5875c6c1daeSBarry Smith }
5885c6c1daeSBarry Smith 
5895c6c1daeSBarry Smith /*@C
5905c6c1daeSBarry Smith   PetscDrawHGGetAxis - Gets the axis context associated with a histogram.
5915c6c1daeSBarry Smith   This is useful if one wants to change some axis property, such as
5925c6c1daeSBarry Smith   labels, color, etc. The axis context should not be destroyed by the
5935c6c1daeSBarry Smith   application code.
5945c6c1daeSBarry Smith 
5955b399a63SLisandro Dalcin   Not Collective, PetscDrawAxis is parallel if PetscDrawHG is parallel
5965c6c1daeSBarry Smith 
5975c6c1daeSBarry Smith   Input Parameter:
5985c6c1daeSBarry Smith . hist - The histogram context
5995c6c1daeSBarry Smith 
6005c6c1daeSBarry Smith   Output Parameter:
6015c6c1daeSBarry Smith . axis - The axis context
6025c6c1daeSBarry Smith 
6035c6c1daeSBarry Smith   Level: intermediate
6045c6c1daeSBarry Smith 
605db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()`
6060afdd333SBarry Smith 
6075c6c1daeSBarry Smith @*/
6089371c9d4SSatish Balay PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis) {
6095c6c1daeSBarry Smith   PetscFunctionBegin;
610e118a51fSLisandro Dalcin   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
61145f3bb6eSLisandro Dalcin   PetscValidPointer(axis, 2);
6125c6c1daeSBarry Smith   *axis = hist->axis;
6135c6c1daeSBarry Smith   PetscFunctionReturn(0);
6145c6c1daeSBarry Smith }
6155c6c1daeSBarry Smith 
6165c6c1daeSBarry Smith /*@C
6175c6c1daeSBarry Smith   PetscDrawHGGetDraw - Gets the draw context associated with a histogram.
6185c6c1daeSBarry Smith 
6195c6c1daeSBarry Smith   Not Collective, PetscDraw is parallel if PetscDrawHG is parallel
6205c6c1daeSBarry Smith 
6215c6c1daeSBarry Smith   Input Parameter:
6225c6c1daeSBarry Smith . hist - The histogram context
6235c6c1daeSBarry Smith 
6245c6c1daeSBarry Smith   Output Parameter:
625e118a51fSLisandro Dalcin . draw  - The draw context
6265c6c1daeSBarry Smith 
6275c6c1daeSBarry Smith   Level: intermediate
6285c6c1daeSBarry Smith 
629db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()`
6300afdd333SBarry Smith 
6315c6c1daeSBarry Smith @*/
6329371c9d4SSatish Balay PetscErrorCode PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *draw) {
6335c6c1daeSBarry Smith   PetscFunctionBegin;
6345c6c1daeSBarry Smith   PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1);
63545f3bb6eSLisandro Dalcin   PetscValidPointer(draw, 2);
636e118a51fSLisandro Dalcin   *draw = hist->win;
6375c6c1daeSBarry Smith   PetscFunctionReturn(0);
6385c6c1daeSBarry Smith }
639