/** @file  tst_psLookupTable_01.c
*
*  @brief Test driver for psLookupTable functions
*
*  This test driver contains the following tests for psLookupTable functions:
*     testLookupAlloc - test allocation and freeing of psLookupTable
*     testLookupRead - test different files and types within files
*                      being read correctly and some failure cases
*     testLookupTableInterpolate - test the interpolation function
*     testLookupTableInterpolateAll - test interpolation of all row values
*
*  @author  Ross Harman, MHPCC
*
*  @version $Revision: 1.13 $  $Name: not supported by cvs2svn $
*  @date  $Date: 2005-03-31 23:01:46 $
*
*  Copyright 2004-5 Maui High Performance Computing Center, University of Hawaii
*
*/

#include "pslib.h"
#include "psTest.h"
#include <string.h>

static psS32 testLookupTableAlloc(void);
static psS32 testLookupTableRead(void);
static psS32 testLookupTableInterpolate(void);
static psS32 testLookupTableInterpolateAll(void);

const psF64 errorTol_psF64 = 1.0e-4;
const psF64 tableU8_validFrom = 0;
const psF64 tableU8_validTo = 3;
const psS32 tableU8_size = 4;
const psS32 tableU8_index[] =
    {
        0,   1,    2,   3
    };
const psU16 tableU8_val1[]  =
    {
        2,   4,    6,   8
    };
const psU32 tableU8_val2[]  =
    {
        4,   8,   12,  16
    };
const psU64 tableU8_val3[]  =
    {
        8,  16,   24,  32
    };
const psS8  tableU8_val4[]  =
    {
        0,  -1,   -2,  -3
    };
const psS16 tableU8_val5[]  =
    {
        -2,  -4,   -6,  -8
    };
const psS32 tableU8_val6[]  =
    {
        -4,  -8,  -12, -16
    };
const psS64 tableU8_val7[]  =
    {
        -8, -16,  -24, -32
    };
const psF32 tableU8_val8[]  =
    {
        -0.5, 0.0,  0.5,0.75
    };
const psF64 tableU8_val9[]  =
    {
        -1.5,-1.0,-0.25,1.75
    };

const psF64 tableS32_validFrom = -1;
const psF64 tableS32_validTo = 33;
const psS32 tableS32_size = 4;
const psS32 tableS32_index[] =
    {
        -1,11,22,33
    };

const psF64 tableF32_validFrom = -10.05;
const psF64 tableF32_validTo = 3500.67;
const psF64 tableF32_size = 4;
const psF32 tableF32_index[] =
    {
        -10.05,1.009,23.45,3500.67
    };

const psF64 table10_validFrom = 1;
const psF64 table10_validTo   = 10;
const psS32 table10_size      = 10;
const psU8  table10_index[]   =
    {
        1,   2,    3,   4,    5,    6,    7,    8,   9,    10
    };
const psU16 table10_val1[]    =
    {
        4,   6,    8,  10,   12,   14,   16,   18,   20,   22
    };
const psU32 table10_val2[]    =
    {
        8,  12,   16,  20,   24,   28,   32,   36,   40,   44
    };
const psU64 table10_val3[]    =
    {
        16,  24,   32,  64,  128,  256,  512, 1024, 2048, 4096
    };
const psS8  table10_val4[]    =
    {
        -1,  -2,   -3,  -4,   -5,   -6,   -7,   -8,   -9,  -10
    };
const psS16 table10_val5[]    =
    {
        -4,  -6,   -8, -10,  -12,  -14,  -16,  -18,  -20,  -22
    };
const psS32 table10_val6[]    =
    {
        -8, -12,  -16, -20,  -24,  -28,  -32,  -36,  -40,  -44
    };
const psS64 table10_val7[]    =
    {
        -16, -24,  -32, -64, -128, -256, -512,-1024,-2048,-4096
    };
const psF32 table10_val8[]    =
    {
        -2.25,-1.5,-0.75, 0.0, 0.75, 1.50, 2.25, 3.00, 3.75, 4.50
    };
const psF64 table10_val9[]    =
    {
        -2.67,0.66, 3.99,7.32,10.65,13.98,17.31,20.64,23.97,27.30
    };
const psF64 interpolVal1[]    =
    {
        12.5, 25, 160, -5.25, -12.5, -25, -160, 0.9375, 11.4825
    };
const psF64 interpolVal2[]    =
    {
        12, 24, 128, -5, -12, -24, -128, 0.75, 10.65
    };
const psF64 interpolVal3[]    =
    {
        4, 8, 16, -1, -4, -8, -16, -2.25, -2.67
    };

testDescription tests[] = {
                              {testLookupTableAlloc,999,"psLookupTableAlloc",0,false},
                              {testLookupTableRead,998,"psLookupTableRead",0,false},
                              {testLookupTableInterpolate,997,"psLookupTableInterpolate",0,false},
                              {testLookupTableInterpolateAll,996,"psLookupTableInterpolateAll",0,false},
                              {NULL}
                          };

psS32 main(psS32 argc, char* argv[])
{
    psLogSetLevel(PS_LOG_INFO);

    if ( ! runTestSuite(stderr,"psLookupTable",tests,argc,argv)) {
        return 1;
    }
    return 0;
}

psS32 testLookupTableAlloc(void)
{
    psLookupTable*  table1 = NULL;

    // Allocate lookup table with valid parameters
    table1 = psLookupTableAlloc("tableF32.dat", tableF32_validFrom, tableF32_validTo);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Null lookup table generated from valid parameters");
        return 1;
    }
    if(strcmp(table1->fileName,"tableF32.dat") != 0) {
        psError(PS_ERR_UNKNOWN,true,"File name not properly stored in psLookupTable structure.");
        return 2;
    }

    if( (fabs(table1->validFrom - tableF32_validFrom) > FLT_EPSILON)  ||
            (fabs(table1->validTo-tableF32_validTo) > FLT_EPSILON) ) {
        psError(PS_ERR_UNKNOWN,true,"Members validTo or validFrom not set properly");
        return 3;
    }
    psFree(table1);

    // Allocate lookup table with invalid filename
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error message for invalid file name");
    table1 = psLookupTableAlloc(NULL,0,3);
    if(table1 != NULL) {
        psError(PS_ERR_UNKNOWN,true,"Null file name accepted by psLookupTableAlloc");
        return 4;
    }

    return 0;
}

psS32 testLookupTableRead(void)
{
    psLookupTable*  table1 = NULL;

    // Allocate table using table with psU8 index and valid types and index-values
    table1 = psLookupTableAlloc("tableU8.dat", 0, 100.5);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to allocate table with tableU8.dat");
        return 1;
    }
    // Read table with index U8
    table1 = psLookupTableRead(table1);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to read table from file tableU8.dat");
        return 2;
    }
    // Verify the validFrom and validTo are updated properly
    if( (fabs(table1->validFrom - tableU8_validFrom) > FLT_EPSILON) ||
            (fabs(table1->validTo - tableU8_validTo) > FLT_EPSILON) ) {
        psError(PS_ERR_UNKNOWN,true,"ValidFrom or validTo not set properly");
        return 3;
    }
    // Verify index and all values in table read properly
    for(psS32 i=0; i < tableU8_size; i++) {
        if(table1->index->data.U8[i] != tableU8_index[i]) {
            psError(PS_ERR_UNKNOWN,true,"Index values do not match: index[%d]=%d  expected %d",i,
                    table1->index->data.U8[i], tableU8_index[i]);
            return 3*i;
        }
        if(((psVector*)table1->values->data[0])->data.U16[i] != tableU8_val1[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 1 do not match: value[%d]=%d expected %d",i,
                    ((psVector*)table1->values->data[0])->data.U16[i], tableU8_val1[i]);
            return 3*i+1;
        }
        if(((psVector*)table1->values->data[1])->data.U32[i] != tableU8_val2[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 2 do not match: value[%d]=%d expected %d",i,
                    ((psVector*)table1->values->data[1])->data.U32[i], tableU8_val2[i]);
            return 3*i+2;
        }
        if(((psVector*)table1->values->data[2])->data.U64[i] != tableU8_val3[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 3 do not match: value[%d]=%lld expected %lld",i,
                    ((psVector*)table1->values->data[2])->data.U64[i], tableU8_val3[i]);
            return 3*i+3;
        }
        if(((psVector*)table1->values->data[3])->data.S8[i] != tableU8_val4[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 4 do not match: value[%d]=%d expected %d",i,
                    ((psVector*)table1->values->data[3])->data.S8[i], tableU8_val4[i]);
            return 3*i+4;
        }
        if(((psVector*)table1->values->data[4])->data.S16[i] != tableU8_val5[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 5 do not match: value[%d]=%d expected %d",i,
                    ((psVector*)table1->values->data[4])->data.S16[i], tableU8_val5[i]);
            return 3*i+5;
        }
        if(((psVector*)table1->values->data[5])->data.S32[i] != tableU8_val6[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 6 do not match: value[%d]=%d expected %d",i,
                    ((psVector*)table1->values->data[5])->data.S32[i], tableU8_val6[i]);
            return 3*i+6;
        }
        if(((psVector*)table1->values->data[6])->data.S64[i] != tableU8_val7[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 7 do not match: value[%d]=%lld expected %lld",i,
                    ((psVector*)table1->values->data[6])->data.S64[i], tableU8_val7[i]);
            return 3*i+7;
        }
        if(fabs(((psVector*)table1->values->data[7])->data.F32[i] - tableU8_val8[i]) > FLT_EPSILON ) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 8 do not match: value[%d]=%g expected %g",i,
                    ((psVector*)table1->values->data[7])->data.F32[i], tableU8_val8[i]);
            return 3*i+8;
        }
        if(fabs(((psVector*)table1->values->data[8])->data.F64[i] - tableU8_val9[i]) > FLT_EPSILON ) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 9 do not match: value[%d]=%g expected %g",i,
                    ((psVector*)table1->values->data[8])->data.F32[i], tableU8_val9[i]);
            return 3*i+9;
        }
    }
    psFree(table1);

    // Allocate table using table with psS32 index and valid types and index-values
    table1 = psLookupTableAlloc("tableS32.dat", -110, 1000.5);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to allocate table with tableS32.dat");
        return 1;
    }
    table1 = psLookupTableRead(table1);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to read table from file tableS32.dat");
        return 2;
    }
    if( (fabs(table1->validFrom - tableS32_validFrom) > FLT_EPSILON) ||
            (fabs(table1->validTo - tableS32_validTo) > FLT_EPSILON) ) {
        psError(PS_ERR_UNKNOWN,true,"ValidFrom or validTo not set properly");
        return 3;
    }
    for(psS32 i=0; i < tableS32_size; i++) {
        if(table1->index->data.S32[i] != tableS32_index[i]) {
            psError(PS_ERR_UNKNOWN,true,"Index values do not match: index[%d]=%d  expected %d",i,
                    table1->index->data.S32[i], tableS32_index[i]);
            return 4*i;
        }
    }
    psFree(table1);

    // Allocate table using table with psF32 index and valid types and index-values
    table1 = psLookupTableAlloc("tableF32.dat", -1100, 5500.5);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to allocate table with tableF32.dat");
        return 1;
    }
    table1 = psLookupTableRead(table1);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to read table from file tableF32.dat");
        return 2;
    }
    if( (fabs(table1->validFrom - tableF32_validFrom) > errorTol_psF64) ||
            (fabs(table1->validTo - tableF32_validTo) > errorTol_psF64) ) {
        psError(PS_ERR_UNKNOWN,true,"ValidFrom or validTo not set properly");
        return 3;
    }
    for(psS32 i=0; i < tableS32_size; i++) {
        if(fabsf(table1->index->data.F32[i] - tableF32_index[i]) > FLT_EPSILON ) {
            psError(PS_ERR_UNKNOWN,true,"Index values do not match: index[%d]=%d  expected %d",i,
                    table1->index->data.F32[i], tableF32_index[i]);
            return 4*i;
        }
    }
    psFree(table1);

    // Allocate table using psU8 index but with unsorted rows and verify the list is
    // sorted properly after being read
    table1 = psLookupTableAlloc("table10.dat",1,2);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to allocate table with table10.dat");
        return 1;
    }
    table1 = psLookupTableRead(table1);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to read table with table10.dat");
        return 2;
    }
    // Verify the validFrom and validTo are updated properly
    if( (fabs(table1->validFrom - table10_validFrom) > FLT_EPSILON) ||
            (fabs(table1->validTo - table10_validTo) > FLT_EPSILON) ) {
        psError(PS_ERR_UNKNOWN,true,"ValidFrom or validTo not set properly");
        return 3;
    }
    // Verify index and all values in table read properly
    for(psS32 i=0; i < table10_size; i++) {
        if(table1->index->data.U8[i] != table10_index[i]) {
            psError(PS_ERR_UNKNOWN,true,"Index values do not match: index[%d]=%d  expected %d",i,
                    table1->index->data.U8[i], table10_index[i]);
            return 3*i;
        }
        if(((psVector*)table1->values->data[0])->data.U16[i] != table10_val1[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 1 do not match: value[%d]=%d expected %d",i,
                    ((psVector*)table1->values->data[0])->data.U16[i], table10_val1[i]);
            return 3*i+1;
        }
        if(((psVector*)table1->values->data[1])->data.U32[i] != table10_val2[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 2 do not match: value[%d]=%d expected %d",i,
                    ((psVector*)table1->values->data[1])->data.U32[i], table10_val2[i]);
            return 3*i+2;
        }
        if(((psVector*)table1->values->data[2])->data.U64[i] != table10_val3[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 3 do not match: value[%d]=%lld expected %lld",i,
                    ((psVector*)table1->values->data[2])->data.U64[i], table10_val3[i]);
            return 3*i+3;
        }
        if(((psVector*)table1->values->data[3])->data.S8[i] != table10_val4[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 4 do not match: value[%d]=%d expected %d",i,
                    ((psVector*)table1->values->data[3])->data.S8[i], table10_val4[i]);
            return 3*i+4;
        }
        if(((psVector*)table1->values->data[4])->data.S16[i] != table10_val5[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 5 do not match: value[%d]=%d expected %d",i,
                    ((psVector*)table1->values->data[4])->data.S16[i], table10_val5[i]);
            return 3*i+5;
        }
        if(((psVector*)table1->values->data[5])->data.S32[i] != table10_val6[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 6 do not match: value[%d]=%d expected %d",i,
                    ((psVector*)table1->values->data[5])->data.S32[i], table10_val6[i]);
            return 3*i+6;
        }
        if(((psVector*)table1->values->data[6])->data.S64[i] != table10_val7[i]) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 7 do not match: value[%d]=%lld expected %lld",i,
                    ((psVector*)table1->values->data[6])->data.S64[i], table10_val7[i]);
            return 3*i+7;
        }
        if(fabs(((psVector*)table1->values->data[7])->data.F32[i] - table10_val8[i]) > FLT_EPSILON ) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 8 do not match: value[%d]=%g expected %g",i,
                    ((psVector*)table1->values->data[7])->data.F32[i], table10_val8[i]);
            return 3*i+8;
        }
        if(fabs(((psVector*)table1->values->data[8])->data.F64[i] - table10_val9[i]) > FLT_EPSILON ) {
            psError(PS_ERR_UNKNOWN,true,"Value in column 9 do not match: value[%d]=%g expected %g",i,
                    ((psVector*)table1->values->data[8])->data.F32[i], table10_val9[i]);
            return 3*i+9;
        }
    }
    psFree(table1);

    // Allocate table using table with invalid type in type row but valid index-values
    table1 = psLookupTableAlloc("table2.dat",0,99.99);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to allocate table with table2.dat");
        return 3;
    }
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message about invalid type");
    table1 = psLookupTableRead(table1);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to read table from file table2.dat");
        return 4;
    }
    psFree(table1);

    // Allocate table using table with invalid value
    table1 = psLookupTableAlloc("table3.dat",0,75.0);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to allocate table with table3.dat");
        return 5;
    }
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message about invalid value");
    table1 = psLookupTableRead(table1);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to read table from file table3.dat");
        return 6;
    }
    psFree(table1);

    // Attempt to read for non-existant file
    table1 = psLookupTableAlloc("nonexistantFile.dat",0,100);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Unable to allocate table with non-existant file");
        return 3;
    }
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error msg about opening file");
    table1 = psLookupTableRead(table1);
    if(table1 == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Returned NULL when table should have been returned");
        return 4;
    }

    // Attempt to read table with NULL specified file
    psFree((char*)table1->fileName);
    table1->fileName = NULL;
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error msg about NULL file name");
    if(psLookupTableRead(table1) != NULL) {
        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with table specifying NULL file name");
        return 5;
    }
    psFree(table1);

    // Attempt to read table with NULL table
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error msg about NULL table");
    if(psLookupTableRead(NULL) != NULL) {
        psError(PS_ERR_UNKNOWN,true,"Did not return NULL with NULL table.");
        return 6;
    }

    return 0;
}

psS32 testLookupTableInterpolate(void)
{
    psLookupStatusType status = 0;
    psLookupTable*  table1 = NULL;
    psF64            out1 = 0;

    // Interpolate values within the list and verify return values
    table1 = psLookupTableAlloc("table10.dat",0,20);
    table1 = psLookupTableRead(table1);
    for(psS32 i = 0; i < table1->numRows-1; i++ ) {
        out1 = psLookupTableInterpolate(table1, 5.25, i, &status);
        if( fabs(out1-interpolVal1[i]) > errorTol_psF64) {
            psError(PS_ERR_UNKNOWN,true,"Did not return expected value. %lg expected %lg",out1,interpolVal1[i]);
            return 3*i;
        }
    }
    for(psS32 i = 0; i < table1->numRows-1; i++ ) {
        out1 = psLookupTableInterpolate(table1, 5.0, i, &status);
        if( fabs(out1-interpolVal2[i]) > errorTol_psF64) {
            psError(PS_ERR_UNKNOWN,true,"Did not return expected value. %lg expected %lg",out1,interpolVal2[i]);
            return 4*i;
        }
    }

    // Interpolate value just below the lowest index value
    out1 = psLookupTableInterpolate(table1,0,0, &status);
    if ( fabs(out1- NAN) > FLT_EPSILON ) {
        psError(PS_ERR_UNKNOWN,true,"Did not return NAN returned %lf",out1);
        return 5;
    }
    if ( status != PS_LOOKUP_PAST_TOP) {
        psError(PS_ERR_UNKNOWN,true,"Did not return status PAST TOP");
        return 6;
    }

    // Interpolate value just above the highest index value
    out1 = psLookupTableInterpolate(table1,11,0, &status);
    if ( fabs(out1-NAN) > FLT_EPSILON ) {
        psError(PS_ERR_UNKNOWN,true,"Did not return NAN returned %lf",out1);
        return 7;
    }
    if ( status != PS_LOOKUP_PAST_BOTTOM) {
        psError(PS_ERR_UNKNOWN,true,"Did not return status PAST BOTTOM");
        return 8;
    }

    // Interpolate value with a column number greater than the table has
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error out of range.");
    out1 = psLookupTableInterpolate(table1, 5, 100, &status);
    if ( fabs(out1-NAN) > FLT_EPSILON ) {
        psError(PS_ERR_UNKNOWN,true,"Did not return NAN returned %lf",out1);
        return 9;
    }
    if ( status != PS_LOOKUP_ERROR ) {
        psError(PS_ERR_UNKNOWN,true,"Did not return status LOOKUP ERROR");
        return 10;
    }

    // Interpolate with NULL table
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate error NULL table");
    out1 = psLookupTableInterpolate(NULL,5,0,&status);
    if( fabs(out1-NAN) > FLT_EPSILON ) {
        psError(PS_ERR_UNKNOWN,true,"Did not return NAN returned %lf",out1);
        return 11;
    }
    if ( status != PS_LOOKUP_ERROR ) {
        psError(PS_ERR_UNKNOWN,true,"Did not return status LOOKUP ERROR");
        return 12;
    }

    // Interpolate with status NULL
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error NULL status");
    out1 = psLookupTableInterpolate(table1,5,0,NULL);
    if ( fabs(out1-NAN) > FLT_EPSILON ) {
        psError(PS_ERR_UNKNOWN,true,"Did not return NAN returned %lf",out1);
        return 13;
    }

    psFree(table1);

    return 0;
}

psS32 testLookupTableInterpolateAll(void)
{
    psLookupTable*  table1 = NULL;
    psVector*        interpValues;
    psVector*        statusVector;

    // Interpolate values within the list and verify return values
    table1 = psLookupTableAlloc("table10.dat",0,20);
    table1 = psLookupTableRead(table1);
    statusVector = psVectorAlloc(table1->numCols,PS_TYPE_U32);
    interpValues = psLookupTableInterpolateAll(table1,5.25, statusVector);
    if(interpValues == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Returned vector is NULL.");
        return 1;
    }
    for(psS32 i = 0; i < table1->numRows-1; i++ ) {
        if( fabs(interpValues->data.F64[i]-interpolVal1[i]) > errorTol_psF64) {
            psError(PS_ERR_UNKNOWN,true,"Did not return expected value. %lg expected %lg",
                    interpValues->data.F64[i],interpolVal1[i]);
            return 2*i;
        }
    }
    for(psS32 j = 0; j < table1->numCols; j++) {
        if(statusVector->data.U32[j] != PS_LOOKUP_SUCCESS) {
            psError(PS_ERR_UNKNOWN,true,"Return status not success for col=%d status=%d",
                    j,statusVector->data.U32[j]);
            return 3*j;
        }
    }
    psFree(statusVector);
    psFree(interpValues);

    // Interpolate values with index outside table
    statusVector = psVectorAlloc(table1->numCols,PS_TYPE_U32);
    interpValues = psLookupTableInterpolateAll(table1,0,statusVector);
    if(interpValues == NULL) {
        psError(PS_ERR_UNKNOWN,true,"Did return NULL");
        return 4;
    }

    for(psS32 i = 0; i < table1->numRows-1; i++ ) {
        if( fabs(interpValues->data.F64[i]-interpolVal3[i]) > errorTol_psF64) {
            psError(PS_ERR_UNKNOWN,true,"Did not return expected value. %lg expected %lg",
                    interpValues->data.F64[i],interpolVal3[i]);
            return 2*i;
        }
    }

    for(psS32 j = 0; j < table1->numCols; j++) {
        if(statusVector->data.S32[j] != PS_LOOKUP_PAST_TOP) {
            psError(PS_ERR_UNKNOWN,true,"Return status did not indicate passed top  for col=%d status=%d",
                    j,statusVector->data.U32[j]);
            return 3*j;
        }
    }
    psFree(interpValues);
    psFree(statusVector);

    // Interpolate values with NULL table
    statusVector = psVectorAlloc(table1->numCols,PS_TYPE_S32);
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message for NULL table");
    interpValues = psLookupTableInterpolateAll(NULL,5,statusVector);
    if(interpValues != NULL ) {
        psError(PS_ERR_UNKNOWN,true,"Did not return NULL for NULL table");
        return 5;
    }
    psFree(statusVector);

    // Interpolate values with NULL status vector
    psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message for NULL status vector");
    interpValues = psLookupTableInterpolateAll(table1,5,NULL);
    if(interpValues != NULL ) {
        psError(PS_ERR_UNKNOWN,true,"Did not return NULL for NULL status vector");
        return 6;
    }
    psFree(table1);

    return 0;
}

