1*5c6c1daeSBarry Smith 2*5c6c1daeSBarry Smith /* 3*5c6c1daeSBarry Smith Contains the data structure for plotting a histogram in a window with an axis. 4*5c6c1daeSBarry Smith */ 5*5c6c1daeSBarry Smith 6*5c6c1daeSBarry Smith #include <petscsys.h> /*I "petscsys.h" I*/ 7*5c6c1daeSBarry Smith 8*5c6c1daeSBarry Smith PetscClassId PETSC_DRAWHG_CLASSID = 0; 9*5c6c1daeSBarry Smith 10*5c6c1daeSBarry Smith struct _p_PetscDrawHG { 11*5c6c1daeSBarry Smith PETSCHEADER(int); 12*5c6c1daeSBarry Smith PetscErrorCode (*destroy)(PetscDrawSP); 13*5c6c1daeSBarry Smith PetscErrorCode (*view)(PetscDrawSP,PetscViewer); 14*5c6c1daeSBarry Smith PetscDraw win; 15*5c6c1daeSBarry Smith PetscDrawAxis axis; 16*5c6c1daeSBarry Smith PetscReal xmin,xmax; 17*5c6c1daeSBarry Smith PetscReal ymin,ymax; 18*5c6c1daeSBarry Smith int numBins; 19*5c6c1daeSBarry Smith int maxBins; 20*5c6c1daeSBarry Smith PetscReal *bins; 21*5c6c1daeSBarry Smith int numValues; 22*5c6c1daeSBarry Smith int maxValues; 23*5c6c1daeSBarry Smith PetscReal *values; 24*5c6c1daeSBarry Smith int color; 25*5c6c1daeSBarry Smith PetscBool calcStats; 26*5c6c1daeSBarry Smith PetscBool integerBins; 27*5c6c1daeSBarry Smith }; 28*5c6c1daeSBarry Smith 29*5c6c1daeSBarry Smith #define CHUNKSIZE 100 30*5c6c1daeSBarry Smith 31*5c6c1daeSBarry Smith #undef __FUNCT__ 32*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGCreate" 33*5c6c1daeSBarry Smith /*@C 34*5c6c1daeSBarry Smith PetscDrawHGCreate - Creates a histogram data structure. 35*5c6c1daeSBarry Smith 36*5c6c1daeSBarry Smith Collective over PetscDraw 37*5c6c1daeSBarry Smith 38*5c6c1daeSBarry Smith Input Parameters: 39*5c6c1daeSBarry Smith + draw - The window where the graph will be made 40*5c6c1daeSBarry Smith - bins - The number of bins to use 41*5c6c1daeSBarry Smith 42*5c6c1daeSBarry Smith Output Parameters: 43*5c6c1daeSBarry Smith . hist - The histogram context 44*5c6c1daeSBarry Smith 45*5c6c1daeSBarry Smith Level: intermediate 46*5c6c1daeSBarry Smith 47*5c6c1daeSBarry Smith Concepts: histogram^creating 48*5c6c1daeSBarry Smith 49*5c6c1daeSBarry Smith .seealso: PetscDrawHGDestroy() 50*5c6c1daeSBarry Smith 51*5c6c1daeSBarry Smith @*/ 52*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGCreate(PetscDraw draw, int bins, PetscDrawHG *hist) { 53*5c6c1daeSBarry Smith PetscDrawHG h; 54*5c6c1daeSBarry Smith MPI_Comm comm; 55*5c6c1daeSBarry Smith PetscBool isnull; 56*5c6c1daeSBarry Smith PetscErrorCode ierr; 57*5c6c1daeSBarry Smith 58*5c6c1daeSBarry Smith PetscFunctionBegin; 59*5c6c1daeSBarry Smith PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID,1); 60*5c6c1daeSBarry Smith PetscValidPointer(hist,3); 61*5c6c1daeSBarry Smith ierr = PetscObjectGetComm((PetscObject) draw, &comm);CHKERRQ(ierr); 62*5c6c1daeSBarry Smith ierr = PetscHeaderCreate(h, _p_PetscDrawHG, int, PETSC_DRAWHG_CLASSID, 0, "PetscDrawHG", "Histogram", "Draw", comm, PetscDrawHGDestroy, PETSC_NULL);CHKERRQ(ierr); 63*5c6c1daeSBarry Smith h->view = PETSC_NULL; 64*5c6c1daeSBarry Smith h->destroy = PETSC_NULL; 65*5c6c1daeSBarry Smith h->win = draw; 66*5c6c1daeSBarry Smith ierr = PetscObjectReference((PetscObject) draw);CHKERRQ(ierr); 67*5c6c1daeSBarry Smith h->color = PETSC_DRAW_GREEN; 68*5c6c1daeSBarry Smith h->xmin = PETSC_MAX_REAL; 69*5c6c1daeSBarry Smith h->xmax = PETSC_MIN_REAL; 70*5c6c1daeSBarry Smith h->ymin = 0.; 71*5c6c1daeSBarry Smith h->ymax = 1.; 72*5c6c1daeSBarry Smith h->numBins = bins; 73*5c6c1daeSBarry Smith h->maxBins = bins; 74*5c6c1daeSBarry Smith ierr = PetscMalloc(h->maxBins * sizeof(PetscReal), &h->bins);CHKERRQ(ierr); 75*5c6c1daeSBarry Smith h->numValues = 0; 76*5c6c1daeSBarry Smith h->maxValues = CHUNKSIZE; 77*5c6c1daeSBarry Smith h->calcStats = PETSC_FALSE; 78*5c6c1daeSBarry Smith h->integerBins = PETSC_FALSE; 79*5c6c1daeSBarry Smith ierr = PetscMalloc(h->maxValues * sizeof(PetscReal), &h->values);CHKERRQ(ierr); 80*5c6c1daeSBarry Smith ierr = PetscLogObjectMemory(h, (h->maxBins + h->maxValues)*sizeof(PetscReal));CHKERRQ(ierr); 81*5c6c1daeSBarry Smith ierr = PetscObjectTypeCompare((PetscObject) draw, PETSC_DRAW_NULL, &isnull);CHKERRQ(ierr); 82*5c6c1daeSBarry Smith if (!isnull) { 83*5c6c1daeSBarry Smith ierr = PetscDrawAxisCreate(draw, &h->axis);CHKERRQ(ierr); 84*5c6c1daeSBarry Smith ierr = PetscLogObjectParent(h, h->axis);CHKERRQ(ierr); 85*5c6c1daeSBarry Smith } else { 86*5c6c1daeSBarry Smith h->axis = PETSC_NULL; 87*5c6c1daeSBarry Smith } 88*5c6c1daeSBarry Smith *hist = h; 89*5c6c1daeSBarry Smith PetscFunctionReturn(0); 90*5c6c1daeSBarry Smith } 91*5c6c1daeSBarry Smith 92*5c6c1daeSBarry Smith #undef __FUNCT__ 93*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGSetNumberBins" 94*5c6c1daeSBarry Smith /*@ 95*5c6c1daeSBarry Smith PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn. 96*5c6c1daeSBarry Smith 97*5c6c1daeSBarry Smith Not Collective (ignored except on processor 0 of PetscDrawHG) 98*5c6c1daeSBarry Smith 99*5c6c1daeSBarry Smith Input Parameter: 100*5c6c1daeSBarry Smith + hist - The histogram context. 101*5c6c1daeSBarry Smith - dim - The number of curves. 102*5c6c1daeSBarry Smith 103*5c6c1daeSBarry Smith Level: intermediate 104*5c6c1daeSBarry Smith 105*5c6c1daeSBarry Smith Concepts: histogram^setting number of bins 106*5c6c1daeSBarry Smith 107*5c6c1daeSBarry Smith @*/ 108*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins) 109*5c6c1daeSBarry Smith { 110*5c6c1daeSBarry Smith PetscErrorCode ierr; 111*5c6c1daeSBarry Smith 112*5c6c1daeSBarry Smith PetscFunctionBegin; 113*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 114*5c6c1daeSBarry Smith if (hist->maxBins < bins) { 115*5c6c1daeSBarry Smith ierr = PetscFree(hist->bins);CHKERRQ(ierr); 116*5c6c1daeSBarry Smith ierr = PetscMalloc(bins * sizeof(PetscReal), &hist->bins);CHKERRQ(ierr); 117*5c6c1daeSBarry Smith ierr = PetscLogObjectMemory(hist, (bins - hist->maxBins) * sizeof(PetscReal));CHKERRQ(ierr); 118*5c6c1daeSBarry Smith hist->maxBins = bins; 119*5c6c1daeSBarry Smith } 120*5c6c1daeSBarry Smith hist->numBins = bins; 121*5c6c1daeSBarry Smith PetscFunctionReturn(0); 122*5c6c1daeSBarry Smith } 123*5c6c1daeSBarry Smith 124*5c6c1daeSBarry Smith #undef __FUNCT__ 125*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGReset" 126*5c6c1daeSBarry Smith /*@ 127*5c6c1daeSBarry Smith PetscDrawHGReset - Clears histogram to allow for reuse with new data. 128*5c6c1daeSBarry Smith 129*5c6c1daeSBarry Smith Not Collective (ignored except on processor 0 of PetscDrawHG) 130*5c6c1daeSBarry Smith 131*5c6c1daeSBarry Smith Input Parameter: 132*5c6c1daeSBarry Smith . hist - The histogram context. 133*5c6c1daeSBarry Smith 134*5c6c1daeSBarry Smith Level: intermediate 135*5c6c1daeSBarry Smith 136*5c6c1daeSBarry Smith Concepts: histogram^resetting 137*5c6c1daeSBarry Smith @*/ 138*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGReset(PetscDrawHG hist) 139*5c6c1daeSBarry Smith { 140*5c6c1daeSBarry Smith PetscFunctionBegin; 141*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 142*5c6c1daeSBarry Smith hist->xmin = PETSC_MAX_REAL; 143*5c6c1daeSBarry Smith hist->xmax = PETSC_MIN_REAL; 144*5c6c1daeSBarry Smith hist->ymin = 0.0; 145*5c6c1daeSBarry Smith hist->ymax = 0.0; 146*5c6c1daeSBarry Smith hist->numValues = 0; 147*5c6c1daeSBarry Smith PetscFunctionReturn(0); 148*5c6c1daeSBarry Smith } 149*5c6c1daeSBarry Smith 150*5c6c1daeSBarry Smith #undef __FUNCT__ 151*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGDestroy" 152*5c6c1daeSBarry Smith /*@C 153*5c6c1daeSBarry Smith PetscDrawHGDestroy - Frees all space taken up by histogram data structure. 154*5c6c1daeSBarry Smith 155*5c6c1daeSBarry Smith Collective over PetscDrawHG 156*5c6c1daeSBarry Smith 157*5c6c1daeSBarry Smith Input Parameter: 158*5c6c1daeSBarry Smith . hist - The histogram context 159*5c6c1daeSBarry Smith 160*5c6c1daeSBarry Smith Level: intermediate 161*5c6c1daeSBarry Smith 162*5c6c1daeSBarry Smith .seealso: PetscDrawHGCreate() 163*5c6c1daeSBarry Smith @*/ 164*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGDestroy(PetscDrawHG *hist) 165*5c6c1daeSBarry Smith { 166*5c6c1daeSBarry Smith PetscErrorCode ierr; 167*5c6c1daeSBarry Smith 168*5c6c1daeSBarry Smith PetscFunctionBegin; 169*5c6c1daeSBarry Smith if (!*hist) PetscFunctionReturn(0); 170*5c6c1daeSBarry Smith PetscValidHeader(*hist,1); 171*5c6c1daeSBarry Smith 172*5c6c1daeSBarry Smith if (--((PetscObject)(*hist))->refct > 0) PetscFunctionReturn(0); 173*5c6c1daeSBarry Smith ierr = PetscDrawAxisDestroy(&(*hist)->axis);CHKERRQ(ierr); 174*5c6c1daeSBarry Smith ierr = PetscDrawDestroy(&(*hist)->win);CHKERRQ(ierr); 175*5c6c1daeSBarry Smith ierr = PetscFree((*hist)->bins);CHKERRQ(ierr); 176*5c6c1daeSBarry Smith ierr = PetscFree((*hist)->values);CHKERRQ(ierr); 177*5c6c1daeSBarry Smith ierr = PetscHeaderDestroy(hist);CHKERRQ(ierr); 178*5c6c1daeSBarry Smith PetscFunctionReturn(0); 179*5c6c1daeSBarry Smith } 180*5c6c1daeSBarry Smith 181*5c6c1daeSBarry Smith #undef __FUNCT__ 182*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGAddValue" 183*5c6c1daeSBarry Smith /*@ 184*5c6c1daeSBarry Smith PetscDrawHGAddValue - Adds another value to the histogram. 185*5c6c1daeSBarry Smith 186*5c6c1daeSBarry Smith Not Collective (ignored except on processor 0 of PetscDrawHG) 187*5c6c1daeSBarry Smith 188*5c6c1daeSBarry Smith Input Parameters: 189*5c6c1daeSBarry Smith + hist - The histogram 190*5c6c1daeSBarry Smith - value - The value 191*5c6c1daeSBarry Smith 192*5c6c1daeSBarry Smith Level: intermediate 193*5c6c1daeSBarry Smith 194*5c6c1daeSBarry Smith Concepts: histogram^adding values 195*5c6c1daeSBarry Smith 196*5c6c1daeSBarry Smith .seealso: PetscDrawHGAddValues() 197*5c6c1daeSBarry Smith @*/ 198*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value) 199*5c6c1daeSBarry Smith { 200*5c6c1daeSBarry Smith PetscFunctionBegin; 201*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 202*5c6c1daeSBarry Smith /* Allocate more memory if necessary */ 203*5c6c1daeSBarry Smith if (hist->numValues >= hist->maxValues) { 204*5c6c1daeSBarry Smith PetscReal *tmp; 205*5c6c1daeSBarry Smith PetscErrorCode ierr; 206*5c6c1daeSBarry Smith 207*5c6c1daeSBarry Smith ierr = PetscMalloc((hist->maxValues+CHUNKSIZE) * sizeof(PetscReal), &tmp);CHKERRQ(ierr); 208*5c6c1daeSBarry Smith ierr = PetscLogObjectMemory(hist, CHUNKSIZE * sizeof(PetscReal));CHKERRQ(ierr); 209*5c6c1daeSBarry Smith ierr = PetscMemcpy(tmp, hist->values, hist->maxValues * sizeof(PetscReal));CHKERRQ(ierr); 210*5c6c1daeSBarry Smith ierr = PetscFree(hist->values);CHKERRQ(ierr); 211*5c6c1daeSBarry Smith hist->values = tmp; 212*5c6c1daeSBarry Smith hist->maxValues += CHUNKSIZE; 213*5c6c1daeSBarry Smith } 214*5c6c1daeSBarry Smith /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the 215*5c6c1daeSBarry Smith stated convention of using half-open intervals (always the way to go) */ 216*5c6c1daeSBarry Smith if (!hist->numValues) { 217*5c6c1daeSBarry Smith hist->xmin = value; 218*5c6c1daeSBarry Smith hist->xmax = value; 219*5c6c1daeSBarry Smith #if 1 220*5c6c1daeSBarry Smith } else { 221*5c6c1daeSBarry Smith /* Update limits */ 222*5c6c1daeSBarry Smith if (value > hist->xmax) 223*5c6c1daeSBarry Smith hist->xmax = value; 224*5c6c1daeSBarry Smith if (value < hist->xmin) 225*5c6c1daeSBarry Smith hist->xmin = value; 226*5c6c1daeSBarry Smith #else 227*5c6c1daeSBarry Smith } else if (hist->numValues == 1) { 228*5c6c1daeSBarry Smith /* Update limits -- We need to overshoot the largest value somewhat */ 229*5c6c1daeSBarry Smith if (value > hist->xmax) { 230*5c6c1daeSBarry Smith hist->xmax = value + 0.001*(value - hist->xmin)/hist->numBins; 231*5c6c1daeSBarry Smith } 232*5c6c1daeSBarry Smith if (value < hist->xmin) { 233*5c6c1daeSBarry Smith hist->xmin = value; 234*5c6c1daeSBarry Smith hist->xmax = hist->xmax + 0.001*(hist->xmax - hist->xmin)/hist->numBins; 235*5c6c1daeSBarry Smith } 236*5c6c1daeSBarry Smith } else { 237*5c6c1daeSBarry Smith /* Update limits -- We need to overshoot the largest value somewhat */ 238*5c6c1daeSBarry Smith if (value > hist->xmax) { 239*5c6c1daeSBarry Smith hist->xmax = value + 0.001*(hist->xmax - hist->xmin)/hist->numBins; 240*5c6c1daeSBarry Smith } 241*5c6c1daeSBarry Smith if (value < hist->xmin) { 242*5c6c1daeSBarry Smith hist->xmin = value; 243*5c6c1daeSBarry Smith } 244*5c6c1daeSBarry Smith #endif 245*5c6c1daeSBarry Smith } 246*5c6c1daeSBarry Smith 247*5c6c1daeSBarry Smith hist->values[hist->numValues++] = value; 248*5c6c1daeSBarry Smith PetscFunctionReturn(0); 249*5c6c1daeSBarry Smith } 250*5c6c1daeSBarry Smith 251*5c6c1daeSBarry Smith #undef __FUNCT__ 252*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGDraw" 253*5c6c1daeSBarry Smith /*@ 254*5c6c1daeSBarry Smith PetscDrawHGDraw - Redraws a histogram. 255*5c6c1daeSBarry Smith 256*5c6c1daeSBarry Smith Not Collective (ignored except on processor 0 of PetscDrawHG) 257*5c6c1daeSBarry Smith 258*5c6c1daeSBarry Smith Input Parameter: 259*5c6c1daeSBarry Smith . hist - The histogram context 260*5c6c1daeSBarry Smith 261*5c6c1daeSBarry Smith Level: intermediate 262*5c6c1daeSBarry Smith 263*5c6c1daeSBarry Smith @*/ 264*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGDraw(PetscDrawHG hist) 265*5c6c1daeSBarry Smith { 266*5c6c1daeSBarry Smith PetscDraw draw = hist->win; 267*5c6c1daeSBarry Smith PetscBool isnull; 268*5c6c1daeSBarry Smith PetscReal xmin,xmax,ymin,ymax,*bins,*values,binSize,binLeft,binRight,maxHeight,mean,var; 269*5c6c1daeSBarry Smith char title[256]; 270*5c6c1daeSBarry Smith char xlabel[256]; 271*5c6c1daeSBarry Smith PetscInt numBins,numBinsOld,numValues,initSize,i,p,bcolor,color; 272*5c6c1daeSBarry Smith PetscErrorCode ierr; 273*5c6c1daeSBarry Smith 274*5c6c1daeSBarry Smith PetscFunctionBegin; 275*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 276*5c6c1daeSBarry Smith ierr = PetscObjectTypeCompare((PetscObject) draw, PETSC_DRAW_NULL, &isnull);CHKERRQ(ierr); 277*5c6c1daeSBarry Smith if (isnull) PetscFunctionReturn(0); 278*5c6c1daeSBarry Smith if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0); 279*5c6c1daeSBarry Smith if (hist->numValues < 1) PetscFunctionReturn(0); 280*5c6c1daeSBarry Smith 281*5c6c1daeSBarry Smith #if 0 282*5c6c1daeSBarry Smith ierr = MPI_Comm_rank(((PetscObject)hist)->comm,&rank);CHKERRQ(ierr); 283*5c6c1daeSBarry Smith if (rank) PetscFunctionReturn(0); 284*5c6c1daeSBarry Smith #endif 285*5c6c1daeSBarry Smith 286*5c6c1daeSBarry Smith color = hist->color; 287*5c6c1daeSBarry Smith if (color == PETSC_DRAW_ROTATE) {bcolor = 2;} else {bcolor = color;} 288*5c6c1daeSBarry Smith xmin = hist->xmin; 289*5c6c1daeSBarry Smith xmax = hist->xmax; 290*5c6c1daeSBarry Smith ymin = hist->ymin; 291*5c6c1daeSBarry Smith ymax = hist->ymax; 292*5c6c1daeSBarry Smith numValues = hist->numValues; 293*5c6c1daeSBarry Smith values = hist->values; 294*5c6c1daeSBarry Smith mean = 0.0; 295*5c6c1daeSBarry Smith var = 0.0; 296*5c6c1daeSBarry Smith 297*5c6c1daeSBarry Smith ierr = PetscDrawClear(draw);CHKERRQ(ierr); 298*5c6c1daeSBarry Smith if (xmin == xmax) { 299*5c6c1daeSBarry Smith /* Calculate number of points in each bin */ 300*5c6c1daeSBarry Smith bins = hist->bins; 301*5c6c1daeSBarry Smith bins[0] = 0.; 302*5c6c1daeSBarry Smith for (p = 0; p < numValues; p++) { 303*5c6c1daeSBarry Smith if (values[p] == xmin) bins[0]++; 304*5c6c1daeSBarry Smith mean += values[p]; 305*5c6c1daeSBarry Smith var += values[p]*values[p]; 306*5c6c1daeSBarry Smith } 307*5c6c1daeSBarry Smith maxHeight = bins[0]; 308*5c6c1daeSBarry Smith if (maxHeight > ymax) ymax = hist->ymax = maxHeight; 309*5c6c1daeSBarry Smith xmax = xmin + 1; 310*5c6c1daeSBarry Smith ierr = PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);CHKERRQ(ierr); 311*5c6c1daeSBarry Smith if (hist->calcStats) { 312*5c6c1daeSBarry Smith mean /= numValues; 313*5c6c1daeSBarry Smith if (numValues > 1) { 314*5c6c1daeSBarry Smith var = (var - numValues*mean*mean) / (numValues-1); 315*5c6c1daeSBarry Smith } else { 316*5c6c1daeSBarry Smith var = 0.0; 317*5c6c1daeSBarry Smith } 318*5c6c1daeSBarry Smith ierr = PetscSNPrintf(title, 256, "Mean: %g Var: %g", (double)mean, (double)var);CHKERRQ(ierr); 319*5c6c1daeSBarry Smith ierr = PetscSNPrintf(xlabel,256, "Total: %D", numValues);CHKERRQ(ierr); 320*5c6c1daeSBarry Smith ierr = PetscDrawAxisSetLabels(hist->axis, title, xlabel, PETSC_NULL);CHKERRQ(ierr); 321*5c6c1daeSBarry Smith } 322*5c6c1daeSBarry Smith ierr = PetscDrawAxisDraw(hist->axis);CHKERRQ(ierr); 323*5c6c1daeSBarry Smith /* Draw bins */ 324*5c6c1daeSBarry Smith binLeft = xmin; 325*5c6c1daeSBarry Smith binRight = xmax; 326*5c6c1daeSBarry Smith ierr = PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[0],bcolor,bcolor,bcolor,bcolor);CHKERRQ(ierr); 327*5c6c1daeSBarry Smith if (color == PETSC_DRAW_ROTATE && bins[0] != 0.0) bcolor++; if (bcolor > 31) bcolor = 2; 328*5c6c1daeSBarry Smith ierr = PetscDrawLine(draw,binLeft,ymin,binLeft,bins[0],PETSC_DRAW_BLACK);CHKERRQ(ierr); 329*5c6c1daeSBarry Smith ierr = PetscDrawLine(draw,binRight,ymin,binRight,bins[0],PETSC_DRAW_BLACK);CHKERRQ(ierr); 330*5c6c1daeSBarry Smith ierr = PetscDrawLine(draw,binLeft,bins[0],binRight,bins[0],PETSC_DRAW_BLACK);CHKERRQ(ierr); 331*5c6c1daeSBarry Smith } else { 332*5c6c1daeSBarry Smith numBins = hist->numBins; 333*5c6c1daeSBarry Smith numBinsOld = hist->numBins; 334*5c6c1daeSBarry Smith if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) { 335*5c6c1daeSBarry Smith initSize = (int) ((int) xmax - xmin)/numBins; 336*5c6c1daeSBarry Smith while (initSize*numBins != (int) xmax - xmin) { 337*5c6c1daeSBarry Smith initSize = PetscMax(initSize - 1, 1); 338*5c6c1daeSBarry Smith numBins = (int) ((int) xmax - xmin)/initSize; 339*5c6c1daeSBarry Smith ierr = PetscDrawHGSetNumberBins(hist, numBins);CHKERRQ(ierr); 340*5c6c1daeSBarry Smith } 341*5c6c1daeSBarry Smith } 342*5c6c1daeSBarry Smith binSize = (xmax - xmin)/numBins; 343*5c6c1daeSBarry Smith bins = hist->bins; 344*5c6c1daeSBarry Smith 345*5c6c1daeSBarry Smith ierr = PetscMemzero(bins, numBins * sizeof(PetscReal));CHKERRQ(ierr); 346*5c6c1daeSBarry Smith maxHeight = 0.0; 347*5c6c1daeSBarry Smith for (i = 0; i < numBins; i++) { 348*5c6c1daeSBarry Smith binLeft = xmin + binSize*i; 349*5c6c1daeSBarry Smith binRight = xmin + binSize*(i+1); 350*5c6c1daeSBarry Smith for (p = 0; p < numValues; p++) { 351*5c6c1daeSBarry Smith if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++; 352*5c6c1daeSBarry Smith /* Handle last bin separately */ 353*5c6c1daeSBarry Smith if ((i == numBins-1) && (values[p] == binRight)) bins[i]++; 354*5c6c1daeSBarry Smith if (!i) { 355*5c6c1daeSBarry Smith mean += values[p]; 356*5c6c1daeSBarry Smith var += values[p]*values[p]; 357*5c6c1daeSBarry Smith } 358*5c6c1daeSBarry Smith } 359*5c6c1daeSBarry Smith maxHeight = PetscMax(maxHeight, bins[i]); 360*5c6c1daeSBarry Smith } 361*5c6c1daeSBarry Smith if (maxHeight > ymax) ymax = hist->ymax = maxHeight; 362*5c6c1daeSBarry Smith 363*5c6c1daeSBarry Smith ierr = PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax);CHKERRQ(ierr); 364*5c6c1daeSBarry Smith if (hist->calcStats) { 365*5c6c1daeSBarry Smith mean /= numValues; 366*5c6c1daeSBarry Smith if (numValues > 1) { 367*5c6c1daeSBarry Smith var = (var - numValues*mean*mean) / (numValues-1); 368*5c6c1daeSBarry Smith } else { 369*5c6c1daeSBarry Smith var = 0.0; 370*5c6c1daeSBarry Smith } 371*5c6c1daeSBarry Smith ierr = PetscSNPrintf(title, 256,"Mean: %g Var: %g", (double)mean, (double)var);CHKERRQ(ierr); 372*5c6c1daeSBarry Smith ierr = PetscSNPrintf(xlabel,256, "Total: %D", numValues);CHKERRQ(ierr); 373*5c6c1daeSBarry Smith ierr = PetscDrawAxisSetLabels(hist->axis, title, xlabel, PETSC_NULL);CHKERRQ(ierr); 374*5c6c1daeSBarry Smith } 375*5c6c1daeSBarry Smith ierr = PetscDrawAxisDraw(hist->axis);CHKERRQ(ierr); 376*5c6c1daeSBarry Smith /* Draw bins */ 377*5c6c1daeSBarry Smith for (i = 0; i < numBins; i++) { 378*5c6c1daeSBarry Smith binLeft = xmin + binSize*i; 379*5c6c1daeSBarry Smith binRight = xmin + binSize*(i+1); 380*5c6c1daeSBarry Smith ierr = PetscDrawRectangle(draw,binLeft,ymin,binRight,bins[i],bcolor,bcolor,bcolor,bcolor);CHKERRQ(ierr); 381*5c6c1daeSBarry Smith if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++; if (bcolor > 31) bcolor = 2; 382*5c6c1daeSBarry Smith ierr = PetscDrawLine(draw,binLeft,ymin,binLeft,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 383*5c6c1daeSBarry Smith ierr = PetscDrawLine(draw,binRight,ymin,binRight,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 384*5c6c1daeSBarry Smith ierr = PetscDrawLine(draw,binLeft,bins[i],binRight,bins[i],PETSC_DRAW_BLACK);CHKERRQ(ierr); 385*5c6c1daeSBarry Smith } 386*5c6c1daeSBarry Smith ierr = PetscDrawHGSetNumberBins(hist, numBinsOld);CHKERRQ(ierr); 387*5c6c1daeSBarry Smith } 388*5c6c1daeSBarry Smith ierr = PetscDrawSynchronizedFlush(draw);CHKERRQ(ierr); 389*5c6c1daeSBarry Smith ierr = PetscDrawPause(draw);CHKERRQ(ierr); 390*5c6c1daeSBarry Smith PetscFunctionReturn(0); 391*5c6c1daeSBarry Smith } 392*5c6c1daeSBarry Smith 393*5c6c1daeSBarry Smith #undef __FUNCT__ 394*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGPrint" 395*5c6c1daeSBarry Smith /*@ 396*5c6c1daeSBarry Smith PetscDrawHGPrint - Prints the histogram information. 397*5c6c1daeSBarry Smith 398*5c6c1daeSBarry Smith Not collective 399*5c6c1daeSBarry Smith 400*5c6c1daeSBarry Smith Input Parameter: 401*5c6c1daeSBarry Smith . hist - The histogram context 402*5c6c1daeSBarry Smith 403*5c6c1daeSBarry Smith Level: beginner 404*5c6c1daeSBarry Smith 405*5c6c1daeSBarry Smith .keywords: draw, histogram 406*5c6c1daeSBarry Smith @*/ 407*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGPrint(PetscDrawHG hist) 408*5c6c1daeSBarry Smith { 409*5c6c1daeSBarry Smith PetscReal xmax,xmin,*bins,*values,binSize,binLeft,binRight,mean,var; 410*5c6c1daeSBarry Smith PetscErrorCode ierr; 411*5c6c1daeSBarry Smith PetscInt numBins,numBinsOld,numValues,initSize,i,p; 412*5c6c1daeSBarry Smith 413*5c6c1daeSBarry Smith PetscFunctionBegin; 414*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 415*5c6c1daeSBarry Smith if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0); 416*5c6c1daeSBarry Smith if (hist->numValues < 1) PetscFunctionReturn(0); 417*5c6c1daeSBarry Smith 418*5c6c1daeSBarry Smith xmax = hist->xmax; 419*5c6c1daeSBarry Smith xmin = hist->xmin; 420*5c6c1daeSBarry Smith numValues = hist->numValues; 421*5c6c1daeSBarry Smith values = hist->values; 422*5c6c1daeSBarry Smith mean = 0.0; 423*5c6c1daeSBarry Smith var = 0.0; 424*5c6c1daeSBarry Smith if (xmax == xmin) { 425*5c6c1daeSBarry Smith /* Calculate number of points in the bin */ 426*5c6c1daeSBarry Smith bins = hist->bins; 427*5c6c1daeSBarry Smith bins[0] = 0.; 428*5c6c1daeSBarry Smith for (p = 0; p < numValues; p++) { 429*5c6c1daeSBarry Smith if (values[p] == xmin) bins[0]++; 430*5c6c1daeSBarry Smith mean += values[p]; 431*5c6c1daeSBarry Smith var += values[p]*values[p]; 432*5c6c1daeSBarry Smith } 433*5c6c1daeSBarry Smith /* Draw bins */ 434*5c6c1daeSBarry Smith PetscPrintf(((PetscObject)hist)->comm, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, xmin, xmax, bins[0]); 435*5c6c1daeSBarry Smith } else { 436*5c6c1daeSBarry Smith numBins = hist->numBins; 437*5c6c1daeSBarry Smith numBinsOld = hist->numBins; 438*5c6c1daeSBarry Smith if (hist->integerBins && (((int) xmax - xmin) + 1.0e-05 > xmax - xmin)) { 439*5c6c1daeSBarry Smith initSize = (int) ((int) xmax - xmin)/numBins; 440*5c6c1daeSBarry Smith while (initSize*numBins != (int) xmax - xmin) { 441*5c6c1daeSBarry Smith initSize = PetscMax(initSize - 1, 1); 442*5c6c1daeSBarry Smith numBins = (int) ((int) xmax - xmin)/initSize; 443*5c6c1daeSBarry Smith ierr = PetscDrawHGSetNumberBins(hist, numBins);CHKERRQ(ierr); 444*5c6c1daeSBarry Smith } 445*5c6c1daeSBarry Smith } 446*5c6c1daeSBarry Smith binSize = (xmax - xmin)/numBins; 447*5c6c1daeSBarry Smith bins = hist->bins; 448*5c6c1daeSBarry Smith 449*5c6c1daeSBarry Smith /* Calculate number of points in each bin */ 450*5c6c1daeSBarry Smith ierr = PetscMemzero(bins, numBins * sizeof(PetscReal));CHKERRQ(ierr); 451*5c6c1daeSBarry Smith for (i = 0; i < numBins; i++) { 452*5c6c1daeSBarry Smith binLeft = xmin + binSize*i; 453*5c6c1daeSBarry Smith binRight = xmin + binSize*(i+1); 454*5c6c1daeSBarry Smith for (p = 0; p < numValues; p++) { 455*5c6c1daeSBarry Smith if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++; 456*5c6c1daeSBarry Smith /* Handle last bin separately */ 457*5c6c1daeSBarry Smith if ((i == numBins-1) && (values[p] == binRight)) bins[i]++; 458*5c6c1daeSBarry Smith if (!i) { 459*5c6c1daeSBarry Smith mean += values[p]; 460*5c6c1daeSBarry Smith var += values[p]*values[p]; 461*5c6c1daeSBarry Smith } 462*5c6c1daeSBarry Smith } 463*5c6c1daeSBarry Smith } 464*5c6c1daeSBarry Smith /* Draw bins */ 465*5c6c1daeSBarry Smith for (i = 0; i < numBins; i++) { 466*5c6c1daeSBarry Smith binLeft = xmin + binSize*i; 467*5c6c1daeSBarry Smith binRight = xmin + binSize*(i+1); 468*5c6c1daeSBarry Smith PetscPrintf(((PetscObject)hist)->comm, "Bin %2d (%6.2g - %6.2g): %.0g\n", i, binLeft, binRight, bins[i]); 469*5c6c1daeSBarry Smith } 470*5c6c1daeSBarry Smith ierr = PetscDrawHGSetNumberBins(hist, numBinsOld);CHKERRQ(ierr); 471*5c6c1daeSBarry Smith } 472*5c6c1daeSBarry Smith 473*5c6c1daeSBarry Smith if (hist->calcStats) { 474*5c6c1daeSBarry Smith mean /= numValues; 475*5c6c1daeSBarry Smith if (numValues > 1) { 476*5c6c1daeSBarry Smith var = (var - numValues*mean*mean) / (numValues-1); 477*5c6c1daeSBarry Smith } else { 478*5c6c1daeSBarry Smith var = 0.0; 479*5c6c1daeSBarry Smith } 480*5c6c1daeSBarry Smith PetscPrintf(((PetscObject)hist)->comm, "Mean: %G Var: %G\n", mean, var); 481*5c6c1daeSBarry Smith PetscPrintf(((PetscObject)hist)->comm, "Total: %d\n", numValues); 482*5c6c1daeSBarry Smith } 483*5c6c1daeSBarry Smith PetscFunctionReturn(0); 484*5c6c1daeSBarry Smith } 485*5c6c1daeSBarry Smith 486*5c6c1daeSBarry Smith #undef __FUNCT__ 487*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGSetColor" 488*5c6c1daeSBarry Smith /*@ 489*5c6c1daeSBarry Smith PetscDrawHGSetColor - Sets the color the bars will be drawn with. 490*5c6c1daeSBarry Smith 491*5c6c1daeSBarry Smith Not Collective (ignored except on processor 0 of PetscDrawHG) 492*5c6c1daeSBarry Smith 493*5c6c1daeSBarry Smith Input Parameters: 494*5c6c1daeSBarry Smith + hist - The histogram context 495*5c6c1daeSBarry Smith - color - one of the colors defined in petscdraw.h or PETSC_DRAW_ROTATE to make each bar a 496*5c6c1daeSBarry Smith different color 497*5c6c1daeSBarry Smith 498*5c6c1daeSBarry Smith Level: intermediate 499*5c6c1daeSBarry Smith 500*5c6c1daeSBarry Smith @*/ 501*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGSetColor(PetscDrawHG hist, int color) 502*5c6c1daeSBarry Smith { 503*5c6c1daeSBarry Smith PetscFunctionBegin; 504*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 505*5c6c1daeSBarry Smith hist->color = color; 506*5c6c1daeSBarry Smith PetscFunctionReturn(0); 507*5c6c1daeSBarry Smith } 508*5c6c1daeSBarry Smith 509*5c6c1daeSBarry Smith #undef __FUNCT__ 510*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGSetLimits" 511*5c6c1daeSBarry Smith /*@ 512*5c6c1daeSBarry Smith PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more 513*5c6c1daeSBarry Smith points are added after this call, the limits will be adjusted to 514*5c6c1daeSBarry Smith include those additional points. 515*5c6c1daeSBarry Smith 516*5c6c1daeSBarry Smith Not Collective (ignored except on processor 0 of PetscDrawHG) 517*5c6c1daeSBarry Smith 518*5c6c1daeSBarry Smith Input Parameters: 519*5c6c1daeSBarry Smith + hist - The histogram context 520*5c6c1daeSBarry Smith - x_min,x_max,y_min,y_max - The limits 521*5c6c1daeSBarry Smith 522*5c6c1daeSBarry Smith Level: intermediate 523*5c6c1daeSBarry Smith 524*5c6c1daeSBarry Smith Concepts: histogram^setting axis 525*5c6c1daeSBarry Smith @*/ 526*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max) 527*5c6c1daeSBarry Smith { 528*5c6c1daeSBarry Smith PetscFunctionBegin; 529*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 530*5c6c1daeSBarry Smith hist->xmin = x_min; 531*5c6c1daeSBarry Smith hist->xmax = x_max; 532*5c6c1daeSBarry Smith hist->ymin = y_min; 533*5c6c1daeSBarry Smith hist->ymax = y_max; 534*5c6c1daeSBarry Smith PetscFunctionReturn(0); 535*5c6c1daeSBarry Smith } 536*5c6c1daeSBarry Smith 537*5c6c1daeSBarry Smith #undef __FUNCT__ 538*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGCalcStats" 539*5c6c1daeSBarry Smith /*@ 540*5c6c1daeSBarry Smith PetscDrawHGCalcStats - Turns on calculation of descriptive statistics 541*5c6c1daeSBarry Smith 542*5c6c1daeSBarry Smith Not collective 543*5c6c1daeSBarry Smith 544*5c6c1daeSBarry Smith Input Parameters: 545*5c6c1daeSBarry Smith + hist - The histogram context 546*5c6c1daeSBarry Smith - calc - Flag for calculation 547*5c6c1daeSBarry Smith 548*5c6c1daeSBarry Smith Level: intermediate 549*5c6c1daeSBarry Smith 550*5c6c1daeSBarry Smith .keywords: draw, histogram, statistics 551*5c6c1daeSBarry Smith 552*5c6c1daeSBarry Smith @*/ 553*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc) 554*5c6c1daeSBarry Smith { 555*5c6c1daeSBarry Smith PetscFunctionBegin; 556*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 557*5c6c1daeSBarry Smith hist->calcStats = calc; 558*5c6c1daeSBarry Smith PetscFunctionReturn(0); 559*5c6c1daeSBarry Smith } 560*5c6c1daeSBarry Smith 561*5c6c1daeSBarry Smith #undef __FUNCT__ 562*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGIntegerBins" 563*5c6c1daeSBarry Smith /*@ 564*5c6c1daeSBarry Smith PetscDrawHGIntegerBins - Turns on integer width bins 565*5c6c1daeSBarry Smith 566*5c6c1daeSBarry Smith Not collective 567*5c6c1daeSBarry Smith 568*5c6c1daeSBarry Smith Input Parameters: 569*5c6c1daeSBarry Smith + hist - The histogram context 570*5c6c1daeSBarry Smith - ints - Flag for integer width bins 571*5c6c1daeSBarry Smith 572*5c6c1daeSBarry Smith Level: intermediate 573*5c6c1daeSBarry Smith 574*5c6c1daeSBarry Smith .keywords: draw, histogram, statistics 575*5c6c1daeSBarry Smith @*/ 576*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints) 577*5c6c1daeSBarry Smith { 578*5c6c1daeSBarry Smith PetscFunctionBegin; 579*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 580*5c6c1daeSBarry Smith hist->integerBins = ints; 581*5c6c1daeSBarry Smith PetscFunctionReturn(0); 582*5c6c1daeSBarry Smith } 583*5c6c1daeSBarry Smith 584*5c6c1daeSBarry Smith #undef __FUNCT__ 585*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGGetAxis" 586*5c6c1daeSBarry Smith /*@C 587*5c6c1daeSBarry Smith PetscDrawHGGetAxis - Gets the axis context associated with a histogram. 588*5c6c1daeSBarry Smith This is useful if one wants to change some axis property, such as 589*5c6c1daeSBarry Smith labels, color, etc. The axis context should not be destroyed by the 590*5c6c1daeSBarry Smith application code. 591*5c6c1daeSBarry Smith 592*5c6c1daeSBarry Smith Not Collective (ignored except on processor 0 of PetscDrawHG) 593*5c6c1daeSBarry Smith 594*5c6c1daeSBarry Smith Input Parameter: 595*5c6c1daeSBarry Smith . hist - The histogram context 596*5c6c1daeSBarry Smith 597*5c6c1daeSBarry Smith Output Parameter: 598*5c6c1daeSBarry Smith . axis - The axis context 599*5c6c1daeSBarry Smith 600*5c6c1daeSBarry Smith Level: intermediate 601*5c6c1daeSBarry Smith 602*5c6c1daeSBarry Smith @*/ 603*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis) 604*5c6c1daeSBarry Smith { 605*5c6c1daeSBarry Smith PetscFunctionBegin; 606*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 607*5c6c1daeSBarry Smith PetscValidPointer(axis,2); 608*5c6c1daeSBarry Smith *axis = hist->axis; 609*5c6c1daeSBarry Smith PetscFunctionReturn(0); 610*5c6c1daeSBarry Smith } 611*5c6c1daeSBarry Smith 612*5c6c1daeSBarry Smith #undef __FUNCT__ 613*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawHGGetDraw" 614*5c6c1daeSBarry Smith /*@C 615*5c6c1daeSBarry Smith PetscDrawHGGetDraw - Gets the draw context associated with a histogram. 616*5c6c1daeSBarry Smith 617*5c6c1daeSBarry Smith Not Collective, PetscDraw is parallel if PetscDrawHG is parallel 618*5c6c1daeSBarry Smith 619*5c6c1daeSBarry Smith Input Parameter: 620*5c6c1daeSBarry Smith . hist - The histogram context 621*5c6c1daeSBarry Smith 622*5c6c1daeSBarry Smith Output Parameter: 623*5c6c1daeSBarry Smith . win - The draw context 624*5c6c1daeSBarry Smith 625*5c6c1daeSBarry Smith Level: intermediate 626*5c6c1daeSBarry Smith 627*5c6c1daeSBarry Smith @*/ 628*5c6c1daeSBarry Smith PetscErrorCode PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *win) 629*5c6c1daeSBarry Smith { 630*5c6c1daeSBarry Smith PetscFunctionBegin; 631*5c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID,1); 632*5c6c1daeSBarry Smith PetscValidPointer(win,2); 633*5c6c1daeSBarry Smith *win = hist->win; 634*5c6c1daeSBarry Smith PetscFunctionReturn(0); 635*5c6c1daeSBarry Smith } 636*5c6c1daeSBarry Smith 637