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