[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 < 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 < 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 < <i>lower bound</i>) < <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 < <i>upper bound</i>) > <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 < 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 < 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 < 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 < <i>lower bound</i>)
> <
> + * <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 < <i>upper bound</i>)
> >
> + * <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]