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 35c3339decSBarry Smith Collective 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 4120f4b53cSBarry Smith Output Parameter: 425c6c1daeSBarry Smith . hist - The histogram context 435c6c1daeSBarry Smith 4420f4b53cSBarry Smith Level: intermediate 4520f4b53cSBarry Smith 4695452b02SPatrick Sanan Notes: 47811af0c4SBarry Smith The difference between a bar chart, `PetscDrawBar`, and a histogram, `PetscDrawHG`, is explained here https://stattrek.com/statistics/charts/histogram.aspx?Tutorial=AP 480afdd333SBarry Smith 49811af0c4SBarry Smith The histogram is only displayed when `PetscDrawHGDraw()` is called. 500afdd333SBarry Smith 51811af0c4SBarry 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 52811af0c4SBarry Smith zeroth MPI process in the communicator. All MPI ranks in the communicator must call `PetscDrawHGDraw()` to display the updated graph. 537e25d57eSBarry 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 @*/ 58d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGCreate(PetscDraw draw, int bins, PetscDrawHG *hist) 59d71ae5a4SJacob Faibussowitsch { 60e118a51fSLisandro Dalcin PetscDrawHG h; 615c6c1daeSBarry Smith 625c6c1daeSBarry Smith PetscFunctionBegin; 635c6c1daeSBarry Smith PetscValidHeaderSpecific(draw, PETSC_DRAW_CLASSID, 1); 64e118a51fSLisandro Dalcin PetscValidLogicalCollectiveInt(draw, bins, 2); 655c6c1daeSBarry Smith PetscValidPointer(hist, 3); 66e118a51fSLisandro Dalcin 679566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(h, PETSC_DRAWHG_CLASSID, "DrawHG", "Histogram", "Draw", PetscObjectComm((PetscObject)draw), PetscDrawHGDestroy, NULL)); 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(PetscDrawAxisCreate(draw, &h->axis)); 91e118a51fSLisandro Dalcin 925c6c1daeSBarry Smith *hist = h; 933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 945c6c1daeSBarry Smith } 955c6c1daeSBarry Smith 965c6c1daeSBarry Smith /*@ 97811af0c4SBarry Smith PetscDrawHGSetNumberBins - Change the number of bins that are to be drawn in the histogram 985c6c1daeSBarry Smith 99c3339decSBarry Smith Logically Collective 1005c6c1daeSBarry Smith 101d8d19677SJose E. Roman Input Parameters: 1025c6c1daeSBarry Smith + hist - The histogram context. 103e118a51fSLisandro Dalcin - bins - The number of bins. 1045c6c1daeSBarry Smith 1055c6c1daeSBarry Smith Level: intermediate 1065c6c1daeSBarry Smith 107db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGIntegerBins()` 1085c6c1daeSBarry Smith @*/ 109d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGSetNumberBins(PetscDrawHG hist, int bins) 110d71ae5a4SJacob Faibussowitsch { 1115c6c1daeSBarry Smith PetscFunctionBegin; 1125c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 113e118a51fSLisandro Dalcin PetscValidLogicalCollectiveInt(hist, bins, 2); 114e118a51fSLisandro Dalcin 1155c6c1daeSBarry Smith if (hist->maxBins < bins) { 1169566063dSJacob Faibussowitsch PetscCall(PetscFree(hist->bins)); 1179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(bins, &hist->bins)); 1185c6c1daeSBarry Smith hist->maxBins = bins; 1195c6c1daeSBarry Smith } 1205c6c1daeSBarry Smith hist->numBins = bins; 1213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1225c6c1daeSBarry Smith } 1235c6c1daeSBarry Smith 1245c6c1daeSBarry Smith /*@ 1255c6c1daeSBarry Smith PetscDrawHGReset - Clears histogram to allow for reuse with new data. 1265c6c1daeSBarry Smith 127c3339decSBarry Smith Logically Collective 1285c6c1daeSBarry Smith 1295c6c1daeSBarry Smith Input Parameter: 1305c6c1daeSBarry Smith . hist - The histogram context. 1315c6c1daeSBarry Smith 1325c6c1daeSBarry Smith Level: intermediate 1335c6c1daeSBarry Smith 134db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()` 1355c6c1daeSBarry Smith @*/ 136d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGReset(PetscDrawHG hist) 137d71ae5a4SJacob Faibussowitsch { 1385c6c1daeSBarry Smith PetscFunctionBegin; 1395c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 140e118a51fSLisandro Dalcin 1415c6c1daeSBarry Smith hist->xmin = PETSC_MAX_REAL; 1425c6c1daeSBarry Smith hist->xmax = PETSC_MIN_REAL; 1435c6c1daeSBarry Smith hist->ymin = 0.0; 14460e16b1bSMatthew G. Knepley hist->ymax = 1.0; 1455c6c1daeSBarry Smith hist->numValues = 0; 1463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1475c6c1daeSBarry Smith } 1485c6c1daeSBarry Smith 1495c6c1daeSBarry Smith /*@C 1505c6c1daeSBarry Smith PetscDrawHGDestroy - Frees all space taken up by histogram data structure. 1515c6c1daeSBarry Smith 152c3339decSBarry Smith Collective 1535c6c1daeSBarry Smith 1545c6c1daeSBarry Smith Input Parameter: 1555c6c1daeSBarry Smith . hist - The histogram context 1565c6c1daeSBarry Smith 1575c6c1daeSBarry Smith Level: intermediate 1585c6c1daeSBarry Smith 159db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG` 1605c6c1daeSBarry Smith @*/ 161d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGDestroy(PetscDrawHG *hist) 162d71ae5a4SJacob Faibussowitsch { 1635c6c1daeSBarry Smith PetscFunctionBegin; 1643ba16761SJacob Faibussowitsch if (!*hist) PetscFunctionReturn(PETSC_SUCCESS); 165e118a51fSLisandro Dalcin PetscValidHeaderSpecific(*hist, PETSC_DRAWHG_CLASSID, 1); 1669371c9d4SSatish Balay if (--((PetscObject)(*hist))->refct > 0) { 1679371c9d4SSatish Balay *hist = NULL; 1683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1699371c9d4SSatish Balay } 1705c6c1daeSBarry Smith 1719566063dSJacob Faibussowitsch PetscCall(PetscFree((*hist)->bins)); 1729566063dSJacob Faibussowitsch PetscCall(PetscFree((*hist)->values)); 1739566063dSJacob Faibussowitsch PetscCall(PetscDrawAxisDestroy(&(*hist)->axis)); 1749566063dSJacob Faibussowitsch PetscCall(PetscDrawDestroy(&(*hist)->win)); 1759566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(hist)); 1763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1775c6c1daeSBarry Smith } 1785c6c1daeSBarry Smith 1795c6c1daeSBarry Smith /*@ 1805c6c1daeSBarry Smith PetscDrawHGAddValue - Adds another value to the histogram. 1815c6c1daeSBarry Smith 182c3339decSBarry Smith Logically Collective 1835c6c1daeSBarry Smith 1845c6c1daeSBarry Smith Input Parameters: 1855c6c1daeSBarry Smith + hist - The histogram 1865c6c1daeSBarry Smith - value - The value 1875c6c1daeSBarry Smith 1885c6c1daeSBarry Smith Level: intermediate 1895c6c1daeSBarry Smith 190db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()` 1915c6c1daeSBarry Smith @*/ 192d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGAddValue(PetscDrawHG hist, PetscReal value) 193d71ae5a4SJacob Faibussowitsch { 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(PetscArraycpy(tmp, hist->values, hist->maxValues)); 2039566063dSJacob Faibussowitsch PetscCall(PetscFree(hist->values)); 204a297a907SKarl Rupp 2055c6c1daeSBarry Smith hist->values = tmp; 2065c6c1daeSBarry Smith hist->maxValues += CHUNKSIZE; 2075c6c1daeSBarry Smith } 2085c6c1daeSBarry Smith /* I disagree with the original Petsc implementation here. There should be no overshoot, but rather the 2095c6c1daeSBarry Smith stated convention of using half-open intervals (always the way to go) */ 210d0c080abSJoseph Pusztay if (!hist->numValues && (hist->xmin == PETSC_MAX_REAL) && (hist->xmax == PETSC_MIN_REAL)) { 2115c6c1daeSBarry Smith hist->xmin = value; 2125c6c1daeSBarry Smith hist->xmax = value; 2135c6c1daeSBarry Smith #if 1 2145c6c1daeSBarry Smith } else { 2155c6c1daeSBarry Smith /* Update limits */ 216a297a907SKarl Rupp if (value > hist->xmax) hist->xmax = value; 217a297a907SKarl Rupp if (value < hist->xmin) hist->xmin = value; 2185c6c1daeSBarry Smith #else 2195c6c1daeSBarry Smith } else if (hist->numValues == 1) { 2205c6c1daeSBarry Smith /* Update limits -- We need to overshoot the largest value somewhat */ 221a297a907SKarl Rupp if (value > hist->xmax) hist->xmax = value + 0.001 * (value - hist->xmin) / hist->numBins; 2225c6c1daeSBarry Smith if (value < hist->xmin) { 2235c6c1daeSBarry Smith hist->xmin = value; 2245c6c1daeSBarry Smith hist->xmax = hist->xmax + 0.001 * (hist->xmax - hist->xmin) / hist->numBins; 2255c6c1daeSBarry Smith } 2265c6c1daeSBarry Smith } else { 2275c6c1daeSBarry Smith /* Update limits -- We need to overshoot the largest value somewhat */ 228a297a907SKarl Rupp if (value > hist->xmax) hist->xmax = value + 0.001 * (hist->xmax - hist->xmin) / hist->numBins; 229a297a907SKarl Rupp if (value < hist->xmin) hist->xmin = value; 2305c6c1daeSBarry Smith #endif 2315c6c1daeSBarry Smith } 2325c6c1daeSBarry Smith 2335c6c1daeSBarry Smith hist->values[hist->numValues++] = value; 2343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2355c6c1daeSBarry Smith } 2365c6c1daeSBarry Smith 2375c6c1daeSBarry Smith /*@ 2385c6c1daeSBarry Smith PetscDrawHGDraw - Redraws a histogram. 2395c6c1daeSBarry Smith 240c3339decSBarry Smith Collective 2415c6c1daeSBarry Smith 2425c6c1daeSBarry Smith Input Parameter: 2435c6c1daeSBarry Smith . hist - The histogram context 2445c6c1daeSBarry Smith 2455c6c1daeSBarry Smith Level: intermediate 2465c6c1daeSBarry Smith 247db781477SPatrick Sanan .seealso: `PetscDrawHGCreate()`, `PetscDrawHG`, `PetscDrawHGDraw()`, `PetscDrawHGAddValue()`, `PetscDrawHGReset()` 2485c6c1daeSBarry Smith @*/ 249d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGDraw(PetscDrawHG hist) 250d71ae5a4SJacob Faibussowitsch { 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)); 2623ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 2639566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)hist), &rank)); 264e118a51fSLisandro Dalcin 2653ba16761SJacob Faibussowitsch if ((hist->xmin >= hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(PETSC_SUCCESS); 2663ba16761SJacob Faibussowitsch if (hist->numValues < 1) PetscFunctionReturn(PETSC_SUCCESS); 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)); 3793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3805c6c1daeSBarry Smith } 3815c6c1daeSBarry Smith 38257fd6651SLisandro Dalcin /*@ 38357fd6651SLisandro Dalcin PetscDrawHGSave - Saves a drawn image 38457fd6651SLisandro Dalcin 385c3339decSBarry Smith Collective 38657fd6651SLisandro Dalcin 38757fd6651SLisandro Dalcin Input Parameter: 38857fd6651SLisandro Dalcin . hist - The histogram context 38957fd6651SLisandro Dalcin 39057fd6651SLisandro Dalcin Level: intermediate 39157fd6651SLisandro Dalcin 392811af0c4SBarry Smith .seealso: `PetscDrawSave()`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()` 39357fd6651SLisandro Dalcin @*/ 394d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGSave(PetscDrawHG hg) 395d71ae5a4SJacob Faibussowitsch { 39657fd6651SLisandro Dalcin PetscFunctionBegin; 39757fd6651SLisandro Dalcin PetscValidHeaderSpecific(hg, PETSC_DRAWHG_CLASSID, 1); 3989566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(hg->win)); 3993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40057fd6651SLisandro Dalcin } 40157fd6651SLisandro Dalcin 4025c6c1daeSBarry Smith /*@ 403811af0c4SBarry Smith PetscDrawHGView - Prints the histogram information to a viewer 4045c6c1daeSBarry Smith 40520f4b53cSBarry Smith Not Collective 4065c6c1daeSBarry Smith 4075c6c1daeSBarry Smith Input Parameter: 4085c6c1daeSBarry Smith . hist - The histogram context 4095c6c1daeSBarry Smith 4105c6c1daeSBarry Smith Level: beginner 4115c6c1daeSBarry Smith 412811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscViewer`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()` 4135c6c1daeSBarry Smith @*/ 414d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGView(PetscDrawHG hist, PetscViewer viewer) 415d71ae5a4SJacob Faibussowitsch { 4165c6c1daeSBarry Smith PetscReal xmax, xmin, *bins, *values, binSize, binLeft, binRight, mean, var; 4175c6c1daeSBarry Smith PetscInt numBins, numBinsOld, numValues, initSize, i, p; 4185c6c1daeSBarry Smith 4195c6c1daeSBarry Smith PetscFunctionBegin; 4205c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 421e118a51fSLisandro Dalcin 4223ba16761SJacob Faibussowitsch if ((hist->xmin > hist->xmax) || (hist->ymin >= hist->ymax)) PetscFunctionReturn(PETSC_SUCCESS); 4233ba16761SJacob Faibussowitsch if (hist->numValues < 1) PetscFunctionReturn(PETSC_SUCCESS); 4245c6c1daeSBarry Smith 42548a46eb9SPierre Jolivet if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)hist), &viewer)); 4269566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)hist, viewer)); 4275c6c1daeSBarry Smith xmax = hist->xmax; 4285c6c1daeSBarry Smith xmin = hist->xmin; 4295c6c1daeSBarry Smith numValues = hist->numValues; 4305c6c1daeSBarry Smith values = hist->values; 4315c6c1daeSBarry Smith mean = 0.0; 4325c6c1daeSBarry Smith var = 0.0; 4335c6c1daeSBarry Smith if (xmax == xmin) { 4345c6c1daeSBarry Smith /* Calculate number of points in the bin */ 4355c6c1daeSBarry Smith bins = hist->bins; 4365c6c1daeSBarry Smith bins[0] = 0.; 4375c6c1daeSBarry Smith for (p = 0; p < numValues; p++) { 4385c6c1daeSBarry Smith if (values[p] == xmin) bins[0]++; 4395c6c1daeSBarry Smith mean += values[p]; 4405c6c1daeSBarry Smith var += values[p] * values[p]; 4415c6c1daeSBarry Smith } 4425c6c1daeSBarry Smith /* Draw bins */ 4439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", 0, (double)xmin, (double)xmax, (double)bins[0])); 4445c6c1daeSBarry Smith } else { 4455c6c1daeSBarry Smith numBins = hist->numBins; 4465c6c1daeSBarry Smith numBinsOld = hist->numBins; 4475c6c1daeSBarry Smith if (hist->integerBins && (((int)xmax - xmin) + 1.0e-05 > xmax - xmin)) { 4485c6c1daeSBarry Smith initSize = (int)((int)xmax - xmin) / numBins; 4495c6c1daeSBarry Smith while (initSize * numBins != (int)xmax - xmin) { 4505c6c1daeSBarry Smith initSize = PetscMax(initSize - 1, 1); 4515c6c1daeSBarry Smith numBins = (int)((int)xmax - xmin) / initSize; 4529566063dSJacob Faibussowitsch PetscCall(PetscDrawHGSetNumberBins(hist, numBins)); 4535c6c1daeSBarry Smith } 4545c6c1daeSBarry Smith } 4555c6c1daeSBarry Smith binSize = (xmax - xmin) / numBins; 4565c6c1daeSBarry Smith bins = hist->bins; 4575c6c1daeSBarry Smith 4585c6c1daeSBarry Smith /* Calculate number of points in each bin */ 4599566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(bins, numBins)); 4605c6c1daeSBarry Smith for (i = 0; i < numBins; i++) { 4615c6c1daeSBarry Smith binLeft = xmin + binSize * i; 4625c6c1daeSBarry Smith binRight = xmin + binSize * (i + 1); 4635c6c1daeSBarry Smith for (p = 0; p < numValues; p++) { 4645c6c1daeSBarry Smith if ((values[p] >= binLeft) && (values[p] < binRight)) bins[i]++; 4655c6c1daeSBarry Smith /* Handle last bin separately */ 4665c6c1daeSBarry Smith if ((i == numBins - 1) && (values[p] == binRight)) bins[i]++; 4675c6c1daeSBarry Smith if (!i) { 4685c6c1daeSBarry Smith mean += values[p]; 4695c6c1daeSBarry Smith var += values[p] * values[p]; 4705c6c1daeSBarry Smith } 4715c6c1daeSBarry Smith } 4725c6c1daeSBarry Smith } 4735c6c1daeSBarry Smith /* Draw bins */ 4745c6c1daeSBarry Smith for (i = 0; i < numBins; i++) { 4755c6c1daeSBarry Smith binLeft = xmin + binSize * i; 4765c6c1daeSBarry Smith binRight = xmin + binSize * (i + 1); 4779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Bin %2d (%6.2g - %6.2g): %.0g\n", (int)i, (double)binLeft, (double)binRight, (double)bins[i])); 4785c6c1daeSBarry Smith } 4799566063dSJacob Faibussowitsch PetscCall(PetscDrawHGSetNumberBins(hist, numBinsOld)); 4805c6c1daeSBarry Smith } 4815c6c1daeSBarry Smith 4825c6c1daeSBarry Smith if (hist->calcStats) { 4835c6c1daeSBarry Smith mean /= numValues; 484a297a907SKarl Rupp if (numValues > 1) var = (var - numValues * mean * mean) / (numValues - 1); 485a297a907SKarl Rupp else var = 0.0; 4869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Mean: %g Var: %g\n", (double)mean, (double)var)); 4879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Total: %" PetscInt_FMT "\n", numValues)); 4885c6c1daeSBarry Smith } 4893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4905c6c1daeSBarry Smith } 4915c6c1daeSBarry Smith 4925c6c1daeSBarry Smith /*@ 4935c6c1daeSBarry Smith PetscDrawHGSetColor - Sets the color the bars will be drawn with. 4945c6c1daeSBarry Smith 495c3339decSBarry Smith Logically Collective 4965c6c1daeSBarry Smith 4975c6c1daeSBarry Smith Input Parameters: 4985c6c1daeSBarry Smith + hist - The histogram context 4992fe279fdSBarry Smith - color - one of the colors defined in petscdraw.h or `PETSC_DRAW_ROTATE` to make each bar a different color 5005c6c1daeSBarry Smith 5015c6c1daeSBarry Smith Level: intermediate 5025c6c1daeSBarry Smith 503811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()` 5045c6c1daeSBarry Smith @*/ 505d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGSetColor(PetscDrawHG hist, int color) 506d71ae5a4SJacob Faibussowitsch { 5075c6c1daeSBarry Smith PetscFunctionBegin; 5085c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 509e118a51fSLisandro Dalcin 5105c6c1daeSBarry Smith hist->color = color; 5113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5125c6c1daeSBarry Smith } 5135c6c1daeSBarry Smith 5145c6c1daeSBarry Smith /*@ 5155c6c1daeSBarry Smith PetscDrawHGSetLimits - Sets the axis limits for a histogram. If more 5165c6c1daeSBarry Smith points are added after this call, the limits will be adjusted to 5175c6c1daeSBarry Smith include those additional points. 5185c6c1daeSBarry Smith 519c3339decSBarry Smith Logically Collective 5205c6c1daeSBarry Smith 5215c6c1daeSBarry Smith Input Parameters: 5225c6c1daeSBarry Smith + hist - The histogram context 5232fe279fdSBarry Smith . x_min - the horizontal lower limit 524*aaa8cc7dSPierre Jolivet . x_max - the horizontal upper limit 5252fe279fdSBarry Smith . y_min - the vertical lower limit 5262fe279fdSBarry Smith - y_max - the vertical upper limit 5275c6c1daeSBarry Smith 5285c6c1daeSBarry Smith Level: intermediate 5295c6c1daeSBarry Smith 530811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGGetDraw()`, `PetscDrawSetSave()`, `PetscDrawSave()`, `PetscDrawHGDraw()`, `PetscDrawHGGetAxis()` 5315c6c1daeSBarry Smith @*/ 532d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGSetLimits(PetscDrawHG hist, PetscReal x_min, PetscReal x_max, int y_min, int y_max) 533d71ae5a4SJacob Faibussowitsch { 5345c6c1daeSBarry Smith PetscFunctionBegin; 5355c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 536e118a51fSLisandro Dalcin 5375c6c1daeSBarry Smith hist->xmin = x_min; 5385c6c1daeSBarry Smith hist->xmax = x_max; 5395c6c1daeSBarry Smith hist->ymin = y_min; 5405c6c1daeSBarry Smith hist->ymax = y_max; 5413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5425c6c1daeSBarry Smith } 5435c6c1daeSBarry Smith 5445c6c1daeSBarry Smith /*@ 545811af0c4SBarry Smith PetscDrawHGCalcStats - Turns on calculation of descriptive statistics associated with the histogram 5465c6c1daeSBarry Smith 54720f4b53cSBarry Smith Not Collective 5485c6c1daeSBarry Smith 5495c6c1daeSBarry Smith Input Parameters: 5505c6c1daeSBarry Smith + hist - The histogram context 5515c6c1daeSBarry Smith - calc - Flag for calculation 5525c6c1daeSBarry Smith 5535c6c1daeSBarry Smith Level: intermediate 5545c6c1daeSBarry Smith 555811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()` 5565c6c1daeSBarry Smith @*/ 557d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGCalcStats(PetscDrawHG hist, PetscBool calc) 558d71ae5a4SJacob Faibussowitsch { 5595c6c1daeSBarry Smith PetscFunctionBegin; 5605c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 561e118a51fSLisandro Dalcin 5625c6c1daeSBarry Smith hist->calcStats = calc; 5633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5645c6c1daeSBarry Smith } 5655c6c1daeSBarry Smith 5665c6c1daeSBarry Smith /*@ 5675c6c1daeSBarry Smith PetscDrawHGIntegerBins - Turns on integer width bins 5685c6c1daeSBarry Smith 56920f4b53cSBarry Smith Not Collective 5705c6c1daeSBarry Smith 5715c6c1daeSBarry Smith Input Parameters: 5725c6c1daeSBarry Smith + hist - The histogram context 5735c6c1daeSBarry Smith - ints - Flag for integer width bins 5745c6c1daeSBarry Smith 5755c6c1daeSBarry Smith Level: intermediate 5765c6c1daeSBarry Smith 577811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()` 5785c6c1daeSBarry Smith @*/ 579d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGIntegerBins(PetscDrawHG hist, PetscBool ints) 580d71ae5a4SJacob Faibussowitsch { 5815c6c1daeSBarry Smith PetscFunctionBegin; 5825c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 583e118a51fSLisandro Dalcin 5845c6c1daeSBarry Smith hist->integerBins = ints; 5853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5865c6c1daeSBarry Smith } 5875c6c1daeSBarry Smith 5885c6c1daeSBarry Smith /*@C 5895c6c1daeSBarry Smith PetscDrawHGGetAxis - Gets the axis context associated with a histogram. 5905c6c1daeSBarry Smith This is useful if one wants to change some axis property, such as 5915c6c1daeSBarry Smith labels, color, etc. The axis context should not be destroyed by the 5925c6c1daeSBarry Smith application code. 5935c6c1daeSBarry Smith 594811af0c4SBarry Smith Not Collective, axis is parallel if hist is parallel 5955c6c1daeSBarry Smith 5965c6c1daeSBarry Smith Input Parameter: 5975c6c1daeSBarry Smith . hist - The histogram context 5985c6c1daeSBarry Smith 5995c6c1daeSBarry Smith Output Parameter: 6005c6c1daeSBarry Smith . axis - The axis context 6015c6c1daeSBarry Smith 6025c6c1daeSBarry Smith Level: intermediate 6035c6c1daeSBarry Smith 604811af0c4SBarry Smith .seealso: `PetscDrawHG`, `PetscDrawAxis`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()` 6055c6c1daeSBarry Smith @*/ 606d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGGetAxis(PetscDrawHG hist, PetscDrawAxis *axis) 607d71ae5a4SJacob Faibussowitsch { 6085c6c1daeSBarry Smith PetscFunctionBegin; 609e118a51fSLisandro Dalcin PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 61045f3bb6eSLisandro Dalcin PetscValidPointer(axis, 2); 6115c6c1daeSBarry Smith *axis = hist->axis; 6123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6135c6c1daeSBarry Smith } 6145c6c1daeSBarry Smith 6155c6c1daeSBarry Smith /*@C 6165c6c1daeSBarry Smith PetscDrawHGGetDraw - Gets the draw context associated with a histogram. 6175c6c1daeSBarry Smith 618811af0c4SBarry Smith Not Collective, draw is parallel if hist is parallel 6195c6c1daeSBarry Smith 6205c6c1daeSBarry Smith Input Parameter: 6215c6c1daeSBarry Smith . hist - The histogram context 6225c6c1daeSBarry Smith 6235c6c1daeSBarry Smith Output Parameter: 624e118a51fSLisandro Dalcin . draw - The draw context 6255c6c1daeSBarry Smith 6265c6c1daeSBarry Smith Level: intermediate 6275c6c1daeSBarry Smith 628811af0c4SBarry Smith .seealso: `PetscDraw`, `PetscDrawHG`, `PetscDrawHGCreate()`, `PetscDrawHGAddValue()`, `PetscDrawHGView()`, `PetscDrawHGDraw()`, `PetscDrawHGSetColor()`, `PetscDrawAxis`, `PetscDrawHGSetLimits()` 6295c6c1daeSBarry Smith @*/ 630d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscDrawHGGetDraw(PetscDrawHG hist, PetscDraw *draw) 631d71ae5a4SJacob Faibussowitsch { 6325c6c1daeSBarry Smith PetscFunctionBegin; 6335c6c1daeSBarry Smith PetscValidHeaderSpecific(hist, PETSC_DRAWHG_CLASSID, 1); 63445f3bb6eSLisandro Dalcin PetscValidPointer(draw, 2); 635e118a51fSLisandro Dalcin *draw = hist->win; 6363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6375c6c1daeSBarry Smith } 638