Actual source code: dscatter.c
petsc-3.3-p7 2013-05-11
2: /*
3: Contains the data structure for drawing scatter plots
4: graphs in a window with an axis. This is intended for scatter
5: plots that change dynamically.
6: */
8: #include <petscsys.h> /*I "petscsys.h" I*/
10: PetscClassId PETSC_DRAWSP_CLASSID = 0;
12: struct _p_PetscDrawSP {
13: PETSCHEADER(int);
14: PetscErrorCode (*destroy)(PetscDrawSP);
15: PetscErrorCode (*view)(PetscDrawSP,PetscViewer);
16: int len,loc;
17: PetscDraw win;
18: PetscDrawAxis axis;
19: PetscReal xmin,xmax,ymin,ymax,*x,*y;
20: int nopts,dim;
21: };
23: #define CHUNCKSIZE 100
27: /*@C
28: PetscDrawSPCreate - Creates a scatter plot data structure.
30: Collective over PetscDraw
32: Input Parameters:
33: + win - the window where the graph will be made.
34: - dim - the number of sets of points which will be drawn
36: Output Parameters:
37: . drawsp - the scatter plot context
39: Level: intermediate
41: Concepts: scatter plot^creating
43: .seealso: PetscDrawSPDestroy()
44: @*/
45: PetscErrorCode PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
46: {
48: PetscBool isnull;
49: PetscObject obj = (PetscObject)draw;
50: PetscDrawSP sp;
55: PetscObjectTypeCompare(obj,PETSC_DRAW_NULL,&isnull);
56: if (isnull) {
57: PetscDrawOpenNull(((PetscObject)obj)->comm,(PetscDraw*)drawsp);
58: return(0);
59: }
60: PetscHeaderCreate(sp,_p_PetscDrawSP,int,PETSC_DRAWSP_CLASSID,0,"PetscDrawSP","Scatter plot","Draw",((PetscObject)obj)->comm,PetscDrawSPDestroy,0);
61: sp->view = 0;
62: sp->destroy = 0;
63: sp->nopts = 0;
64: sp->win = draw;
65: sp->dim = dim;
66: sp->xmin = 1.e20;
67: sp->ymin = 1.e20;
68: sp->xmax = -1.e20;
69: sp->ymax = -1.e20;
70: PetscMalloc2(dim*CHUNCKSIZE,PetscReal,&sp->x,dim*CHUNCKSIZE,PetscReal,&sp->y);
71: PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
72: sp->len = dim*CHUNCKSIZE;
73: sp->loc = 0;
74: PetscDrawAxisCreate(draw,&sp->axis);
75: PetscLogObjectParent(sp,sp->axis);
76: *drawsp = sp;
77: return(0);
78: }
82: /*@
83: PetscDrawSPSetDimension - Change the number of sets of points that are to be drawn.
85: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
87: Input Parameter:
88: + sp - the line graph context.
89: - dim - the number of curves.
91: Level: intermediate
93: Concepts: scatter plot^setting number of data types
95: @*/
96: PetscErrorCode PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
97: {
101: if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) return(0);
103: if (sp->dim == dim) return(0);
105: PetscFree2(sp->x,sp->y);
106: sp->dim = dim;
107: PetscMalloc2(dim*CHUNCKSIZE,PetscReal,&sp->x,dim*CHUNCKSIZE,PetscReal,&sp->y);
108: PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
109: sp->len = dim*CHUNCKSIZE;
110: return(0);
111: }
115: /*@
116: PetscDrawSPReset - Clears line graph to allow for reuse with new data.
118: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
120: Input Parameter:
121: . sp - the line graph context.
123: Level: intermediate
125: Concepts: scatter plot^resetting
127: @*/
128: PetscErrorCode PetscDrawSPReset(PetscDrawSP sp)
129: {
131: if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) return(0);
133: sp->xmin = 1.e20;
134: sp->ymin = 1.e20;
135: sp->xmax = -1.e20;
136: sp->ymax = -1.e20;
137: sp->loc = 0;
138: sp->nopts = 0;
139: return(0);
140: }
144: /*@C
145: PetscDrawSPDestroy - Frees all space taken up by scatter plot data structure.
147: Collective over PetscDrawSP
149: Input Parameter:
150: . sp - the line graph context
152: Level: intermediate
154: .seealso: PetscDrawSPCreate()
155: @*/
156: PetscErrorCode PetscDrawSPDestroy(PetscDrawSP *sp)
157: {
161: if (!*sp) return(0);
164: if (--((PetscObject)(*sp))->refct > 0) return(0);
165: if (((PetscObject)(*sp))->classid == PETSC_DRAW_CLASSID){
166: PetscDrawDestroy((PetscDraw*) sp);
167: return(0);
168: }
169: PetscDrawAxisDestroy(&(*sp)->axis);
170: PetscFree2((*sp)->x,(*sp)->y);
171: PetscHeaderDestroy(sp);
172: return(0);
173: }
177: /*@
178: PetscDrawSPAddPoint - Adds another point to each of the scatter plots.
180: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
182: Input Parameters:
183: + sp - the scatter plot data structure
184: - x, y - the points to two vectors containing the new x and y
185: point for each curve.
187: Level: intermediate
189: Concepts: scatter plot^adding points
191: .seealso: PetscDrawSPAddPoints()
192: @*/
193: PetscErrorCode PetscDrawSPAddPoint(PetscDrawSP sp,PetscReal *x,PetscReal *y)
194: {
196: PetscInt i;
199: if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) return(0);
202: if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
203: PetscReal *tmpx,*tmpy;
204: PetscMalloc2(sp->len+sp->dim*CHUNCKSIZE,PetscReal,&tmpx,sp->len+sp->dim*CHUNCKSIZE,PetscReal,&tmpy);
205: PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
206: PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
207: PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
208: PetscFree2(sp->x,sp->y);
209: sp->x = tmpx;
210: sp->y = tmpy;
211: sp->len += sp->dim*CHUNCKSIZE;
212: }
213: for (i=0; i<sp->dim; i++) {
214: if (x[i] > sp->xmax) sp->xmax = x[i];
215: if (x[i] < sp->xmin) sp->xmin = x[i];
216: if (y[i] > sp->ymax) sp->ymax = y[i];
217: if (y[i] < sp->ymin) sp->ymin = y[i];
219: sp->x[sp->loc] = x[i];
220: sp->y[sp->loc++] = y[i];
221: }
222: sp->nopts++;
223: return(0);
224: }
229: /*@C
230: PetscDrawSPAddPoints - Adds several points to each of the scatter plots.
232: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
234: Input Parameters:
235: + sp - the LineGraph data structure
236: . xx,yy - points to two arrays of pointers that point to arrays
237: containing the new x and y points for each curve.
238: - n - number of points being added
240: Level: intermediate
242: Concepts: scatter plot^adding points
244: .seealso: PetscDrawSPAddPoint()
245: @*/
246: PetscErrorCode PetscDrawSPAddPoints(PetscDrawSP sp,int n,PetscReal **xx,PetscReal **yy)
247: {
249: PetscInt i,j,k;
250: PetscReal *x,*y;
253: if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) return(0);
256: if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
257: PetscReal *tmpx,*tmpy;
258: PetscInt chunk = CHUNCKSIZE;
259: if (n > chunk) chunk = n;
260: PetscMalloc2(sp->len+sp->dim*chunk,PetscReal,&tmpx,sp->len+sp->dim*chunk,PetscReal,&tmpy);
261: PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
262: PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
263: PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
264: PetscFree2(sp->x,sp->y);
265: sp->x = tmpx;
266: sp->y = tmpy;
267: sp->len += sp->dim*CHUNCKSIZE;
268: }
269: for (j=0; j<sp->dim; j++) {
270: x = xx[j]; y = yy[j];
271: k = sp->loc + j;
272: for (i=0; i<n; i++) {
273: if (x[i] > sp->xmax) sp->xmax = x[i];
274: if (x[i] < sp->xmin) sp->xmin = x[i];
275: if (y[i] > sp->ymax) sp->ymax = y[i];
276: if (y[i] < sp->ymin) sp->ymin = y[i];
278: sp->x[k] = x[i];
279: sp->y[k] = y[i];
280: k += sp->dim;
281: }
282: }
283: sp->loc += n*sp->dim;
284: sp->nopts += n;
285: return(0);
286: }
290: /*@
291: PetscDrawSPDraw - Redraws a scatter plot.
293: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
295: Input Parameter:
296: . sp - the line graph context
298: Level: intermediate
300: .seealso: PetscDrawLGDraw(), PetscDrawLGSPDraw()
302: @*/
303: PetscErrorCode PetscDrawSPDraw(PetscDrawSP sp)
304: {
305: PetscReal xmin=sp->xmin,xmax=sp->xmax,ymin=sp->ymin,ymax=sp->ymax;
307: PetscInt i,j,dim = sp->dim,nopts = sp->nopts;
308: PetscMPIInt rank;
309: PetscDraw draw = sp->win;
312: if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) return(0);
315: if (nopts < 1) return(0);
316: if (xmin > xmax || ymin > ymax) return(0);
317: PetscDrawClear(draw);
318: PetscDrawAxisSetLimits(sp->axis,xmin,xmax,ymin,ymax);
319: PetscDrawAxisDraw(sp->axis);
320:
321: MPI_Comm_rank(((PetscObject)sp)->comm,&rank);
322: if (!rank) {
323: for (i=0; i<dim; i++) {
324: for (j=0; j<nopts; j++) {
325: PetscDrawString(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED,"x");
326: }
327: }
328: }
329: PetscDrawFlush(sp->win);
330: PetscDrawPause(sp->win);
331: return(0);
332: }
333:
336: /*@
337: PetscDrawSPSetLimits - Sets the axis limits for a line graph. If more
338: points are added after this call, the limits will be adjusted to
339: include those additional points.
341: Not Collective (ignored on all processors except processor 0 of PetscDrawSP)
343: Input Parameters:
344: + xsp - the line graph context
345: - x_min,x_max,y_min,y_max - the limits
347: Level: intermediate
349: Concepts: scatter plot^setting axis
351: @*/
352: PetscErrorCode PetscDrawSPSetLimits(PetscDrawSP sp,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
353: {
355: if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) return(0);
357: sp->xmin = x_min;
358: sp->xmax = x_max;
359: sp->ymin = y_min;
360: sp->ymax = y_max;
361: return(0);
362: }
363:
366: /*@C
367: PetscDrawSPGetAxis - Gets the axis context associated with a line graph.
368: This is useful if one wants to change some axis property, such as
369: labels, color, etc. The axis context should not be destroyed by the
370: application code.
372: Not Collective (except PetscDrawAxis can only be used on processor 0 of PetscDrawSP)
374: Input Parameter:
375: . sp - the line graph context
377: Output Parameter:
378: . axis - the axis context
380: Level: intermediate
382: @*/
383: PetscErrorCode PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
384: {
386: if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) {
387: *axis = 0;
388: return(0);
389: }
391: *axis = sp->axis;
392: return(0);
393: }
397: /*@C
398: PetscDrawSPGetDraw - Gets the draw context associated with a line graph.
400: Not Collective, PetscDraw is parallel if PetscDrawSP is parallel
402: Input Parameter:
403: . sp - the line graph context
405: Output Parameter:
406: . draw - the draw context
408: Level: intermediate
410: @*/
411: PetscErrorCode PetscDrawSPGetDraw(PetscDrawSP sp,PetscDraw *draw)
412: {
416: if (sp && ((PetscObject)sp)->classid == PETSC_DRAW_CLASSID) {
417: *draw = (PetscDraw)sp;
418: } else {
419: *draw = sp->win;
420: }
421: return(0);
422: }