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: int DRAWSP_COOKIE;

 12: struct _p_DrawSP {
 13:   PETSCHEADER(int)
 14:   int           (*destroy)(PetscDrawSP);
 15:   int           (*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

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

 28:     Collective over PetscDraw

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

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

 37:    Level: intermediate

 39:    Concepts: scatter plot^creating

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

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

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

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

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

 88:    Level: intermediate

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

 92: @*/
 93: int PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
 94: {

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

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

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

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

116:    Input Parameter:
117: .  sp - the line graph context.

119:    Level: intermediate

121:   Concepts: scatter plot^resetting

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

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

141:    Collective over PetscDrawSP

143:    Input Parameter:
144: .  sp - the line graph context

146:    Level: intermediate

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


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

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

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

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

179:    Level: intermediate

181:    Concepts: scatter plot^adding points

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

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

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

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


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

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

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

229:    Level: intermediate

231:    Concepts: scatter plot^adding points

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

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

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

275: /*@
276:    PetscDrawSPDraw - Redraws a scatter plot.

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

280:    Input Parameter:
281: .  sp - the line graph context

283:    Level: intermediate

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

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

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

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

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

325:    Level: intermediate

327:    Concepts: scatter plot^setting axis

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

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

350:    Input Parameter:
351: .  sp - the line graph context

353:    Output Parameter:
354: .  axis - the axis context

356:    Level: intermediate

358: @*/
359: int PetscDrawSPGetAxis(PetscDrawSP sp,PetscDrawAxis *axis)
360: {
362:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) {
363:     *axis = 0;
364:     return(0);
365:   }
367:   *axis = sp->axis;
368:   return(0);
369: }

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

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

376:    Input Parameter:
377: .  sp - the line graph context

379:    Output Parameter:
380: .  draw - the draw context

382:    Level: intermediate

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