Listing 5: The serial correlation test

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  */
/* Repeat Step 1 through Step 4 N times, then proceed to Step 5:    */
/*                                                                  */
/*   Step 1: Generate T variates, Xk, 0 <= Xk <= 32767, 1 <= k <= T.*/
/*                                                                  */
/*   Step 2: Calculate NumCorr correlation coefficients as follows: */
/*                                                                  */
/*           err = bjcorr(X, T, Corr, NumCorr);                     */
/*                                                                  */
/*           where                                                  */
/*                                                                  */
/*               Corr      receiving area for correlation           */
/*             coefficients                                         */
/*               NumCorr   User-specified number <= T - 3           */
/*                                                                  */
/*   Step 3: Calculate a test statistic, Ut:                        */
/*                                                                  */
/*           Ut = T * (T + 2) * Sum{Corr[j]^2 / (T-j), j = 1, J}    */
/*                                                                  */
/*           where                                                  */
/*               J = NumCorr                                        */
/*                                                                  */
/*                                                                  */
/*   Step 4: Calculate a chi-square probability (Pt) associated     */
/*      with Ut, with J degrees of freedom ; save it in an          */
/*      array of size N,                                            */
/*                                                                  */
/*           When N probabilities, Pt, have been computed,          */
/*           go  to  Step  5.                                       */
/*                                                                  */
/*   Step 5: Run a KS analysis on Pt(j), 1 <= j <= N.               */
/*                                                                  */
/*  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++  */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mconf.h>
#include <srcrdefs.h>
#include <miscdefs.h>

#define LOW_PROB        1.0e-8

int     Variates[32768u];
double  CorCoefs[32768u];
/* ============================================================== */
/* CalcSerCorChiSq - Gets Chi-square p-value for NumCorr          */
/* Coefficients                                                   */
/* ============================================================== */
void
CalcSerCorChiSq(SERCOR_DATA_STRU * SerCorData)
{
    UINT    k;
    UINT    NumCoefs = SerCorData->NumCoefs,
            NumVar   = SerCorData->NumVarPerPass;

    double  ChiSqProb, ChiSqStat;
    double  CoefSos = 0, CoefSum = 0, RmsCoefs, Sum = 0;
    double  LoLimit, HiLimit;

    /* ----------------------------------------- */
    /* Step 1: Generate Array of Random Deviates */
    /* ----------------------------------------- */
    for (k = 0; k < NumVar; ++k)
    {
        Variates[k] = SerCorData->RandFun();
    }

    /* ------------------------------------------ */
    /* Step 2: Calculate Correlation Coefficients */
    /* ------------------------------------------ */
    SerCorData->CallStatus =
        BJCoef(Variates, NumVar, CorCoefs, NumCoefs);

    if (SerCorData->CallStatus == OK)
    {
        /* ---------------------------------------------------- */
        /* Calculate Limits on Acceptable Chi-Square Statistics */
        /* ---------------------------------------------------- */
        ChiSqDist(LOW_PROB, NumCoefs, &LoLimit, &HiLimit);

        /* -------------------------------- */
        /* Step 3: Calculate Test Statistic */
        /* -------------------------------- */
        for (k = 0; k < NumCoefs; ++k)
        {
            double  SqrCoef = SQR(CorCoefs[k]);

            /* ------------------- */
            /* Sum of Coefficients */
            /* ------------------- */
            CoefSum += CorCoefs[k];

            /* ------------------------------ */
            /* Sum of Squares of Coefficients */
            /* ------------------------------ */
            CoefSos += SqrCoef;

            /* ------------------------- */
            /* Accumulate Test Statistic */
            /* ------------------------- */
            Sum += SqrCoef / (double) (NumVar - (k+1));
        }

        /* ----------------------------- */
        /* Finish Step 3: Test Statistic */
        /* ----------------------------- */
        ChiSqStat = Sum * (double)NumVar * (double)(NumVar + 2);

        /* ---------------------------------------- */
        /* Step 4: Calculate Chi-Square Probability */
        /* ---------------------------------------- */
        if (ChiSqStat < LoLimit)
        {
              ChiSqProb = LOW_PROB;
        }       else if (ChiSqStat > HiLimit)
        {
              ChiSqProb = 1.0 - LOW_PROB;
        }
        else
        {
             ChiSqProb = chdtr(NumCoefs, ChiSqStat);
        }
        SerCorData->ChiSqProb = ChiSqProb;

        /* --------------------------------------------------- */
        /* Maintain Counts of Numbers of Variates and Outliers */
        /* --------------------------------------------------- */
        SerCorData->TotCoefs += NumCoefs;
        SerCorData->TotSos   += CoefSos;
        SerCorData->TotSum   += CoefSum;

        RmsCoefs = sqrt(CoefSos / (double)NumCoefs);

        for (k = 0; k < NumCoefs; ++k)
        {
            if (fabs(CorCoefs[k]) > 2*RmsCoefs)
            {
                ++SerCorData->NumOutliers;
            }
        }
    }
                                  /* End of if */
}
/* End of File */