Actual source code: dscatter.c

  1: /*$Id: dscatter.c,v 1.38 2001/04/10 19:34:23 bsmith Exp $*/
  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 petsc.h

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

 21: #define CHUNCKSIZE 100

 23: /*@C
 24:     PetscDrawSPCreate - Creates a scatter plot data structure.

 26:     Collective over PetscDraw

 28:     Input Parameters:
 29: +   win - the window where the graph will be made.
 30: -   dim - the number of sets of points which will be drawn

 32:     Output Parameters:
 33: .   drawsp - the scatter plot context

 35:    Level: intermediate

 37:    Concepts: scatter plot^creating

 39: .seealso:  PetscDrawSPDestroy()
 40: @*/
 41: int PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
 42: {
 43:   int         ierr;
 44:   PetscTruth  isnull;
 45:   PetscObject obj = (PetscObject)draw;
 46:   PetscDrawSP sp;

 51:   PetscTypeCompare(obj,PETSC_DRAW_NULL,&isnull);
 52:   if (isnull) {
 53:     PetscDrawOpenNull(obj->comm,(PetscDraw*)drawsp);
 54:     return(0);
 55:   }
 56:   PetscHeaderCreate(sp,_p_DrawSP,int,DRAWSP_COOKIE,0,"PetscDrawSP",obj->comm,PetscDrawSPDestroy,0);
 57:   sp->view    = 0;
 58:   sp->destroy = 0;
 59:   sp->nopts   = 0;
 60:   sp->win     = draw;
 61:   sp->dim     = dim;
 62:   sp->xmin    = 1.e20;
 63:   sp->ymin    = 1.e20;
 64:   sp->xmax    = -1.e20;
 65:   sp->ymax    = -1.e20;
 66:   PetscMalloc(2*dim*CHUNCKSIZE*sizeof(PetscReal),&sp->x);
 67:   PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
 68:   sp->y       = sp->x + dim*CHUNCKSIZE;
 69:   sp->len     = dim*CHUNCKSIZE;
 70:   sp->loc     = 0;
 71:   PetscDrawAxisCreate(draw,&sp->axis);
 72:   PetscLogObjectParent(sp,sp->axis);
 73:   *drawsp = sp;
 74:   return(0);
 75: }

 77: /*@
 78:    PetscDrawSPSetDimension - Change the number of sets of points  that are to be drawn.

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

 82:    Input Parameter:
 83: +  sp - the line graph context.
 84: -  dim - the number of curves.

 86:    Level: intermediate

 88:    Concepts: scatter plot^setting number of data types

 90: @*/
 91: int PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
 92: {

 96:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
 98:   if (sp->dim == dim) return(0);

100:   PetscFree(sp->x);
101:   sp->dim     = dim;
102:   PetscMalloc(2*dim*CHUNCKSIZE*sizeof(PetscReal),&sp->x);
103:   PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
104:   sp->y       = sp->x + dim*CHUNCKSIZE;
105:   sp->len     = dim*CHUNCKSIZE;
106:   return(0);
107: }

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

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

114:    Input Parameter:
115: .  sp - the line graph context.

117:    Level: intermediate

119:   Concepts: scatter plot^resetting

121: @*/
122: int PetscDrawSPReset(PetscDrawSP sp)
123: {
125:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
127:   sp->xmin  = 1.e20;
128:   sp->ymin  = 1.e20;
129:   sp->xmax  = -1.e20;
130:   sp->ymax  = -1.e20;
131:   sp->loc   = 0;
132:   sp->nopts = 0;
133:   return(0);
134: }

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

139:    Collective over PetscDrawSP

141:    Input Parameter:
142: .  sp - the line graph context

144:    Level: intermediate

146: .seealso:  PetscDrawSPCreate()
147: @*/
148: int PetscDrawSPDestroy(PetscDrawSP sp)
149: {


155:   if (--sp->refct > 0) return(0);
156:   if (sp->cookie == PETSC_DRAW_COOKIE){
157:     PetscDrawDestroy((PetscDraw) sp);
158:     return(0);
159:   }
160:   PetscDrawAxisDestroy(sp->axis);
161:   PetscFree(sp->x);
162:   PetscLogObjectDestroy(sp);
163:   PetscHeaderDestroy(sp);
164:   return(0);
165: }

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

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

172:    Input Parameters:
173: +  sp - the scatter plot data structure
174: -  x, y - the points to two vectors containing the new x and y 
175:           point for each curve.

177:    Level: intermediate

179:    Concepts: scatter plot^adding points

181: .seealso: PetscDrawSPAddPoints()
182: @*/
183: int PetscDrawSPAddPoint(PetscDrawSP sp,PetscReal *x,PetscReal *y)
184: {
185:   int i,ierr;

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

191:   if (sp->loc+sp->dim >= sp->len) { /* allocate more space */
192:     PetscReal *tmpx,*tmpy;
193:     PetscMalloc((2*sp->len+2*sp->dim*CHUNCKSIZE)*sizeof(PetscReal),&tmpx);
194:     PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
195:     tmpy = tmpx + sp->len + sp->dim*CHUNCKSIZE;
196:     PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
197:     PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
198:     PetscFree(sp->x);
199:     sp->x = tmpx; sp->y = tmpy;
200:     sp->len += sp->dim*CHUNCKSIZE;
201:   }
202:   for (i=0; i<sp->dim; i++) {
203:     if (x[i] > sp->xmax) sp->xmax = x[i];
204:     if (x[i] < sp->xmin) sp->xmin = x[i];
205:     if (y[i] > sp->ymax) sp->ymax = y[i];
206:     if (y[i] < sp->ymin) sp->ymin = y[i];

208:     sp->x[sp->loc]   = x[i];
209:     sp->y[sp->loc++] = y[i];
210:   }
211:   sp->nopts++;
212:   return(0);
213: }


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

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

221:    Input Parameters:
222: +  sp - the LineGraph data structure
223: .  xx,yy - points to two arrays of pointers that point to arrays 
224:            containing the new x and y points for each curve.
225: -  n - number of points being added

227:    Level: intermediate

229:    Concepts: scatter plot^adding points

231: .seealso: PetscDrawSPAddPoint()
232: @*/
233: int PetscDrawSPAddPoints(PetscDrawSP sp,int n,PetscReal **xx,PetscReal **yy)
234: {
235:   int       i,j,k,ierr;
236:   PetscReal *x,*y;

239:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
241:   if (sp->loc+n*sp->dim >= sp->len) { /* allocate more space */
242:     PetscReal *tmpx,*tmpy;
243:     int    chunk = CHUNCKSIZE;
244:     if (n > chunk) chunk = n;
245:     PetscMalloc((2*sp->len+2*sp->dim*chunk)*sizeof(PetscReal),&tmpx);
246:     PetscLogObjectMemory(sp,2*sp->dim*CHUNCKSIZE*sizeof(PetscReal));
247:     tmpy = tmpx + sp->len + sp->dim*chunk;
248:     PetscMemcpy(tmpx,sp->x,sp->len*sizeof(PetscReal));
249:     PetscMemcpy(tmpy,sp->y,sp->len*sizeof(PetscReal));
250:     PetscFree(sp->x);
251:     sp->x   = tmpx; sp->y = tmpy;
252:     sp->len += sp->dim*CHUNCKSIZE;
253:   }
254:   for (j=0; j<sp->dim; j++) {
255:     x = xx[j]; y = yy[j];
256:     k = sp->loc + j;
257:     for (i=0; i<n; i++) {
258:       if (x[i] > sp->xmax) sp->xmax = x[i];
259:       if (x[i] < sp->xmin) sp->xmin = x[i];
260:       if (y[i] > sp->ymax) sp->ymax = y[i];
261:       if (y[i] < sp->ymin) sp->ymin = y[i];

263:       sp->x[k]   = x[i];
264:       sp->y[k] = y[i];
265:       k += sp->dim;
266:     }
267:   }
268:   sp->loc   += n*sp->dim;
269:   sp->nopts += n;
270:   return(0);
271: }

273: /*@
274:    PetscDrawSPDraw - Redraws a scatter plot.

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

278:    Input Parameter:
279: .  sp - the line graph context

281:    Level: intermediate

283: @*/
284: int PetscDrawSPDraw(PetscDrawSP sp)
285: {
286:   PetscReal xmin=sp->xmin,xmax=sp->xmax,ymin=sp->ymin,ymax=sp->ymax;
287:   int       ierr,i,j,dim = sp->dim,nopts = sp->nopts,rank;
288:   PetscDraw draw = sp->win;

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

294:   if (nopts < 1) return(0);
295:   if (xmin > xmax || ymin > ymax) return(0);
296:   PetscDrawClear(draw);
297:   PetscDrawAxisSetLimits(sp->axis,xmin,xmax,ymin,ymax);
298:   PetscDrawAxisDraw(sp->axis);
299: 
300:   MPI_Comm_rank(sp->comm,&rank);
301:   if (rank)   return(0);
302:   for (i=0; i<dim; i++) {
303:     for (j=0; j<nopts; j++) {
304:       PetscDrawString(draw,sp->x[j*dim+i],sp->y[j*dim+i],PETSC_DRAW_RED,"x");
305:     }
306:   }
307:   PetscDrawFlush(sp->win);
308:   PetscDrawPause(sp->win);
309:   return(0);
310: }
311: 
312: /*@
313:    PetscDrawSPSetLimits - Sets the axis limits for a line graph. If more
314:    points are added after this call, the limits will be adjusted to
315:    include those additional points.

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

319:    Input Parameters:
320: +  xsp - the line graph context
321: -  x_min,x_max,y_min,y_max - the limits

323:    Level: intermediate

325:    Concepts: scatter plot^setting axis

327: @*/
328: int PetscDrawSPSetLimits(PetscDrawSP sp,PetscReal x_min,PetscReal x_max,PetscReal y_min,PetscReal y_max)
329: {
331:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
333:   sp->xmin = x_min;
334:   sp->xmax = x_max;
335:   sp->ymin = y_min;
336:   sp->ymax = y_max;
337:   return(0);
338: }
339: 
340: /*@C
341:    PetscDrawSPGetAxis - Gets the axis context associated with a line graph.
342:    This is useful if one wants to change some axis property, such as
343:    labels, color, etc. The axis context should not be destroyed by the
344:    application code.

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

348:    Input Parameter:
349: .  sp - the line graph context

351:    Output Parameter:
352: .  axis - the axis context

354:    Level: intermediate

356: @*/
357: int PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
358: {
360:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) {
361:     *axis = 0;
362:     return(0);
363:   }
365:   *axis = sp->axis;
366:   return(0);
367: }

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

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

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

377:    Output Parameter:
378: .  draw - the draw context

380:    Level: intermediate

382: @*/
383: int PetscDrawSPGetDraw(PetscDrawSP sp,PetscDraw *draw)
384: {
387:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) {
388:     *draw = (PetscDraw)sp;
389:   } else {
390:     *draw = sp->win;
391:   }
392:   return(0);
393: }