Actual source code: dscatter.c

  1: /*
  2:        Contains the data structure for drawing scatter plots
  3:     graphs in a window with an axis. This is intended for scatter
  4:     plots that change dynamically.
  5: */

 7:  #include petsc.h

  9: PetscCookie DRAWSP_COOKIE = 0;

 11: struct _p_DrawSP {
 12:   PETSCHEADER(int)
 13:   PetscErrorCode (*destroy)(PetscDrawSP);
 14:   PetscErrorCode (*view)(PetscDrawSP,PetscViewer);
 15:   int           len,loc;
 16:   PetscDraw     win;
 17:   PetscDrawAxis axis;
 18:   PetscReal     xmin,xmax,ymin,ymax,*x,*y;
 19:   int           nopts,dim;
 20: };

 22: #define CHUNCKSIZE 100

 26: /*@C
 27:     PetscDrawSPCreate - Creates a scatter plot data structure.

 29:     Collective over PetscDraw

 31:     Input Parameters:
 32: +   win - the window where the graph will be made.
 33: -   dim - the number of sets of points which will be drawn

 35:     Output Parameters:
 36: .   drawsp - the scatter plot context

 38:    Level: intermediate

 40:    Concepts: scatter plot^creating

 42: .seealso:  PetscDrawSPDestroy()
 43: @*/
 44: PetscErrorCode PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
 45: {
 47:   PetscTruth  isnull;
 48:   PetscObject obj = (PetscObject)draw;
 49:   PetscDrawSP sp;

 54:   PetscTypeCompare(obj,PETSC_DRAW_NULL,&isnull);
 55:   if (isnull) {
 56:     PetscDrawOpenNull(obj->comm,(PetscDraw*)drawsp);
 57:     return(0);
 58:   }
 59:   PetscHeaderCreate(sp,_p_DrawSP,int,DRAWSP_COOKIE,0,"PetscDrawSP",obj->comm,PetscDrawSPDestroy,0);
 60:   sp->view    = 0;
 61:   sp->destroy = 0;
 62:   sp->nopts   = 0;
 63:   sp->win     = draw;
 64:   sp->dim     = dim;
 65:   sp->xmin    = 1.e20;
 66:   sp->ymin    = 1.e20;
 67:   sp->xmax    = -1.e20;
 68:   sp->ymax    = -1.e20;
 69:   PetscMalloc(2*dim*CHUNCKSIZE*sizeof(PetscReal),&sp->x);
 70:   PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
 71:   sp->y       = sp->x + dim*CHUNCKSIZE;
 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 && sp->cookie == PETSC_DRAW_COOKIE) return(0);
103:   if (sp->dim == dim) return(0);

105:   PetscFree(sp->x);
106:   sp->dim     = dim;
107:   PetscMalloc(2*dim*CHUNCKSIZE*sizeof(PetscReal),&sp->x);
108:   PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
109:   sp->y       = sp->x + dim*CHUNCKSIZE;
110:   sp->len     = dim*CHUNCKSIZE;
111:   return(0);
112: }

116: /*@
117:    PetscDrawSPReset - Clears line graph to allow for reuse with new data.

119:    Not Collective (ignored on all processors except processor 0 of PetscDrawSP)

121:    Input Parameter:
122: .  sp - the line graph context.

124:    Level: intermediate

126:   Concepts: scatter plot^resetting

128: @*/
129: PetscErrorCode PetscDrawSPReset(PetscDrawSP sp)
130: {
132:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
134:   sp->xmin  = 1.e20;
135:   sp->ymin  = 1.e20;
136:   sp->xmax  = -1.e20;
137:   sp->ymax  = -1.e20;
138:   sp->loc   = 0;
139:   sp->nopts = 0;
140:   return(0);
141: }

145: /*@C
146:    PetscDrawSPDestroy - Frees all space taken up by scatter plot data structure.

148:    Collective over PetscDrawSP

150:    Input Parameter:
151: .  sp - the line graph context

153:    Level: intermediate

155: .seealso:  PetscDrawSPCreate()
156: @*/
157: PetscErrorCode PetscDrawSPDestroy(PetscDrawSP sp)
158: {


164:   if (--sp->refct > 0) return(0);
165:   if (sp->cookie == PETSC_DRAW_COOKIE){
166:     PetscDrawDestroy((PetscDraw) sp);
167:     return(0);
168:   }
169:   PetscDrawAxisDestroy(sp->axis);
170:   PetscFree(sp->x);
171:   PetscLogObjectDestroy(sp);
172:   PetscHeaderDestroy(sp);
173:   return(0);
174: }

178: /*@
179:    PetscDrawSPAddPoint - Adds another point to each of the scatter plots.

181:    Not Collective (ignored on all processors except processor 0 of PetscDrawSP)

183:    Input Parameters:
184: +  sp - the scatter plot data structure
185: -  x, y - the points to two vectors containing the new x and y 
186:           point for each curve.

188:    Level: intermediate

190:    Concepts: scatter plot^adding points

192: .seealso: PetscDrawSPAddPoints()
193: @*/
194: PetscErrorCode PetscDrawSPAddPoint(PetscDrawSP sp,PetscReal *x,PetscReal *y)
195: {
197:   int i;

200:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);

203:   if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
204:     PetscReal *tmpx,*tmpy;
205:     PetscMalloc((2*sp->len+2*sp->dim*CHUNCKSIZE)*sizeof(PetscReal),&tmpx);
206:     PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
207:     tmpy = tmpx + sp->len + sp->dim*CHUNCKSIZE;
208:     PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
209:     PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
210:     PetscFree(sp->x);
211:     sp->x = tmpx; sp->y = tmpy;
212:     sp->len += sp->dim*CHUNCKSIZE;
213:   }
214:   for (i=0; i<sp->dim; i++) {
215:     if (x[i] > sp->xmax) sp->xmax = x[i];
216:     if (x[i] < sp->xmin) sp->xmin = x[i];
217:     if (y[i] > sp->ymax) sp->ymax = y[i];
218:     if (y[i] < sp->ymin) sp->ymin = y[i];

220:     sp->x[sp->loc]   = x[i];
221:     sp->y[sp->loc++] = y[i];
222:   }
223:   sp->nopts++;
224:   return(0);
225: }


230: /*@C
231:    PetscDrawSPAddPoints - Adds several points to each of the scatter plots.

233:    Not Collective (ignored on all processors except processor 0 of PetscDrawSP)

235:    Input Parameters:
236: +  sp - the LineGraph data structure
237: .  xx,yy - points to two arrays of pointers that point to arrays 
238:            containing the new x and y points for each curve.
239: -  n - number of points being added

241:    Level: intermediate

243:    Concepts: scatter plot^adding points

245: .seealso: PetscDrawSPAddPoint()
246: @*/
247: PetscErrorCode PetscDrawSPAddPoints(PetscDrawSP sp,int n,PetscReal **xx,PetscReal **yy)
248: {
250:   int       i,j,k;
251:   PetscReal *x,*y;

254:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
256:   if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
257:     PetscReal *tmpx,*tmpy;
258:     int    chunk = CHUNCKSIZE;
259:     if (n > chunk) chunk = n;
260:     PetscMalloc((2*sp->len+2*sp->dim*chunk)*sizeof(PetscReal),&tmpx);
261:     PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
262:     tmpy = tmpx + sp->len + sp->dim*chunk;
263:     PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
264:     PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
265:     PetscFree(sp->x);
266:     sp->x   = tmpx; 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:   int       i,j,dim = sp->dim,nopts = sp->nopts,rank;
308:   PetscDraw draw = sp->win;

311:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);

314:   if (nopts < 1) return(0);
315:   if (xmin > xmax || ymin > ymax) return(0);
316:   PetscDrawClear(draw);
317:   PetscDrawAxisSetLimits(sp->axis,xmin,xmax,ymin,ymax);
318:   PetscDrawAxisDraw(sp->axis);
319: 
320:   MPI_Comm_rank(sp->comm,&rank);
321:   if (!rank) {
322:     for (i=0; i<dim; i++) {
323:       for (j=0; j<nopts; j++) {
324:         PetscDrawString(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED,"x");
325:       }
326:     }
327:   }
328:   PetscDrawFlush(sp->win);
329:   PetscDrawPause(sp->win);
330:   return(0);
331: }
332: 
335: /*@
336:    PetscDrawSPSetLimits - Sets the axis limits for a line graph. If more
337:    points are added after this call, the limits will be adjusted to
338:    include those additional points.

340:    Not Collective (ignored on all processors except processor 0 of PetscDrawSP)

342:    Input Parameters:
343: +  xsp - the line graph context
344: -  x_min,x_max,y_min,y_max - the limits

346:    Level: intermediate

348:    Concepts: scatter plot^setting axis

350: @*/
351: PetscErrorCode PetscDrawSPSetLimits(PetscDrawSP sp,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
352: {
354:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
356:   sp->xmin = x_min;
357:   sp->xmax = x_max;
358:   sp->ymin = y_min;
359:   sp->ymax = y_max;
360:   return(0);
361: }
362: 
365: /*@C
366:    PetscDrawSPGetAxis - Gets the axis context associated with a line graph.
367:    This is useful if one wants to change some axis property, such as
368:    labels, color, etc. The axis context should not be destroyed by the
369:    application code.

371:    Not Collective (except PetscDrawAxis can only be used on processor 0 of PetscDrawSP)

373:    Input Parameter:
374: .  sp - the line graph context

376:    Output Parameter:
377: .  axis - the axis context

379:    Level: intermediate

381: @*/
382: PetscErrorCode PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
383: {
385:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) {
386:     *axis = 0;
387:     return(0);
388:   }
390:   *axis = sp->axis;
391:   return(0);
392: }

396: /*@C
397:    PetscDrawSPGetDraw - Gets the draw context associated with a line graph.

399:    Not Collective, PetscDraw is parallel if PetscDrawSP is parallel

401:    Input Parameter:
402: .  sp - the line graph context

404:    Output Parameter:
405: .  draw - the draw context

407:    Level: intermediate

409: @*/
410: PetscErrorCode PetscDrawSPGetDraw(PetscDrawSP sp,PetscDraw *draw)
411: {
415:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) {
416:     *draw = (PetscDraw)sp;
417:   } else {
418:     *draw = sp->win;
419:   }
420:   return(0);
421: }