15c6c1daeSBarry Smith 25c6c1daeSBarry Smith /* 35c6c1daeSBarry Smith Contains the data structure for plotting a histogram in a window with an axis. 45c6c1daeSBarry Smith */ 59804daf3SBarry Smith #include <petscdraw.h> /*I "petscdraw.h" I*/ 6af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 734a5a0e3SBarry Smith #include <petscviewer.h> /*I "petscviewer.h" I*/ 85c6c1daeSBarry Smith 95c6c1daeSBarry Smith PetscClassId PETSC_DRAWHG_CLASSID = 0; 105c6c1daeSBarry Smith 115c6c1daeSBarry Smith struct _p_PetscDrawHG { 125c6c1daeSBarry Smith PETSCHEADER(int); 135c6c1daeSBarry Smith PetscErrorCode (*destroy)(PetscDrawSP); 145c6c1daeSBarry Smith PetscErrorCode (*view)(PetscDrawSP, PetscViewer); 155c6c1daeSBarry Smith PetscDraw win; 165c6c1daeSBarry Smith PetscDrawAxis axis; 175c6c1daeSBarry Smith PetscReal xmin, xmax; 185c6c1daeSBarry Smith PetscReal ymin, ymax; 195c6c1daeSBarry Smith int numBins; 205c6c1daeSBarry Smith int maxBins; 215c6c1daeSBarry Smith PetscReal *bins; 225c6c1daeSBarry Smith int numValues; 235c6c1daeSBarry Smith int maxValues; 245c6c1daeSBarry Smith PetscReal *values; 255c6c1daeSBarry Smith int color; 265c6c1daeSBarry Smith PetscBool calcStats; 275c6c1daeSBarry Smith PetscBool integerBins; 285c6c1daeSBarry Smith }; 295c6c1daeSBarry Smith 305c6c1daeSBarry Smith #define CHUNKSIZE 100 315c6c1daeSBarry Smith 325c6c1daeSBarry Smith /*@C 335c6c1daeSBarry Smith PetscDrawHGCreate - Creates a histogram data structure. 345c6c1daeSBarry Smith 35*811af0c4SBarry Smith Collective on draw 365c6c1daeSBarry Smith 375c6c1daeSBarry Smith Input Parameters: 385c6c1daeSBarry Smith + draw - The window where the graph will be made 395c6c1daeSBarry Smith - bins - The number of bins to use 405c6c1daeSBarry Smith 415c6c1daeSBarry Smith Output Parameters: 425c6c1daeSBarry Smith . hist - The histogram context 435c6c1daeSBarry Smith 4495452b02SPatrick Sanan Notes: 45*811af0c4SBarry Smith The difference between a bar chart, `PetscDrawBar`, and a histogram, `PetscDrawHG`, is explained here https://stattrek.com/statistics/charts/histogram.aspx?Tutorial=AP 460afdd333SBarry Smith 47*811af0c4SBarry Smith The histogram is only displayed when `PetscDrawHGDraw()` is called. 480afdd333SBarry Smith 49*811af0c4SBarry Smith The MPI communicator that owns the `PetscDraw` owns this `PetscDrawHG`, but the calls to set options and add data are ignored on all processes except the 50*811af0c4SBarry Smith zeroth MPI process in the communicator. All MPI ranks in the communicator must call `PetscDrawHGDraw()` to display the updated graph. 517e25d57eSBarry Smith 525c6c1daeSBarry Smith Level: intermediate 535c6c1daeSBarry Smith 54db781477SPatrick Sanan .seealso: `PetscDrawHGDestroy()`, `PetscDrawHG`, `PetscDrawBarCreate()`, `PetscDrawBar`, `PetscDrawLGCreate()`, `PetscDrawLG`, `PetscDrawSPCreate()`, `PetscDrawSP`, 55db781477SPatrick Sanan `PetscDrawHGSetNumberBins()`, `PetscDrawHGReset()`, `PetscDrawHGAddValue()`, `PetscDrawHGDraw()`, `PetscDrawHGSave()`, `PetscDrawHGView()`, `PetscDrawHGSetColor()`, 56db781477SPatrick Sanan `PetscDrawHGSetLimits()`, `PetscDrawHGCalcStats()`, `PetscDrawHGIntegerBins()`, `PetscDrawHGGetAxis()`, `PetscDrawAxis`, `PetscDrawHGGetDraw()` 575c6c1daeSBarry Smith @*/ 589371c9d4SSatish Balay PetscErrorCode PetscDrawHGCreate(PetscDraw draw, int bins, PetscDrawHG *hist) { 59e118a51fSLisandro Dalcin PetscDrawHG h; 605c6c1daeSBarry Smith 615c6c1daeSBarry Smith PetscFunctionBegin; 625c6c1daeSBarry Smith PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 63e118a51fSLisandro Dalcin PetscValidLogicalCollectiveInt(draw, bins, 2); 645c6c1daeSBarry Smith PetscValidPointer(hist, 3); 65e118a51fSLisandro Dalcin 669566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(h, PETSC_DRAWHG_CLASSID, "DrawHG", "Histogram", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawHGDestroy, NULL)); 679566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)draw, (PetscObject)h)); 68e118a51fSLisandro Dalcin 699566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)draw)); 70e118a51fSLisandro Dalcin h->win = draw; 71a297a907SKarl Rupp 720298fd71SBarry Smith h->view = NULL; 730298fd71SBarry Smith h->destroy = NULL; 745c6c1daeSBarry Smith h->color = PETSC_DRAW_GREEN; 755c6c1daeSBarry Smith h->xmin = PETSC_MAX_REAL; 765c6c1daeSBarry Smith h->xmax = PETSC_MIN_REAL; 775c6c1daeSBarry Smith h->ymin = 0.; 785c6c1daeSBarry Smith h->ymax = 1.; 795c6c1daeSBarry Smith h->numBins = bins; 805c6c1daeSBarry Smith h->maxBins = bins; 81a297a907SKarl Rupp 829566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(h->maxBins, &h->bins)); 83a297a907SKarl Rupp 845c6c1daeSBarry Smith h->numValues = 0; 855c6c1daeSBarry Smith h->maxValues = CHUNKSIZE; 865c6c1daeSBarry Smith h->calcStats = PETSC_FALSE; 875c6c1daeSBarry Smith h->integerBins = PETSC_FALSE; 88a297a907SKarl Rupp 899566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(h->maxValues, &h->values)); 909566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)h, (h->maxBins + h->maxValues) * sizeof(PetscReal))); 91a297a907SKarl Rupp 929566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisCreate(draw, &h->axis)); 939566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)h, (PetscObject)h->axis)); 94e118a51fSLisandro Dalcin 955c6c1daeSBarry Smith *hist = h; 965c6c1daeSBarry Smith PetscFunctionReturn(0); 975c6c1daeSBarry Smith } 985c6c1daeSBarry Smith 995c6c1daeSBarry Smith /*@ 100*811af0c4SBarry Smith PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn in the histogram 1015c6c1daeSBarry Smith 102*811af0c4SBarry Smith Logically Collective on hist 1035c6c1daeSBarry Smith 104d8d19677SJose E. Roman Input Parameters: 1055c6c1daeSBarry Smith + hist - The histogram context. 106e118a51fSLisandro Dalcin - bins - The number of bins. 1075c6c1daeSBarry Smith 1085c6c1daeSBarry Smith Level: intermediate 1095c6c1daeSBarry Smith 110db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGIntegerBins()` 1115c6c1daeSBarry Smith @*/ 1129371c9d4SSatish Balay PetscErrorCode PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins) { 1135c6c1daeSBarry Smith PetscFunctionBegin; 1145c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 115e118a51fSLisandro Dalcin PetscValidLogicalCollectiveInt(hist, bins, 2); 116e118a51fSLisandro Dalcin 1175c6c1daeSBarry Smith if (hist->maxBins < bins) { 1189566063dSJacob Faibussowitsch PetscCall(PetscFree(hist->bins)); 1199566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(bins, &hist->bins)); 1209566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)hist, (bins - hist->maxBins) * sizeof(PetscReal))); 1215c6c1daeSBarry Smith hist->maxBins = bins; 1225c6c1daeSBarry Smith } 1235c6c1daeSBarry Smith hist->numBins = bins; 1245c6c1daeSBarry Smith PetscFunctionReturn(0); 1255c6c1daeSBarry Smith } 1265c6c1daeSBarry Smith 1275c6c1daeSBarry Smith /*@ 1285c6c1daeSBarry Smith PetscDrawHGReset - Clears histogram to allow for reuse with new data. 1295c6c1daeSBarry Smith 130*811af0c4SBarry Smith Logically Collective on hist 1315c6c1daeSBarry Smith 1325c6c1daeSBarry Smith Input Parameter: 1335c6c1daeSBarry Smith . hist - The histogram context. 1345c6c1daeSBarry Smith 1355c6c1daeSBarry Smith Level: intermediate 1365c6c1daeSBarry Smith 137db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()` 1385c6c1daeSBarry Smith @*/ 1399371c9d4SSatish Balay PetscErrorCode PetscDrawHGReset(PetscDrawHG hist) { 1405c6c1daeSBarry Smith PetscFunctionBegin; 1415c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 142e118a51fSLisandro Dalcin 1435c6c1daeSBarry Smith hist->xmin = PETSC_MAX_REAL; 1445c6c1daeSBarry Smith hist->xmax = PETSC_MIN_REAL; 1455c6c1daeSBarry Smith hist->ymin = 0.0; 1465c6c1daeSBarry Smith hist->ymax = 0.0; 1475c6c1daeSBarry Smith hist->numValues = 0; 1485c6c1daeSBarry Smith PetscFunctionReturn(0); 1495c6c1daeSBarry Smith } 1505c6c1daeSBarry Smith 1515c6c1daeSBarry Smith /*@C 1525c6c1daeSBarry Smith PetscDrawHGDestroy - Frees all space taken up by histogram data structure. 1535c6c1daeSBarry Smith 154*811af0c4SBarry Smith Collective on hist 1555c6c1daeSBarry Smith 1565c6c1daeSBarry Smith Input Parameter: 1575c6c1daeSBarry Smith . hist - The histogram context 1585c6c1daeSBarry Smith 1595c6c1daeSBarry Smith Level: intermediate 1605c6c1daeSBarry Smith 161db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG` 1625c6c1daeSBarry Smith @*/ 1639371c9d4SSatish Balay PetscErrorCode PetscDrawHGDestroy(PetscDrawHG *hist) { 1645c6c1daeSBarry Smith PetscFunctionBegin; 1655c6c1daeSBarry Smith if (!*hist) PetscFunctionReturn(0); 166e118a51fSLisandro Dalcin PetscValidHeaderSpecific(*hist, PETSC_DRAWHG_CLASSID, 1); 1679371c9d4SSatish Balay if (--((PetscObject)(*hist))->refct > 0) { 1689371c9d4SSatish Balay *hist = NULL; 1699371c9d4SSatish Balay PetscFunctionReturn(0); 1709371c9d4SSatish Balay } 1715c6c1daeSBarry Smith 1729566063dSJacob Faibussowitsch PetscCall(PetscFree((*hist)->bins)); 1739566063dSJacob Faibussowitsch PetscCall(PetscFree((*hist)->values)); 1749566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisDestroy(&(*hist)->axis)); 1759566063dSJacob Faibussowitsch PetscCall(PetscDrawDestroy(&(*hist)->win)); 1769566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(hist)); 1775c6c1daeSBarry Smith PetscFunctionReturn(0); 1785c6c1daeSBarry Smith } 1795c6c1daeSBarry Smith 1805c6c1daeSBarry Smith /*@ 1815c6c1daeSBarry Smith PetscDrawHGAddValue - Adds another value to the histogram. 1825c6c1daeSBarry Smith 183*811af0c4SBarry Smith Logically Collective on hist 1845c6c1daeSBarry Smith 1855c6c1daeSBarry Smith Input Parameters: 1865c6c1daeSBarry Smith + hist - The histogram 1875c6c1daeSBarry Smith - value - The value 1885c6c1daeSBarry Smith 1895c6c1daeSBarry Smith Level: intermediate 1905c6c1daeSBarry Smith 191db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()` 1925c6c1daeSBarry Smith @*/ 1939371c9d4SSatish Balay PetscErrorCode PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value) { 1945c6c1daeSBarry Smith PetscFunctionBegin; 1955c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 196e118a51fSLisandro Dalcin 1975c6c1daeSBarry Smith /* Allocate more memory if necessary */ 1985c6c1daeSBarry Smith if (hist->numValues >= hist->maxValues) { 1995c6c1daeSBarry Smith PetscReal *tmp; 2005c6c1daeSBarry Smith 2019566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(hist->maxValues + CHUNKSIZE, &tmp)); 2029566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)hist, CHUNKSIZE * sizeof(PetscReal))); 2039566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(tmp, hist->values, hist->maxValues)); 2049566063dSJacob Faibussowitsch PetscCall(PetscFree(hist->values)); 205a297a907SKarl Rupp 2065c6c1daeSBarry Smith hist->values = tmp; 2075c6c1daeSBarry Smith hist->maxValues += CHUNKSIZE; 2085c6c1daeSBarry Smith } 2095c6c1daeSBarry Smith /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the 2105c6c1daeSBarry Smith stated convention of using half-open intervals (always the way to go) */ 211d0c080abSJoseph Pusztay if (!hist->numValues && (hist->xmin == PETSC_MAX_REAL) && (hist->xmax == PETSC_MIN_REAL)) { 2125c6c1daeSBarry Smith hist->xmin = value; 2135c6c1daeSBarry Smith hist->xmax = value; 2145c6c1daeSBarry Smith #if 1 2155c6c1daeSBarry Smith } else { 2165c6c1daeSBarry Smith /* Update limits */ 217a297a907SKarl Rupp if (value > hist->xmax) hist->xmax = value; 218a297a907SKarl Rupp if (value < hist->xmin) hist->xmin = value; 2195c6c1daeSBarry Smith #else 2205c6c1daeSBarry Smith } else if (hist->numValues == 1) { 2215c6c1daeSBarry Smith /* Update limits -- We need to overshoot the largest value somewhat */ 222a297a907SKarl Rupp if (value > hist->xmax) hist->xmax = value + 0.001 * (value - hist->xmin) / hist->numBins; 2235c6c1daeSBarry Smith if (value < hist->xmin) { 2245c6c1daeSBarry Smith hist->xmin = value; 2255c6c1daeSBarry Smith hist->xmax = hist->xmax + 0.001 * (hist->xmax - hist->xmin) / hist->numBins; 2265c6c1daeSBarry Smith } 2275c6c1daeSBarry Smith } else { 2285c6c1daeSBarry Smith /* Update limits -- We need to overshoot the largest value somewhat */ 229a297a907SKarl Rupp if (value > hist->xmax) hist->xmax = value + 0.001 * (hist->xmax - hist->xmin) / hist->numBins; 230a297a907SKarl Rupp if (value < hist->xmin) hist->xmin = value; 2315c6c1daeSBarry Smith #endif 2325c6c1daeSBarry Smith } 2335c6c1daeSBarry Smith 2345c6c1daeSBarry Smith hist->values[hist->numValues++] = value; 2355c6c1daeSBarry Smith PetscFunctionReturn(0); 2365c6c1daeSBarry Smith } 2375c6c1daeSBarry Smith 2385c6c1daeSBarry Smith /*@ 2395c6c1daeSBarry Smith PetscDrawHGDraw - Redraws a histogram. 2405c6c1daeSBarry Smith 241*811af0c4SBarry Smith Collective on hist 2425c6c1daeSBarry Smith 2435c6c1daeSBarry Smith Input Parameter: 2445c6c1daeSBarry Smith . hist - The histogram context 2455c6c1daeSBarry Smith 2465c6c1daeSBarry Smith Level: intermediate 2475c6c1daeSBarry Smith 248db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()` 2495c6c1daeSBarry Smith @*/ 2509371c9d4SSatish Balay PetscErrorCode PetscDrawHGDraw(PetscDrawHG hist) { 251e118a51fSLisandro Dalcin PetscDraw draw; 2525c6c1daeSBarry Smith PetscBool isnull; 2535c6c1daeSBarry Smith PetscReal xmin, xmax, ymin, ymax, *bins, *values, binSize, binLeft, binRight, maxHeight, mean, var; 2545c6c1daeSBarry Smith char title[256]; 2555c6c1daeSBarry Smith char xlabel[256]; 2565c6c1daeSBarry Smith PetscInt numBins, numBinsOld, numValues, initSize, i, p, bcolor, color; 257e118a51fSLisandro Dalcin PetscMPIInt rank; 2585c6c1daeSBarry Smith 2595c6c1daeSBarry Smith PetscFunctionBegin; 2605c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 2619566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(hist->win, &isnull)); 2628f69470aSLisandro Dalcin if (isnull) PetscFunctionReturn(0); 2639566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)hist), &rank)); 264e118a51fSLisandro Dalcin 2655c6c1daeSBarry Smith if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0); 2665c6c1daeSBarry Smith if (hist->numValues < 1) PetscFunctionReturn(0); 2675c6c1daeSBarry Smith 2685c6c1daeSBarry Smith color = hist->color; 26971917b75SLisandro Dalcin if (color == PETSC_DRAW_ROTATE) bcolor = PETSC_DRAW_BLACK + 1; 270a297a907SKarl Rupp else bcolor = color; 271a297a907SKarl Rupp 2725c6c1daeSBarry Smith xmin = hist->xmin; 2735c6c1daeSBarry Smith xmax = hist->xmax; 2745c6c1daeSBarry Smith ymin = hist->ymin; 2755c6c1daeSBarry Smith ymax = hist->ymax; 2765c6c1daeSBarry Smith numValues = hist->numValues; 2775c6c1daeSBarry Smith values = hist->values; 2785c6c1daeSBarry Smith mean = 0.0; 2795c6c1daeSBarry Smith var = 0.0; 2805c6c1daeSBarry Smith 2815b399a63SLisandro Dalcin draw = hist->win; 2829566063dSJacob Faibussowitsch PetscCall(PetscDrawCheckResizedWindow(draw)); 2839566063dSJacob Faibussowitsch PetscCall(PetscDrawClear(draw)); 284e118a51fSLisandro Dalcin 2855c6c1daeSBarry Smith if (xmin == xmax) { 2865c6c1daeSBarry Smith /* Calculate number of points in each bin */ 2875c6c1daeSBarry Smith bins = hist->bins; 2885c6c1daeSBarry Smith bins[0] = 0.; 2895c6c1daeSBarry Smith for (p = 0; p < numValues; p++) { 2905c6c1daeSBarry Smith if (values[p] == xmin) bins[0]++; 2915c6c1daeSBarry Smith mean += values[p]; 2925c6c1daeSBarry Smith var += values[p] * values[p]; 2935c6c1daeSBarry Smith } 2945c6c1daeSBarry Smith maxHeight = bins[0]; 2955c6c1daeSBarry Smith if (maxHeight > ymax) ymax = hist->ymax = maxHeight; 2965c6c1daeSBarry Smith xmax = xmin + 1; 2979566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax)); 2985c6c1daeSBarry Smith if (hist->calcStats) { 2995c6c1daeSBarry Smith mean /= numValues; 300a297a907SKarl Rupp if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1); 301a297a907SKarl Rupp else var = 0.0; 3029566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(title, 256, "Mean: %g Var: %g", (double)mean, (double)var)); 3039566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues)); 3049566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL)); 3055c6c1daeSBarry Smith } 3069566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisDraw(hist->axis)); 307d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 308dd400576SPatrick Sanan if (rank == 0) { /* Draw bins */ 3095c6c1daeSBarry Smith binLeft = xmin; 3105c6c1daeSBarry Smith binRight = xmax; 3119566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[0], bcolor, bcolor, bcolor, bcolor)); 3129566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[0], PETSC_DRAW_BLACK)); 3139566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[0], PETSC_DRAW_BLACK)); 3149566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, binLeft, bins[0], binRight, bins[0], PETSC_DRAW_BLACK)); 315e118a51fSLisandro Dalcin } 316d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 3175c6c1daeSBarry Smith } else { 3185c6c1daeSBarry Smith numBins = hist->numBins; 3195c6c1daeSBarry Smith numBinsOld = hist->numBins; 3205c6c1daeSBarry Smith if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) { 3215c6c1daeSBarry Smith initSize = (int)((int)xmax - xmin) / numBins; 3225c6c1daeSBarry Smith while (initSize * numBins != (int)xmax - xmin) { 3235c6c1daeSBarry Smith initSize = PetscMax(initSize - 1, 1); 3245c6c1daeSBarry Smith numBins = (int)((int)xmax - xmin) / initSize; 3259566063dSJacob Faibussowitsch PetscCall(PetscDrawHGSetNumberBins(hist, numBins)); 3265c6c1daeSBarry Smith } 3275c6c1daeSBarry Smith } 3285c6c1daeSBarry Smith binSize = (xmax - xmin) / numBins; 3295c6c1daeSBarry Smith bins = hist->bins; 3305c6c1daeSBarry Smith 3319566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(bins, numBins)); 332a297a907SKarl Rupp 3335c6c1daeSBarry Smith maxHeight = 0.0; 3345c6c1daeSBarry Smith for (i = 0; i < numBins; i++) { 3355c6c1daeSBarry Smith binLeft = xmin + binSize * i; 3365c6c1daeSBarry Smith binRight = xmin + binSize * (i + 1); 3375c6c1daeSBarry Smith for (p = 0; p < numValues; p++) { 3385c6c1daeSBarry Smith if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++; 3395c6c1daeSBarry Smith /* Handle last bin separately */ 3405c6c1daeSBarry Smith if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++; 3415c6c1daeSBarry Smith if (!i) { 3425c6c1daeSBarry Smith mean += values[p]; 3435c6c1daeSBarry Smith var += values[p] * values[p]; 3445c6c1daeSBarry Smith } 3455c6c1daeSBarry Smith } 3465c6c1daeSBarry Smith maxHeight = PetscMax(maxHeight, bins[i]); 3475c6c1daeSBarry Smith } 3485c6c1daeSBarry Smith if (maxHeight > ymax) ymax = hist->ymax = maxHeight; 3495c6c1daeSBarry Smith 3509566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLimits(hist->axis, xmin, xmax, ymin, ymax)); 3515c6c1daeSBarry Smith if (hist->calcStats) { 3525c6c1daeSBarry Smith mean /= numValues; 353a297a907SKarl Rupp if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1); 354a297a907SKarl Rupp else var = 0.0; 3559566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(title, 256, "Mean: %g Var: %g", (double)mean, (double)var)); 3569566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(xlabel, 256, "Total: %" PetscInt_FMT, numValues)); 3579566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisSetLabels(hist->axis, title, xlabel, NULL)); 3585c6c1daeSBarry Smith } 3599566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisDraw(hist->axis)); 360d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 361dd400576SPatrick Sanan if (rank == 0) { /* Draw bins */ 3625c6c1daeSBarry Smith for (i = 0; i < numBins; i++) { 3635c6c1daeSBarry Smith binLeft = xmin + binSize * i; 3645c6c1daeSBarry Smith binRight = xmin + binSize * (i + 1); 3659566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, binLeft, ymin, binRight, bins[i], bcolor, bcolor, bcolor, bcolor)); 3669566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, binLeft, ymin, binLeft, bins[i], PETSC_DRAW_BLACK)); 3679566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, binRight, ymin, binRight, bins[i], PETSC_DRAW_BLACK)); 3689566063dSJacob Faibussowitsch PetscCall(PetscDrawLine(draw, binLeft, bins[i], binRight, bins[i], PETSC_DRAW_BLACK)); 369e118a51fSLisandro Dalcin if (color == PETSC_DRAW_ROTATE && bins[i]) bcolor++; 37071917b75SLisandro Dalcin if (bcolor > PETSC_DRAW_BASIC_COLORS - 1) bcolor = PETSC_DRAW_BLACK + 1; 371e118a51fSLisandro Dalcin } 3725c6c1daeSBarry Smith } 373d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 3749566063dSJacob Faibussowitsch PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld)); 3755c6c1daeSBarry Smith } 376e118a51fSLisandro Dalcin 3779566063dSJacob Faibussowitsch PetscCall(PetscDrawFlush(draw)); 3789566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 3795c6c1daeSBarry Smith PetscFunctionReturn(0); 3805c6c1daeSBarry Smith } 3815c6c1daeSBarry Smith 38257fd6651SLisandro Dalcin /*@ 38357fd6651SLisandro Dalcin PetscDrawHGSave - Saves a drawn image 38457fd6651SLisandro Dalcin 385*811af0c4SBarry Smith Collective on hg 38657fd6651SLisandro Dalcin 38757fd6651SLisandro Dalcin Input Parameter: 38857fd6651SLisandro Dalcin . hist - The histogram context 38957fd6651SLisandro Dalcin 39057fd6651SLisandro Dalcin Level: intermediate 39157fd6651SLisandro Dalcin 392*811af0c4SBarry Smith .seealso: `PetscDrawSave()`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()` 39357fd6651SLisandro Dalcin @*/ 3949371c9d4SSatish Balay PetscErrorCode PetscDrawHGSave(PetscDrawHG hg) { 39557fd6651SLisandro Dalcin PetscFunctionBegin; 39657fd6651SLisandro Dalcin PetscValidHeaderSpecific(hg, PETSC_DRAWHG_CLASSID, 1); 3979566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(hg->win)); 39857fd6651SLisandro Dalcin PetscFunctionReturn(0); 39957fd6651SLisandro Dalcin } 40057fd6651SLisandro Dalcin 4015c6c1daeSBarry Smith /*@ 402*811af0c4SBarry Smith PetscDrawHGView - Prints the histogram information to a viewer 4035c6c1daeSBarry Smith 4045c6c1daeSBarry Smith Not collective 4055c6c1daeSBarry Smith 4065c6c1daeSBarry Smith Input Parameter: 4075c6c1daeSBarry Smith . hist - The histogram context 4085c6c1daeSBarry Smith 4095c6c1daeSBarry Smith Level: beginner 4105c6c1daeSBarry Smith 411*811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscViewer`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()` 4125c6c1daeSBarry Smith @*/ 4139371c9d4SSatish Balay PetscErrorCode PetscDrawHGView(PetscDrawHG hist, PetscViewer viewer) { 4145c6c1daeSBarry Smith PetscReal xmax, xmin, *bins, *values, binSize, binLeft, binRight, mean, var; 4155c6c1daeSBarry Smith PetscInt numBins, numBinsOld, numValues, initSize, i, p; 4165c6c1daeSBarry Smith 4175c6c1daeSBarry Smith PetscFunctionBegin; 4185c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 419e118a51fSLisandro Dalcin 4205c6c1daeSBarry Smith if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(0); 4215c6c1daeSBarry Smith if (hist->numValues < 1) PetscFunctionReturn(0); 4225c6c1daeSBarry Smith 42348a46eb9SPierre Jolivet if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist), &viewer)); 4249566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)hist, viewer)); 4255c6c1daeSBarry Smith xmax = hist->xmax; 4265c6c1daeSBarry Smith xmin = hist->xmin; 4275c6c1daeSBarry Smith numValues = hist->numValues; 4285c6c1daeSBarry Smith values = hist->values; 4295c6c1daeSBarry Smith mean = 0.0; 4305c6c1daeSBarry Smith var = 0.0; 4315c6c1daeSBarry Smith if (xmax == xmin) { 4325c6c1daeSBarry Smith /* Calculate number of points in the bin */ 4335c6c1daeSBarry Smith bins = hist->bins; 4345c6c1daeSBarry Smith bins[0] = 0.; 4355c6c1daeSBarry Smith for (p = 0; p < numValues; p++) { 4365c6c1daeSBarry Smith if (values[p] == xmin) bins[0]++; 4375c6c1daeSBarry Smith mean += values[p]; 4385c6c1daeSBarry Smith var += values[p] * values[p]; 4395c6c1daeSBarry Smith } 4405c6c1daeSBarry Smith /* Draw bins */ 4419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0])); 4425c6c1daeSBarry Smith } else { 4435c6c1daeSBarry Smith numBins = hist->numBins; 4445c6c1daeSBarry Smith numBinsOld = hist->numBins; 4455c6c1daeSBarry Smith if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) { 4465c6c1daeSBarry Smith initSize = (int)((int)xmax - xmin) / numBins; 4475c6c1daeSBarry Smith while (initSize * numBins != (int)xmax - xmin) { 4485c6c1daeSBarry Smith initSize = PetscMax(initSize - 1, 1); 4495c6c1daeSBarry Smith numBins = (int)((int)xmax - xmin) / initSize; 4509566063dSJacob Faibussowitsch PetscCall(PetscDrawHGSetNumberBins(hist, numBins)); 4515c6c1daeSBarry Smith } 4525c6c1daeSBarry Smith } 4535c6c1daeSBarry Smith binSize = (xmax - xmin) / numBins; 4545c6c1daeSBarry Smith bins = hist->bins; 4555c6c1daeSBarry Smith 4565c6c1daeSBarry Smith /* Calculate number of points in each bin */ 4579566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(bins, numBins)); 4585c6c1daeSBarry Smith for (i = 0; i < numBins; i++) { 4595c6c1daeSBarry Smith binLeft = xmin + binSize * i; 4605c6c1daeSBarry Smith binRight = xmin + binSize * (i + 1); 4615c6c1daeSBarry Smith for (p = 0; p < numValues; p++) { 4625c6c1daeSBarry Smith if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++; 4635c6c1daeSBarry Smith /* Handle last bin separately */ 4645c6c1daeSBarry Smith if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++; 4655c6c1daeSBarry Smith if (!i) { 4665c6c1daeSBarry Smith mean += values[p]; 4675c6c1daeSBarry Smith var += values[p] * values[p]; 4685c6c1daeSBarry Smith } 4695c6c1daeSBarry Smith } 4705c6c1daeSBarry Smith } 4715c6c1daeSBarry Smith /* Draw bins */ 4725c6c1daeSBarry Smith for (i = 0; i < numBins; i++) { 4735c6c1daeSBarry Smith binLeft = xmin + binSize * i; 4745c6c1daeSBarry Smith binRight = xmin + binSize * (i + 1); 4759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i])); 4765c6c1daeSBarry Smith } 4779566063dSJacob Faibussowitsch PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld)); 4785c6c1daeSBarry Smith } 4795c6c1daeSBarry Smith 4805c6c1daeSBarry Smith if (hist->calcStats) { 4815c6c1daeSBarry Smith mean /= numValues; 482a297a907SKarl Rupp if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1); 483a297a907SKarl Rupp else var = 0.0; 4849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Mean: %g Var: %g\n", (double)mean, (double)var)); 4859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Total: %" PetscInt_FMT "\n", numValues)); 4865c6c1daeSBarry Smith } 4875c6c1daeSBarry Smith PetscFunctionReturn(0); 4885c6c1daeSBarry Smith } 4895c6c1daeSBarry Smith 4905c6c1daeSBarry Smith /*@ 4915c6c1daeSBarry Smith PetscDrawHGSetColor - Sets the color the bars will be drawn with. 4925c6c1daeSBarry Smith 493*811af0c4SBarry Smith Logically Collective on hist 4945c6c1daeSBarry Smith 4955c6c1daeSBarry Smith Input Parameters: 4965c6c1daeSBarry Smith + hist - The histogram context 497*811af0c4SBarry Smith - color - one of the colors defined in petscdraw.h or `PETSC_DRAW_ROTATE` to make each bar a 4985c6c1daeSBarry Smith different color 4995c6c1daeSBarry Smith 5005c6c1daeSBarry Smith Level: intermediate 5015c6c1daeSBarry Smith 502*811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()` 5035c6c1daeSBarry Smith @*/ 5049371c9d4SSatish Balay PetscErrorCode PetscDrawHGSetColor(PetscDrawHG hist, int color) { 5055c6c1daeSBarry Smith PetscFunctionBegin; 5065c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 507e118a51fSLisandro Dalcin 5085c6c1daeSBarry Smith hist->color = color; 5095c6c1daeSBarry Smith PetscFunctionReturn(0); 5105c6c1daeSBarry Smith } 5115c6c1daeSBarry Smith 5125c6c1daeSBarry Smith /*@ 5135c6c1daeSBarry Smith PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more 5145c6c1daeSBarry Smith points are added after this call, the limits will be adjusted to 5155c6c1daeSBarry Smith include those additional points. 5165c6c1daeSBarry Smith 517*811af0c4SBarry Smith Logically Collective on hist 5185c6c1daeSBarry Smith 5195c6c1daeSBarry Smith Input Parameters: 5205c6c1daeSBarry Smith + hist - The histogram context 5215c6c1daeSBarry Smith - x_min,x_max,y_min,y_max - The limits 5225c6c1daeSBarry Smith 5235c6c1daeSBarry Smith Level: intermediate 5245c6c1daeSBarry Smith 525*811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()` 5265c6c1daeSBarry Smith @*/ 5279371c9d4SSatish Balay PetscErrorCode PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max) { 5285c6c1daeSBarry Smith PetscFunctionBegin; 5295c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 530e118a51fSLisandro Dalcin 5315c6c1daeSBarry Smith hist->xmin = x_min; 5325c6c1daeSBarry Smith hist->xmax = x_max; 5335c6c1daeSBarry Smith hist->ymin = y_min; 5345c6c1daeSBarry Smith hist->ymax = y_max; 5355c6c1daeSBarry Smith PetscFunctionReturn(0); 5365c6c1daeSBarry Smith } 5375c6c1daeSBarry Smith 5385c6c1daeSBarry Smith /*@ 539*811af0c4SBarry Smith PetscDrawHGCalcStats - Turns on calculation of descriptive statistics associated with the histogram 5405c6c1daeSBarry Smith 5415c6c1daeSBarry Smith Not collective 5425c6c1daeSBarry Smith 5435c6c1daeSBarry Smith Input Parameters: 5445c6c1daeSBarry Smith + hist - The histogram context 5455c6c1daeSBarry Smith - calc - Flag for calculation 5465c6c1daeSBarry Smith 5475c6c1daeSBarry Smith Level: intermediate 5485c6c1daeSBarry Smith 549*811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()` 5505c6c1daeSBarry Smith @*/ 5519371c9d4SSatish Balay PetscErrorCode PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc) { 5525c6c1daeSBarry Smith PetscFunctionBegin; 5535c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 554e118a51fSLisandro Dalcin 5555c6c1daeSBarry Smith hist->calcStats = calc; 5565c6c1daeSBarry Smith PetscFunctionReturn(0); 5575c6c1daeSBarry Smith } 5585c6c1daeSBarry Smith 5595c6c1daeSBarry Smith /*@ 5605c6c1daeSBarry Smith PetscDrawHGIntegerBins - Turns on integer width bins 5615c6c1daeSBarry Smith 5625c6c1daeSBarry Smith Not collective 5635c6c1daeSBarry Smith 5645c6c1daeSBarry Smith Input Parameters: 5655c6c1daeSBarry Smith + hist - The histogram context 5665c6c1daeSBarry Smith - ints - Flag for integer width bins 5675c6c1daeSBarry Smith 5685c6c1daeSBarry Smith Level: intermediate 5695c6c1daeSBarry Smith 570*811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()` 5715c6c1daeSBarry Smith @*/ 5729371c9d4SSatish Balay PetscErrorCode PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints) { 5735c6c1daeSBarry Smith PetscFunctionBegin; 5745c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 575e118a51fSLisandro Dalcin 5765c6c1daeSBarry Smith hist->integerBins = ints; 5775c6c1daeSBarry Smith PetscFunctionReturn(0); 5785c6c1daeSBarry Smith } 5795c6c1daeSBarry Smith 5805c6c1daeSBarry Smith /*@C 5815c6c1daeSBarry Smith PetscDrawHGGetAxis - Gets the axis context associated with a histogram. 5825c6c1daeSBarry Smith This is useful if one wants to change some axis property, such as 5835c6c1daeSBarry Smith labels, color, etc. The axis context should not be destroyed by the 5845c6c1daeSBarry Smith application code. 5855c6c1daeSBarry Smith 586*811af0c4SBarry Smith Not Collective, axis is parallel if hist is parallel 5875c6c1daeSBarry Smith 5885c6c1daeSBarry Smith Input Parameter: 5895c6c1daeSBarry Smith . hist - The histogram context 5905c6c1daeSBarry Smith 5915c6c1daeSBarry Smith Output Parameter: 5925c6c1daeSBarry Smith . axis - The axis context 5935c6c1daeSBarry Smith 5945c6c1daeSBarry Smith Level: intermediate 5955c6c1daeSBarry Smith 596*811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscDrawAxis`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()` 5975c6c1daeSBarry Smith @*/ 5989371c9d4SSatish Balay PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis) { 5995c6c1daeSBarry Smith PetscFunctionBegin; 600e118a51fSLisandro Dalcin PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 60145f3bb6eSLisandro Dalcin PetscValidPointer(axis, 2); 6025c6c1daeSBarry Smith *axis = hist->axis; 6035c6c1daeSBarry Smith PetscFunctionReturn(0); 6045c6c1daeSBarry Smith } 6055c6c1daeSBarry Smith 6065c6c1daeSBarry Smith /*@C 6075c6c1daeSBarry Smith PetscDrawHGGetDraw - Gets the draw context associated with a histogram. 6085c6c1daeSBarry Smith 609*811af0c4SBarry Smith Not Collective, draw is parallel if hist is parallel 6105c6c1daeSBarry Smith 6115c6c1daeSBarry Smith Input Parameter: 6125c6c1daeSBarry Smith . hist - The histogram context 6135c6c1daeSBarry Smith 6145c6c1daeSBarry Smith Output Parameter: 615e118a51fSLisandro Dalcin . draw - The draw context 6165c6c1daeSBarry Smith 6175c6c1daeSBarry Smith Level: intermediate 6185c6c1daeSBarry Smith 619*811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()` 6205c6c1daeSBarry Smith @*/ 6219371c9d4SSatish Balay PetscErrorCode PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *draw) { 6225c6c1daeSBarry Smith PetscFunctionBegin; 6235c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 62445f3bb6eSLisandro Dalcin PetscValidPointer(draw, 2); 625e118a51fSLisandro Dalcin *draw = hist->win; 6265c6c1daeSBarry Smith PetscFunctionReturn(0); 6275c6c1daeSBarry Smith } 628