/** * Computes the Fisher scores for all the permutations in a single pass. * The algorithm works by starting on one side (min a) and moving to the other side (max a). * We compute all the probabilities that we encounter on the way incrementally. * Then we sort the probabilities in increasing order and sum them up in that direction. * The result is a mapping between the permutation probabilities and p-values. * TODO - we may want to cache the resulting list in case of multiple calls * */ public double[,] computeAllPermutationsScores() { int cPermutations = getMaxPossibleA() - getMinPossibleA() + 1; List <double> alProbabilities = new List <double>(); double[,] adScores = new double[cPermutations, 2]; //We start from the table with the maximal value to avoid numeric computation problems ContingencyTable ctMaxValue = getMaxValueTable(); ContingencyTable ctIterator = ctMaxValue; double pStart = ctIterator.getHypergeometricProbability(); double pCurrent = pStart, dSum = 0.0; int iCurrent = 0; //iterate to the right side while (ctIterator != null) { //Add the probability of the current permutation to the list alProbabilities.Add(pCurrent); //Increment the probability pCurrent = ctIterator.incrementalHypergeometricProbability(pCurrent); //Increment the table - will return null once a exceeds the max value ctIterator = ctIterator.next(); } //iterate to the left side ctIterator = ctMaxValue; pCurrent = ctIterator.decrementalHypergeometricProbability(pStart); ctIterator = ctIterator.previous(); while (ctIterator != null) { //Add the probability of the current permutation to the list alProbabilities.Add(pCurrent); //Decrement the probability pCurrent = ctIterator.decrementalHypergeometricProbability(pCurrent); //Decrement the table - will return null once a drops below the min value ctIterator = ctIterator.previous(); } //Sort the observed probabilities in increasing order alProbabilities.Sort(); //BUGBUG - suspecting that we do not handle well identical entries. Not sure if this bug is occuring. dSum = 0.0; //Sum the probabilities in increasing order, computing two sided p-values //BUGBUG - Not sure how to make this work for one sided tests. for (iCurrent = 0; iCurrent < alProbabilities.Count; iCurrent++) { pCurrent = (double)alProbabilities[iCurrent]; dSum += pCurrent; if (dSum > 1.0) { dSum = 1.0; } adScores[iCurrent, 0] = pCurrent; adScores[iCurrent, 1] = dSum; } return(adScores); }
public double[] computeAllFisherStatistics(double[] adResults, ref bool bApproximated) { double p0 = getHypergeometricProbability();// probability of seeing the actual data double p0Epsilon = p0 * 0.00001; double p = p0, pt = 0, ptMax = 0.0, pLeft = p0, pRight = p0; ContingencyTable ctMaxTable = getMaxValueTable(), ctIterator = ctMaxTable; int iMaxA = getMaxPossibleA(), iMinA = getMinPossibleA(); int cPermutations = 0, cRemiaingPermutations = iMaxA - iMinA; int iCurrentA = 0; double[] adMapping = new double[iMaxA + 1]; adResults[0] = p0; ptMax = ctIterator.getHypergeometricProbability(); pt = ptMax; while (ctIterator != null) { cPermutations++; iCurrentA = ctIterator.getA(); adMapping[iCurrentA] = pt; if (iCurrentA > m_iA) { pRight += pt; } if (iCurrentA < m_iA) { pLeft += pt; } if (p0 + p0Epsilon >= pt && iCurrentA != m_iA) { p = p + pt; } pt = ctIterator.incrementalHypergeometricProbability(pt); ctIterator = ctIterator.next(); if ((ctIterator != null) && (pt == double.Epsilon)) { pt *= (iMaxA - ctIterator.getA() + 1); p += pt; pRight += pt; bApproximated = true; for (iCurrentA = ctIterator.getA(); iCurrentA <= iMaxA; iCurrentA++) { adMapping[iCurrentA] = double.Epsilon; } ctIterator = null; } } //Iterate to the left side - decreasing values of a ctIterator = ctMaxTable.previous(); pt = ctMaxTable.decrementalHypergeometricProbability(ptMax); while (ctIterator != null) { cPermutations++; iCurrentA = ctIterator.getA(); adMapping[iCurrentA] = pt; if (iCurrentA > m_iA) { pRight += pt; } if (iCurrentA < m_iA) { pLeft += pt; } if (p0 + p0Epsilon >= pt && iCurrentA != m_iA) { p = p + pt; } pt = ctIterator.decrementalHypergeometricProbability(pt); ctIterator = ctIterator.previous(); if ((ctIterator != null) && (pt == double.Epsilon)) { pt *= (ctIterator.getA() - getMinPossibleA()); p += pt; pLeft += pt; bApproximated = true; for (iCurrentA = ctIterator.getA(); iCurrentA >= iMinA; iCurrentA--) { adMapping[iCurrentA] = double.Epsilon; } ctIterator = null; } } for (iCurrentA = iMinA - 1; iCurrentA >= 0; iCurrentA--) { adMapping[iCurrentA] = 0.0; } adResults[1] = pLeft; adResults[2] = pRight; adResults[3] = p; return(adMapping); }