Actual source code: dscatter.c

      1: #define PETSC_DLL
      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: PetscCookie DRAWSP_COOKIE = 0;

     12: struct _p_DrawSP {
     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 PETSC_DLLEXPORT PetscDrawSPCreate(PetscDraw draw,int dim,PetscDrawSP *drawsp)
     46: {
     48:   PetscTruth  isnull;
     49:   PetscObject obj = (PetscObject)draw;
     50:   PetscDrawSP sp;

     55:   PetscTypeCompare(obj,PETSC_DRAW_NULL,&isnull);
     56:   if (isnull) {
     57:     PetscDrawOpenNull(obj->comm,(PetscDraw*)drawsp);
     58:     return(0);
     59:   }
     60:   PetscHeaderCreate(sp,_p_DrawSP,int,DRAWSP_COOKIE,0,"PetscDrawSP",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:   PetscMalloc(2*dim*CHUNCKSIZE*sizeof(PetscReal),&sp->x);
     71:   PetscLogObjectMemory(sp,2*dim*CHUNCKSIZE*sizeof(PetscReal));
     72:   sp->y       = sp->x + dim*CHUNCKSIZE;
     73:   sp->len     = dim*CHUNCKSIZE;
     74:   sp->loc     = 0;
     75:   PetscDrawAxisCreate(draw,&sp->axis);
     76:   PetscLogObjectParent(sp,sp->axis);
     77:   *drawsp = sp;
     78:   return(0);
     79: }

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

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

     88:    Input Parameter:
     89: +  sp - the line graph context.
     90: -  dim - the number of curves.

     92:    Level: intermediate

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

     96: @*/
     97: PetscErrorCode PETSC_DLLEXPORT PetscDrawSPSetDimension(PetscDrawSP sp,int dim)
     98: {

    102:   if (sp && sp->cookie == PETSC_DRAW_COOKIE) return(0);
    104:   if (sp->dim == dim) return(0);

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

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

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

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

    125:    Level: intermediate

    127:   Concepts: scatter plot^resetting

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

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

    149:    Collective over PetscDrawSP

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

    154:    Level: intermediate

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

    165:   if (--sp->refct > 0) return(0);
    166:   if (sp->cookie == PETSC_DRAW_COOKIE){
    167:     PetscDrawDestroy((PetscDraw) sp);
    168:     return(0);
    169:   }
    170:   PetscDrawAxisDestroy(sp->axis);
    171:   PetscFree(sp->x);
    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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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 PETSC_DLLEXPORT 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: }