Index: /trunk/psLib/test/math/tap_psHist00.c
===================================================================
--- /trunk/psLib/test/math/tap_psHist00.c	(revision 10813)
+++ /trunk/psLib/test/math/tap_psHist00.c	(revision 10813)
@@ -0,0 +1,81 @@
+/*****************************************************************************
+    This routine must ensure that the psHistogram structure is correctly
+    allocated and deallocated by the procedure psHistogramAlloc().
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+#define ERROR_TOLERANCE 0.001
+
+psS32 genericTest(psS32 numBins, psS32 lower, psS32 higher)
+{
+    // Allocate the psHistogram structure
+    {
+        psMemId id = psMemGetId();
+        psHistogram *myHist = psHistogramAlloc(lower, higher, numBins);
+        ok(myHist != NULL, "psHistogram allocated successfully");
+        skip_start(myHist == NULL, 7, "Skipping tests because psHistogramAlloc() failed");
+        ok(myHist->nums->n = numBins, "psHistogramAlloc() set the correct number of bins");
+        ok(myHist->bounds->n == numBins+1, "psHistogramAlloc() set the correct number of bounds");
+        bool errorFlag = false;
+        for (int i=0;i<numBins;i++)
+        {
+            if (myHist->nums->data.F32[i] != 0.0) {
+                diag("ERROR: myHist->nums->data.U32[%d] not initialized to 0.\n", i);
+                errorFlag = true;
+            }
+            myHist->nums->data.F32[i] = 0.0;
+        }
+        ok(!errorFlag, "psHistogramAlloc() initialized the data to 0.0");
+        ok(myHist->minNum == 0, "psHistogramAlloc() initialized minNum to 0.0");
+        ok(myHist->maxNum == 0, "psHistogramAlloc() initialized maxNum to 0.0");
+        ok(myHist->uniform == true, "psHistogramAlloc() initialized ->uniform to true");
+
+        errorFlag = false;
+        for (int i=0;i<numBins;i++)
+        {
+            psF32 expectedBound = (psF32) (i + 1);
+            if (fabs(expectedBound - myHist->bounds->data.F32[i]) > ERROR_TOLERANCE) {
+                diag("Bin number %d bounds: (%6.3f - %6.3f)\n", i,
+                     myHist->bounds->data.F32[i],
+                     myHist->bounds->data.F32[i+1]);
+                diag("Was %f, expected %f\n", myHist->bounds->data.F32[i], expectedBound);
+                errorFlag = true;
+            }
+        }
+        ok(!errorFlag, "psHistogramAlloc() set the histogram bounds correctly");
+
+        skip_end();
+        psFree(myHist);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // XXX: How should we test these kinds of things?
+    if (0) {
+        psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message.");
+        psHistogram *myHist = psHistogramAlloc(higher, lower, 1);
+        if (myHist != NULL) {
+            printf("ERROR: myHist != NULL\n");
+        }
+    }
+    return(1);
+}
+
+psS32 main()
+{
+    psLogSetFormat("HLNM");
+    psTraceSetLevel(".", 0);
+    psTraceSetLevel("p_psVectorBinDisect", 0);
+    psTraceSetLevel("psHistogramAlloc", 0);
+    psTraceSetLevel("psHistogramAllocGeneric", 0);
+    psTraceSetLevel("UpdateHistogramBins", 0);
+    psTraceSetLevel("psVectorHistogram", 0);
+    plan_tests(36);
+
+    genericTest(1, 1, 2);
+    genericTest(2, 1, 3);
+    genericTest(10, 1, 11);
+    genericTest(20, 1, 21);
+}
Index: /trunk/psLib/test/math/tap_psHist01.c
===================================================================
--- /trunk/psLib/test/math/tap_psHist01.c	(revision 10813)
+++ /trunk/psLib/test/math/tap_psHist01.c	(revision 10813)
@@ -0,0 +1,85 @@
+/*****************************************************************************
+    This routine must ensure that the psHistogram structure is correctly
+    allocated and deallocated by the procedure psHistogramAllocGeneric().
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+#define ERROR_TOLERANCE 0.001
+
+psS32 genericTest(psS32 numBins, psS32 lower, psS32 higher)
+{
+    // Allocate the psHistogram structure
+    {
+        psMemId id = psMemGetId();
+        psVector *myBounds = psVectorAlloc(numBins+1, PS_TYPE_F32);
+        myBounds->n = myBounds->nalloc;
+        for (int i=0;i<numBins+1;i++)
+        {
+            myBounds->data.F32[i] = lower + ((higher - lower) / (float) numBins) *
+                                    (float) i;
+        }
+        psHistogram *myHist = psHistogramAllocGeneric(myBounds);
+        ok(myHist != NULL, "psHistogram allocated successfully");
+        skip_start(myHist == NULL, 7, "Skipping tests because psHistogramAlloc() failed");
+        ok(myHist->nums->n = numBins, "psHistogramAllocGeneric() set the correct number of bins");
+        ok(myHist->bounds->n == numBins+1, "psHistogramAllocGeneric() set the correct number of bounds");
+        bool errorFlag = false;
+        for (int i=0;i<numBins;i++)
+        {
+            if (myHist->nums->data.F32[i] != 0.0) {
+                diag("ERROR: myHist->nums->data.F32[%d] not initialized to 0.\n", i);
+                errorFlag = false;
+            }
+            myHist->nums->data.F32[i] = 0.0;
+        }
+        ok(!errorFlag, "psHistogramAllocGeneric() initialized the data to 0.0");
+        ok(myHist->minNum == 0, "psHistogramAllocGeneric() initialized minNum to 0.0");
+        ok(myHist->maxNum == 0, "psHistogramAllocGeneric() initialized maxNum to 0.0");
+        ok(myHist->uniform == false, "psHistogramAllocGeneric() initialized ->uniform to false");
+
+        errorFlag = false;
+        for (int i=0;i<numBins;i++)
+        {
+            psF32 expectedBound = (psF32) (i + 1);
+            if (fabs(expectedBound - myHist->bounds->data.F32[i]) > ERROR_TOLERANCE) {
+                diag("Bin number %d bounds: (%6.3f - %6.3f)\n", i,
+                     myHist->bounds->data.F32[i],
+                     myHist->bounds->data.F32[i+1]);
+                diag("Was %f, expected %f\n", myHist->bounds->data.F32[i], expectedBound);
+                errorFlag = true;
+            }
+        }
+        ok(!errorFlag, "psHistogramAlloc() set the histogram bounds correctly");
+
+        skip_end();
+        psFree(myHist);
+        psFree(myBounds);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+
+    }
+    return(1);
+}
+
+
+psS32 main()
+{
+    psLogSetFormat("HLNM");
+    //
+    // We list pertinent psStats.c functions here for debugging ease.
+    //
+    psTraceSetLevel(".", 0);
+    psTraceSetLevel("p_psVectorBinDisect", 0);
+    psTraceSetLevel("psHistogramAlloc", 0);
+    psTraceSetLevel("psHistogramAllocGeneric", 0);
+    psTraceSetLevel("UpdateHistogramBins", 0);
+    psTraceSetLevel("psVectorHistogram", 0);
+    plan_tests(36);
+
+    genericTest(1, 1, 2);
+    genericTest(2, 1, 3);
+    genericTest(10, 1, 11);
+    genericTest(20, 1, 21);
+}
Index: /trunk/psLib/test/math/tap_psHist02.c
===================================================================
--- /trunk/psLib/test/math/tap_psHist02.c	(revision 10813)
+++ /trunk/psLib/test/math/tap_psHist02.c	(revision 10813)
@@ -0,0 +1,170 @@
+/*****************************************************************************
+   This routine must ensure that the psHistogram structure is correctly
+   populated by the procedure psGetArrayHistogram().
+ 
+*****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+#define ERROR_TOLERANCE 0.001
+#define NUM_DATA 10000
+
+psS32 genericTest(psS32 numBins, psS32 lower, psS32 higher)
+{
+    if ((numBins%2) != 0) {
+        diag("Configuration error: must run this test with even number of bins");
+        return(0);
+    }
+    if ((NUM_DATA%numBins) != 0) {
+        diag("Configuration error: NUM_DATA must be an integer multiple of numBins");
+        return(0);
+    }
+
+    // Allocate the psHistogram structure, ensure that psVectorHistogram() sets
+    // the data correctly when called with a NULL mask.
+    {
+        psMemId id = psMemGetId();
+        psVector *myData = psVectorAlloc( NUM_DATA, PS_TYPE_F32 );
+        myData->n = myData->nalloc;
+        for (int i = 0;i < NUM_DATA;i++)
+        {
+            myData->data.F32[ i ] = lower + ( ( higher - lower ) / ( float ) NUM_DATA ) * ( float ) i;
+        }
+
+        psHistogram *myHist = psHistogramAlloc(lower, higher, numBins );
+        myHist = psVectorHistogram( myHist, myData, NULL, NULL, 0 );
+        ok(myHist != NULL, "psVectorHistogram() returned a non-NULL psHistogram");
+        skip_start(myHist == NULL, 1, "Skipping tests because psVectorHistogram() returned NULL");
+
+        bool errorFlag = false;
+        for (int i = 0;i < numBins;i++)
+        {
+            if (fabs(myHist->nums->data.F32[i] - (NUM_DATA/numBins)) > ERROR_TOLERANCE) {
+                diag("Bin number %d bounds: (%.2f - %.2f) data (%.2f) should be (%.2f)\n",
+                     i,
+                     myHist->bounds->data.F32[i],
+                     myHist->bounds->data.F32[i + 1],
+                     myHist->nums->data.F32[i], (float) (NUM_DATA/numBins));
+                errorFlag = true;
+            }
+        }
+        ok(!errorFlag, "psVectorHistogram() correctly set the histogram");
+        skip_end();
+        psFree(myHist);
+        psFree(myData);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Allocate the psHistogram structure, ensure that psVectorHistogram() sets
+    // the data correctly when called with a mask.
+    {
+        psMemId id = psMemGetId();
+        psVector *myData = psVectorAlloc( NUM_DATA, PS_TYPE_F32 );
+        myData->n = myData->nalloc;
+        for (int i = 0;i < NUM_DATA;i++)
+        {
+            myData->data.F32[ i ] = lower + ( ( higher - lower ) / ( float ) NUM_DATA ) * ( float ) i;
+        }
+
+        psVector *myMask = psVectorAlloc( NUM_DATA, PS_TYPE_U8 );
+        myMask->n = myMask->nalloc;
+        for (int i = 0;i < NUM_DATA;i++)
+        {
+            if ( i >= ( NUM_DATA / 2 ) ) {
+                myMask->data.U8[ i ] = 1;
+            } else {
+                myMask->data.U8[ i ] = 0;
+            }
+        }
+        psHistogram *myHist = psHistogramAlloc(lower, higher, numBins );
+        myHist = psVectorHistogram(myHist, myData, NULL, myMask, 1);
+        ok(myHist != NULL, "psVectorHistogram() returned a non-NULL psHistogram");
+        skip_start(myHist == NULL, 1, "Skipping tests because psVectorHistogram() returned NULL");
+
+        bool errorFlag = false;
+        for (int i = 0;i < numBins;i++)
+        {
+            if (i < numBins/2) {
+                if (fabs(myHist->nums->data.F32[i] - (NUM_DATA/numBins)) > ERROR_TOLERANCE) {
+                    diag("Bin number %d bounds: (%6.3f - %6.3f) data (%f) should be (%.2f)\n", i,
+                         myHist->bounds->data.F32[ i ],
+                         myHist->bounds->data.F32[ i + 1 ],
+                         myHist->nums->data.F32[ i ], (float) (NUM_DATA/numBins) );
+                    errorFlag = true;
+                }
+            } else {
+                if (fabs(myHist->nums->data.F32[i]) > ERROR_TOLERANCE) {
+                    diag("Bin number %d bounds: (%6.3f - %6.3f) data (%f) should be (%.2f)\n", i,
+                         myHist->bounds->data.F32[ i ],
+                         myHist->bounds->data.F32[ i + 1 ],
+                         myHist->nums->data.F32[ i ], 0.0);
+                    errorFlag = true;
+                }
+            }
+        }
+        ok(!errorFlag, "psVectorHistogram() correctly set the histogram");
+        skip_end();
+        psFree(myHist);
+        psFree(myMask);
+        psFree(myData);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Verify the return value is null and program execution doesn't stop,
+    // if input parameter myHist is null.
+    {
+        psMemId id = psMemGetId();
+        psVector *myData = psVectorAlloc( NUM_DATA, PS_TYPE_F32 );
+        myData->n = myData->nalloc;
+        for (int i = 0;i < NUM_DATA;i++)
+        {
+            myData->data.F32[ i ] = lower + ( ( higher - lower ) / ( float ) NUM_DATA ) * ( float ) i;
+        }
+        ok(NULL == psVectorHistogram( NULL, myData, NULL, NULL, 0 ), "psVectorHistogram() returned NULL with a NULL psHistogram input");
+        psFree( myData );
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Verify the return value is the same as the input parameter myHist and
+    // program execution doesn't stop, if the input parameter myArray is
+    // null.
+    {
+        psMemId id = psMemGetId();
+        psHistogram *myHist = psHistogramAlloc(lower, higher, numBins );
+        ok(NULL != psVectorHistogram( myHist, NULL, NULL, NULL, 0 ), "psVectorHistogram() returns non-NULL with a NULL input array");
+        psFree(myHist);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Verify the return value is the same as the input parameter myHist and
+    // program execution doesn't stop, if the input parameter myArray has no
+    // elements.
+    // XXX: This code segment is commented out because psVectorAlloc returns
+    // NULL if called with an N element data.
+    {
+        psMemId id = psMemGetId();
+        psVector *myData = psVectorAlloc(0, PS_TYPE_F32);
+        psHistogram *myHist = psHistogramAlloc(lower, higher, numBins);
+        myHist = psVectorHistogram(myHist, NULL, NULL, NULL, 0);
+        ok(NULL != psVectorHistogram( myHist, NULL, NULL, NULL, 0 ), "psVectorHistogram() returns non-NULL with an empty input array");
+        psFree(myHist);
+        psFree(myData);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    return(1);
+}
+
+psS32 main()
+{
+    psLogSetFormat("HLNM");
+    plan_tests(48);
+
+    genericTest(2, 1, 3);
+    genericTest(10, 1, 11);
+    genericTest(20, 1, 21);
+    genericTest(500, 1, 501);
+}
Index: /trunk/psLib/test/math/tap_psHist03.c
===================================================================
--- /trunk/psLib/test/math/tap_psHist03.c	(revision 10813)
+++ /trunk/psLib/test/math/tap_psHist03.c	(revision 10813)
@@ -0,0 +1,92 @@
+/*****************************************************************************
+    This routine must ensure that the psHistogram structure is correctly
+    allocated and deallocated by the procedure psHistogramAllocGeneric() and
+    that it can be populated correctly by psVectorHistogram().
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+#define ERROR_TOLERANCE 0.001
+#define NUM_DATA 20
+
+psS32 genericTest(psS32 numBins, psS32 lower, psS32 higher)
+{
+    if (numBins > NUM_DATA) {
+        diag("Configuration error: NUM_DATA must be larger than numBins");
+        return(0);
+    }
+
+    {
+        psMemId id = psMemGetId();
+        psVector *myData = psVectorAlloc( NUM_DATA, PS_TYPE_F32 );
+        myData->n = myData->nalloc;
+        for (int i = 0;i < NUM_DATA;i++ ) {
+            myData->data.F32[ i ] = lower + ((higher-lower) / (float) NUM_DATA) * (float) i;
+        }
+
+        psVector *myBounds = psVectorAlloc(numBins+1, PS_TYPE_F32);
+        myBounds->n = myBounds->nalloc;
+        for (int i=0;i<numBins+1;i++) {
+            myBounds->data.F32[i] = lower + ((higher - lower) / (float) numBins) * (float) i;
+        }
+
+        psHistogram *myHist = psHistogramAllocGeneric(myBounds);
+        ok(myHist->nums->n == numBins, "psHistogramAllocGeneric() set correct number of bins");
+        ok(myHist->bounds->n == numBins+1, "sHistogramAllocGeneric() set correct number of bounds");
+
+        bool errorFlag = false;
+        for (int i=0;i<numBins;i++) {
+            if (fabs(myHist->nums->data.F32[i]) > ERROR_TOLERANCE) {
+                diag("ERROR: myHist->nums->data.F32[%d] not initialized to 0.\n", i);
+                errorFlag = true;
+            }
+            myHist->nums->data.F32[i] = 0.0;
+        }
+        ok(!errorFlag, "psVectorHistogram() correctly initialized the bins");
+        ok(myHist->minNum == 0, "psHistogramAlloc() initialized minNum to 0.0");
+        ok(myHist->maxNum == 0, "psHistogramAlloc() initialized maxNum to 0.0");
+        ok(myHist->uniform == false, "psHistogramAlloc() initialized ->uniform to false");
+
+        myHist = psVectorHistogram( myHist, myData, NULL, NULL, 0 );
+        for (int i=0;i<numBins;i++) {
+            psF32 expected = ((float) NUM_DATA) / ((float) numBins);
+            if (fabs(myHist->nums->data.F32[i] - expected) > ERROR_TOLERANCE) {
+                diag("Bin number %d bounds: (%.2f - %.2f): data: (%.2f) should be (%.2f)\n", i,
+                     myHist->bounds->data.F32[i],
+                     myHist->bounds->data.F32[i+1],
+                     myHist->nums->data.F32[i], expected);
+                errorFlag = true;
+            }
+        }
+        ok(!errorFlag, "psVectorHistogram() correctly initialized the bins");
+
+        psFree(myData);
+        psFree(myHist);
+        psFree(myBounds);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+    return (1);
+}
+
+psS32 main()
+{
+    psLogSetFormat("HLNM");
+    //
+    // We list pertinent psStats.c functions here for debugging ease.
+    //
+    psTraceSetLevel(".", 0);
+    psTraceSetLevel(".psLib", 0);
+    psTraceSetLevel("p_psVectorBinDisect", 0);
+    psTraceSetLevel("psHistogramAlloc", 0);
+    psTraceSetLevel("psHistogramAllocGeneric", 0);
+    psTraceSetLevel("UpdateHistogramBins", 0);
+    psTraceSetLevel("psVectorHistogram", 0);
+    plan_tests(32);
+
+    genericTest(1, 1, 2);
+    genericTest(2, 1, 3);
+    genericTest(10, 1, 11);
+    genericTest(20, 1, 21);
+}
