Index: trunk/psLib/test/math/tst_psStats09.c
===================================================================
--- trunk/psLib/test/math/tst_psStats09.c	(revision 6304)
+++ trunk/psLib/test/math/tst_psStats09.c	(revision 6307)
@@ -4,37 +4,38 @@
     psVectorStats().
  
-    XXX: Must add tests for various data types, other than psF32.  Copy code
-    from tst_psStats00.c-tst_psStats02.c.
+    XXX: The capability is here to test a wide variety of input parameters.
+    We must do this, later.
  *****************************************************************************/
 #include <stdio.h>
 #include "pslib_strict.h"
 #include "psTest.h"
-#include "psTest.h"
-#include "psImageStats.h"
 #include "float.h"
 #include <math.h>
 
-#define N 500
-#define MY_MEAN  30.0
-#define MY_RANGE 2.0
-#define VERBOSE 1
-
-#define TST_IN_NULL  0x00000000
-#define TST_IN_F32  0x00000000
-#define TST_IN_F64  0x00000000
-#define TST_IN_S8  0x00000000
-#define TST_IN_U16  0x00000000
-#define TST_IN_S32  0x00000000
-#define TST_ERRORS_NULL  0x00000000
-#define TST_ERRORS_F32  0x00000000
-#define TST_ERRORS_F64  0x00000000
-#define TST_ERRORS_S8  0x00000000
-#define TST_ERRORS_U16  0x00000000
-#define TST_ERRORS_S32  0x00000000
-#define TST_MASK_NULL  0x00000000
-#define TST_MASK_U8  0x00000000
-#define TST_MASK_S32  0x00000000
-
-psS32 genericClippedStatsTest(
+#define NUM_DATA 1000
+#define VERBOSE 0
+#define PERCENT_OUTLIERS 2
+#define ERROR_TOLERANCE .10
+#define ERRORS 1000.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,
@@ -43,11 +44,15 @@
 {
     psS32 currentId = psMemGetId();
-    psS32 testStatus = true;
+    psBool testStatus = true;
     psS32 memLeaks = 0;
     psVector *in = NULL;
     psVector *errors = NULL;
     psVector *mask = NULL;
+    srand(SEED);
     printPositiveTestHeader(stdout, "psMathUtils functions", "psVectorStats Clipped Stats Routine");
 
+    if (expectedRC == true) {
+        printf("This test should not generate any errors.\n");
+    }
     if (expectedRC == false) {
         printf("This test should generate an error message, and return NULL.\n");
@@ -128,5 +133,4 @@
     }
 
-
     if (flags & TST_ERRORS_NULL) {
         printf("        using a NULL errors vector\n");
@@ -137,5 +141,5 @@
         errors = psVectorAlloc(numData, PS_TYPE_F32);
         for (psS32 i=0;i<numData;i++) {
-            errors->data.F32[i] = (psF32) i;
+            errors->data.F32[i] = ERRORS;
         }
 
@@ -151,5 +155,5 @@
         errors = psVectorAlloc(numData, PS_TYPE_F64);
         for (psS32 i=0;i<numData;i++) {
-            errors->data.F64[i] = (psF64) i;
+            errors->data.F64[i] = ERRORS;
         }
 
@@ -165,5 +169,5 @@
         errors = psVectorAlloc(numData, PS_TYPE_S8);
         for (psS32 i=0;i<numData;i++) {
-            errors->data.S8[i] = (psS8) i;
+            errors->data.S8[i] = (psS8) ERRORS;
         }
 
@@ -179,5 +183,5 @@
         errors = psVectorAlloc(numData, PS_TYPE_U16);
         for (psS32 i=0;i<numData;i++) {
-            errors->data.U16[i] = (psU16) i;
+            errors->data.U16[i] = (psU16) ERRORS;
         }
 
@@ -193,5 +197,5 @@
         errors = psVectorAlloc(numData, PS_TYPE_S32);
         for (psS32 i=0;i<numData;i++) {
-            errors->data.S32[i] = (psS32) i;
+            errors->data.S32[i] = (psS32) ERRORS;
         }
 
@@ -212,5 +216,5 @@
         mask = psVectorAlloc(numData, PS_TYPE_U8);
         for (psS32 i=0;i<numData;i++) {
-            mask->data.U8[i] = (psU8) i;
+            mask->data.U8[i] = (psU8) 0;
         }
 
@@ -226,5 +230,5 @@
         mask = psVectorAlloc(numData, PS_TYPE_S32);
         for (psS32 i=0;i<numData;i++) {
-            mask->data.S32[i] = (psS32) i;
+            mask->data.S32[i] = (psS32) 0;
         }
 
@@ -236,7 +240,98 @@
     }
 
+
+    //
+    // 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, NULL, NULL, maskValue);
+        if (rc == NULL) {
+            printf("TEST ERROR: the psVectorStats() function returned NULL.\n");
+            testStatus = false;
+        } else {
+            sampleMean = myStats->sampleMean;
+            sampleStdev = myStats->sampleStdev;
+        }
+        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) (10 * numData);
+            }
+        }
+
+        if (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) (10 * numData);
+            }
+        }
+
+        if (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) (10 * numData);
+            }
+        }
+
+        if (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) (10 * numData);
+            }
+        }
+
+        if (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) (10 * numData);
+            }
+        }
+
+        if (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_CLIPPED_MEAN | PS_STAT_CLIPPED_STDEV);
     psStats *rc = psVectorStats(myStats, in, errors, mask, maskValue);
-
     if (rc == NULL) {
         if (expectedRC == true) {
@@ -250,6 +345,24 @@
         }
 
-    }
-
+        if (fabs(myStats->clippedMean - sampleMean) > (ERROR_TOLERANCE * sampleMean)) {
+            printf("TEST ERROR: the clipped mean was %.2f, should have been %.2f\n", myStats->clippedMean, sampleMean);
+            testStatus = false;
+        } else if (VERBOSE) {
+            printf("GOOD: the clipped mean was %.2f, should have been %.2f\n", myStats->clippedMean, sampleMean);
+        }
+
+        if (fabs(myStats->clippedStdev - sampleStdev) > (ERROR_TOLERANCE * sampleStdev)) {
+            printf("TEST ERROR: the clipped stdev was %.2f, should have been %.2f\n", myStats->clippedStdev, sampleStdev);
+            testStatus = false;
+        } else if (VERBOSE) {
+            printf("GOOD: the clipped stdev was %.2f, should have been %.2f\n", myStats->clippedStdev, sampleStdev);
+        }
+
+    }
+
+    psFree(myStats);
+    psFree(in);
+    psFree(errors);
+    psFree(mask);
     psMemCheckCorruption(1);
     memLeaks = psMemCheckLeaks(currentId,NULL,stderr,false);
@@ -261,25 +374,36 @@
 }
 
-
-
-
+#define TRACE_LEVEL 0
 psS32 main()
 {
     psLogSetFormat("HLNM");
+    psBool testStatus = true;
+
     //
     // We list pertinent psStats.c functions here for debugging ease.
     //
-    psTraceSetLevel(".", 0);
-    psTraceSetLevel("p_psGetStatValue", 0);
-    psTraceSetLevel("p_psVectorSampleMean", 0);
-    psTraceSetLevel("p_psVectorMax", 0);
-    psTraceSetLevel("p_psVectorMin", 0);
-    psTraceSetLevel("p_psVectorCheckNonEmpty", 0);
-    psTraceSetLevel("p_psVectorNValues", 0);
-    psTraceSetLevel("p_psVectorClippedStats", 0);
-    psTraceSetLevel("p_psNormalizeVectorRange", 0);
-    psTraceSetLevel("psStatsAlloc", 0);
-    psTraceSetLevel("p_psConvertToF32", 0);
-    psTraceSetLevel("psVectorStats", 0);
-
+    psTraceSetLevel(".", TRACE_LEVEL);
+    psTraceSetLevel("p_psGetStatValue", 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);
+
+    testStatus &= genericClippedStatsTest(TST_IN_NULL | TST_ERRORS_NULL | TST_MASK_NULL, NUM_DATA, 1, false);
+    testStatus &= genericClippedStatsTest(TST_IN_F32 | TST_ERRORS_NULL | TST_MASK_NULL, NUM_DATA, 1, true);
+    testStatus &= genericClippedStatsTest(TST_IN_F64 | TST_ERRORS_NULL | TST_MASK_NULL, NUM_DATA, 1, true);
+    testStatus &= genericClippedStatsTest(TST_IN_F32 | TST_ERRORS_F32 | TST_MASK_NULL, NUM_DATA, 1, true);
+    testStatus &= genericClippedStatsTest(TST_IN_F32 | TST_ERRORS_NULL | TST_MASK_U8, NUM_DATA, 1, true);
+
+    if (testStatus) {
+        printf("TEST PASSED\n");
+    } else {
+        printf("TEST FAILED\n");
+    }
 }
