Actual source code: hists.c
1: /*$Id: hists.c,v 1.26 2001/04/10 19:34:23 bsmith Exp $*/
3: /*
4: Contains the data structure for plotting a histogram in a window with an axis.
5: */
7: #include "petsc.h" /*I "petsc.h" I*/
9: struct _p_DrawHG {
10: PETSCHEADER(int)
11: int (*destroy)(PetscDrawSP);
12: int (*view)(PetscDrawSP,PetscViewer);
13: PetscDraw win;
14: PetscDrawAxis axis;
15: PetscReal xmin,xmax;
16: PetscReal ymin,ymax;
17: int numBins;
18: PetscReal *bins;
19: int numValues;
20: int maxValues;
21: PetscReal *values;
22: int color;
23: };
25: #define CHUNKSIZE 100
27: /*@C
28: PetscDrawHGCreate - Creates a histogram data structure.
30: Collective over PetscDraw
32: Input Parameters:
33: + draw - The window where the graph will be made
34: - bins - The number of bins to use
36: Output Parameters:
37: . hist - The histogram context
39: Level: intermediate
41: Contributed by: Matthew Knepley
43: Concepts: histogram^creating
45: .seealso: PetscDrawHGDestroy()
47: @*/
48: int PetscDrawHGCreate(PetscDraw draw,int bins,PetscDrawHG *hist)
49: {
50: int ierr;
51: PetscTruth isnull;
52: PetscObject obj = (PetscObject)draw;
53: PetscDrawHG h;
58: PetscTypeCompare(obj,PETSC_DRAW_NULL,&isnull);
59: if (isnull) {
60: PetscDrawOpenNull(obj->comm,(PetscDraw*)hist);
61: return(0);
62: }
63: PetscHeaderCreate(h,_p_DrawHG,int,DRAWHG_COOKIE,0,"PetscDrawHG",obj->comm,PetscDrawHGDestroy,0);
64: h->view = 0;
65: h->destroy = 0;
66: h->win = draw;
67: h->color = PETSC_DRAW_GREEN;
68: h->xmin = PETSC_MAX;
69: h->xmax = PETSC_MIN;
70: h->ymin = 0.;
71: h->ymax = 1.;
72: h->numBins = bins;
73: PetscMalloc(bins*sizeof(PetscReal),&h->bins);
74: h->numValues = 0;
75: h->maxValues = CHUNKSIZE;
76: ierr = PetscMalloc(h->maxValues*sizeof(PetscReal),&h->values);
77: PetscLogObjectMemory(h,bins*sizeof(PetscReal) + h->maxValues*sizeof(PetscReal));
78: PetscDrawAxisCreate(draw,&h->axis);
79: PetscLogObjectParent(h,h->axis);
80: *hist = h;
81: return(0);
82: }
84: /*@
85: PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn.
87: Not Collective (ignored except on processor 0 of PetscDrawHG)
89: Input Parameter:
90: + hist - The histogram context.
91: - dim - The number of curves.
93: Level: intermediate
95: Contributed by: Matthew Knepley
97: Concepts: histogram^setting number of bins
99: @*/
100: int PetscDrawHGSetNumberBins(PetscDrawHG hist,int bins)
101: {
105: if (hist && hist->cookie == PETSC_DRAW_COOKIE) return(0);
108: if (hist->numBins == bins) return(0);
110: ierr = PetscFree(hist->bins);
111: PetscMalloc(bins*sizeof(PetscReal),&hist->bins);
112: PetscLogObjectMemory(hist,(bins - hist->numBins) * sizeof(PetscReal));
113: hist->numBins = bins;
114: return(0);
115: }
117: /*@
118: PetscDrawHGReset - Clears histogram to allow for reuse with new data.
120: Not Collective (ignored except on processor 0 of PetscDrawHG)
122: Input Parameter:
123: . hist - The histogram context.
125: Level: intermediate
127: Contributed by: Matthew Knepley
129: Concepts: histogram^resetting
131: @*/
132: int PetscDrawHGReset(PetscDrawHG hist)
133: {
135: if (hist && hist->cookie == PETSC_DRAW_COOKIE) return(0);
137: hist->xmin = PETSC_MAX;
138: hist->xmax = PETSC_MIN;
139: hist->ymin = 0;
140: hist->ymax = 0;
141: hist->numValues = 0;
142: return(0);
143: }
145: /*@C
146: PetscDrawHGDestroy - Frees all space taken up by histogram data structure.
148: Collective over PetscDrawHG
150: Input Parameter:
151: . hist - The histogram context
153: Level: intermediate
155: Contributed by: Matthew Knepley
157: .seealso: PetscDrawHGCreate()
158: @*/
159: int PetscDrawHGDestroy(PetscDrawHG hist)
160: {
166: if (--hist->refct > 0) return(0);
167: if (hist->cookie == PETSC_DRAW_COOKIE){
168: PetscDrawDestroy((PetscDraw) hist);
169: return(0);
170: }
172: PetscDrawAxisDestroy(hist->axis);
173: PetscFree(hist->bins);
174: PetscFree(hist->values);
175: PetscLogObjectDestroy(hist);
176: PetscHeaderDestroy(hist);
177: return(0);
178: }
180: /*@
181: PetscDrawHGAddValue - Adds another value to the histogram.
183: Not Collective (ignored except on processor 0 of PetscDrawHG)
185: Input Parameters:
186: + hist - The histogram
187: - value - The value
189: Level: intermediate
191: Contributed by: Matthew Knepley
193: Concepts: histogram^adding values
195: .seealso: PetscDrawHGAddValues()
196: @*/
197: int PetscDrawHGAddValue(PetscDrawHG hist,PetscReal value)
198: {
200: if (hist && hist->cookie == PETSC_DRAW_COOKIE) return(0);
203: /* Allocate more memory if necessary */
204: if (hist->numValues >= hist->maxValues) {
205: PetscReal *tmp;
206: int ierr;
208: PetscMalloc((hist->maxValues+CHUNKSIZE)*sizeof(PetscReal),&tmp);
209: PetscLogObjectMemory(hist,CHUNKSIZE * sizeof(PetscReal));
210: PetscMemcpy(tmp,hist->values,hist->maxValues * sizeof(PetscReal));
211: PetscFree(hist->values);
212: hist->values = tmp;
213: hist->maxValues += CHUNKSIZE;
214: }
215: if (!hist->numValues) {
216: hist->xmin = value;
217: hist->xmax = value;
218: } else if (hist->numValues == 1) {
219: /* Update limits -- We need to overshoot the largest value somewhat */
220: if (value > hist->xmax)
221: hist->xmax = value + 0.001*(value - hist->xmin)/hist->numBins;
222: if (value < hist->xmin)
223: {
224: hist->xmin = value;
225: hist->xmax = hist->xmax + 0.001*(hist->xmax - hist->xmin)/hist->numBins;
226: }
227: } else {
228: /* Update limits -- We need to overshoot the largest value somewhat */
229: if (value > hist->xmax) {
230: hist->xmax = value + 0.001*(hist->xmax - hist->xmin)/hist->numBins;
231: }
232: if (value < hist->xmin) {
233: hist->xmin = value;
234: }
235: }
237: hist->values[hist->numValues++] = value;
238: return(0);
239: }
241: /*@
242: PetscDrawHGDraw - Redraws a histogram.
244: Not Collective (ignored except on processor 0 of PetscDrawHG)
246: Input Parameter:
247: . hist - The histogram context
249: Level: intermediate
251: Contributed by: Matthew Knepley
253: @*/
254: int PetscDrawHGDraw(PetscDrawHG hist)
255: {
256: PetscDraw draw;
257: PetscReal xmin,xmax,ymin,ymax,*bins,*values,binSize,binLeft,binRight,maxHeight;
258: int numBins,numValues,i,p,ierr,bcolor,color,rank;
261: if (hist && hist->cookie == PETSC_DRAW_COOKIE) return(0);
263: if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) return(0);
264: if (hist->numValues < 1) return(0);
266: MPI_Comm_rank(hist->comm,&rank);
267: if (rank) return(0);
269: color = hist->color;
270: if (color == PETSC_DRAW_ROTATE) {bcolor = 2;} else {bcolor = color;}
271: draw = hist->win;
272: xmin = hist->xmin;
273: xmax = hist->xmax;
274: ymin = hist->ymin;
275: ymax = hist->ymax;
276: numBins = hist->numBins;
277: bins = hist->bins;
278: numValues = hist->numValues;
279: values = hist->values;
280: binSize = (xmax - xmin)/numBins;
282: PetscDrawClear(draw);
283: /* Calculate number of points in each bin */
284: PetscMemzero(bins,numBins * sizeof(PetscReal));
285: maxHeight = 0;
286: for (i = 0; i < numBins; i++) {
287: binLeft = xmin + binSize*i;
288: binRight = xmin + binSize*(i+1);
289: for(p = 0; p < numValues; p++) {
290: if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++;
291: }
292: maxHeight = PetscMax(maxHeight,bins[i]);
293: }
294: if (maxHeight > ymax) ymax = hist->ymax = maxHeight;
295: PetscDrawAxisSetLimits(hist->axis,xmin,xmax,ymin,ymax);
296: PetscDrawAxisDraw(hist->axis);
297: /* PetscDraw bins */
298: for (i = 0; i < numBins; i++) {
299: binLeft = xmin + binSize*i;
300: binRight = xmin + binSize*(i+1);
301: PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[i],bcolor,bcolor,bcolor,bcolor);
302: if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++; if (bcolor > 31) bcolor = 2;
303: PetscDrawLine(draw,binLeft,ymin,binLeft,bins[i],PETSC_DRAW_BLACK);
304: PetscDrawLine(draw,binRight,ymin,binRight,bins[i],PETSC_DRAW_BLACK);
305: PetscDrawLine(draw,binLeft,bins[i],binRight,bins[i],PETSC_DRAW_BLACK);
306: }
307: PetscDrawFlush(draw);
308: PetscDrawPause(draw);
309: return(0);
310: }
311:
312: /*@
313: PetscDrawHGSetColor - Sets the color the bars will be drawn with.
315: Not Collective (ignored except on processor 0 of PetscDrawHG)
317: Input Parameters:
318: + hist - The histogram context
319: - color - one of the colors defined in petscdraw.h or PETSC_DRAW_ROTATE to make each bar a
320: different color
322: Level: intermediate
324: @*/
325: int PetscDrawHGSetColor(PetscDrawHG hist,int color)
326: {
328: if (hist && hist->cookie == PETSC_DRAW_COOKIE) return(0);
330: hist->color = color;
331: return(0);
332: }
334: /*@
335: PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more
336: points are added after this call, the limits will be adjusted to
337: include those additional points.
339: Not Collective (ignored except on processor 0 of PetscDrawHG)
341: Input Parameters:
342: + hist - The histogram context
343: - x_min,x_max,y_min,y_max - The limits
345: Level: intermediate
347: Contributed by: Matthew Knepley
349: Concepts: histogram^setting axis
351: @*/
352: int PetscDrawHGSetLimits(PetscDrawHG hist,PetscReal x_min,PetscReal x_max,int y_min,int y_max)
353: {
355: if (hist && hist->cookie == PETSC_DRAW_COOKIE) return(0);
357: hist->xmin = x_min;
358: hist->xmax = x_max;
359: hist->ymin = y_min;
360: hist->ymax = y_max;
361: return(0);
362: }
363:
364: /*@C
365: PetscDrawHGGetAxis - Gets the axis context associated with a histogram.
366: This is useful if one wants to change some axis property, such as
367: labels, color, etc. The axis context should not be destroyed by the
368: application code.
370: Not Collective (ignored except on processor 0 of PetscDrawHG)
372: Input Parameter:
373: . hist - The histogram context
375: Output Parameter:
376: . axis - The axis context
378: Level: intermediate
380: Contributed by: Matthew Knepley
382: @*/
383: int PetscDrawHGGetAxis(PetscDrawHG hist,PetscDrawAxis *axis)
384: {
386: if (hist && hist->cookie == PETSC_DRAW_COOKIE) {
387: *axis = 0;
388: return(0);
389: }
391: *axis = hist->axis;
392: return(0);
393: }
395: /*@C
396: PetscDrawHGGetDraw - Gets the draw context associated with a histogram.
398: Not Collective, PetscDraw is parallel if PetscDrawHG is parallel
400: Input Parameter:
401: . hist - The histogram context
403: Output Parameter:
404: . win - The draw context
406: Level: intermediate
408: Contributed by: Matthew Knepley
410: @*/
411: int PetscDrawHGGetDraw(PetscDrawHG hist,PetscDraw *win)
412: {
415: if (hist && hist->cookie == PETSC_DRAW_COOKIE) {
416: *win = (PetscDraw)hist;
417: } else {
418: *win = hist->win;
419: }
420: return(0);
421: }