[EMAIL PROTECTED] a écrit :
> Author: brentworden
> Date: Thu Sep 25 20:09:53 2008
> New Revision: 699157
> 
> URL: http://svn.apache.org/viewvc?rev=699157&view=rev
> Log:
> MATH-227.  fixed F distribution inverse CDF computation for small denominator 
> degrees of freedom.

I would like to propagate this change to the 2.0 branch where most work
happens now. However I don't want to apply it directly using svn
commands because lots of noise has been added by some space characters
being replaced with tab characters everywhere in this commit.

I tracked the modification to the following change. Could you confirm
the only thing related to bug fix is the replacement of:

    protected double getInitialDomain(double p) {
        return getDenominatorDegreesOfFreedom() /
            (getDenominatorDegreesOfFreedom() - 2.0);
    }

by:

    protected double getInitialDomain(double p) {
        double ret = 1.0;
        double d = getDenominatorDegreesOfFreedom();
        if (d > 2.0) {
            // use mean
            ret = d / (d - 2.0);
        }
        return ret;
    }

thanks,
Luc

> 
> Modified:
>     
> commons/proper/math/trunk/src/java/org/apache/commons/math/distribution/FDistributionImpl.java
>     commons/proper/math/trunk/src/site/xdoc/changes.xml
>     
> commons/proper/math/trunk/src/test/org/apache/commons/math/distribution/FDistributionTest.java
> 
> Modified: 
> commons/proper/math/trunk/src/java/org/apache/commons/math/distribution/FDistributionImpl.java
> URL: 
> http://svn.apache.org/viewvc/commons/proper/math/trunk/src/java/org/apache/commons/math/distribution/FDistributionImpl.java?rev=699157&r1=699156&r2=699157&view=diff
> ==============================================================================
> --- 
> commons/proper/math/trunk/src/java/org/apache/commons/math/distribution/FDistributionImpl.java
>  (original)
> +++ 
> commons/proper/math/trunk/src/java/org/apache/commons/math/distribution/FDistributionImpl.java
>  Thu Sep 25 20:09:53 2008
> @@ -24,168 +24,188 @@
>  /**
>   * Default implementation of
>   * [EMAIL PROTECTED] org.apache.commons.math.distribution.FDistribution}.
> - *
> - * @version $Revision$ $Date$
> + * 
> + * @version $Revision$ $Date: 2008-02-08 09:44:11 -0600 (Fri, 08 Feb
> + *          2008) $
>   */
> -public class FDistributionImpl
> -    extends AbstractContinuousDistribution
> -    implements FDistribution, Serializable  {
> -
> -    /** Serializable version identifier */
> -    private static final long serialVersionUID = -8516354193418641566L;
> -
> -    /** The numerator degrees of freedom*/
> -    private double numeratorDegreesOfFreedom;
> -
> -    /** The numerator degrees of freedom*/
> -    private double denominatorDegreesOfFreedom;
> -    
> -    /**
> -     * Create a F distribution using the given degrees of freedom.
> -     * @param numeratorDegreesOfFreedom the numerator degrees of freedom.
> -     * @param denominatorDegreesOfFreedom the denominator degrees of freedom.
> -     */
> -    public FDistributionImpl(double numeratorDegreesOfFreedom,
> -            double denominatorDegreesOfFreedom) {
> -        super();
> -        setNumeratorDegreesOfFreedom(numeratorDegreesOfFreedom);
> -        setDenominatorDegreesOfFreedom(denominatorDegreesOfFreedom);
> -    }
> -    
> -    /**
> -     * For this distribution, X, this method returns P(X < x).
> -     * 
> -     * The implementation of this method is based on:
> -     * <ul>
> -     * <li>
> -     * <a href="http://mathworld.wolfram.com/F-Distribution.html";>
> -     * F-Distribution</a>, equation (4).</li>
> -     * </ul>
> -     * 
> -     * @param x the value at which the CDF is evaluated.
> -     * @return CDF for this distribution. 
> -     * @throws MathException if the cumulative probability can not be
> -     *            computed due to convergence or other numerical errors.
> -     */
> -    public double cumulativeProbability(double x) throws MathException {
> -        double ret;
> -        if (x <= 0.0) {
> -            ret = 0.0;
> -        } else {
> -            double n = getNumeratorDegreesOfFreedom();
> -            double m = getDenominatorDegreesOfFreedom();
> -            
> -            ret = Beta.regularizedBeta((n * x) / (m + n * x),
> -                0.5 * n,
> -                0.5 * m);
> -        }
> -        return ret;
> -    }
> -    
> -    /**
> -     * For this distribution, X, this method returns the critical point x, 
> such
> -     * that P(X &lt; x) = <code>p</code>.
> -     * <p>
> -     * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for 
> p=1.</p>
> -     *
> -     * @param p the desired probability
> -     * @return x, such that P(X &lt; x) = <code>p</code>
> -     * @throws MathException if the inverse cumulative probability can not be
> -     *         computed due to convergence or other numerical errors.
> -     * @throws IllegalArgumentException if <code>p</code> is not a valid
> -     *         probability.
> -     */
> -    public double inverseCumulativeProbability(final double p) 
> -        throws MathException {
> -        if (p == 0) {
> -            return 0d;
> -        }
> -        if (p == 1) {
> -            return Double.POSITIVE_INFINITY;
> -        }
> -        return super.inverseCumulativeProbability(p);
> -    }
> -        
> -    /**
> -     * Access the domain value lower bound, based on <code>p</code>, used to
> -     * bracket a CDF root.  This method is used by
> -     * [EMAIL PROTECTED] #inverseCumulativeProbability(double)} to find 
> critical values.
> -     * 
> -     * @param p the desired probability for the critical value
> -     * @return domain value lower bound, i.e.
> -     *         P(X &lt; <i>lower bound</i>) &lt; <code>p</code> 
> -     */
> -    protected double getDomainLowerBound(double p) {
> -        return 0.0;
> -    }
> -
> -    /**
> -     * Access the domain value upper bound, based on <code>p</code>, used to
> -     * bracket a CDF root.  This method is used by
> -     * [EMAIL PROTECTED] #inverseCumulativeProbability(double)} to find 
> critical values.
> -     * 
> -     * @param p the desired probability for the critical value
> -     * @return domain value upper bound, i.e.
> -     *         P(X &lt; <i>upper bound</i>) &gt; <code>p</code> 
> -     */
> -    protected double getDomainUpperBound(double p) {
> -        return Double.MAX_VALUE;
> -    }
> -
> -    /**
> -     * Access the initial domain value, based on <code>p</code>, used to
> -     * bracket a CDF root.  This method is used by
> -     * [EMAIL PROTECTED] #inverseCumulativeProbability(double)} to find 
> critical values.
> -     * 
> -     * @param p the desired probability for the critical value
> -     * @return initial domain value
> -     */
> -    protected double getInitialDomain(double p) {
> -        return getDenominatorDegreesOfFreedom() /
> -            (getDenominatorDegreesOfFreedom() - 2.0);
> -    }
> -    
> -    /**
> -     * Modify the numerator degrees of freedom.
> -     * @param degreesOfFreedom the new numerator degrees of freedom.
> -     * @throws IllegalArgumentException if <code>degreesOfFreedom</code> is 
> not
> -     *         positive.
> -     */
> -    public void setNumeratorDegreesOfFreedom(double degreesOfFreedom) {
> -        if (degreesOfFreedom <= 0.0) {
> -            throw new IllegalArgumentException(
> -                "degrees of freedom must be positive.");
> -        }
> -        this.numeratorDegreesOfFreedom = degreesOfFreedom;
> -    }
> -    
> -    /**
> -     * Access the numerator degrees of freedom.
> -     * @return the numerator degrees of freedom.
> -     */
> -    public double getNumeratorDegreesOfFreedom() {
> -        return numeratorDegreesOfFreedom;
> -    }
> -    
> -    /**
> -     * Modify the denominator degrees of freedom.
> -     * @param degreesOfFreedom the new denominator degrees of freedom.
> -     * @throws IllegalArgumentException if <code>degreesOfFreedom</code> is 
> not
> -     *         positive.
> -     */
> -    public void setDenominatorDegreesOfFreedom(double degreesOfFreedom) {
> -        if (degreesOfFreedom <= 0.0) {
> -            throw new IllegalArgumentException(
> -                "degrees of freedom must be positive.");
> -        }
> -        this.denominatorDegreesOfFreedom = degreesOfFreedom;
> -    }
> -    
> -    /**
> -     * Access the denominator degrees of freedom.
> -     * @return the denominator degrees of freedom.
> -     */
> -    public double getDenominatorDegreesOfFreedom() {
> -        return denominatorDegreesOfFreedom;
> -    }
> +public class FDistributionImpl extends AbstractContinuousDistribution 
> implements
> +             FDistribution, Serializable {
> +
> +     /** Serializable version identifier */
> +     private static final long serialVersionUID = -8516354193418641566L;
> +
> +     /** The numerator degrees of freedom */
> +     private double numeratorDegreesOfFreedom;
> +
> +     /** The numerator degrees of freedom */
> +     private double denominatorDegreesOfFreedom;
> +
> +     /**
> +      * Create a F distribution using the given degrees of freedom.
> +      * 
> +      * @param numeratorDegreesOfFreedom
> +      *            the numerator degrees of freedom.
> +      * @param denominatorDegreesOfFreedom
> +      *            the denominator degrees of freedom.
> +      */
> +     public FDistributionImpl(double numeratorDegreesOfFreedom,
> +                     double denominatorDegreesOfFreedom) {
> +             super();
> +             setNumeratorDegreesOfFreedom(numeratorDegreesOfFreedom);
> +             setDenominatorDegreesOfFreedom(denominatorDegreesOfFreedom);
> +     }
> +
> +     /**
> +      * For this distribution, X, this method returns P(X &lt; x).
> +      * 
> +      * The implementation of this method is based on:
> +      * <ul>
> +      * <li>
> +      * <a href="http://mathworld.wolfram.com/F-Distribution.html";>
> +      * F-Distribution</a>, equation (4).</li>
> +      * </ul>
> +      * 
> +      * @param x
> +      *            the value at which the CDF is evaluated.
> +      * @return CDF for this distribution.
> +      * @throws MathException
> +      *             if the cumulative probability can not be computed due to
> +      *             convergence or other numerical errors.
> +      */
> +     public double cumulativeProbability(double x) throws MathException {
> +             double ret;
> +             if (x <= 0.0) {
> +                     ret = 0.0;
> +             } else {
> +                     double n = getNumeratorDegreesOfFreedom();
> +                     double m = getDenominatorDegreesOfFreedom();
> +
> +                     ret = Beta.regularizedBeta((n * x) / (m + n * x), 0.5 * 
> n, 0.5 * m);
> +             }
> +             return ret;
> +     }
> +
> +     /**
> +      * For this distribution, X, this method returns the critical point x, 
> such
> +      * that P(X &lt; x) = <code>p</code>.
> +      * <p>
> +      * Returns 0 for p=0 and <code>Double.POSITIVE_INFINITY</code> for p=1.
> +      * </p>
> +      * 
> +      * @param p
> +      *            the desired probability
> +      * @return x, such that P(X &lt; x) = <code>p</code>
> +      * @throws MathException
> +      *             if the inverse cumulative probability can not be 
> computed due
> +      *             to convergence or other numerical errors.
> +      * @throws IllegalArgumentException
> +      *             if <code>p</code> is not a valid probability.
> +      */
> +     public double inverseCumulativeProbability(final double p)
> +                     throws MathException {
> +             if (p == 0) {
> +                     return 0d;
> +             }
> +             if (p == 1) {
> +                     return Double.POSITIVE_INFINITY;
> +             }
> +             return super.inverseCumulativeProbability(p);
> +     }
> +
> +     /**
> +      * Access the domain value lower bound, based on <code>p</code>, used to
> +      * bracket a CDF root. This method is used by
> +      * [EMAIL PROTECTED] #inverseCumulativeProbability(double)} to find 
> critical values.
> +      * 
> +      * @param p
> +      *            the desired probability for the critical value
> +      * @return domain value lower bound, i.e. P(X &lt; <i>lower bound</i>) 
> &lt;
> +      *         <code>p</code>
> +      */
> +     protected double getDomainLowerBound(double p) {
> +             return 0.0;
> +     }
> +
> +     /**
> +      * Access the domain value upper bound, based on <code>p</code>, used to
> +      * bracket a CDF root. This method is used by
> +      * [EMAIL PROTECTED] #inverseCumulativeProbability(double)} to find 
> critical values.
> +      * 
> +      * @param p
> +      *            the desired probability for the critical value
> +      * @return domain value upper bound, i.e. P(X &lt; <i>upper bound</i>) 
> &gt;
> +      *         <code>p</code>
> +      */
> +     protected double getDomainUpperBound(double p) {
> +             return Double.MAX_VALUE;
> +     }
> +
> +     /**
> +      * Access the initial domain value, based on <code>p</code>, used to 
> bracket
> +      * a CDF root. This method is used by
> +      * [EMAIL PROTECTED] #inverseCumulativeProbability(double)} to find 
> critical values.
> +      * 
> +      * @param p
> +      *            the desired probability for the critical value
> +      * @return initial domain value
> +      */
> +     protected double getInitialDomain(double p) {
> +             double ret = 1.0;
> +             double d = getDenominatorDegreesOfFreedom();
> +             if (d > 2.0) {
> +                     // use mean
> +                     ret = d / (d - 2.0);
> +             }
> +             return ret;
> +     }
> +
> +     /**
> +      * Modify the numerator degrees of freedom.
> +      * 
> +      * @param degreesOfFreedom
> +      *            the new numerator degrees of freedom.
> +      * @throws IllegalArgumentException
> +      *             if <code>degreesOfFreedom</code> is not positive.
> +      */
> +     public void setNumeratorDegreesOfFreedom(double degreesOfFreedom) {
> +             if (degreesOfFreedom <= 0.0) {
> +                     throw new IllegalArgumentException(
> +                                     "degrees of freedom must be positive.");
> +             }
> +             this.numeratorDegreesOfFreedom = degreesOfFreedom;
> +     }
> +
> +     /**
> +      * Access the numerator degrees of freedom.
> +      * 
> +      * @return the numerator degrees of freedom.
> +      */
> +     public double getNumeratorDegreesOfFreedom() {
> +             return numeratorDegreesOfFreedom;
> +     }
> +
> +     /**
> +      * Modify the denominator degrees of freedom.
> +      * 
> +      * @param degreesOfFreedom
> +      *            the new denominator degrees of freedom.
> +      * @throws IllegalArgumentException
> +      *             if <code>degreesOfFreedom</code> is not positive.
> +      */
> +     public void setDenominatorDegreesOfFreedom(double degreesOfFreedom) {
> +             if (degreesOfFreedom <= 0.0) {
> +                     throw new IllegalArgumentException(
> +                                     "degrees of freedom must be positive.");
> +             }
> +             this.denominatorDegreesOfFreedom = degreesOfFreedom;
> +     }
> +
> +     /**
> +      * Access the denominator degrees of freedom.
> +      * 
> +      * @return the denominator degrees of freedom.
> +      */
> +     public double getDenominatorDegreesOfFreedom() {
> +             return denominatorDegreesOfFreedom;
> +     }
>  }
> 
> Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
> URL: 
> http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=699157&r1=699156&r2=699157&view=diff
> ==============================================================================
> --- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
> +++ commons/proper/math/trunk/src/site/xdoc/changes.xml Thu Sep 25 20:09:53 
> 2008
> @@ -65,6 +65,9 @@
>        <action dev="brentworden" type="fix" issue="MATH-204" due-to="Mick">
>          Added root checks for the endpoints.
>        </action>
> +      <action dev="brentworden" type="fix" issue="MATH-227" due-to="Joerg 
> Henning">
> +        Fixed F distribution inverse CDF computation for small denominator 
> degrees of freedom.
> +      </action>
>      </release>
>      <release version="1.2" date="2008-02-24"
>      description="This release combines bug fixes and new features. Most 
> notable
> 
> Modified: 
> commons/proper/math/trunk/src/test/org/apache/commons/math/distribution/FDistributionTest.java
> URL: 
> http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/org/apache/commons/math/distribution/FDistributionTest.java?rev=699157&r1=699156&r2=699157&view=diff
> ==============================================================================
> --- 
> commons/proper/math/trunk/src/test/org/apache/commons/math/distribution/FDistributionTest.java
>  (original)
> +++ 
> commons/proper/math/trunk/src/test/org/apache/commons/math/distribution/FDistributionTest.java
>  Thu Sep 25 20:09:53 2008
> @@ -105,4 +105,18 @@
>          double x = fd.inverseCumulativeProbability(p);
>          assertEquals(.999, x, 1.0e-5);
>      }
> +
> +    public void testSmallDegreesOfFreedom() throws Exception {
> +        org.apache.commons.math.distribution.FDistributionImpl fd =
> +            new org.apache.commons.math.distribution.FDistributionImpl(
> +                1.0, 1.0);
> +        double p = fd.cumulativeProbability(0.975);
> +        double x = fd.inverseCumulativeProbability(p);
> +        assertEquals(0.975, x, 1.0e-5);
> +
> +        fd.setDenominatorDegreesOfFreedom(2.0);
> +        p = fd.cumulativeProbability(0.975);
> +        x = fd.inverseCumulativeProbability(p);
> +        assertEquals(0.975, x, 1.0e-5);
> +    }
>  }
> 
> 
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to