src/main/java/org/ncgr/gwas/CochranArmitage.java
public double test(int[][] countTable) {
        if (countTable == null) {
            throw new IllegalArgumentException("Contingency table cannot be null/empty.");
        }
        
        if ((countTable.length!=numRows) || (countTable[0].length!=numCols)) {
            throw new IllegalArgumentException("Contingency table must be "+numRows+" rows by "+numCols+" columns");
        }
        
        int totalSum=0;
        int[] rowSum = new int[numRows];
        int[] colSum = new int[numCols];
        
        // calculate marginal and overall sums for the contingency table
        for (int i=0; i<numRows; i++) {
            for (int j=0; j<numCols; j++) {
                rowSum[i] += countTable[i][j];
                colSum[j] += countTable[i][j];
                totalSum += countTable[i][j];
            }
        }

        // calculate the test statistic and variance based on the formulae at
        // http://en.wikipedia.org/wiki/Cochran-Armitage_test_for_trend
        stat = 0.0;
        variance = 0.0;
        for (int j=0; j<numCols; j++) {
            stat += weights[j] * (countTable[0][j]*rowSum[1] - 
                                  countTable[1][j]*rowSum[0]);
            variance += weights[j]*weights[j]*colSum[j]*(totalSum-colSum[j]);

            if (j!=numCols-1) {
                for (int k=j+1;k<numCols;k++) {
                    variance -= 2*weights[j]*weights[k]*colSum[j]*colSum[k];
                }
            }
        }
        variance *= rowSum[0]*rowSum[1]/totalSum;

        // standardized statistic is stat divided by SD
        standardStatistic = stat/Math.sqrt(variance);

        // use Apache Commons normal distribution to calculate two-tailed p-value
        pValue = 2*normDist.cumulativeProbability(-Math.abs(standardStatistic));

        // return the p-value
        return pValue;
    }
/**
     * Computes the Cochran-Armitage test for trend for the passed contingency table which matches numRows and numCols
     * @param countTable = 2xnumCols contingency table.
     * @return the p-value of the Cochran-Armitage statistic of the passed table
     */
Computes the Cochran-Armitage test for trend for the passed contingency table which matches numRows and numCols
@param countTable = 2xnumCols contingency table.
@return the p-value of the Cochran-Armitage statistic of the passed table
Computes the Cochran - Armitage test for trend for the passed contingency table which matches numRows and numCols @param countTable = 2xnumCols contingency table . @return the p - value of the Cochran - Armitage statistic of the passed table
public double test(int[][] countTable) {
        if (countTable == null) {
            throw new IllegalArgumentException("Contingency table cannot be null/empty.");
        }
        if ((countTable.length!=numRows) || (countTable[0].length!=numCols)) {
            throw new IllegalArgumentException("Contingency table must be "+numRows+" rows by "+numCols+" columns");
        }
        int totalSum=0;
        int[] rowSum = new int[numRows];
        int[] colSum = new int[numCols];
        for (int i=0; i<numRows; i++) {
            for (int j=0; j<numCols; j++) {
                rowSum[i] += countTable[i][j];
                colSum[j] += countTable[i][j];
                totalSum += countTable[i][j];
            }
        }
        stat = 0.0;
        variance = 0.0;
        for (int j=0; j<numCols; j++) {
            stat += weights[j] * (countTable[0][j]*rowSum[1] - 
                                  countTable[1][j]*rowSum[0]);
            variance += weights[j]*weights[j]*colSum[j]*(totalSum-colSum[j]);
            if (j!=numCols-1) {
                for (int k=j+1;k<numCols;k++) {
                    variance -= 2*weights[j]*weights[k]*colSum[j]*colSum[k];
                }
            }
        }
        variance *= rowSum[0]*rowSum[1]/totalSum;
        standardStatistic = stat/Math.sqrt(variance);
        pValue = 2*normDist.cumulativeProbability(-Math.abs(standardStatistic));
        return pValue;
    }
public double test ( int [ ] [ ] countTable ) { if ( countTable == null ) { throw new IllegalArgumentException ( "Contingency table cannot be null/empty." ) ; } if ( ( countTable . length != numRows ) || ( countTable [ 0 ] . length != numCols ) ) { throw new IllegalArgumentException ( "Contingency table must be " + numRows + " rows by " + numCols + " columns" ) ; } int totalSum = 0 ; int [ ] rowSum = new int [ numRows ] ; int [ ] colSum = new int [ numCols ] ; for ( int i = 0 ; i < numRows ; i ++ ) { for ( int j = 0 ; j < numCols ; j ++ ) { rowSum [ i ] += countTable [ i ] [ j ] ; colSum [ j ] += countTable [ i ] [ j ] ; totalSum += countTable [ i ] [ j ] ; } } stat = 0.0 ; variance = 0.0 ; for ( int j = 0 ; j < numCols ; j ++ ) { stat += weights [ j ] * ( countTable [ 0 ] [ j ] * rowSum [ 1 ] - countTable [ 1 ] [ j ] * rowSum [ 0 ] ) ; variance += weights [ j ] * weights [ j ] * colSum [ j ] * ( totalSum - colSum [ j ] ) ; if ( j != numCols - 1 ) { for ( int k = j + 1 ; k < numCols ; k ++ ) { variance -= 2 * weights [ j ] * weights [ k ] * colSum [ j ] * colSum [ k ] ; } } } variance *= rowSum [ 0 ] * rowSum [ 1 ] / totalSum ; standardStatistic = stat / Math . sqrt ( variance ) ; pValue = 2 * normDist . cumulativeProbability ( - Math . abs ( standardStatistic ) ) ; return pValue ; }
Computes the Cochran-Armitage test for trend for the passed contingency table which matches numRows and numCols
 @param countTable = 2xnumCols contingency table.
Computes the Cochran - Armitage test for trend for the passed contingency table which matches numRows and numCols @param countTable = 2xnumCols contingency table .
// calculate marginal and overall sums for the contingency table // calculate the test statistic and variance based on the formulae at // http://en.wikipedia.org/wiki/Cochran-Armitage_test_for_trend // standardized statistic is stat divided by SD // use Apache Commons normal distribution to calculate two-tailed p-value // return the p-value