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: }