Index: /trunk/psLib/test/math/tap_psStats00.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats00.c	(revision 10831)
+++ /trunk/psLib/test/math/tap_psStats00.c	(revision 10831)
@@ -0,0 +1,295 @@
+@file  tst_psStats00.c
+*
+*  @brief Contains tests for psVectorStats with sample mean calculations
+*
+*  We extensively test the code with data type PS_TYPE_F32.  If these pass, we
+*  do
+    a much simpler test with data type PS_TYPE_U8, PS_TYPE_U16, PS_TYPE_F64.
+    *
+    *  @author GLG, MHPCC
+    *
+*  @version $Revision:
+1.8 $  $Name:
+    $
+*  @date $Date:
+2006/07/28 00:
+44:
+    05 $
+    *
+    *  Copyright 2004-2005 Maui High Performance Computing Center, Univ. of Hawaii
+    */
+    #include <stdio.h>
+    #include <string.h>
+    #include <pslib.h>
+    #include "tap.h"
+    #include "pstap.h"
+
+    #define N 15
+
+    static psF32 samplesF32[N] =
+            {
+                1.1, 2.2, -3.3, 4.4, 5.5, -6.6, 7.7, 8.8, -9.9, 10.0,
+                11.01, -12.02, 13.03, 14.04, -15.05
+            };
+static psS8  samplesS8[N]  =
+    {
+        1, 2, -3, 4, 5, -6, 7, 8, -9, 10, 11, -12, 13, 14, -15
+    };
+static psU16 samplesU16[N] =
+    {
+        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+    };
+static psF64 samplesF64[N] =
+    {
+        1.1, 2.2, -3.3, 4.4, 5.5, -6.6, 7.7, 8.8, -9.9, 10.0,
+        11.01, -12.02, 13.03, 14.04, -15.05
+    };
+static psF32 errorsF32[N] =
+    {
+        -0.10,  0.11, -0.12,  0.13, -0.14,  0.15, -0.16,  0.17,
+        -0.18,  0.19, -0.20,  0.21, -0.22,  0.23, -0.24
+    };
+
+static psF64 expectedMeanNoMaskF32              =  2.060667;
+static psF64 expectedMeanWithMaskF32            =  2.123846;
+static psF64 expectedMeanNoMaskS8               =  2.000000;
+static psF64 expectedMeanNoMaskU16              =  8.000000;
+static psF64 expectedMeanNoMaskF64              =  2.060667;
+static psF64 expectedMeanRangeNoMaskF32         =  0.137500;
+static psF64 expectedMeanRangeWithMaskF32       = -0.366667;
+static psF64 expectedWeightMeanNoMaskF32        =  1.807210;
+static psF64 expectedWeightMeanWithMaskF32      =  1.890217;
+static psF64 expectedWeightMeanNoMaskRangeF32   =  0.640952;
+static psF64 expectedWeightMeanWithMaskRangeF32 =  0.046574;
+
+#include <unistd.h>
+psS32 main(psS32 argc, char* argv[] )
+{
+    psMemId idGlobal = psMemGetId();
+    psLogSetFormat("HLNM");
+    plan_tests(46);
+
+    // Allocate data vectors for F32 tests
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+    psVector *myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    psVector *myErrors = psVectorAlloc(N, PS_TYPE_F32);
+    myErrors->n = N;
+    psVector *maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+    // Set the appropriate values for the vector data.
+    for (long i = 0; i < N; i++) {
+        myVector->data.F32[i] =  samplesF32[i];
+        myErrors->data.F32[i] =  errorsF32[i];
+        if (i > 1) {
+            maskVector->data.U8[i] = 0;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    // Call psVectorStats() with no vector mask.
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedMeanNoMaskF32, 1e-4,
+                     "The mean was %f, should be %f", myStats->sampleMean, expectedMeanNoMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke psVectorStats with no vector mask and error vector
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, myErrors, NULL, 0);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedWeightMeanNoMaskF32, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedWeightMeanNoMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke psVectorStats with no vector mask and data range
+    {
+        psMemId id = psMemGetId();
+        myStats->options = PS_STAT_SAMPLE_MEAN | PS_STAT_USE_RANGE;
+        myStats->min = -10.0;
+        myStats->max =   8.0;
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedMeanRangeNoMaskF32, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedMeanRangeNoMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Invoke psVectorStats with no vector mask, errors and data range
+    {
+        psMemId id = psMemGetId();
+        myStats->options = PS_STAT_SAMPLE_MEAN | PS_STAT_USE_RANGE;
+        myStats = psVectorStats(myStats, myVector, myErrors, NULL, 0);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedWeightMeanNoMaskRangeF32, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedWeightMeanNoMaskRangeF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Call psVectorStats() with vector mask=1
+    {
+        psMemId id = psMemGetId();
+        myStats->options = PS_STAT_SAMPLE_MEAN;
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedMeanWithMaskF32, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedMeanWithMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke psVectorStats with vector mask and error vector
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, myErrors, maskVector, 1);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedWeightMeanWithMaskF32, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedWeightMeanWithMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke psVectorStats with vector mask and data range
+    {
+        psMemId id = psMemGetId();
+        myStats->options = PS_STAT_SAMPLE_MEAN | PS_STAT_USE_RANGE;
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedMeanRangeWithMaskF32, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedMeanRangeWithMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke psVectorStats with vector mask, errors, and data range
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, myErrors, maskVector, 1);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedWeightMeanWithMaskRangeF32, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedWeightMeanWithMaskRangeF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Call psVectorStats() with vector mask=2.
+    {
+        psMemId id = psMemGetId();
+        myStats->options = PS_STAT_SAMPLE_MEAN;
+        for (psS32 i = 0; i < N; i++) {
+            if (maskVector->data.U8[i] == 1) {
+                maskVector->data.U8[i] = 2;
+            }
+        }
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 2);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedMeanWithMaskF32, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedMeanWithMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Call psVectorStats() with vector mask=3.
+    {
+        psMemId id = psMemGetId();
+        for (psS32 i = 0; i < N; i++)
+        {
+            if (maskVector->data.U8[i] == 2) {
+                maskVector->data.U8[i] = 3;
+            }
+        }
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 4);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedMeanNoMaskF32, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedMeanNoMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Mask all values and verify return is NAN
+    {
+        psMemId id = psMemGetId();
+        for(psS32 i = 0; i < N; i++)
+        {
+            maskVector->data.U8[i] = 1;
+        }
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(isnan(myStats->sampleMean), "psVectorStats() returned NAN");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Call psVectorStats() with NULL inputs.
+    {
+        psMemId id = psMemGetId();
+        ok(psVectorStats(myStats, NULL, NULL, NULL, 0) == NULL, "psVectorStats() returned NULL with NULL inputs");
+        ok(psVectorStats(NULL, myVector, NULL, NULL, 0) == NULL, "psVectorStats() returned NULL with NULL inputs");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+
+
+
+
+
+
+
+
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(myErrors);
+    psFree(maskVector);
+    ok(!psMemCheckLeaks (idGlobal, NULL, NULL, false), "no memory leaks");
+    ok(!psMemCheckLeaks (idGlobal, NULL, NULL, false), "no memory leaks");
+
+
+    // Test SampleMean: S8
+    {
+        psMemId id = psMemGetId();
+        psStats* myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        psVector* myVector = psVectorAlloc(N, PS_TYPE_S8);
+        for (psS32 i = 0; i < N; i++)
+        {
+            myVector->data.S8[i] =  samplesS8[i];
+        }
+
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedMeanNoMaskS8, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedMeanNoMaskS8);
+        psFree(myStats);
+        psFree(myVector);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+
+    // Test SampleMean: U16
+    {
+        psMemId id = psMemGetId();
+        psStats* myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        psVector* myVector = psVectorAlloc(N, PS_TYPE_U16);
+        myVector->n = N;
+        for (psS32 i = 0; i < N; i++)
+        {
+            myVector->data.U16[i] =  samplesU16[i];
+        }
+
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedMeanNoMaskU16, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedMeanNoMaskU16);
+        psFree(myStats);
+        psFree(myVector);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test SampleMean: F64
+    {
+        psMemId id = psMemGetId();
+        psStats* myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        psVector* myVector = psVectorAlloc(N, PS_TYPE_F64);
+        myVector->n = N;
+        for (psS32 i = 0; i < N; i++)
+        {
+            myVector->data.F64[i] =  samplesF64[i];
+        }
+
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->sampleMean), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMean, expectedMeanNoMaskF64, 1e-4, "The mean was %f, should be %f", myStats->sampleMean, expectedMeanNoMaskF64);
+        psFree(myStats);
+        psFree(myVector);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+}
Index: /trunk/psLib/test/math/tap_psStats01.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats01.c	(revision 10831)
+++ /trunk/psLib/test/math/tap_psStats01.c	(revision 10831)
@@ -0,0 +1,179 @@
+/** @file  tst_psStats01.c
+*
+*  @brief Contains tests for psVectorStats with max calculations.
+*
+*  We extensively test the code with data type PS_TYPE_F32.  If these pass, we
+*  do a much simpler test with data types PS_TYPE_U8, PS_TYPE_U16, PS_TYPE_F64.
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
+*  @date $Date: 2006-12-26 20:33:55 $
+*
+* Copyright 2004-2005 Maui High Performance Computing Center, Univ. of Hawaii
+*/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+
+#define N 15
+
+static psF32 samplesF32[N] = { 1.1, 2.2, -3.3, 4.4, 5.5, -6.6, 7.7, 8.8, -9.9, 10.0,
+                               11.01, -12.02, 13.03, 14.04, -15.05 };
+static psS8  samplesS8[N]  = {1, 2, -3, 4, 5, -6, 7, 8, -9, 10, 11, -12, 13, 14, -15};
+static psU16 samplesU16[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+static psF64 samplesF64[N] = { 1.1, 2.2, -3.3, 4.4, 5.5, -6.6, 7.7, 8.8, -9.9, 10.0,
+                               11.01, -12.02, 13.03, 14.04, -15.05 };
+
+static psF64 expectedMaxNoMaskF32                = 14.04;
+static psF64 expectedMaxNoMaskS8                 = 14.00;
+static psF64 expectedMaxNoMaskU16                = 15.00;
+static psF64 expectedMaxNoMaskF64                = 14.04;
+
+static psF64 expectedMaxWithMaskF32              = 13.03;
+static psF64 expectedMaxRangeNoMaskF32           = 10.00;
+static psF64 expectedMaxRangeWithMaskF32         = 13.03;
+
+psS32 main(psS32 argc, char* argv[] )
+{
+    psMemId idGlobal = psMemGetId();
+    psLogSetFormat("HLNM");
+    plan_tests(24);
+
+    psStats* myStats = psStatsAlloc(PS_STAT_MAX);
+    psVector* myVector =  psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    psVector* maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+    for (psS32 i = 0; i < N; i++) {
+        myVector->data.F32[i] = samplesF32[i];
+        if (i < 13) {
+            maskVector->data.U8[i] = 0;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    // Call psVectorStats() with no vector mask
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->max), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->max, expectedMaxNoMaskF32, 1e-4,
+                     "The max was %f, should be %f", myStats->max, expectedMaxNoMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Call psVectorStats() with vector mask
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(!isnan(myStats->max), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->max, expectedMaxWithMaskF32, 1e-4,
+                     "The max was %f, should be %f", myStats->max, expectedMaxWithMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke function with data range with no mask
+    {
+        psMemId id = psMemGetId();
+        myStats->options = PS_STAT_MAX | PS_STAT_USE_RANGE;
+        myStats->max = 10.2;
+        myStats->min = 0.0;
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->max), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->max, expectedMaxRangeNoMaskF32, 1e-4,
+                     "The max was %f, should be %f", myStats->max, expectedMaxRangeNoMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke function with data range and mask
+    {
+        psMemId id = psMemGetId();
+        myStats->max = 14.0;
+        myStats->min = 0.0;
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(!isnan(myStats->max), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->max, expectedMaxRangeWithMaskF32, 1e-4,
+                     "The max was %f, should be %f", myStats->max, expectedMaxRangeWithMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke function with data range with no valid data
+    {
+        psMemId id = psMemGetId();
+        myStats->max = 100.00;
+        myStats->min = 90.00;
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(isnan(myStats->max), "psVectorStats() returned NAN");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+    ok(!psMemCheckLeaks (idGlobal, NULL, NULL, false), "no memory leaks");
+
+    // Test StatsMax: S8
+    {
+        psMemId id = psMemGetId();
+        psStats* myStats = psStatsAlloc(PS_STAT_MAX);
+        psVector* myVector = psVectorAlloc(N, PS_TYPE_S8);
+        myVector->n = N;
+        for (psS32 i = 0; i < N; i++)
+        {
+            myVector->data.S8[i] = samplesS8[i];
+        }
+
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->max), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->max, expectedMaxNoMaskS8, 1e-4,
+                     "The max was %f, should be %f", myStats->max, expectedMaxNoMaskS8);
+        psFree(myStats);
+        psFree(myVector);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test StatsMax: U16
+    {
+        psMemId id = psMemGetId();
+        psStats* myStats = psStatsAlloc(PS_STAT_MAX);
+        psVector* myVector = psVectorAlloc(N, PS_TYPE_U16);
+        myVector->n = N;
+        for (psS32 i = 0; i < N; i++)
+        {
+            myVector->data.U16[i] = samplesU16[i];
+        }
+
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->max), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->max, expectedMaxNoMaskU16, 1e-4,
+                     "The max was %f, should be %f", myStats->max, expectedMaxNoMaskU16);
+        psFree(myStats);
+        psFree(myVector);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test StatsMax: F64
+    {
+        psMemId id = psMemGetId();
+        psStats* myStats = psStatsAlloc(PS_STAT_MAX);
+        psVector* myVector = psVectorAlloc(N, PS_TYPE_F64);
+        myVector->n = N;
+        for (psS32 i = 0; i < N; i++)
+        {
+            myVector->data.F64[i] = samplesF64[i];
+        }
+
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->max), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->max, expectedMaxNoMaskF64, 1e-4,
+                     "The max was %f, should be %f", myStats->max, expectedMaxNoMaskF64);
+        psFree(myStats);
+        psFree(myVector);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+}
+
Index: /trunk/psLib/test/math/tap_psStats02.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats02.c	(revision 10831)
+++ /trunk/psLib/test/math/tap_psStats02.c	(revision 10831)
@@ -0,0 +1,185 @@
+/** @file  tst_psStats02.c
+*
+*  @brief Contains tests for psVectorStats with min calculations
+*
+*  We extensively test the code with data type PS_TYPE_F32.  If these pass, we
+*  do a much simpler test with data types PS_TYPE_U8, PS_TYPE_U16, PS_TYPE_F64.
+*
+*  If the psStats,c code every changes such that vectors of different type
+*  are handled by different routines, then these tests must be extended.
+*
+*  @author GLG, MHPCC
+*
+*  @version $Revision: 1.1 $  $Name: not supported by cvs2svn $
+*  @date $Date: 2006-12-26 20:33:55 $
+*
+* Copyright 2004-2005 Maui High Performance Computing Center, Univ. of Hawaii
+*/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+#define N 15
+
+static psF32 samplesF32[N] = { 1.1, 2.2, -3.3, 4.4, 5.5, -6.6, 7.7, 8.8, -9.9, 10.0,
+                               11.01, -12.02, 13.03, 14.04, -15.05 };
+static psS8  samplesS8[N]  = {1, 2, -3, 4, 5, -6, 7, 8, -9, 10, 11, -12, 13, 14, -15};
+static psU16 samplesU16[N] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+static psF64 samplesF64[N] = { 1.1, 2.2, -3.3, 4.4, 5.5, -6.6, 7.7, 8.8, -9.9, 10.0,
+                               11.01, -12.02, 13.03, 14.04, -15.05 };
+
+static psF64 expectedMinNoMaskF32                = -15.05;
+static psF64 expectedMinNoMaskS8                 = -15.00;
+static psF64 expectedMinNoMaskU16                = 1.00;
+static psF64 expectedMinNoMaskF64                = -15.05;
+
+static psF64 expectedMinWithMaskF32              = -12.02;
+static psF64 expectedMinRangeNoMaskF32           =   1.10;
+static psF64 expectedMinRangeWithMaskF32         = -12.02;
+
+psS32 main(psS32 argc, char* argv[] )
+{
+    psMemId idGlobal = psMemGetId();
+    psLogSetFormat("HLNM");
+    plan_tests(24);
+
+    psStats* myStats = psStatsAlloc(PS_STAT_MIN);
+    psVector* myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    psVector* maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+    for (psS32 i = 0; i < N; i++) {
+        myVector->data.F32[i] = samplesF32[i];
+        if (i < 13) {
+            maskVector->data.U8[i] = 0;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with no vector mask.                    */
+    /*************************************************************************/
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->min), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->min, expectedMinNoMaskF32, 1e-4,
+                     "The min was %f, should be %f", myStats->min, expectedMinNoMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    /*************************************************************************/
+    /*  Call psVectorStats() with vector mask.                       */
+    /*************************************************************************/
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(!isnan(myStats->min), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->min, expectedMinWithMaskF32, 1e-4,
+                     "The min was %f, should be %f", myStats->min, expectedMinWithMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke function with data range with no mask
+    {
+        psMemId id = psMemGetId();
+        myStats->options = PS_STAT_MIN | PS_STAT_USE_RANGE;
+        myStats->max = 10.2;
+        myStats->min = 0.0;
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->min), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->min, expectedMinRangeNoMaskF32, 1e-4,
+                     "The min was %f, should be %f", myStats->min, expectedMinRangeNoMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke function with data range and mask
+    {
+        psMemId id = psMemGetId();
+        myStats->max = 10.1;
+        myStats->min = -15.00;
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(!isnan(myStats->min), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->min, expectedMinRangeWithMaskF32, 1e-4,
+                     "The min was %f, should be %f", myStats->min, expectedMinRangeWithMaskF32);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Invoke function with data range with no valid data
+    {
+        psMemId id = psMemGetId();
+        myStats->max = 100.00;
+        myStats->min = 90.00;
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(isnan(myStats->min), "psVectorStats() returned NAN");
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+    ok(!psMemCheckLeaks (idGlobal, NULL, NULL, false), "no memory leaks");
+
+
+    // Test StatsMin: S8
+    {
+        psMemId id = psMemGetId();
+        psStats* myStats = psStatsAlloc(PS_STAT_MIN);
+        psVector* myVector = psVectorAlloc(N, PS_TYPE_S8);
+        myVector->n = N;
+        for (psS32 i = 0; i < N; i++)
+        {
+            myVector->data.S8[i] = samplesS8[i];
+        }
+
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->min), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->min, expectedMinNoMaskS8, 1e-4,
+                     "The min was %f, should be %f", myStats->min, expectedMinNoMaskS8);
+        psFree(myStats);
+        psFree(myVector);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test StatsMin: U16
+    {
+        psMemId id = psMemGetId();
+        psStats* myStats = psStatsAlloc(PS_STAT_MAX);
+        psVector* myVector = psVectorAlloc(N, PS_TYPE_U16);
+        myVector->n = N;
+        for (psS32 i = 0; i < N; i++)
+        {
+            myVector->data.U16[i] = samplesU16[i];
+        }
+
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->min), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->min, expectedMinNoMaskU16, 1e-4,
+                     "The min was %f, should be %f", myStats->min, expectedMinNoMaskU16);
+        psFree(myStats);
+        psFree(myVector);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Test StatsMin: F64
+    {
+        psMemId id = psMemGetId();
+        psStats* myStats = psStatsAlloc(PS_STAT_MIN);
+        psVector* myVector = psVectorAlloc(N, PS_TYPE_F64);
+        myVector->n = N;
+        for (psS32 i = 0; i < N; i++)
+        {
+            myVector->data.F64[i] = samplesF64[i];
+        }
+
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->min), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->min, expectedMinNoMaskF64, 1e-4,
+                     "The min was %f, should be %f", myStats->min, expectedMinNoMaskF64);
+        psFree(myStats);
+        psFree(myVector);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+}
+
Index: /trunk/psLib/test/math/tap_psStats03.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats03.c	(revision 10831)
+++ /trunk/psLib/test/math/tap_psStats03.c	(revision 10831)
@@ -0,0 +1,64 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_MEDIAN is correctly computed
+    by the procedure psVectorStats().
+ 
+    XXX: Must add tests for various data types, other than psF32.  Copy code
+    from tst_psStats00.c-tst_psStats02.c.
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+
+#define N1 1029   // This should be an odd number.
+#define N ((4 * N1) + 1)
+float realMedianWithMask = (float) (N-3)/4;
+float realMedianNoMask = (float) (N-1)/2;
+
+psS32 main()
+{
+    psMemId idGlobal = psMemGetId();
+    psLogSetFormat("HLNM");
+    plan_tests(7);
+
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN);
+    psVector *myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    psVector *maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+    // Set the appropriate values for the vector data.
+    for (int i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    // Call psVectorStats() with no vector mask
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->sampleMedian), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMedian, realMedianNoMask, 1e-4,
+                     "The sample median was %f, should be %f", myStats->sampleMedian, realMedianNoMask);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Call psVectorStats() with vector mask
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(!isnan(myStats->sampleMedian), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleMedian, realMedianWithMask, 1e-4,
+                     "The sample median was %f, should be %f", myStats->sampleMedian, realMedianWithMask);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+    ok(!psMemCheckLeaks (idGlobal, NULL, NULL, false), "no memory leaks");
+}
Index: /trunk/psLib/test/math/tap_psStats05.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats05.c	(revision 10831)
+++ /trunk/psLib/test/math/tap_psStats05.c	(revision 10831)
@@ -0,0 +1,49 @@
+/*****************************************************************************
+    This routine must ensure that the psStats structure is correctly
+    allocated and deallocated by the procedure psStatsAlloc().
+ 
+    XXX: This should be test 00.  It should be merged into other tests
+         since it's so trivial.
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+#define MISC_FLOAT_NUMBER 342.0
+
+psS32 main()
+{
+    psLogSetFormat("HLNM");
+    plan_tests(1);
+
+    {
+        psMemId id = psMemGetId();
+        psStats *myStats =psStatsAlloc(PS_STAT_SAMPLE_MEAN);
+        myStats->sampleMean = MISC_FLOAT_NUMBER;
+        myStats->sampleMedian = MISC_FLOAT_NUMBER;
+        myStats->sampleStdev = MISC_FLOAT_NUMBER;
+        myStats->sampleUQ = MISC_FLOAT_NUMBER;
+        myStats->sampleLQ = MISC_FLOAT_NUMBER;
+        myStats->robustMedian = MISC_FLOAT_NUMBER;
+        myStats->robustStdev = MISC_FLOAT_NUMBER;
+        myStats->robustUQ = MISC_FLOAT_NUMBER;
+        myStats->robustLQ = MISC_FLOAT_NUMBER;
+        myStats->robustN50 = MISC_FLOAT_NUMBER;
+        myStats->fittedMean = MISC_FLOAT_NUMBER;
+        myStats->fittedStdev = MISC_FLOAT_NUMBER;
+        myStats->fittedNfit = MISC_FLOAT_NUMBER;
+        myStats->clippedMean = MISC_FLOAT_NUMBER;
+        myStats->clippedStdev = MISC_FLOAT_NUMBER;
+        myStats->clippedNvalues = MISC_FLOAT_NUMBER;
+        myStats->clipSigma = MISC_FLOAT_NUMBER;
+        myStats->clipIter = MISC_FLOAT_NUMBER;
+        myStats->min = MISC_FLOAT_NUMBER;
+        myStats->max = MISC_FLOAT_NUMBER;
+        myStats->binsize = MISC_FLOAT_NUMBER;
+        myStats->nSubsample = MISC_FLOAT_NUMBER;
+        myStats->options = 0x0;
+        psFree(myStats);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+}
Index: /trunk/psLib/test/math/tap_psStats06.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats06.c	(revision 10831)
+++ /trunk/psLib/test/math/tap_psStats06.c	(revision 10831)
@@ -0,0 +1,65 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_STDEV is correctly computed
+    by the procedure psArrayStats().
+ 
+    XXX: Must add tests for various data types, other than psF32.  Copy code
+    from tst_psStats00.c-tst_psStats02.c.
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+//#include "float.h"
+//#include <math.h>
+#define N 15
+float realStdevNoMask = 4.472136;
+float realStdevWithMask = 2.160247;
+
+psS32 main()
+{
+    psMemId idGlobal = psMemGetId();
+    psLogSetFormat("HLNM");
+    plan_tests(7);
+
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_STDEV);
+    psVector *myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    psVector *maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+    psS32 count           = 0;
+    for (int i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+            count++;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+    // Call psVectorStats() with no vector mask
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->sampleStdev), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleStdev, realStdevNoMask, 1e-4,
+                     "The mean was %f, should be %f", myStats->sampleStdev, realStdevNoMask);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Call psVectorStats() with vector mask
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(!isnan(myStats->sampleStdev), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleStdev, realStdevWithMask, 1e-4,
+                     "The mean was %f, should be %f", myStats->sampleStdev, realStdevWithMask);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+    ok(!psMemCheckLeaks (idGlobal, NULL, NULL, false), "no memory leaks");
+}
Index: /trunk/psLib/test/math/tap_psStats07.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats07.c	(revision 10831)
+++ /trunk/psLib/test/math/tap_psStats07.c	(revision 10831)
@@ -0,0 +1,507 @@
+/*****************************************************************************
+   This routine must ensure that PS_STAT_ROBUST_QUARTILE is correctly computed
+   by the procedure psArrayStats().
+ 
+   XXX: Must add tests for various data types, other than psF32.  Copy code
+   from tst_psStats00.c-tst_psStats02.c.
+*****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+
+#define NUM_DATA 1000
+#define MEAN 32.0
+#define STDEV 2.0
+#define PERCENT_OUTLIERS 1
+#define OUTLIER_MAGNITUDE (NUM_DATA * 10)
+#define ERROR_TOLERANCE .10
+#define ERRORS 1000.0
+#define SEED 1995
+#define VERBOSE 0
+#define EXTRA_VERBOSE 0
+
+#define TST_IN_NULL             0x00000001
+#define TST_IN_F32              0x00000002
+#define TST_IN_F64              0x00000004
+#define TST_IN_S8               0x00000008
+#define TST_IN_U16              0x00000010
+#define TST_IN_S32              0x00000020
+#define TST_ERRORS_NULL         0x00000040
+#define TST_ERRORS_F32          0x00000080
+#define TST_ERRORS_F64          0x00000100
+#define TST_ERRORS_S8           0x00000200
+#define TST_ERRORS_U16          0x00000400
+#define TST_ERRORS_S32          0x00000800
+#define TST_MASK_NULL           0x00001000
+#define TST_MASK_U8             0x00002000
+#define TST_MASK_S32            0x00004000
+
+/*****************************************************************************
+    p_psGaussianDev()
+ This private routine (formerly a psLib API routine) creates a psVector of the
+ specified size and type F32 and fills it with a random Gaussian distribution
+ of numbers with the specified mean and sigma.
+ 
+XXX: It's possible to have a different seed everytime.  However, for now,
+for testability, we use a common seed.
+ *****************************************************************************/
+#define PS_XXX_GAUSSIAN_SEED 1995
+psVector* p_psGaussianDev(psF32 mean,
+                          psF32 sigma,
+                          unsigned int Npts)
+{
+    PS_ASSERT_INT_NONNEGATIVE(Npts, NULL);
+
+    //    psRandom *r = psRandomAlloc(PS_RANDOM_TAUS, p_psRandomGetSystemSeed());
+    psRandom *r = psRandomAlloc(PS_RANDOM_TAUS, PS_XXX_GAUSSIAN_SEED);
+    psVector* gauss = psVectorAlloc(Npts, PS_TYPE_F32);
+    for (unsigned int i = 0; i < Npts; i++) {
+        gauss->data.F32[i] = mean + p_psRandomGaussian(r, sigma);
+        gauss->n++;
+    }
+    psFree(r);
+
+    return(gauss);
+}
+
+psBool genericRobustStatsTest(
+    unsigned int flags,
+    psS32 numData,
+    psU32 maskValue,
+    psBool expectedRC)
+{
+    psS32 currentId = psMemGetId();
+    psBool testStatus = true;
+    psS32 memLeaks = 0;
+    psVector *in = NULL;
+    psVector *errors = NULL;
+    psVector *mask = NULL;
+    srand(SEED);
+
+    if (expectedRC == true) {
+        if (VERBOSE)
+            printf("This test should not generate any errors.\n");
+    }
+    if (expectedRC == false) {
+        if (VERBOSE)
+            printf("This test should generate an error message, and return NULL.\n");
+    }
+    psVector *gaussVector = p_psGaussianDev(MEAN, STDEV, numData);
+
+
+    if (flags & TST_IN_NULL) {
+        if (VERBOSE)
+            printf("        using a NULL in vector\n");
+    }
+
+    if (flags & TST_IN_F32) {
+        if (VERBOSE)
+            printf("        using a psF32 in vector\n");
+        in = psVectorAlloc(numData, PS_TYPE_F32);
+        for (psS32 i=0;i<numData;i++) {
+            in->data.F32[i] = gaussVector->data.F32[i];
+            in->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original in data %d: (%.1f)\n", i, in->data.F32[i]);
+            }
+        }
+    }
+
+    if (flags & TST_IN_F64) {
+        if (VERBOSE)
+            printf("        using a psF64 in vector\n");
+        in = psVectorAlloc(numData, PS_TYPE_F64);
+        for (psS32 i=0;i<numData;i++) {
+            in->data.F64[i] = (psF64) gaussVector->data.F32[i];
+            in->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original in data %d: (%.1f)\n", i, in->data.F64[i]);
+            }
+        }
+    }
+
+    if (flags & TST_IN_S8) {
+        if (VERBOSE)
+            printf("        using a psS8 in vector\n");
+        in = psVectorAlloc(numData, PS_TYPE_S8);
+        for (psS32 i=0;i<numData;i++) {
+            in->data.S8[i] = (psS8) gaussVector->data.F32[i];
+            in->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original in data %d: (%d)\n", i, in->data.S8[i]);
+            }
+        }
+    }
+
+    if (flags & TST_IN_U16) {
+        if (VERBOSE)
+            printf("        using a psU16 in vector\n");
+        in = psVectorAlloc(numData, PS_TYPE_U16);
+        for (psS32 i=0;i<numData;i++) {
+            in->data.U16[i] = (psU16) gaussVector->data.F32[i];
+            in->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original in data %d: (%d)\n", i, in->data.U16[i]);
+            }
+        }
+    }
+
+    if (flags & TST_IN_S32) {
+        if (VERBOSE)
+            printf("        using a psS32 in vector\n");
+        in = psVectorAlloc(numData, PS_TYPE_S32);
+        for (psS32 i=0;i<numData;i++) {
+            in->data.S32[i] = (psS32) gaussVector->data.F32[i];
+            in->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original in data %d: (%d)\n", i, in->data.S32[i]);
+            }
+        }
+    }
+    psFree(gaussVector);
+
+    //    in->n = in->nalloc;
+    if (flags & TST_ERRORS_NULL) {
+        if (VERBOSE)
+            printf("        using a NULL errors vector\n");
+    }
+
+    if (flags & TST_ERRORS_F32) {
+        if (VERBOSE)
+            printf("        using a psF32 errors vector\n");
+        errors = psVectorAlloc(numData, PS_TYPE_F32);
+        for (psS32 i=0;i<numData;i++) {
+            errors->data.F32[i] = ERRORS;
+            errors->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original errors data %d: (%.1f)\n", i, errors->data.F32[i]);
+            }
+        }
+    }
+
+    if (flags & TST_ERRORS_F64) {
+        if (VERBOSE)
+            printf("        using a psF64 errors vector\n");
+        errors = psVectorAlloc(numData, PS_TYPE_F64);
+        for (psS32 i=0;i<numData;i++) {
+            errors->data.F64[i] = ERRORS;
+            errors->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original errors data %d: (%.1f)\n", i, errors->data.F64[i]);
+            }
+        }
+    }
+
+    if (flags & TST_ERRORS_S8) {
+        if (VERBOSE)
+            printf("        using a psS8 errors vector\n");
+        errors = psVectorAlloc(numData, PS_TYPE_S8);
+        for (psS32 i=0;i<numData;i++) {
+            errors->data.S8[i] = (psS8) ERRORS;
+            errors->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original errors data %d: (%d)\n", i, errors->data.S8[i]);
+            }
+        }
+    }
+
+    if (flags & TST_ERRORS_U16) {
+        if (VERBOSE)
+            printf("        using a psU16 errors vector\n");
+        errors = psVectorAlloc(numData, PS_TYPE_U16);
+        for (psS32 i=0;i<numData;i++) {
+            errors->data.U16[i] = (psU16) ERRORS;
+            errors->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original errors data %d: (%d)\n", i, errors->data.U16[i]);
+            }
+        }
+    }
+
+    if (flags & TST_ERRORS_S32) {
+        if (VERBOSE)
+            printf("        using a psS32 errors vector\n");
+        errors = psVectorAlloc(numData, PS_TYPE_S32);
+        for (psS32 i=0;i<numData;i++) {
+            errors->data.S32[i] = (psS32) ERRORS;
+            errors->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original errors data %d: (%d)\n", i, errors->data.S32[i]);
+            }
+        }
+    }
+
+
+    if (flags & TST_MASK_NULL) {
+        if (VERBOSE)
+            printf("        using a NULL mask vector\n");
+    }
+
+    if (flags & TST_MASK_U8) {
+        if (VERBOSE)
+            printf("        using a psU8 mask vector\n");
+        mask = psVectorAlloc(numData, PS_TYPE_U8);
+        for (psS32 i=0;i<numData;i++) {
+            mask->data.U8[i] = (psU8) 0;
+            mask->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original mask data %d: (%d)\n", i, mask->data.U8[i]);
+            }
+        }
+    }
+
+    if (flags & TST_MASK_S32) {
+        if (VERBOSE)
+            printf("        using a psS32 mask vector\n");
+        mask = psVectorAlloc(numData, PS_TYPE_S32);
+        for (psS32 i=0;i<numData;i++) {
+            mask->data.S32[i] = (psS32) 0;
+            mask->n++;
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original mask data %d: (%d)\n", i, mask->data.S32[i]);
+            }
+        }
+    }
+
+
+    //
+    // We calculate the sample mean and stdev without and outliers in the data.
+    // We will use this later in determining if the clipped stats are correct.
+    //
+    psF32 sampleMean;
+    psF32 sampleStdev;
+    psF32 sampleMedian;
+    psF32 sampleLQ;
+    psF32 sampleUQ;
+    if (expectedRC == true) {
+        psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV | PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_QUARTILE);
+        psStats *rc = psVectorStats(myStats, in, NULL, NULL, maskValue);
+        if (rc == NULL) {
+            diag("TEST ERROR: the psVectorStats() function returned NULL.\n");
+            testStatus = false;
+        } else {
+            sampleMean = myStats->sampleMean;
+            sampleStdev = myStats->sampleStdev;
+            sampleMedian = myStats->sampleMedian;
+            sampleLQ = myStats->sampleLQ;
+            sampleUQ = myStats->sampleUQ;
+        }
+        psFree(myStats);
+    }
+
+    //
+    // We add a few outliers to the input data.
+    //
+    if (flags & TST_IN_F32) {
+        for (psS32 i=0;i<numData;i++) {
+            if (PERCENT_OUTLIERS > (random() % 100)) {
+                in->data.F32[i] = (psF32) OUTLIER_MAGNITUDE;
+            }
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original in data %d: (%.1f)\n", i, in->data.F32[i]);
+            }
+        }
+    }
+    if (flags & TST_IN_F64) {
+        for (psS32 i=0;i<numData;i++) {
+            if (PERCENT_OUTLIERS > (random() % 100)) {
+                in->data.F64[i] = (psF64) OUTLIER_MAGNITUDE;
+            }
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original in data %d: (%.1f)\n", i, in->data.F64[i]);
+            }
+        }
+    }
+    if (flags & TST_IN_S8) {
+        for (psS32 i=0;i<numData;i++) {
+            if (PERCENT_OUTLIERS > (random() % 100)) {
+                in->data.S8[i] = (psS8) OUTLIER_MAGNITUDE;
+            }
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original in data %d: (%d)\n", i, in->data.S8[i]);
+            }
+        }
+    }
+    if (flags & TST_IN_U16) {
+        for (psS32 i=0;i<numData;i++) {
+            if (PERCENT_OUTLIERS > (random() % 100)) {
+                in->data.U16[i] = (psU16) OUTLIER_MAGNITUDE;
+            }
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original in data %d: (%d)\n", i, in->data.U16[i]);
+            }
+        }
+    }
+    if (flags & TST_IN_S32) {
+        for (psS32 i=0;i<numData;i++) {
+            if (PERCENT_OUTLIERS > (random() % 100)) {
+                in->data.S32[i] = (psS32) OUTLIER_MAGNITUDE;
+            }
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Original in data %d: (%d)\n", i, in->data.S32[i]);
+            }
+        }
+    }
+
+    //
+    // We call psVectorStats() and calculate the clipped stats.
+    //
+    psStats *myStats = psStatsAlloc(
+                           PS_STAT_ROBUST_MEDIAN |
+                           PS_STAT_ROBUST_STDEV |
+                           PS_STAT_ROBUST_QUARTILE |
+                           PS_STAT_FITTED_MEAN |
+                           PS_STAT_FITTED_STDEV);
+    psStats *rc = psVectorStats(myStats, in, errors, mask, maskValue);
+
+    if (rc == NULL) {
+        if (expectedRC == true) {
+            diag("TEST ERROR: the psVectorStats() function returned NULL.\n");
+            testStatus = false;
+        }
+    } else {
+        if (expectedRC == false) {
+            diag("TEST ERROR: the psVectorStats() function returned non-NULL.\n");
+            testStatus = false;
+        }
+
+        //
+        // Fitted Mean
+        //
+        if (fabs(myStats->fittedMean - sampleMean) > (ERROR_TOLERANCE * sampleMean)) {
+            diag("TEST ERROR: the fitted mean was %.2f, should have been %.2f\n", myStats->fittedMean, sampleMean);
+            testStatus = false;
+        } else if (EXTRA_VERBOSE) {
+            printf("GOOD: the fitted mean was %.2f, should have been %.2f\n", myStats->fittedMean, sampleMean);
+        }
+
+        //
+        // Fitted Stdev
+        //
+        if (fabs(myStats->fittedStdev - sampleStdev) > (ERROR_TOLERANCE * sampleStdev)) {
+            diag("TEST ERROR: the fitted stdev was %.2f, should have been %.2f\n", myStats->fittedStdev, sampleStdev);
+            testStatus = false;
+        } else if (EXTRA_VERBOSE) {
+            printf("GOOD: the fitted stdev was %.2f, should have been %.2f\n", myStats->fittedStdev, sampleStdev);
+        }
+
+        //
+        // Robust Stdev
+        //
+        if (fabs(myStats->robustStdev - sampleStdev) > (ERROR_TOLERANCE * sampleStdev)) {
+            diag("TEST ERROR: the robust stdev was %.2f, should have been %.2f\n", myStats->robustStdev, sampleStdev);
+            testStatus = false;
+        } else if (EXTRA_VERBOSE) {
+            printf("GOOD: the robust stdev was %.2f, should have been %.2f\n", myStats->robustStdev, sampleStdev);
+        }
+
+        //
+        // Robust Median
+        //
+        if (fabs(myStats->robustMedian - sampleMedian) > (ERROR_TOLERANCE * sampleMedian)) {
+            diag("TEST ERROR: the robust median was %.2f, should have been %.2f\n", myStats->robustMedian, sampleMedian);
+            testStatus = false;
+        } else if (EXTRA_VERBOSE) {
+            printf("GOOD: the robust median was %.2f, should have been %.2f\n", myStats->robustMedian, sampleMedian);
+        }
+
+        //
+        // Robust LQ
+        //
+        if (fabs(myStats->robustLQ - sampleLQ) > (ERROR_TOLERANCE * sampleLQ)) {
+            diag("TEST ERROR: the robust LQ was %.2f, should have been %.2f\n", myStats->robustLQ, sampleLQ);
+            testStatus = false;
+        } else if (EXTRA_VERBOSE) {
+            printf("GOOD: the robust LQ was %.2f, should have been %.2f\n", myStats->robustLQ, sampleLQ);
+        }
+
+        //
+        // Robust UQ
+        //
+        if (fabs(myStats->robustUQ - sampleUQ) > (ERROR_TOLERANCE * sampleUQ)) {
+            diag("TEST ERROR: the robust UQ was %.2f, should have been %.2f\n", myStats->robustUQ, sampleUQ);
+            testStatus = false;
+        } else if (EXTRA_VERBOSE) {
+            printf("GOOD: the robust UQ was %.2f, should have been %.2f\n", myStats->robustUQ, sampleUQ);
+        }
+    }
+
+    psFree(myStats);
+    psFree(in);
+    psFree(errors);
+    psFree(mask);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    return(testStatus);
+}
+
+
+psS32 main()
+{
+    psMemId id = psMemGetId();
+    psLogSetFormat("HLNM");
+    plan_tests(3);
+
+    ok(genericRobustStatsTest(TST_IN_F32 | TST_ERRORS_NULL | TST_MASK_NULL, NUM_DATA, 1, true), "RobustStatsTest() F32 data");
+    ok(genericRobustStatsTest(TST_IN_F32 | TST_ERRORS_NULL | TST_MASK_U8, NUM_DATA, 1, true), "RobustStatsTest() F32 data, non-NULL errors and mask vector");
+
+    ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+}
+
Index: /trunk/psLib/test/math/tap_psStats08.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats08.c	(revision 10831)
+++ /trunk/psLib/test/math/tap_psStats08.c	(revision 10831)
@@ -0,0 +1,86 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_SAMPLE_QUARTILE is correctly computed
+    by the procedure psArrayStats().
+ 
+    XXX: Must add tests for various data types, other than psF32.  Copy code
+    from tst_psStats00.c-tst_psStats02.c.
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+#define N1 25
+#define N (8 * N1) // Don't change this (N must be a multiple of 8)
+float realLQNoMask   = N/4.0;
+float realUQNoMask   = 3.0 * (N/4.0);
+float realLQWithMask   = N/8.0;
+float realUQWithMask   = 3.0 * (N/8.0);
+
+psS32 main()
+{
+    psMemId idGlobal = psMemGetId();
+    psLogSetFormat("HLNM");
+    plan_tests(14);
+
+    psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_QUARTILE);
+    psVector *myVector = psVectorAlloc(N, PS_TYPE_F32);
+    myVector->n = N;
+    psVector *maskVector = psVectorAlloc(N, PS_TYPE_U8);
+    maskVector->n = N;
+    for (int i=0;i<N;i++) {
+        myVector->data.F32[i] = (float) i;
+        if (i < (N/2)) {
+            maskVector->data.U8[i] = 0;
+        } else {
+            maskVector->data.U8[i] = 1;
+        }
+    }
+
+
+    // Call psVectorStats() with no vector mask; test sampleLQ
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->sampleLQ), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleLQ, realLQNoMask, 1e-4,
+                     "The sampleLQ was %f, should be %f", myStats->sampleLQ, realLQNoMask);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Call psVectorStats() with no vector mask; test sampleUQ
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, NULL, 0);
+        ok(!isnan(myStats->sampleUQ), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleUQ, realUQNoMask, 1e-4,
+                     "The sampleUQ was %f, should be %f", myStats->sampleUQ, realUQNoMask);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Call psVectorStats() with vector mask; test sampleLQ
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(!isnan(myStats->sampleLQ), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleLQ, realLQWithMask, 1e-4,
+                     "The sampleLQ was %f, should be %f", myStats->sampleLQ, realLQWithMask);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    // Call psVectorStats() with vector mask; test sampleUQ
+    {
+        psMemId id = psMemGetId();
+        myStats = psVectorStats(myStats, myVector, NULL, maskVector, 1);
+        ok(!isnan(myStats->sampleUQ), "psVectorStats() returned non-NAN");
+        ok_float_tol(myStats->sampleUQ, realUQNoMask, 1e-4,
+                     "The sampleUQ was %f, should be %f", myStats->sampleUQ, realUQNoMask);
+        ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+    }
+
+    psFree(myStats);
+    psFree(myVector);
+    psFree(maskVector);
+    ok(!psMemCheckLeaks (idGlobal, NULL, NULL, false), "no memory leaks");
+    ok(!psMemCheckLeaks (idGlobal, NULL, NULL, false), "no memory leaks");
+}
Index: /trunk/psLib/test/math/tap_psStats09.c
===================================================================
--- /trunk/psLib/test/math/tap_psStats09.c	(revision 10831)
+++ /trunk/psLib/test/math/tap_psStats09.c	(revision 10831)
@@ -0,0 +1,374 @@
+/*****************************************************************************
+    This routine must ensure that PS_STAT_CLIPPED_MEAN and
+    PS_STAT_CLIPPED_STDEV is calculate correctly by the procedure
+    psVectorStats().
+ 
+    XXX: The capability is here to test a wide variety of input parameters.
+    We must do this, later.
+ *****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <pslib.h>
+#include "tap.h"
+#include "pstap.h"
+
+#define NUM_DATA 1000
+#define VERBOSE 0
+#define EXTRA_VERBOSE 0
+#define PERCENT_OUTLIERS 2
+#define ERROR_TOLERANCE .10
+#define ERRORS 1.0
+#define SEED 1995
+
+#define TST_IN_NULL  0x00000001
+#define TST_IN_F32  0x00000002
+#define TST_IN_F64  0x00000004
+#define TST_IN_S8  0x00000008
+#define TST_IN_U16  0x00000010
+#define TST_IN_S32  0x00000020
+#define TST_ERRORS_NULL  0x00000040
+#define TST_ERRORS_F32  0x00000080
+#define TST_ERRORS_F64  0x00000100
+#define TST_ERRORS_S8  0x00000200
+#define TST_ERRORS_U16  0x00000400
+#define TST_ERRORS_S32  0x00000800
+#define TST_MASK_NULL  0x00001000
+#define TST_MASK_U8  0x00002000
+#define TST_MASK_S32  0x00004000
+
+
+psBool genericClippedStatsTest(
+    unsigned int flags,
+    psS32 numData,
+    psU32 maskValue,
+    psBool expectedRC)
+{
+    psS32 currentId = psMemGetId();
+    psBool testStatus = true;
+    psS32 memLeaks = 0;
+    psVector *in = NULL;
+    psVector *errors = NULL;
+    psVector *mask = NULL;
+    srand(SEED);
+
+    psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 1); // Random number generator; using known seed
+    psVector *truth = psVectorAlloc(numData, PS_TYPE_F64);
+    truth->n = numData;
+    for (long i = 0; i < numData; i++) {
+        truth->data.F64[i] = psRandomGaussian(rng);
+    }
+    psFree(rng);
+
+    if (expectedRC == true) {
+        if (VERBOSE)
+            printf("This test should not generate any errors.\n");
+    }
+    if (expectedRC == false) {
+        if (VERBOSE)
+            printf("This test should generate an error message, and return NULL.\n");
+    }
+
+    if (flags & TST_IN_NULL) {
+        if (VERBOSE)
+            printf("        using a NULL in vector\n");
+    }
+
+    if (flags & TST_IN_F32) {
+        if (VERBOSE)
+            printf("        using a psF32 in vector\n");
+        in = psVectorCopy(in, truth, PS_TYPE_F32);
+    }
+
+    if (flags & TST_IN_F64) {
+        if (VERBOSE)
+            printf("        using a psF64 in vector\n");
+        in = psVectorCopy(in, truth, PS_TYPE_F64);
+    }
+
+    if (flags & TST_IN_S8) {
+        if (VERBOSE)
+            printf("        using a psS8 in vector\n");
+        in = psVectorCopy(in, truth, PS_TYPE_S8);
+    }
+
+    if (flags & TST_IN_U16) {
+        if (VERBOSE)
+            printf("        using a psU16 in vector\n");
+        in = psVectorCopy(in, truth, PS_TYPE_U16);
+    }
+
+    if (flags & TST_IN_S32) {
+        if (VERBOSE)
+            printf("        using a psS32 in vector\n");
+        in = psVectorCopy(in, truth, PS_TYPE_S32);
+    }
+
+    if (flags & TST_ERRORS_NULL) {
+        if (VERBOSE)
+            printf("        using a NULL errors vector\n");
+    }
+
+    if (flags & TST_ERRORS_F32) {
+        if (VERBOSE)
+            printf("        using a psF32 errors vector\n");
+        errors = psVectorAlloc(numData, PS_TYPE_F32);
+        for (psS32 i=0;i<numData;i++) {
+            errors->data.F32[i] = ERRORS;
+            errors->n++;
+        }
+    }
+
+    if (flags & TST_ERRORS_F64) {
+        if (VERBOSE)
+            printf("        using a psF64 errors vector\n");
+        errors = psVectorAlloc(numData, PS_TYPE_F64);
+        for (psS32 i=0;i<numData;i++) {
+            errors->data.F64[i] = ERRORS;
+            errors->n++;
+        }
+    }
+
+    if (flags & TST_ERRORS_S8) {
+        if (VERBOSE)
+            printf("        using a psS8 errors vector\n");
+        errors = psVectorAlloc(numData, PS_TYPE_S8);
+        for (psS32 i=0;i<numData;i++) {
+            errors->data.S8[i] = (psS8) ERRORS;
+            errors->n++;
+        }
+    }
+
+    if (flags & TST_ERRORS_U16) {
+        if (VERBOSE)
+            printf("        using a psU16 errors vector\n");
+        errors = psVectorAlloc(numData, PS_TYPE_U16);
+        for (psS32 i=0;i<numData;i++) {
+            errors->data.U16[i] = (psU16) ERRORS;
+            errors->n++;
+        }
+    }
+
+    if (flags & TST_ERRORS_S32) {
+        if (VERBOSE)
+            printf("        using a psS32 errors vector\n");
+        errors = psVectorAlloc(numData, PS_TYPE_S32);
+        for (psS32 i=0;i<numData;i++) {
+            errors->data.S32[i] = (psS32) ERRORS;
+            errors->n++;
+        }
+    }
+
+
+    if (flags & TST_MASK_NULL) {
+        if (VERBOSE)
+            printf("        using a NULL mask vector\n");
+    }
+
+    if (flags & TST_MASK_U8) {
+        if (VERBOSE)
+            printf("        using a psU8 mask vector\n");
+        mask = psVectorAlloc(numData, PS_TYPE_U8);
+        for (psS32 i=0;i<numData;i++) {
+            mask->data.U8[i] = (psU8) 0;
+            mask->n++;
+        }
+    }
+
+    if (flags & TST_MASK_S32) {
+        if (VERBOSE)
+            printf("        using a psS32 mask vector\n");
+        mask = psVectorAlloc(numData, PS_TYPE_S32);
+        for (psS32 i=0;i<numData;i++) {
+            mask->data.S32[i] = (psS32) 0;
+            mask->n++;
+        }
+    }
+
+
+    //
+    // We add a few outliers to the input data.
+    //
+    psVector *outliers = psVectorAlloc(numData, PS_TYPE_U8);
+    outliers->n = numData;
+    psVectorInit(outliers, 0);
+    long numOutliers = 0;
+    if (flags & TST_IN_F32) {
+        for (psS32 i=0;i<numData;i++) {
+            if (PERCENT_OUTLIERS > (random() % 100)) {
+                in->data.F32[i] = 100.0;
+                outliers->data.U8[i] = 1;
+                numOutliers++;
+            }
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Data %d: (%f)\n", i, in->data.F32[i]);
+            }
+        }
+    }
+    if (flags & TST_IN_F64) {
+        for (psS32 i=0;i<numData;i++) {
+            if (PERCENT_OUTLIERS > (random() % 100)) {
+                in->data.F64[i] = 100.0;
+                outliers->data.U8[i] = 1;
+                numOutliers++;
+            }
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Data %d: (%f)\n", i, in->data.F64[i]);
+            }
+        }
+    }
+    if (flags & TST_IN_S8) {
+        for (psS32 i=0;i<numData;i++) {
+            if (PERCENT_OUTLIERS > (random() % 100)) {
+                in->data.S8[i] = 100;
+                outliers->data.U8[i] = 1;
+                numOutliers++;
+            }
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Data %d: (%d)\n", i, in->data.S8[i]);
+            }
+        }
+    }
+    if (flags & TST_IN_U16) {
+        for (psS32 i=0;i<numData;i++) {
+            if (PERCENT_OUTLIERS > (random() % 100)) {
+                in->data.U16[i] = 100;
+                outliers->data.U8[i] = 1;
+                numOutliers++;
+            }
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Data %d: (%d)\n", i, in->data.U16[i]);
+            }
+        }
+    }
+    if (flags & TST_IN_S32) {
+        for (psS32 i=0;i<numData;i++) {
+            if (PERCENT_OUTLIERS > (random() % 100)) {
+                in->data.S32[i] = 100;
+                outliers->data.U8[i] = 1;
+                numOutliers++;
+            }
+        }
+
+        if (EXTRA_VERBOSE) {
+            for (psS32 i=0;i<numData;i++) {
+                printf("Data %d: (%d)\n", i, in->data.S32[i]);
+            }
+        }
+    }
+
+    if (VERBOSE)
+        printf("%ld outliers.\n", numOutliers);
+
+    //
+    // We calculate the sample mean and stdev without and outliers in the data.
+    // We will use this later in determining if the clipped stats are correct.
+    //
+    psF32 sampleMean;
+    psF32 sampleStdev;
+    if (expectedRC == true) {
+        psStats *myStats = psStatsAlloc(PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_STDEV);
+        psStats *rc = psVectorStats(myStats, in, errors, outliers, 1);
+        if (rc == NULL) {
+            diag("TEST ERROR: the psVectorStats() function returned NULL.\n");
+            testStatus = false;
+        } else {
+            sampleMean = myStats->sampleMean;
+            sampleStdev = myStats->sampleStdev;
+        }
+        psFree(myStats);
+    }
+    psFree(outliers);
+
+    //
+    // We call psVectorStats() and calculate the clipped stats.
+    //
+    psStats *myStats = psStatsAlloc(PS_STAT_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);
+    myStats->clipSigma = 5.0;
+    myStats->clipIter = 2;
+    psStats *rc = psVectorStats(myStats, in, errors, mask, maskValue);
+    if (rc == NULL) {
+        if (expectedRC == true) {
+            diag("TEST ERROR: the psVectorStats() function returned NULL.\n");
+            testStatus = false;
+        }
+    } else {
+        if (expectedRC == false) {
+            diag("TEST ERROR: the psVectorStats() function returned non-NULL.\n");
+            testStatus = false;
+        }
+
+        if (VERBOSE)
+            printf("Used %ld data points after clipping %ld.\n", myStats->clippedNvalues,
+                   in->n - myStats->clippedNvalues);
+
+        if (fabs(myStats->clippedMean - sampleMean) > (ERROR_TOLERANCE * sampleMean)) {
+            diag("TEST ERROR: the clipped mean was %f, should have been %f\n", myStats->clippedMean, sampleMean);
+            testStatus = false;
+        } else if (EXTRA_VERBOSE) {
+            printf("GOOD: the clipped mean was %f, should have been %f\n", myStats->clippedMean, sampleMean);
+        }
+
+        if (fabs(myStats->clippedStdev - sampleStdev) > (ERROR_TOLERANCE * sampleStdev)) {
+            diag("TEST ERROR: the clipped stdev was %f, should have been %f\n", myStats->clippedStdev, sampleStdev);
+            testStatus = false;
+        } else if (EXTRA_VERBOSE) {
+            printf("GOOD: the clipped stdev was %f, should have been %f\n", myStats->clippedStdev, sampleStdev);
+        }
+
+    }
+
+    psFree(myStats);
+    psFree(truth);
+    psFree(in);
+    psFree(errors);
+    psFree(mask);
+    psMemCheckCorruption(1);
+    memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
+    if (0 != memLeaks) {
+        psAbort(__func__,"Memory Leaks! (%d leaks)", memLeaks);
+    }
+
+    return(testStatus);
+}
+
+#define TRACE_LEVEL 0
+psS32 main()
+{
+    psMemId id = psMemGetId();
+    psLogSetFormat("HLNM");
+    plan_tests(6);
+
+    //
+    // We list pertinent psStats.c functions here for debugging ease.
+    //
+    psTraceSetLevel(".", TRACE_LEVEL);
+    psTraceSetLevel("p_psVectorSampleMean", TRACE_LEVEL);
+    psTraceSetLevel("p_psVectorMax", TRACE_LEVEL);
+    psTraceSetLevel("p_psVectorMin", TRACE_LEVEL);
+    psTraceSetLevel("p_psVectorCheckNonEmpty", TRACE_LEVEL);
+    psTraceSetLevel("p_psVectorNValues", TRACE_LEVEL);
+    psTraceSetLevel("p_psVectorClippedStats", TRACE_LEVEL);
+    psTraceSetLevel("p_psNormalizeVectorRange", TRACE_LEVEL);
+    psTraceSetLevel("psStatsAlloc", TRACE_LEVEL);
+    psTraceSetLevel("p_psConvertToF32", TRACE_LEVEL);
+    psTraceSetLevel("psVectorStats", TRACE_LEVEL);
+
+    ok(genericClippedStatsTest(TST_IN_NULL | TST_ERRORS_NULL | TST_MASK_NULL, NUM_DATA, 1, false), "GenericClippedStatsTest(): NULL data");
+    ok(genericClippedStatsTest(TST_IN_F32 | TST_ERRORS_NULL | TST_MASK_NULL, NUM_DATA, 1, true), "GenericClippedStatsTest(): F32 data");
+    ok(genericClippedStatsTest(TST_IN_F64 | TST_ERRORS_NULL | TST_MASK_NULL, NUM_DATA, 1, true), "GenericClippedStatsTest(): F64 data");
+    ok(genericClippedStatsTest(TST_IN_F32 | TST_ERRORS_F32 | TST_MASK_NULL, NUM_DATA, 1, true), "GenericClippedStatsTest(): non-NULL error vector");
+    ok(genericClippedStatsTest(TST_IN_F32 | TST_ERRORS_NULL | TST_MASK_U8, NUM_DATA, 1, true), "GenericClippedStatsTest(): non-NULL mask vector");
+    ok(!psMemCheckLeaks (id, NULL, NULL, false), "no memory leaks");
+}
