示例#1
0
 public double getCachedValue(ContingencyTable ct)
 {
     int[] aKey = new int[] { ct.getA(), ct.getB(), ct.getC(), ct.getD() };
     if (m_slContingencyTables.ContainsKey(aKey))
     {
         return(m_slContingencyTables[aKey]);
     }
     return(double.NaN);
 }
示例#2
0
        /**
         * Computes the hypergeometric probablity using the following factorization:
         * (a+b)!(a+c)!(b+d)!(c+d)!     (a+b)!    (a+c)!    (c+d)!     (b+d)!
         * ------------------------ =  ------- * ------- * -------- * --------
         *       a!b!c!d!n!              a!b!       c!        d!         n!
         *  The assumption is that (a+b) is the smallest marginal.
         *  A better implementation would check for the smallest marginal and factor according to it, but the current implementation seems fast enough.
         * */
        public static double pr(ContingencyTable ct)
        {
            double pt = 1;
            double iFactorial = 0;
            int    a = ct.getA(), b = ct.getB(), c = ct.getC(), d = ct.getD();
            double iDenominator    = a + b + c + d;
            double iMinDenominator = b + d;

            for (iFactorial = a + 1; iFactorial <= a + b; iFactorial++) // (a+b)!/a!b!
            {
                pt *= iFactorial / (iFactorial - a);
                while ((pt > 1) && (iDenominator > iMinDenominator))
                {
                    pt /= iDenominator;
                    iDenominator--;
                }
            }
            for (iFactorial = c + 1; iFactorial <= a + c; iFactorial++) // (a+c)!/c!
            {
                pt *= iFactorial;
                while ((pt > 1) && (iDenominator > iMinDenominator))
                {
                    pt /= iDenominator;
                    iDenominator--;
                }
            }
            for (iFactorial = d + 1; iFactorial <= c + d; iFactorial++) // (c+d)!/d!
            {
                pt *= iFactorial;
                while ((pt > 1) && (iDenominator > iMinDenominator))
                {
                    pt /= iDenominator;
                    iDenominator--;
                }
            }

            if (pt == 0.0) //underflow
            {
                return(double.Epsilon);
            }

            while ((iDenominator > iMinDenominator) && (pt > 0.0))
            {
                pt /= iDenominator;
                if (pt == 0.0) //underflow
                {
                    return(double.Epsilon);
                }
                iDenominator--;
            }
            if (pt > 1.0) //numerical error
            {
                pt = 1.0;
            }

            return(pt);
        }
示例#3
0
 public void setCachedValue(ContingencyTable ct, double dValue)
 {
     int[] aKey = new int[] { ct.getA(), ct.getB(), ct.getC(), ct.getD() };
     if (!m_slContingencyTables.ContainsKey(aKey))
     {
         m_slContingencyTables.Add(aKey, dValue);
     }
     else
     {
         m_slContingencyTables[aKey] = dValue;
     }
 }
示例#4
0
        /**
         * Computes the Fisher 2 sided p-value.
         * We iterate over all the premutations and sum the ones that have a lower probability (more extreme).
         * We compute from scratch only a single hypergeometric probability - the probability of the "real" table.
         * Then we iterate by incrementing the table and the probability (right side) and by decrementing the table and the probability (left side).
         * The algorithm has the complexity of O(n), but usually runs much faster.
         * Adding another possible optimization - when the p-value exceeds a cutoff - return 1. This is useful when we only need to know whether one value is larger than the other.
         * When the values are too small to be represented by a double (less than 1-E302) the computation returns an upper bound on the real value.
         * */
        private double computeFisher2TailPermutationTest(double dObservedTableProbability, double dCutoff)
        {
            double           p0 = dObservedTableProbability;
            double           p0Epsilon = p0 * 0.00001;
            double           p = p0, pt = 0, pAbove = 0.0, pLeft = p0, pRight = 0.0;
            ContingencyTable ctIterator = null;
            int cPermutations = 0, cRemiaingPermutations = getMaxPossibleA() - getMinPossibleA();

            m_dMinimalPValue = p0;

            if (p0 == double.Epsilon)
            {
                return(p0 * cRemiaingPermutations); //an upper bound estimation
            }
            //Iterate to the right side - increasing values of a
            if (g_ttTestType == TestType.Right || g_ttTestType == TestType.TwoSided)
            {
                ctIterator = next();
                pt         = incrementalHypergeometricProbability(p0);
                while (ctIterator != null)
                {
                    if (pt < m_dMinimalPValue)
                    {
                        m_dMinimalPValue = pt;
                    }
                    cPermutations++;

                    if (p0 + p0Epsilon >= pt)
                    {
                        p      = p + pt;
                        pLeft += pt;
                        if (p > dCutoff)
                        {
                            return(1.0);
                        }
                    }
                    else
                    {
                        pAbove += pt;
                    }
                    pt         = ctIterator.incrementalHypergeometricProbability(pt);
                    ctIterator = ctIterator.next();

                    if ((ctIterator != null) && (pt <= p0Epsilon))
                    {
                        pt        *= (getMaxPossibleA() - ctIterator.getA() + 1);
                        p         += pt;
                        pLeft     += pt;
                        ctIterator = null;
                    }
                }
            }
            //Iterate to the left side - decreasing values of a
            if (g_ttTestType == TestType.Left || g_ttTestType == TestType.TwoSided)
            {
                ctIterator = previous();
                pt         = decrementalHypergeometricProbability(p0);
                double dBackward = pt;
                while (ctIterator != null)
                {
                    if (pt < m_dMinimalPValue)
                    {
                        m_dMinimalPValue = pt;
                    }
                    cPermutations++;
                    if (p0 + p0Epsilon >= pt)
                    {
                        p       = p + pt;
                        pRight += pt;
                        if (p > dCutoff)
                        {
                            return(1.0);
                        }
                    }
                    else
                    {
                        pAbove += pt;
                    }
                    double dBefore = pt;
                    pt         = ctIterator.decrementalHypergeometricProbability(pt);
                    ctIterator = ctIterator.previous();

                    if ((ctIterator != null) && (pt <= p0Epsilon))
                    {
                        pt        *= (ctIterator.getA() - getMinPossibleA());
                        p         += pt;
                        pRight    += pt;
                        ctIterator = null;
                    }
                }
            }

            m_cComputedFisherScores++;

            return(p);
        }
示例#5
0
        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);
        }