set eol-style property to native

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@506713 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2007-02-12 22:35:08 +00:00
parent 2fe2d9a4aa
commit 2b25d6352a
22 changed files with 3600 additions and 3600 deletions

View File

@ -1,54 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import java.io.Serializable;
import org.apache.commons.math.MathException;
/**
* Implements the <a href="http://mathworld.wolfram.com/NevillesAlgorithm.html">
* Neville's Algorithm</a> for interpolation of real univariate functions. For
* reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X,
* chapter 2.
* <p>
* The actual code of Neville's evalution is in PolynomialFunctionLagrangeForm,
* this class provides an easy-to-use interface to it.
*
* @version $Revision$ $Date$
*/
public class NevilleInterpolator implements UnivariateRealInterpolator,
Serializable {
/** serializable version identifier */
static final long serialVersionUID = 3003707660147873733L;
/**
* Computes an interpolating function for the data set.
*
* @param x the interpolating points array
* @param y the interpolating values array
* @return a function which interpolates the data set
* @throws MathException if arguments are invalid
*/
public UnivariateRealFunction interpolate(double x[], double y[]) throws
MathException {
PolynomialFunctionLagrangeForm p;
p = new PolynomialFunctionLagrangeForm(x, y);
return p;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import java.io.Serializable;
import org.apache.commons.math.MathException;
/**
* Implements the <a href="http://mathworld.wolfram.com/NevillesAlgorithm.html">
* Neville's Algorithm</a> for interpolation of real univariate functions. For
* reference, see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X,
* chapter 2.
* <p>
* The actual code of Neville's evalution is in PolynomialFunctionLagrangeForm,
* this class provides an easy-to-use interface to it.
*
* @version $Revision$ $Date$
*/
public class NevilleInterpolator implements UnivariateRealInterpolator,
Serializable {
/** serializable version identifier */
static final long serialVersionUID = 3003707660147873733L;
/**
* Computes an interpolating function for the data set.
*
* @param x the interpolating points array
* @param y the interpolating values array
* @return a function which interpolates the data set
* @throws MathException if arguments are invalid
*/
public UnivariateRealFunction interpolate(double x[], double y[]) throws
MathException {
PolynomialFunctionLagrangeForm p;
p = new PolynomialFunctionLagrangeForm(x, y);
return p;
}
}

View File

@ -1,215 +1,215 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import java.io.Serializable;
import org.apache.commons.math.FunctionEvaluationException;
/**
* Implements the representation of a real polynomial function in
* Newton Form. For reference, see <b>Elementary Numerical Analysis</b>,
* ISBN 0070124477, chapter 2.
* <p>
* The formula of polynomial in Newton form is
* p(x) = a[0] + a[1](x-c[0]) + a[2](x-c[0])(x-c[1]) + ... +
* a[n](x-c[0])(x-c[1])...(x-c[n-1])
* Note that the length of a[] is one more than the length of c[]
*
* @version $Revision$ $Date$
*/
public class PolynomialFunctionNewtonForm implements UnivariateRealFunction,
Serializable {
/** serializable version identifier */
static final long serialVersionUID = -3353896576191389897L;
/**
* The coefficients of the polynomial, ordered by degree -- i.e.
* coefficients[0] is the constant term and coefficients[n] is the
* coefficient of x^n where n is the degree of the polynomial.
*/
private double coefficients[];
/**
* Members of c[] are called centers of the Newton polynomial.
* When all c[i] = 0, a[] becomes normal polynomial coefficients,
* i.e. a[i] = coefficients[i].
*/
private double a[], c[];
/**
* Whether the polynomial coefficients are available.
*/
private boolean coefficientsComputed;
/**
* Construct a Newton polynomial with the given a[] and c[]. The order of
* centers are important in that if c[] shuffle, then values of a[] would
* completely change, not just a permutation of old a[].
* <p>
* The constructor makes copy of the input arrays and assigns them.
*
* @param a the coefficients in Newton form formula
* @param c the centers
* @throws IllegalArgumentException if input arrays are not valid
*/
PolynomialFunctionNewtonForm(double a[], double c[]) throws
IllegalArgumentException {
verifyInputArray(a, c);
this.a = new double[a.length];
this.c = new double[c.length];
System.arraycopy(a, 0, this.a, 0, a.length);
System.arraycopy(c, 0, this.c, 0, c.length);
coefficientsComputed = false;
}
/**
* Calculate the function value at the given point.
*
* @param z the point at which the function value is to be computed
* @return the function value
* @throws FunctionEvaluationException if a runtime error occurs
* @see UnivariateRealFunction#value(double)
*/
public double value(double z) throws FunctionEvaluationException {
return evaluate(a, c, z);
}
/**
* Returns the degree of the polynomial.
*
* @return the degree of the polynomial
*/
public int degree() {
return c.length;
}
/**
* Returns a copy of coefficients in Newton form formula.
* <p>
* Changes made to the returned copy will not affect the polynomial.
*
* @return a fresh copy of coefficients in Newton form formula
*/
public double[] getNewtonCoefficients() {
double[] out = new double[a.length];
System.arraycopy(a, 0, out, 0, a.length);
return out;
}
/**
* Returns a copy of the centers array.
* <p>
* Changes made to the returned copy will not affect the polynomial.
*
* @return a fresh copy of the centers array
*/
public double[] getCenters() {
double[] out = new double[c.length];
System.arraycopy(c, 0, out, 0, c.length);
return out;
}
/**
* Returns a copy of the coefficients array.
* <p>
* Changes made to the returned copy will not affect the polynomial.
*
* @return a fresh copy of the coefficients array
*/
public double[] getCoefficients() {
if (!coefficientsComputed) {
computeCoefficients();
}
double[] out = new double[coefficients.length];
System.arraycopy(coefficients, 0, out, 0, coefficients.length);
return out;
}
/**
* Evaluate the Newton polynomial using nested multiplication. It is
* also called <a href="http://mathworld.wolfram.com/HornersRule.html">
* Horner's Rule</a> and takes O(N) time.
*
* @param a the coefficients in Newton form formula
* @param c the centers
* @param z the point at which the function value is to be computed
* @return the function value
* @throws FunctionEvaluationException if a runtime error occurs
* @throws IllegalArgumentException if inputs are not valid
*/
public static double evaluate(double a[], double c[], double z) throws
FunctionEvaluationException, IllegalArgumentException {
verifyInputArray(a, c);
int n = c.length;
double value = a[n];
for (int i = n-1; i >= 0; i--) {
value = a[i] + (z - c[i]) * value;
}
return value;
}
/**
* Calculate the normal polynomial coefficients given the Newton form.
* It also uses nested multiplication but takes O(N^2) time.
*/
protected void computeCoefficients() {
int i, j, n = degree();
coefficients = new double[n+1];
for (i = 0; i <= n; i++) {
coefficients[i] = 0.0;
}
coefficients[0] = a[n];
for (i = n-1; i >= 0; i--) {
for (j = n-i; j > 0; j--) {
coefficients[j] = coefficients[j-1] - c[i] * coefficients[j];
}
coefficients[0] = a[i] - c[i] * coefficients[0];
}
coefficientsComputed = true;
}
/**
* Verifies that the input arrays are valid.
* <p>
* The centers must be distinct for interpolation purposes, but not
* for general use. Thus it is not verified here.
*
* @throws IllegalArgumentException if not valid
* @see DividedDifferenceInterpolator#computeDividedDifference(double[],
* double[])
*/
protected static void verifyInputArray(double a[], double c[]) throws
IllegalArgumentException {
if (a.length < 1 || c.length < 1) {
throw new IllegalArgumentException
("Input arrays must not be empty.");
}
if (a.length != c.length + 1) {
throw new IllegalArgumentException
("Bad input array sizes, should have difference 1.");
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import java.io.Serializable;
import org.apache.commons.math.FunctionEvaluationException;
/**
* Implements the representation of a real polynomial function in
* Newton Form. For reference, see <b>Elementary Numerical Analysis</b>,
* ISBN 0070124477, chapter 2.
* <p>
* The formula of polynomial in Newton form is
* p(x) = a[0] + a[1](x-c[0]) + a[2](x-c[0])(x-c[1]) + ... +
* a[n](x-c[0])(x-c[1])...(x-c[n-1])
* Note that the length of a[] is one more than the length of c[]
*
* @version $Revision$ $Date$
*/
public class PolynomialFunctionNewtonForm implements UnivariateRealFunction,
Serializable {
/** serializable version identifier */
static final long serialVersionUID = -3353896576191389897L;
/**
* The coefficients of the polynomial, ordered by degree -- i.e.
* coefficients[0] is the constant term and coefficients[n] is the
* coefficient of x^n where n is the degree of the polynomial.
*/
private double coefficients[];
/**
* Members of c[] are called centers of the Newton polynomial.
* When all c[i] = 0, a[] becomes normal polynomial coefficients,
* i.e. a[i] = coefficients[i].
*/
private double a[], c[];
/**
* Whether the polynomial coefficients are available.
*/
private boolean coefficientsComputed;
/**
* Construct a Newton polynomial with the given a[] and c[]. The order of
* centers are important in that if c[] shuffle, then values of a[] would
* completely change, not just a permutation of old a[].
* <p>
* The constructor makes copy of the input arrays and assigns them.
*
* @param a the coefficients in Newton form formula
* @param c the centers
* @throws IllegalArgumentException if input arrays are not valid
*/
PolynomialFunctionNewtonForm(double a[], double c[]) throws
IllegalArgumentException {
verifyInputArray(a, c);
this.a = new double[a.length];
this.c = new double[c.length];
System.arraycopy(a, 0, this.a, 0, a.length);
System.arraycopy(c, 0, this.c, 0, c.length);
coefficientsComputed = false;
}
/**
* Calculate the function value at the given point.
*
* @param z the point at which the function value is to be computed
* @return the function value
* @throws FunctionEvaluationException if a runtime error occurs
* @see UnivariateRealFunction#value(double)
*/
public double value(double z) throws FunctionEvaluationException {
return evaluate(a, c, z);
}
/**
* Returns the degree of the polynomial.
*
* @return the degree of the polynomial
*/
public int degree() {
return c.length;
}
/**
* Returns a copy of coefficients in Newton form formula.
* <p>
* Changes made to the returned copy will not affect the polynomial.
*
* @return a fresh copy of coefficients in Newton form formula
*/
public double[] getNewtonCoefficients() {
double[] out = new double[a.length];
System.arraycopy(a, 0, out, 0, a.length);
return out;
}
/**
* Returns a copy of the centers array.
* <p>
* Changes made to the returned copy will not affect the polynomial.
*
* @return a fresh copy of the centers array
*/
public double[] getCenters() {
double[] out = new double[c.length];
System.arraycopy(c, 0, out, 0, c.length);
return out;
}
/**
* Returns a copy of the coefficients array.
* <p>
* Changes made to the returned copy will not affect the polynomial.
*
* @return a fresh copy of the coefficients array
*/
public double[] getCoefficients() {
if (!coefficientsComputed) {
computeCoefficients();
}
double[] out = new double[coefficients.length];
System.arraycopy(coefficients, 0, out, 0, coefficients.length);
return out;
}
/**
* Evaluate the Newton polynomial using nested multiplication. It is
* also called <a href="http://mathworld.wolfram.com/HornersRule.html">
* Horner's Rule</a> and takes O(N) time.
*
* @param a the coefficients in Newton form formula
* @param c the centers
* @param z the point at which the function value is to be computed
* @return the function value
* @throws FunctionEvaluationException if a runtime error occurs
* @throws IllegalArgumentException if inputs are not valid
*/
public static double evaluate(double a[], double c[], double z) throws
FunctionEvaluationException, IllegalArgumentException {
verifyInputArray(a, c);
int n = c.length;
double value = a[n];
for (int i = n-1; i >= 0; i--) {
value = a[i] + (z - c[i]) * value;
}
return value;
}
/**
* Calculate the normal polynomial coefficients given the Newton form.
* It also uses nested multiplication but takes O(N^2) time.
*/
protected void computeCoefficients() {
int i, j, n = degree();
coefficients = new double[n+1];
for (i = 0; i <= n; i++) {
coefficients[i] = 0.0;
}
coefficients[0] = a[n];
for (i = n-1; i >= 0; i--) {
for (j = n-i; j > 0; j--) {
coefficients[j] = coefficients[j-1] - c[i] * coefficients[j];
}
coefficients[0] = a[i] - c[i] * coefficients[0];
}
coefficientsComputed = true;
}
/**
* Verifies that the input arrays are valid.
* <p>
* The centers must be distinct for interpolation purposes, but not
* for general use. Thus it is not verified here.
*
* @throws IllegalArgumentException if not valid
* @see DividedDifferenceInterpolator#computeDividedDifference(double[],
* double[])
*/
protected static void verifyInputArray(double a[], double c[]) throws
IllegalArgumentException {
if (a.length < 1 || c.length < 1) {
throw new IllegalArgumentException
("Input arrays must not be empty.");
}
if (a.length != c.length + 1) {
throw new IllegalArgumentException
("Bad input array sizes, should have difference 1.");
}
}
}

View File

@ -1,61 +1,61 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
/**
* Cauchy Distribution.
* Instances of CauchyDistribution objects should be created using
* {@link DistributionFactory#createCauchyDistribution(double, double)}.<p>
*
* <p>
* References:<p>
* <ul>
* <li><a href="http://mathworld.wolfram.com/CauchyDistribution.html">
* Cauchy Distribution</a></li>
* </ul>
* </p>
*
* @since 1.1
* @version $Revision$ $Date$
*/
public interface CauchyDistribution extends ContinuousDistribution {
/**
* Access the median.
* @return median for this distribution
*/
double getMedian();
/**
* Access the scale parameter.
* @return scale parameter for this distribution
*/
double getScale();
/**
* Modify the median.
* @param median for this distribution
*/
void setMedian(double median);
/**
* Modify the scale parameter.
* @param s scale parameter for this distribution
*/
void setScale(double s);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
/**
* Cauchy Distribution.
* Instances of CauchyDistribution objects should be created using
* {@link DistributionFactory#createCauchyDistribution(double, double)}.<p>
*
* <p>
* References:<p>
* <ul>
* <li><a href="http://mathworld.wolfram.com/CauchyDistribution.html">
* Cauchy Distribution</a></li>
* </ul>
* </p>
*
* @since 1.1
* @version $Revision$ $Date$
*/
public interface CauchyDistribution extends ContinuousDistribution {
/**
* Access the median.
* @return median for this distribution
*/
double getMedian();
/**
* Access the scale parameter.
* @return scale parameter for this distribution
*/
double getScale();
/**
* Modify the median.
* @param median for this distribution
*/
void setMedian(double median);
/**
* Modify the scale parameter.
* @param s scale parameter for this distribution
*/
void setScale(double s);
}

View File

@ -1,196 +1,196 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
import java.io.Serializable;
/**
* Default implementation of
* {@link org.apache.commons.math.distribution.CauchyDistribution}.
*
* @since 1.1
* @version $Revision$ $Date$
*/
public class CauchyDistributionImpl extends AbstractContinuousDistribution
implements CauchyDistribution, Serializable {
/** Serializable version identifier */
private static final long serialVersionUID = 8589540077390120676L;
/** The median of this distribution. */
private double median = 0;
/** The scale of this distribution. */
private double scale = 1;
/**
* Creates cauchy distribution with the medain equal to zero and scale
* equal to one.
*/
public CauchyDistributionImpl(){
this(0.0, 1.0);
}
/**
* Create a cauchy distribution using the given median and scale.
* @param median median for this distribution
* @param s scale parameter for this distribution
*/
public CauchyDistributionImpl(double median, double s){
super();
setMedian(median);
setScale(s);
}
/**
* For this disbution, X, this method returns P(X &lt; <code>x</code>).
* @param x the value at which the CDF is evaluated.
* @return CDF evaluted at <code>x</code>.
*/
public double cumulativeProbability(double x) {
return 0.5 + (Math.atan((x - median) / scale) / Math.PI);
}
/**
* Access the median.
* @return median for this distribution
*/
public double getMedian() {
return median;
}
/**
* Access the scale parameter.
* @return scale parameter for this distribution
*/
public double getScale() {
return scale;
}
/**
* For this distribution, X, this method returns the critical point x, such
* that P(X &lt; x) = <code>p</code>.
* <p>
* Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and
* <code>Double.POSITIVE_INFINITY</code> for p=1.
*
* @param p the desired probability
* @return x, such that P(X &lt; x) = <code>p</code>
* @throws IllegalArgumentException if <code>p</code> is not a valid
* probability.
*/
public double inverseCumulativeProbability(double p) {
double ret;
if (p < 0.0 || p > 1.0) {
throw new IllegalArgumentException
("probability argument must be between 0 and 1 (inclusive)");
} else if (p == 0) {
ret = Double.NEGATIVE_INFINITY;
} else if (p == 1) {
ret = Double.POSITIVE_INFINITY;
} else {
ret = median + scale * Math.tan(Math.PI * (p - .5));
}
return ret;
}
/**
* Modify the median.
* @param median for this distribution
*/
public void setMedian(double median) {
this.median = median;
}
/**
* Modify the scale parameter.
* @param s scale parameter for this distribution
* @throws IllegalArgumentException if <code>sd</code> is not positive.
*/
public void setScale(double s) {
if (s <= 0.0) {
throw new IllegalArgumentException(
"Scale must be positive.");
}
scale = s;
}
/**
* Access the domain value lower bound, based on <code>p</code>, used to
* bracket a CDF root. This method is used by
* {@link #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) {
double ret;
if (p < .5) {
ret = -Double.MAX_VALUE;
} else {
ret = getMedian();
}
return ret;
}
/**
* Access the domain value upper bound, based on <code>p</code>, used to
* bracket a CDF root. This method is used by
* {@link #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) {
double ret;
if (p < .5) {
ret = getMedian();
} else {
ret = Double.MAX_VALUE;
}
return ret;
}
/**
* Access the initial domain value, based on <code>p</code>, used to
* bracket a CDF root. This method is used by
* {@link #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;
if (p < .5) {
ret = getMedian() - getScale();
} else if (p > .5) {
ret = getMedian() + getScale();
} else {
ret = getMedian();
}
return ret;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
import java.io.Serializable;
/**
* Default implementation of
* {@link org.apache.commons.math.distribution.CauchyDistribution}.
*
* @since 1.1
* @version $Revision$ $Date$
*/
public class CauchyDistributionImpl extends AbstractContinuousDistribution
implements CauchyDistribution, Serializable {
/** Serializable version identifier */
private static final long serialVersionUID = 8589540077390120676L;
/** The median of this distribution. */
private double median = 0;
/** The scale of this distribution. */
private double scale = 1;
/**
* Creates cauchy distribution with the medain equal to zero and scale
* equal to one.
*/
public CauchyDistributionImpl(){
this(0.0, 1.0);
}
/**
* Create a cauchy distribution using the given median and scale.
* @param median median for this distribution
* @param s scale parameter for this distribution
*/
public CauchyDistributionImpl(double median, double s){
super();
setMedian(median);
setScale(s);
}
/**
* For this disbution, X, this method returns P(X &lt; <code>x</code>).
* @param x the value at which the CDF is evaluated.
* @return CDF evaluted at <code>x</code>.
*/
public double cumulativeProbability(double x) {
return 0.5 + (Math.atan((x - median) / scale) / Math.PI);
}
/**
* Access the median.
* @return median for this distribution
*/
public double getMedian() {
return median;
}
/**
* Access the scale parameter.
* @return scale parameter for this distribution
*/
public double getScale() {
return scale;
}
/**
* For this distribution, X, this method returns the critical point x, such
* that P(X &lt; x) = <code>p</code>.
* <p>
* Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and
* <code>Double.POSITIVE_INFINITY</code> for p=1.
*
* @param p the desired probability
* @return x, such that P(X &lt; x) = <code>p</code>
* @throws IllegalArgumentException if <code>p</code> is not a valid
* probability.
*/
public double inverseCumulativeProbability(double p) {
double ret;
if (p < 0.0 || p > 1.0) {
throw new IllegalArgumentException
("probability argument must be between 0 and 1 (inclusive)");
} else if (p == 0) {
ret = Double.NEGATIVE_INFINITY;
} else if (p == 1) {
ret = Double.POSITIVE_INFINITY;
} else {
ret = median + scale * Math.tan(Math.PI * (p - .5));
}
return ret;
}
/**
* Modify the median.
* @param median for this distribution
*/
public void setMedian(double median) {
this.median = median;
}
/**
* Modify the scale parameter.
* @param s scale parameter for this distribution
* @throws IllegalArgumentException if <code>sd</code> is not positive.
*/
public void setScale(double s) {
if (s <= 0.0) {
throw new IllegalArgumentException(
"Scale must be positive.");
}
scale = s;
}
/**
* Access the domain value lower bound, based on <code>p</code>, used to
* bracket a CDF root. This method is used by
* {@link #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) {
double ret;
if (p < .5) {
ret = -Double.MAX_VALUE;
} else {
ret = getMedian();
}
return ret;
}
/**
* Access the domain value upper bound, based on <code>p</code>, used to
* bracket a CDF root. This method is used by
* {@link #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) {
double ret;
if (p < .5) {
ret = getMedian();
} else {
ret = Double.MAX_VALUE;
}
return ret;
}
/**
* Access the initial domain value, based on <code>p</code>, used to
* bracket a CDF root. This method is used by
* {@link #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;
if (p < .5) {
ret = getMedian() - getScale();
} else if (p > .5) {
ret = getMedian() + getScale();
} else {
ret = getMedian();
}
return ret;
}
}

View File

@ -1,65 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
/**
* Weibull Distribution. This interface defines the two parameter form of the
* distribution as defined by
* <a href="http://mathworld.wolfram.com/WeibullDistribution.html">
* Weibull Distribution</a>, equations (1) and (2).
*
* Instances of WeibullDistribution objects should be created using
* {@link DistributionFactory#createWeibullDistribution(double, double)}
*
* <p>
* References:
* <ul>
* <li><a href="http://mathworld.wolfram.com/WeibullDistribution.html">
* Weibull Distribution</a></li>
* </ul>
* </p>
*
* @since 1.1
* @version $Revision: 1.12 $ $Date: 2004-06-23 11:26:18 -0500 (Wed, 23 Jun 2004) $
*/
public interface WeibullDistribution extends ContinuousDistribution {
/**
* Access the shape parameter.
* @return the shape parameter.
*/
double getShape();
/**
* Access the scale parameter.
* @return the scale parameter.
*/
double getScale();
/**
* Modify the shape parameter.
* @param alpha The new shape parameter value.
*/
void setShape(double alpha);
/**
* Modify the scale parameter.
* @param beta The new scale parameter value.
*/
void setScale(double beta);
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
/**
* Weibull Distribution. This interface defines the two parameter form of the
* distribution as defined by
* <a href="http://mathworld.wolfram.com/WeibullDistribution.html">
* Weibull Distribution</a>, equations (1) and (2).
*
* Instances of WeibullDistribution objects should be created using
* {@link DistributionFactory#createWeibullDistribution(double, double)}
*
* <p>
* References:
* <ul>
* <li><a href="http://mathworld.wolfram.com/WeibullDistribution.html">
* Weibull Distribution</a></li>
* </ul>
* </p>
*
* @since 1.1
* @version $Revision: 1.12 $ $Date: 2004-06-23 11:26:18 -0500 (Wed, 23 Jun 2004) $
*/
public interface WeibullDistribution extends ContinuousDistribution {
/**
* Access the shape parameter.
* @return the shape parameter.
*/
double getShape();
/**
* Access the scale parameter.
* @return the scale parameter.
*/
double getScale();
/**
* Modify the shape parameter.
* @param alpha The new shape parameter value.
*/
void setShape(double alpha);
/**
* Modify the scale parameter.
* @param beta The new scale parameter value.
*/
void setScale(double beta);
}

View File

@ -1,173 +1,173 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
import java.io.Serializable;
/**
* Default implementation of
* {@link org.apache.commons.math.distribution.WeibullDistribution}.
*
* @since 1.1
* @version $Revision: 1.13 $ $Date: 2004-07-24 16:41:37 -0500 (Sat, 24 Jul 2004) $
*/
public class WeibullDistributionImpl extends AbstractContinuousDistribution
implements WeibullDistribution, Serializable {
/** Serializable version identifier */
private static final long serialVersionUID = 8589540077390120676L;
/** The shape parameter. */
private double alpha;
/** The scale parameter. */
private double beta;
/**
* Creates weibull distribution with the given shape and scale and a
* location equal to zero.
* @param alpha the shape parameter.
* @param beta the scale parameter.
*/
public WeibullDistributionImpl(double alpha, double beta){
super();
setShape(alpha);
setScale(beta);
}
/**
* For this disbution, X, this method returns P(X &lt; <code>x</code>).
* @param x the value at which the CDF is evaluated.
* @return CDF evaluted at <code>x</code>.
*/
public double cumulativeProbability(double x) {
double ret;
if (x <= 0.0) {
ret = 0.0;
} else {
ret = 1.0 - Math.exp(-Math.pow(x / getScale(), getShape()));
}
return ret;
}
/**
* Access the shape parameter.
* @return the shape parameter.
*/
public double getShape() {
return alpha;
}
/**
* Access the scale parameter.
* @return the scale parameter.
*/
public double getScale() {
return beta;
}
/**
* For this distribution, X, this method returns the critical point x, such
* that P(X &lt; x) = <code>p</code>.
* <p>
* Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and
* <code>Double.POSITIVE_INFINITY</code> for p=1.
*
* @param p the desired probability
* @return x, such that P(X &lt; x) = <code>p</code>
* @throws IllegalArgumentException if <code>p</code> is not a valid
* probability.
*/
public double inverseCumulativeProbability(double p) {
double ret;
if (p < 0.0 || p > 1.0) {
throw new IllegalArgumentException
("probability argument must be between 0 and 1 (inclusive)");
} else if (p == 0) {
ret = 0.0;
} else if (p == 1) {
ret = Double.POSITIVE_INFINITY;
} else {
ret = getScale() * Math.pow(-Math.log(1.0 - p), 1.0 / getShape());
}
return ret;
}
/**
* Modify the shape parameter.
* @param alpha the new shape parameter value.
*/
public void setShape(double alpha) {
if (alpha <= 0.0) {
throw new IllegalArgumentException(
"Shape must be positive.");
}
this.alpha = alpha;
}
/**
* Modify the scale parameter.
* @param beta the new scale parameter value.
*/
public void setScale(double beta) {
if (beta <= 0.0) {
throw new IllegalArgumentException(
"Scale must be positive.");
}
this.beta = beta;
}
/**
* Access the domain value lower bound, based on <code>p</code>, used to
* bracket a CDF root. This method is used by
* {@link #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
* {@link #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
* {@link #inverseCumulativeProbability(double)} to find critical values.
*
* @param p the desired probability for the critical value
* @return initial domain value
*/
protected double getInitialDomain(double p) {
// use median
return Math.pow(getScale() * Math.log(2.0), 1.0 / getShape());
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
import java.io.Serializable;
/**
* Default implementation of
* {@link org.apache.commons.math.distribution.WeibullDistribution}.
*
* @since 1.1
* @version $Revision: 1.13 $ $Date: 2004-07-24 16:41:37 -0500 (Sat, 24 Jul 2004) $
*/
public class WeibullDistributionImpl extends AbstractContinuousDistribution
implements WeibullDistribution, Serializable {
/** Serializable version identifier */
private static final long serialVersionUID = 8589540077390120676L;
/** The shape parameter. */
private double alpha;
/** The scale parameter. */
private double beta;
/**
* Creates weibull distribution with the given shape and scale and a
* location equal to zero.
* @param alpha the shape parameter.
* @param beta the scale parameter.
*/
public WeibullDistributionImpl(double alpha, double beta){
super();
setShape(alpha);
setScale(beta);
}
/**
* For this disbution, X, this method returns P(X &lt; <code>x</code>).
* @param x the value at which the CDF is evaluated.
* @return CDF evaluted at <code>x</code>.
*/
public double cumulativeProbability(double x) {
double ret;
if (x <= 0.0) {
ret = 0.0;
} else {
ret = 1.0 - Math.exp(-Math.pow(x / getScale(), getShape()));
}
return ret;
}
/**
* Access the shape parameter.
* @return the shape parameter.
*/
public double getShape() {
return alpha;
}
/**
* Access the scale parameter.
* @return the scale parameter.
*/
public double getScale() {
return beta;
}
/**
* For this distribution, X, this method returns the critical point x, such
* that P(X &lt; x) = <code>p</code>.
* <p>
* Returns <code>Double.NEGATIVE_INFINITY</code> for p=0 and
* <code>Double.POSITIVE_INFINITY</code> for p=1.
*
* @param p the desired probability
* @return x, such that P(X &lt; x) = <code>p</code>
* @throws IllegalArgumentException if <code>p</code> is not a valid
* probability.
*/
public double inverseCumulativeProbability(double p) {
double ret;
if (p < 0.0 || p > 1.0) {
throw new IllegalArgumentException
("probability argument must be between 0 and 1 (inclusive)");
} else if (p == 0) {
ret = 0.0;
} else if (p == 1) {
ret = Double.POSITIVE_INFINITY;
} else {
ret = getScale() * Math.pow(-Math.log(1.0 - p), 1.0 / getShape());
}
return ret;
}
/**
* Modify the shape parameter.
* @param alpha the new shape parameter value.
*/
public void setShape(double alpha) {
if (alpha <= 0.0) {
throw new IllegalArgumentException(
"Shape must be positive.");
}
this.alpha = alpha;
}
/**
* Modify the scale parameter.
* @param beta the new scale parameter value.
*/
public void setScale(double beta) {
if (beta <= 0.0) {
throw new IllegalArgumentException(
"Scale must be positive.");
}
this.beta = beta;
}
/**
* Access the domain value lower bound, based on <code>p</code>, used to
* bracket a CDF root. This method is used by
* {@link #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
* {@link #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
* {@link #inverseCumulativeProbability(double)} to find critical values.
*
* @param p the desired probability for the critical value
* @return initial domain value
*/
protected double getInitialDomain(double p) {
// use median
return Math.pow(getScale() * Math.log(2.0), 1.0 / getShape());
}
}

View File

@ -1,389 +1,389 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.fraction;
import java.io.Serializable;
import java.text.FieldPosition;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Locale;
import org.apache.commons.math.ConvergenceException;
/**
* Formats a Fraction number in proper format or improper format. The number
* format for each of the whole number, numerator and, denominator can be
* configured.
*
* @since 1.1
* @version $Revision$ $Date$
*/
public class FractionFormat extends Format implements Serializable {
/** Serializable version identifier */
private static final long serialVersionUID = -6337346779577272306L;
/** The format used for the denominator. */
private NumberFormat denominatorFormat;
/** The format used for the numerator. */
private NumberFormat numeratorFormat;
/**
* Create an improper formatting instance with the default number format
* for the numerator and denominator.
*/
public FractionFormat() {
this(getDefaultNumberFormat());
}
/**
* Create an improper formatting instance with a custom number format for
* both the numerator and denominator.
* @param format the custom format for both the numerator and denominator.
*/
public FractionFormat(NumberFormat format) {
this(format, (NumberFormat)format.clone());
}
/**
* Create an improper formatting instance with a custom number format for
* the numerator and a custom number format for the denominator.
* @param numeratorFormat the custom format for the numerator.
* @param denominatorFormat the custom format for the denominator.
*/
public FractionFormat(NumberFormat numeratorFormat,
NumberFormat denominatorFormat)
{
super();
this.numeratorFormat = numeratorFormat;
this.denominatorFormat = denominatorFormat;
}
/**
* This static method calls formatFraction() on a default instance of
* FractionFormat.
*
* @param f Fraction object to format
* @return A formatted fraction in proper form.
*/
public static String formatFraction(Fraction f) {
return getImproperInstance().format(f);
}
/**
* Get the set of locales for which complex formats are available. This
* is the same set as the {@link NumberFormat} set.
* @return available complex format locales.
*/
public static Locale[] getAvailableLocales() {
return NumberFormat.getAvailableLocales();
}
/**
* Returns the default complex format for the current locale.
* @return the default complex format.
*/
public static FractionFormat getImproperInstance() {
return getImproperInstance(Locale.getDefault());
}
/**
* Returns the default complex format for the given locale.
* @param locale the specific locale used by the format.
* @return the complex format specific to the given locale.
*/
public static FractionFormat getImproperInstance(Locale locale) {
NumberFormat f = getDefaultNumberFormat(locale);
return new FractionFormat(f);
}
/**
* Returns the default complex format for the current locale.
* @return the default complex format.
*/
public static FractionFormat getProperInstance() {
return getProperInstance(Locale.getDefault());
}
/**
* Returns the default complex format for the given locale.
* @param locale the specific locale used by the format.
* @return the complex format specific to the given locale.
*/
public static FractionFormat getProperInstance(Locale locale) {
NumberFormat f = getDefaultNumberFormat(locale);
return new ProperFractionFormat(f);
}
/**
* Create a default number format. The default number format is based on
* {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only
* customizing is the maximum number of fraction digits, which is set to 0.
* @return the default number format.
*/
protected static NumberFormat getDefaultNumberFormat() {
return getDefaultNumberFormat(Locale.getDefault());
}
/**
* Create a default number format. The default number format is based on
* {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only
* customizing is the maximum number of fraction digits, which is set to 0.
* @param locale the specific locale used by the format.
* @return the default number format specific to the given locale.
*/
private static NumberFormat getDefaultNumberFormat(Locale locale) {
NumberFormat nf = NumberFormat.getNumberInstance(locale);
nf.setMaximumFractionDigits(0);
nf.setParseIntegerOnly(true);
return nf;
}
/**
* Formats a {@link Fraction} object to produce a string. The fraction is
* output in improper format.
*
* @param fraction the object to format.
* @param toAppendTo where the text is to be appended
* @param pos On input: an alignment field, if desired. On output: the
* offsets of the alignment field
* @return the value passed in as toAppendTo.
*/
public StringBuffer format(Fraction fraction, StringBuffer toAppendTo,
FieldPosition pos) {
pos.setBeginIndex(0);
pos.setEndIndex(0);
getNumeratorFormat().format(fraction.getNumerator(), toAppendTo, pos);
toAppendTo.append(" / ");
getDenominatorFormat().format(fraction.getDenominator(), toAppendTo,
pos);
return toAppendTo;
}
/**
* Formats a object to produce a string. <code>obj</code> must be either a
* {@link Fraction} object or a {@link Number} object. Any other type of
* object will result in an {@link IllegalArgumentException} being thrown.
*
* @param obj the object to format.
* @param toAppendTo where the text is to be appended
* @param pos On input: an alignment field, if desired. On output: the
* offsets of the alignment field
* @return the value passed in as toAppendTo.
* @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition)
* @throws IllegalArgumentException is <code>obj</code> is not a valid type.
*/
public StringBuffer format(Object obj, StringBuffer toAppendTo,
FieldPosition pos)
{
StringBuffer ret = null;
if (obj instanceof Fraction) {
ret = format( (Fraction)obj, toAppendTo, pos);
} else if (obj instanceof Number) {
try {
ret = format( new Fraction(((Number)obj).doubleValue()),
toAppendTo, pos);
} catch (ConvergenceException ex) {
throw new IllegalArgumentException(
"Cannot convert given object to a fraction.");
}
} else {
throw new IllegalArgumentException(
"Cannot format given object as a fraction");
}
return ret;
}
/**
* Access the denominator format.
* @return the denominator format.
*/
public NumberFormat getDenominatorFormat() {
return denominatorFormat;
}
/**
* Access the numerator format.
* @return the numerator format.
*/
public NumberFormat getNumeratorFormat() {
return numeratorFormat;
}
/**
* Parses a string to produce a {@link Fraction} object.
* @param source the string to parse
* @return the parsed {@link Fraction} object.
* @exception ParseException if the beginning of the specified string
* cannot be parsed.
*/
public Fraction parse(String source) throws ParseException {
ParsePosition parsePosition = new ParsePosition(0);
Fraction result = parse(source, parsePosition);
if (parsePosition.getIndex() == 0) {
throw new ParseException("Unparseable fraction number: \"" +
source + "\"", parsePosition.getErrorIndex());
}
return result;
}
/**
* Parses a string to produce a {@link Fraction} object. This method
* expects the string to be formatted as an improper fraction.
* @param source the string to parse
* @param pos input/ouput parsing parameter.
* @return the parsed {@link Fraction} object.
*/
public Fraction parse(String source, ParsePosition pos) {
int initialIndex = pos.getIndex();
// parse whitespace
parseAndIgnoreWhitespace(source, pos);
// parse numerator
Number num = getNumeratorFormat().parse(source, pos);
if (num == null) {
// invalid integer number
// set index back to initial, error index should already be set
// character examined.
pos.setIndex(initialIndex);
return null;
}
// parse '/'
int startIndex = pos.getIndex();
char c = parseNextCharacter(source, pos);
switch (c) {
case 0 :
// no '/'
// return num as a fraction
return new Fraction(num.intValue(), 1);
case '/' :
// found '/', continue parsing denominator
break;
default :
// invalid '/'
// set index back to initial, error index should be the last
// character examined.
pos.setIndex(initialIndex);
pos.setErrorIndex(startIndex);
return null;
}
// parse whitespace
parseAndIgnoreWhitespace(source, pos);
// parse denominator
Number den = getDenominatorFormat().parse(source, pos);
if (den == null) {
// invalid integer number
// set index back to initial, error index should already be set
// character examined.
pos.setIndex(initialIndex);
return null;
}
return new Fraction(num.intValue(), den.intValue());
}
/**
* Parses a string to produce a object.
* @param source the string to parse
* @param pos input/ouput parsing parameter.
* @return the parsed object.
* @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition)
*/
public Object parseObject(String source, ParsePosition pos) {
return parse(source, pos);
}
/**
* Modify the denominator format.
* @param format the new denominator format value.
* @throws IllegalArgumentException if <code>format</code> is
* <code>null</code>.
*/
public void setDenominatorFormat(NumberFormat format) {
if (format == null) {
throw new IllegalArgumentException(
"denominator format can not be null.");
}
this.denominatorFormat = format;
}
/**
* Modify the numerator format.
* @param format the new numerator format value.
* @throws IllegalArgumentException if <code>format</code> is
* <code>null</code>.
*/
public void setNumeratorFormat(NumberFormat format) {
if (format == null) {
throw new IllegalArgumentException(
"numerator format can not be null.");
}
this.numeratorFormat = format;
}
/**
* Parses <code>source</code> until a non-whitespace character is found.
* @param source the string to parse
* @param pos input/ouput parsing parameter. On output, <code>pos</code>
* holds the index of the next non-whitespace character.
*/
protected static void parseAndIgnoreWhitespace(
String source, ParsePosition pos)
{
parseNextCharacter(source, pos);
pos.setIndex(pos.getIndex() - 1);
}
/**
* Parses <code>source</code> until a non-whitespace character is found.
* @param source the string to parse
* @param pos input/ouput parsing parameter.
* @return the first non-whitespace character.
*/
protected static char parseNextCharacter(String source, ParsePosition pos) {
int index = pos.getIndex();
int n = source.length();
char ret = 0;
if (index < n) {
char c;
do {
c = source.charAt(index++);
} while (Character.isWhitespace(c) && index < n);
pos.setIndex(index);
if (index < n) {
ret = c;
}
}
return ret;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.fraction;
import java.io.Serializable;
import java.text.FieldPosition;
import java.text.Format;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.util.Locale;
import org.apache.commons.math.ConvergenceException;
/**
* Formats a Fraction number in proper format or improper format. The number
* format for each of the whole number, numerator and, denominator can be
* configured.
*
* @since 1.1
* @version $Revision$ $Date$
*/
public class FractionFormat extends Format implements Serializable {
/** Serializable version identifier */
private static final long serialVersionUID = -6337346779577272306L;
/** The format used for the denominator. */
private NumberFormat denominatorFormat;
/** The format used for the numerator. */
private NumberFormat numeratorFormat;
/**
* Create an improper formatting instance with the default number format
* for the numerator and denominator.
*/
public FractionFormat() {
this(getDefaultNumberFormat());
}
/**
* Create an improper formatting instance with a custom number format for
* both the numerator and denominator.
* @param format the custom format for both the numerator and denominator.
*/
public FractionFormat(NumberFormat format) {
this(format, (NumberFormat)format.clone());
}
/**
* Create an improper formatting instance with a custom number format for
* the numerator and a custom number format for the denominator.
* @param numeratorFormat the custom format for the numerator.
* @param denominatorFormat the custom format for the denominator.
*/
public FractionFormat(NumberFormat numeratorFormat,
NumberFormat denominatorFormat)
{
super();
this.numeratorFormat = numeratorFormat;
this.denominatorFormat = denominatorFormat;
}
/**
* This static method calls formatFraction() on a default instance of
* FractionFormat.
*
* @param f Fraction object to format
* @return A formatted fraction in proper form.
*/
public static String formatFraction(Fraction f) {
return getImproperInstance().format(f);
}
/**
* Get the set of locales for which complex formats are available. This
* is the same set as the {@link NumberFormat} set.
* @return available complex format locales.
*/
public static Locale[] getAvailableLocales() {
return NumberFormat.getAvailableLocales();
}
/**
* Returns the default complex format for the current locale.
* @return the default complex format.
*/
public static FractionFormat getImproperInstance() {
return getImproperInstance(Locale.getDefault());
}
/**
* Returns the default complex format for the given locale.
* @param locale the specific locale used by the format.
* @return the complex format specific to the given locale.
*/
public static FractionFormat getImproperInstance(Locale locale) {
NumberFormat f = getDefaultNumberFormat(locale);
return new FractionFormat(f);
}
/**
* Returns the default complex format for the current locale.
* @return the default complex format.
*/
public static FractionFormat getProperInstance() {
return getProperInstance(Locale.getDefault());
}
/**
* Returns the default complex format for the given locale.
* @param locale the specific locale used by the format.
* @return the complex format specific to the given locale.
*/
public static FractionFormat getProperInstance(Locale locale) {
NumberFormat f = getDefaultNumberFormat(locale);
return new ProperFractionFormat(f);
}
/**
* Create a default number format. The default number format is based on
* {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only
* customizing is the maximum number of fraction digits, which is set to 0.
* @return the default number format.
*/
protected static NumberFormat getDefaultNumberFormat() {
return getDefaultNumberFormat(Locale.getDefault());
}
/**
* Create a default number format. The default number format is based on
* {@link NumberFormat#getNumberInstance(java.util.Locale)} with the only
* customizing is the maximum number of fraction digits, which is set to 0.
* @param locale the specific locale used by the format.
* @return the default number format specific to the given locale.
*/
private static NumberFormat getDefaultNumberFormat(Locale locale) {
NumberFormat nf = NumberFormat.getNumberInstance(locale);
nf.setMaximumFractionDigits(0);
nf.setParseIntegerOnly(true);
return nf;
}
/**
* Formats a {@link Fraction} object to produce a string. The fraction is
* output in improper format.
*
* @param fraction the object to format.
* @param toAppendTo where the text is to be appended
* @param pos On input: an alignment field, if desired. On output: the
* offsets of the alignment field
* @return the value passed in as toAppendTo.
*/
public StringBuffer format(Fraction fraction, StringBuffer toAppendTo,
FieldPosition pos) {
pos.setBeginIndex(0);
pos.setEndIndex(0);
getNumeratorFormat().format(fraction.getNumerator(), toAppendTo, pos);
toAppendTo.append(" / ");
getDenominatorFormat().format(fraction.getDenominator(), toAppendTo,
pos);
return toAppendTo;
}
/**
* Formats a object to produce a string. <code>obj</code> must be either a
* {@link Fraction} object or a {@link Number} object. Any other type of
* object will result in an {@link IllegalArgumentException} being thrown.
*
* @param obj the object to format.
* @param toAppendTo where the text is to be appended
* @param pos On input: an alignment field, if desired. On output: the
* offsets of the alignment field
* @return the value passed in as toAppendTo.
* @see java.text.Format#format(java.lang.Object, java.lang.StringBuffer, java.text.FieldPosition)
* @throws IllegalArgumentException is <code>obj</code> is not a valid type.
*/
public StringBuffer format(Object obj, StringBuffer toAppendTo,
FieldPosition pos)
{
StringBuffer ret = null;
if (obj instanceof Fraction) {
ret = format( (Fraction)obj, toAppendTo, pos);
} else if (obj instanceof Number) {
try {
ret = format( new Fraction(((Number)obj).doubleValue()),
toAppendTo, pos);
} catch (ConvergenceException ex) {
throw new IllegalArgumentException(
"Cannot convert given object to a fraction.");
}
} else {
throw new IllegalArgumentException(
"Cannot format given object as a fraction");
}
return ret;
}
/**
* Access the denominator format.
* @return the denominator format.
*/
public NumberFormat getDenominatorFormat() {
return denominatorFormat;
}
/**
* Access the numerator format.
* @return the numerator format.
*/
public NumberFormat getNumeratorFormat() {
return numeratorFormat;
}
/**
* Parses a string to produce a {@link Fraction} object.
* @param source the string to parse
* @return the parsed {@link Fraction} object.
* @exception ParseException if the beginning of the specified string
* cannot be parsed.
*/
public Fraction parse(String source) throws ParseException {
ParsePosition parsePosition = new ParsePosition(0);
Fraction result = parse(source, parsePosition);
if (parsePosition.getIndex() == 0) {
throw new ParseException("Unparseable fraction number: \"" +
source + "\"", parsePosition.getErrorIndex());
}
return result;
}
/**
* Parses a string to produce a {@link Fraction} object. This method
* expects the string to be formatted as an improper fraction.
* @param source the string to parse
* @param pos input/ouput parsing parameter.
* @return the parsed {@link Fraction} object.
*/
public Fraction parse(String source, ParsePosition pos) {
int initialIndex = pos.getIndex();
// parse whitespace
parseAndIgnoreWhitespace(source, pos);
// parse numerator
Number num = getNumeratorFormat().parse(source, pos);
if (num == null) {
// invalid integer number
// set index back to initial, error index should already be set
// character examined.
pos.setIndex(initialIndex);
return null;
}
// parse '/'
int startIndex = pos.getIndex();
char c = parseNextCharacter(source, pos);
switch (c) {
case 0 :
// no '/'
// return num as a fraction
return new Fraction(num.intValue(), 1);
case '/' :
// found '/', continue parsing denominator
break;
default :
// invalid '/'
// set index back to initial, error index should be the last
// character examined.
pos.setIndex(initialIndex);
pos.setErrorIndex(startIndex);
return null;
}
// parse whitespace
parseAndIgnoreWhitespace(source, pos);
// parse denominator
Number den = getDenominatorFormat().parse(source, pos);
if (den == null) {
// invalid integer number
// set index back to initial, error index should already be set
// character examined.
pos.setIndex(initialIndex);
return null;
}
return new Fraction(num.intValue(), den.intValue());
}
/**
* Parses a string to produce a object.
* @param source the string to parse
* @param pos input/ouput parsing parameter.
* @return the parsed object.
* @see java.text.Format#parseObject(java.lang.String, java.text.ParsePosition)
*/
public Object parseObject(String source, ParsePosition pos) {
return parse(source, pos);
}
/**
* Modify the denominator format.
* @param format the new denominator format value.
* @throws IllegalArgumentException if <code>format</code> is
* <code>null</code>.
*/
public void setDenominatorFormat(NumberFormat format) {
if (format == null) {
throw new IllegalArgumentException(
"denominator format can not be null.");
}
this.denominatorFormat = format;
}
/**
* Modify the numerator format.
* @param format the new numerator format value.
* @throws IllegalArgumentException if <code>format</code> is
* <code>null</code>.
*/
public void setNumeratorFormat(NumberFormat format) {
if (format == null) {
throw new IllegalArgumentException(
"numerator format can not be null.");
}
this.numeratorFormat = format;
}
/**
* Parses <code>source</code> until a non-whitespace character is found.
* @param source the string to parse
* @param pos input/ouput parsing parameter. On output, <code>pos</code>
* holds the index of the next non-whitespace character.
*/
protected static void parseAndIgnoreWhitespace(
String source, ParsePosition pos)
{
parseNextCharacter(source, pos);
pos.setIndex(pos.getIndex() - 1);
}
/**
* Parses <code>source</code> until a non-whitespace character is found.
* @param source the string to parse
* @param pos input/ouput parsing parameter.
* @return the first non-whitespace character.
*/
protected static char parseNextCharacter(String source, ParsePosition pos) {
int index = pos.getIndex();
int n = source.length();
char ret = 0;
if (index < n) {
char c;
do {
c = source.charAt(index++);
} while (Character.isWhitespace(c) && index < n);
pos.setIndex(index);
if (index < n) {
ret = c;
}
}
return ret;
}
}

View File

@ -1,230 +1,230 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.fraction;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
import org.apache.commons.math.util.MathUtils;
/**
* Formats a Fraction number in proper format. The number format for each of
* the whole number, numerator and, denominator can be configured.
* <p>
* Minus signs are only allowed in the whole number part - i.e.,
* "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and
* will result in a <code>ParseException</code>.
*
* @since 1.1
* @version $Revision$ $Date$
*/
public class ProperFractionFormat extends FractionFormat {
/** Serializable version identifier */
private static final long serialVersionUID = -6337346779577272307L;
/** The format used for the whole number. */
private NumberFormat wholeFormat;
/**
* Create a proper formatting instance with the default number format for
* the whole, numerator, and denominator.
*/
public ProperFractionFormat() {
this(getDefaultNumberFormat());
}
/**
* Create a proper formatting instance with a custom number format for the
* whole, numerator, and denominator.
* @param format the custom format for the whole, numerator, and
* denominator.
*/
public ProperFractionFormat(NumberFormat format) {
this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone());
}
/**
* Create a proper formatting instance with a custom number format for each
* of the whole, numerator, and denominator.
* @param wholeFormat the custom format for the whole.
* @param numeratorFormat the custom format for the numerator.
* @param denominatorFormat the custom format for the denominator.
*/
public ProperFractionFormat(NumberFormat wholeFormat,
NumberFormat numeratorFormat,
NumberFormat denominatorFormat)
{
super(numeratorFormat, denominatorFormat);
setWholeFormat(wholeFormat);
}
/**
* Formats a {@link Fraction} object to produce a string. The fraction
* is output in proper format.
*
* @param fraction the object to format.
* @param toAppendTo where the text is to be appended
* @param pos On input: an alignment field, if desired. On output: the
* offsets of the alignment field
* @return the value passed in as toAppendTo.
*/
public StringBuffer format(Fraction fraction, StringBuffer toAppendTo,
FieldPosition pos) {
pos.setBeginIndex(0);
pos.setEndIndex(0);
int num = fraction.getNumerator();
int den = fraction.getDenominator();
int whole = num / den;
num = num % den;
if (whole != 0) {
getWholeFormat().format(whole, toAppendTo, pos);
toAppendTo.append(' ');
num = Math.abs(num);
}
getNumeratorFormat().format(num, toAppendTo, pos);
toAppendTo.append(" / ");
getDenominatorFormat().format(den, toAppendTo,
pos);
return toAppendTo;
}
/**
* Access the whole format.
* @return the whole format.
*/
public NumberFormat getWholeFormat() {
return wholeFormat;
}
/**
* Parses a string to produce a {@link Fraction} object. This method
* expects the string to be formatted as a proper fraction.
* <p>
* Minus signs are only allowed in the whole number part - i.e.,
* "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and
* will result in a <code>ParseException</code>.
*
* @param source the string to parse
* @param pos input/ouput parsing parameter.
* @return the parsed {@link Fraction} object.
*/
public Fraction parse(String source, ParsePosition pos) {
// try to parse improper fraction
Fraction ret = super.parse(source, pos);
if (ret != null) {
return ret;
}
int initialIndex = pos.getIndex();
// parse whitespace
parseAndIgnoreWhitespace(source, pos);
// parse whole
Number whole = getWholeFormat().parse(source, pos);
if (whole == null) {
// invalid integer number
// set index back to initial, error index should already be set
// character examined.
pos.setIndex(initialIndex);
return null;
}
// parse whitespace
parseAndIgnoreWhitespace(source, pos);
// parse numerator
Number num = getNumeratorFormat().parse(source, pos);
if (num == null) {
// invalid integer number
// set index back to initial, error index should already be set
// character examined.
pos.setIndex(initialIndex);
return null;
}
if (num.intValue() < 0) {
// minus signs should be leading, invalid expression
pos.setIndex(initialIndex);
return null;
}
// parse '/'
int startIndex = pos.getIndex();
char c = parseNextCharacter(source, pos);
switch (c) {
case 0 :
// no '/'
// return num as a fraction
return new Fraction(num.intValue(), 1);
case '/' :
// found '/', continue parsing denominator
break;
default :
// invalid '/'
// set index back to initial, error index should be the last
// character examined.
pos.setIndex(initialIndex);
pos.setErrorIndex(startIndex);
return null;
}
// parse whitespace
parseAndIgnoreWhitespace(source, pos);
// parse denominator
Number den = getDenominatorFormat().parse(source, pos);
if (den == null) {
// invalid integer number
// set index back to initial, error index should already be set
// character examined.
pos.setIndex(initialIndex);
return null;
}
if (den.intValue() < 0) {
// minus signs must be leading, invalid
pos.setIndex(initialIndex);
return null;
}
int w = whole.intValue();
int n = num.intValue();
int d = den.intValue();
return new Fraction(((Math.abs(w) * d) + n) * MathUtils.sign(w), d);
}
/**
* Modify the whole format.
* @param format The new whole format value.
* @throws IllegalArgumentException if <code>format</code> is
* <code>null</code>.
*/
public void setWholeFormat(NumberFormat format) {
if (format == null) {
throw new IllegalArgumentException(
"whole format can not be null.");
}
this.wholeFormat = format;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.fraction;
import java.text.FieldPosition;
import java.text.NumberFormat;
import java.text.ParsePosition;
import org.apache.commons.math.util.MathUtils;
/**
* Formats a Fraction number in proper format. The number format for each of
* the whole number, numerator and, denominator can be configured.
* <p>
* Minus signs are only allowed in the whole number part - i.e.,
* "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and
* will result in a <code>ParseException</code>.
*
* @since 1.1
* @version $Revision$ $Date$
*/
public class ProperFractionFormat extends FractionFormat {
/** Serializable version identifier */
private static final long serialVersionUID = -6337346779577272307L;
/** The format used for the whole number. */
private NumberFormat wholeFormat;
/**
* Create a proper formatting instance with the default number format for
* the whole, numerator, and denominator.
*/
public ProperFractionFormat() {
this(getDefaultNumberFormat());
}
/**
* Create a proper formatting instance with a custom number format for the
* whole, numerator, and denominator.
* @param format the custom format for the whole, numerator, and
* denominator.
*/
public ProperFractionFormat(NumberFormat format) {
this(format, (NumberFormat)format.clone(), (NumberFormat)format.clone());
}
/**
* Create a proper formatting instance with a custom number format for each
* of the whole, numerator, and denominator.
* @param wholeFormat the custom format for the whole.
* @param numeratorFormat the custom format for the numerator.
* @param denominatorFormat the custom format for the denominator.
*/
public ProperFractionFormat(NumberFormat wholeFormat,
NumberFormat numeratorFormat,
NumberFormat denominatorFormat)
{
super(numeratorFormat, denominatorFormat);
setWholeFormat(wholeFormat);
}
/**
* Formats a {@link Fraction} object to produce a string. The fraction
* is output in proper format.
*
* @param fraction the object to format.
* @param toAppendTo where the text is to be appended
* @param pos On input: an alignment field, if desired. On output: the
* offsets of the alignment field
* @return the value passed in as toAppendTo.
*/
public StringBuffer format(Fraction fraction, StringBuffer toAppendTo,
FieldPosition pos) {
pos.setBeginIndex(0);
pos.setEndIndex(0);
int num = fraction.getNumerator();
int den = fraction.getDenominator();
int whole = num / den;
num = num % den;
if (whole != 0) {
getWholeFormat().format(whole, toAppendTo, pos);
toAppendTo.append(' ');
num = Math.abs(num);
}
getNumeratorFormat().format(num, toAppendTo, pos);
toAppendTo.append(" / ");
getDenominatorFormat().format(den, toAppendTo,
pos);
return toAppendTo;
}
/**
* Access the whole format.
* @return the whole format.
*/
public NumberFormat getWholeFormat() {
return wholeFormat;
}
/**
* Parses a string to produce a {@link Fraction} object. This method
* expects the string to be formatted as a proper fraction.
* <p>
* Minus signs are only allowed in the whole number part - i.e.,
* "-3 1/2" is legitimate and denotes -7/2, but "-3 -1/2" is invalid and
* will result in a <code>ParseException</code>.
*
* @param source the string to parse
* @param pos input/ouput parsing parameter.
* @return the parsed {@link Fraction} object.
*/
public Fraction parse(String source, ParsePosition pos) {
// try to parse improper fraction
Fraction ret = super.parse(source, pos);
if (ret != null) {
return ret;
}
int initialIndex = pos.getIndex();
// parse whitespace
parseAndIgnoreWhitespace(source, pos);
// parse whole
Number whole = getWholeFormat().parse(source, pos);
if (whole == null) {
// invalid integer number
// set index back to initial, error index should already be set
// character examined.
pos.setIndex(initialIndex);
return null;
}
// parse whitespace
parseAndIgnoreWhitespace(source, pos);
// parse numerator
Number num = getNumeratorFormat().parse(source, pos);
if (num == null) {
// invalid integer number
// set index back to initial, error index should already be set
// character examined.
pos.setIndex(initialIndex);
return null;
}
if (num.intValue() < 0) {
// minus signs should be leading, invalid expression
pos.setIndex(initialIndex);
return null;
}
// parse '/'
int startIndex = pos.getIndex();
char c = parseNextCharacter(source, pos);
switch (c) {
case 0 :
// no '/'
// return num as a fraction
return new Fraction(num.intValue(), 1);
case '/' :
// found '/', continue parsing denominator
break;
default :
// invalid '/'
// set index back to initial, error index should be the last
// character examined.
pos.setIndex(initialIndex);
pos.setErrorIndex(startIndex);
return null;
}
// parse whitespace
parseAndIgnoreWhitespace(source, pos);
// parse denominator
Number den = getDenominatorFormat().parse(source, pos);
if (den == null) {
// invalid integer number
// set index back to initial, error index should already be set
// character examined.
pos.setIndex(initialIndex);
return null;
}
if (den.intValue() < 0) {
// minus signs must be leading, invalid
pos.setIndex(initialIndex);
return null;
}
int w = whole.intValue();
int n = num.intValue();
int d = den.intValue();
return new Fraction(((Math.abs(w) * d) + n) * MathUtils.sign(w), d);
}
/**
* Modify the whole format.
* @param format The new whole format value.
* @throws IllegalArgumentException if <code>format</code> is
* <code>null</code>.
*/
public void setWholeFormat(NumberFormat format) {
if (format == null) {
throw new IllegalArgumentException(
"whole format can not be null.");
}
this.wholeFormat = format;
}
}

View File

@ -1,22 +1,22 @@
<html>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- $Revision$ $Date$ -->
<body>
Fraction number type and fraction number formatting.
</body>
</html>
<html>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- $Revision$ $Date$ -->
<body>
Fraction number type and fraction number formatting.
</body>
</html>

View File

@ -1,138 +1,138 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Divided Difference interpolator.
* <p>
* The error of polynomial interpolation is
* f(z) - p(z) = f^(n)(zeta) * (z-x[0])(z-x[1])...(z-x[n-1]) / n!
* where f^(n) is the n-th derivative of the approximated function and
* zeta is some point in the interval determined by x[] and z.
* <p>
* Since zeta is unknown, f^(n)(zeta) cannot be calculated. But we can bound
* it and use the absolute value upper bound for estimates. For reference,
* see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, chapter 2.
*
* @version $Revision$ $Date$
*/
public final class DividedDifferenceInterpolatorTest extends TestCase {
/**
* Test of interpolator for the sine function.
* <p>
* |sin^(n)(zeta)| <= 1.0, zeta in [0, 2*PI]
*/
public void testSinFunction() throws MathException {
UnivariateRealFunction f = new SinFunction();
UnivariateRealInterpolator interpolator = new DividedDifferenceInterpolator();
double x[], y[], z, expected, result, tolerance;
// 6 interpolating points on interval [0, 2*PI]
int n = 6;
double min = 0.0, max = 2 * Math.PI;
x = new double[n];
y = new double[n];
for (int i = 0; i < n; i++) {
x[i] = min + i * (max - min) / n;
y[i] = f.value(x[i]);
}
double derivativebound = 1.0;
UnivariateRealFunction p = interpolator.interpolate(x, y);
z = Math.PI / 4; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = Math.PI * 1.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
}
/**
* Test of interpolator for the exponential function.
* <p>
* |expm1^(n)(zeta)| <= e, zeta in [-1, 1]
*/
public void testExpm1Function() throws MathException {
UnivariateRealFunction f = new Expm1Function();
UnivariateRealInterpolator interpolator = new DividedDifferenceInterpolator();
double x[], y[], z, expected, result, tolerance;
// 5 interpolating points on interval [-1, 1]
int n = 5;
double min = -1.0, max = 1.0;
x = new double[n];
y = new double[n];
for (int i = 0; i < n; i++) {
x[i] = min + i * (max - min) / n;
y[i] = f.value(x[i]);
}
double derivativebound = Math.E;
UnivariateRealFunction p = interpolator.interpolate(x, y);
z = 0.0; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = 0.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = -0.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
}
/**
* Test of parameters for the interpolator.
*/
public void testParameters() throws Exception {
UnivariateRealInterpolator interpolator = new DividedDifferenceInterpolator();
try {
// bad abscissas array
double x[] = { 1.0, 2.0, 2.0, 4.0 };
double y[] = { 0.0, 4.0, 4.0, 2.5 };
UnivariateRealFunction p = interpolator.interpolate(x, y);
p.value(0.0);
fail("Expecting MathException - bad abscissas array");
} catch (MathException ex) {
// expected
}
}
/**
* Returns the partial error term (z-x[0])(z-x[1])...(z-x[n-1])/n!
*/
protected double partialerror(double x[], double z) throws
IllegalArgumentException {
if (x.length < 1) {
throw new IllegalArgumentException
("Interpolation array cannot be empty.");
}
double out = 1;
for (int i = 0; i < x.length; i++) {
out *= (z - x[i]) / (i + 1);
}
return out;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Divided Difference interpolator.
* <p>
* The error of polynomial interpolation is
* f(z) - p(z) = f^(n)(zeta) * (z-x[0])(z-x[1])...(z-x[n-1]) / n!
* where f^(n) is the n-th derivative of the approximated function and
* zeta is some point in the interval determined by x[] and z.
* <p>
* Since zeta is unknown, f^(n)(zeta) cannot be calculated. But we can bound
* it and use the absolute value upper bound for estimates. For reference,
* see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, chapter 2.
*
* @version $Revision$ $Date$
*/
public final class DividedDifferenceInterpolatorTest extends TestCase {
/**
* Test of interpolator for the sine function.
* <p>
* |sin^(n)(zeta)| <= 1.0, zeta in [0, 2*PI]
*/
public void testSinFunction() throws MathException {
UnivariateRealFunction f = new SinFunction();
UnivariateRealInterpolator interpolator = new DividedDifferenceInterpolator();
double x[], y[], z, expected, result, tolerance;
// 6 interpolating points on interval [0, 2*PI]
int n = 6;
double min = 0.0, max = 2 * Math.PI;
x = new double[n];
y = new double[n];
for (int i = 0; i < n; i++) {
x[i] = min + i * (max - min) / n;
y[i] = f.value(x[i]);
}
double derivativebound = 1.0;
UnivariateRealFunction p = interpolator.interpolate(x, y);
z = Math.PI / 4; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = Math.PI * 1.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
}
/**
* Test of interpolator for the exponential function.
* <p>
* |expm1^(n)(zeta)| <= e, zeta in [-1, 1]
*/
public void testExpm1Function() throws MathException {
UnivariateRealFunction f = new Expm1Function();
UnivariateRealInterpolator interpolator = new DividedDifferenceInterpolator();
double x[], y[], z, expected, result, tolerance;
// 5 interpolating points on interval [-1, 1]
int n = 5;
double min = -1.0, max = 1.0;
x = new double[n];
y = new double[n];
for (int i = 0; i < n; i++) {
x[i] = min + i * (max - min) / n;
y[i] = f.value(x[i]);
}
double derivativebound = Math.E;
UnivariateRealFunction p = interpolator.interpolate(x, y);
z = 0.0; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = 0.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = -0.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
}
/**
* Test of parameters for the interpolator.
*/
public void testParameters() throws Exception {
UnivariateRealInterpolator interpolator = new DividedDifferenceInterpolator();
try {
// bad abscissas array
double x[] = { 1.0, 2.0, 2.0, 4.0 };
double y[] = { 0.0, 4.0, 4.0, 2.5 };
UnivariateRealFunction p = interpolator.interpolate(x, y);
p.value(0.0);
fail("Expecting MathException - bad abscissas array");
} catch (MathException ex) {
// expected
}
}
/**
* Returns the partial error term (z-x[0])(z-x[1])...(z-x[n-1])/n!
*/
protected double partialerror(double x[], double z) throws
IllegalArgumentException {
if (x.length < 1) {
throw new IllegalArgumentException
("Interpolation array cannot be empty.");
}
double out = 1;
for (int i = 0; i < x.length; i++) {
out *= (z - x[i]) / (i + 1);
}
return out;
}
}

View File

@ -1,40 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
/**
* Auxillary class for testing purposes.
*
* @version $Revision$ $Date$
*/
public class Expm1Function implements DifferentiableUnivariateRealFunction {
public double value(double x) throws FunctionEvaluationException {
// Math.expm1() is available in jdk 1.5 but not in jdk 1.4.2.
return Math.exp(x) - 1.0;
}
public UnivariateRealFunction derivative() {
return new UnivariateRealFunction() {
public double value(double x) throws FunctionEvaluationException {
return Math.exp(x);
}
};
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
/**
* Auxillary class for testing purposes.
*
* @version $Revision$ $Date$
*/
public class Expm1Function implements DifferentiableUnivariateRealFunction {
public double value(double x) throws FunctionEvaluationException {
// Math.expm1() is available in jdk 1.5 but not in jdk 1.4.2.
return Math.exp(x) - 1.0;
}
public UnivariateRealFunction derivative() {
return new UnivariateRealFunction() {
public double value(double x) throws FunctionEvaluationException {
return Math.exp(x);
}
};
}
}

View File

@ -1,178 +1,178 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import org.apache.commons.math.TestUtils;
import org.apache.commons.math.complex.Complex;
import junit.framework.TestCase;
/**
* Testcase for Laguerre solver.
* <p>
* Laguerre's method is very efficient in solving polynomials. Test runs
* show that for a default absolute accuracy of 1E-6, it generally takes
* less than 5 iterations to find one root, provided solveAll() is not
* invoked, and 15 to 20 iterations to find all roots for quintic function.
*
* @version $Revision$ $Date$
*/
public final class LaguerreSolverTest extends TestCase {
/**
* Test of solver for the linear function.
*/
public void testLinearFunction() throws MathException {
double min, max, expected, result, tolerance;
// p(x) = 4x - 1
double coefficients[] = { -1.0, 4.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f);
min = 0.0; max = 1.0; expected = 0.25;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quadratic function.
*/
public void testQuadraticFunction() throws MathException {
double min, max, expected, result, tolerance;
// p(x) = 2x^2 + 5x - 3 = (x+3)(2x-1)
double coefficients[] = { -3.0, 5.0, 2.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f);
min = 0.0; max = 2.0; expected = 0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -4.0; max = -1.0; expected = -3.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quintic function.
*/
public void testQuinticFunction() throws MathException {
double min, max, expected, result, tolerance;
// p(x) = x^5 - x^4 - 12x^3 + x^2 - x - 12 = (x+1)(x+3)(x-4)(x^2-x+1)
double coefficients[] = { -12.0, -1.0, 1.0, -12.0, -1.0, 1.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f);
min = -2.0; max = 2.0; expected = -1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -5.0; max = -2.5; expected = -3.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = 3.0; max = 6.0; expected = 4.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quintic function using solveAll().
*/
public void testQuinticFunction2() throws MathException {
double initial = 0.0, tolerance;
Complex expected, result[];
// p(x) = x^5 + 4x^3 + x^2 + 4 = (x+1)(x^2-x+1)(x^2+4)
double coefficients[] = { 4.0, 0.0, 1.0, 4.0, 0.0, 1.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
LaguerreSolver solver = new LaguerreSolver(f);
result = solver.solveAll(coefficients, initial);
expected = new Complex(0.0, -2.0);
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected.abs() * solver.getRelativeAccuracy()));
TestUtils.assertContains(result, expected, tolerance);
expected = new Complex(0.0, 2.0);
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected.abs() * solver.getRelativeAccuracy()));
TestUtils.assertContains(result, expected, tolerance);
expected = new Complex(0.5, 0.5 * Math.sqrt(3.0));
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected.abs() * solver.getRelativeAccuracy()));
TestUtils.assertContains(result, expected, tolerance);
expected = new Complex(-1.0, 0.0);
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected.abs() * solver.getRelativeAccuracy()));
TestUtils.assertContains(result, expected, tolerance);
expected = new Complex(0.5, -0.5 * Math.sqrt(3.0));
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected.abs() * solver.getRelativeAccuracy()));
TestUtils.assertContains(result, expected, tolerance);
}
/**
* Test of parameters for the solver.
*/
public void testParameters() throws Exception {
double coefficients[] = { -3.0, 5.0, 2.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f);
try {
// bad interval
solver.solve(1, -1);
fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// no bracketing
solver.solve(2, 3);
fail("Expecting IllegalArgumentException - no bracketing");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// bad function
UnivariateRealFunction f2 = new SinFunction();
UnivariateRealSolver solver2 = new LaguerreSolver(f2);
fail("Expecting IllegalArgumentException - bad function");
} catch (IllegalArgumentException ex) {
// expected
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import org.apache.commons.math.TestUtils;
import org.apache.commons.math.complex.Complex;
import junit.framework.TestCase;
/**
* Testcase for Laguerre solver.
* <p>
* Laguerre's method is very efficient in solving polynomials. Test runs
* show that for a default absolute accuracy of 1E-6, it generally takes
* less than 5 iterations to find one root, provided solveAll() is not
* invoked, and 15 to 20 iterations to find all roots for quintic function.
*
* @version $Revision$ $Date$
*/
public final class LaguerreSolverTest extends TestCase {
/**
* Test of solver for the linear function.
*/
public void testLinearFunction() throws MathException {
double min, max, expected, result, tolerance;
// p(x) = 4x - 1
double coefficients[] = { -1.0, 4.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f);
min = 0.0; max = 1.0; expected = 0.25;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quadratic function.
*/
public void testQuadraticFunction() throws MathException {
double min, max, expected, result, tolerance;
// p(x) = 2x^2 + 5x - 3 = (x+3)(2x-1)
double coefficients[] = { -3.0, 5.0, 2.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f);
min = 0.0; max = 2.0; expected = 0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -4.0; max = -1.0; expected = -3.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quintic function.
*/
public void testQuinticFunction() throws MathException {
double min, max, expected, result, tolerance;
// p(x) = x^5 - x^4 - 12x^3 + x^2 - x - 12 = (x+1)(x+3)(x-4)(x^2-x+1)
double coefficients[] = { -12.0, -1.0, 1.0, -12.0, -1.0, 1.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f);
min = -2.0; max = 2.0; expected = -1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -5.0; max = -2.5; expected = -3.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = 3.0; max = 6.0; expected = 4.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quintic function using solveAll().
*/
public void testQuinticFunction2() throws MathException {
double initial = 0.0, tolerance;
Complex expected, result[];
// p(x) = x^5 + 4x^3 + x^2 + 4 = (x+1)(x^2-x+1)(x^2+4)
double coefficients[] = { 4.0, 0.0, 1.0, 4.0, 0.0, 1.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
LaguerreSolver solver = new LaguerreSolver(f);
result = solver.solveAll(coefficients, initial);
expected = new Complex(0.0, -2.0);
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected.abs() * solver.getRelativeAccuracy()));
TestUtils.assertContains(result, expected, tolerance);
expected = new Complex(0.0, 2.0);
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected.abs() * solver.getRelativeAccuracy()));
TestUtils.assertContains(result, expected, tolerance);
expected = new Complex(0.5, 0.5 * Math.sqrt(3.0));
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected.abs() * solver.getRelativeAccuracy()));
TestUtils.assertContains(result, expected, tolerance);
expected = new Complex(-1.0, 0.0);
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected.abs() * solver.getRelativeAccuracy()));
TestUtils.assertContains(result, expected, tolerance);
expected = new Complex(0.5, -0.5 * Math.sqrt(3.0));
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected.abs() * solver.getRelativeAccuracy()));
TestUtils.assertContains(result, expected, tolerance);
}
/**
* Test of parameters for the solver.
*/
public void testParameters() throws Exception {
double coefficients[] = { -3.0, 5.0, 2.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f);
try {
// bad interval
solver.solve(1, -1);
fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// no bracketing
solver.solve(2, 3);
fail("Expecting IllegalArgumentException - no bracketing");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// bad function
UnivariateRealFunction f2 = new SinFunction();
UnivariateRealSolver solver2 = new LaguerreSolver(f2);
fail("Expecting IllegalArgumentException - bad function");
} catch (IllegalArgumentException ex) {
// expected
}
}
}

View File

@ -1,215 +1,215 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Muller solver.
* <p>
* Muller's method converges almost quadratically near roots, but it can
* be very slow in regions far away from zeros. Test runs show that for
* reasonably good initial values, for a default absolute accuracy of 1E-6,
* it generally takes 5 to 10 iterations for the solver to converge.
* <p>
* Tests for the exponential function illustrate the situations where
* Muller solver performs poorly.
*
* @version $Revision$ $Date$
*/
public final class MullerSolverTest extends TestCase {
/**
* Test of solver for the sine function.
*/
public void testSinFunction() throws MathException {
UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = 3.0; max = 4.0; expected = Math.PI;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -1.0; max = 1.5; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the sine function using solve2().
*/
public void testSinFunction2() throws MathException {
UnivariateRealFunction f = new SinFunction();
MullerSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = 3.0; max = 4.0; expected = Math.PI;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = -1.0; max = 1.5; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quintic function.
*/
public void testQuinticFunction() throws MathException {
UnivariateRealFunction f = new QuinticFunction();
UnivariateRealSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = -0.4; max = 0.2; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = 0.75; max = 1.5; expected = 1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -0.9; max = -0.2; expected = -0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quintic function using solve2().
*/
public void testQuinticFunction2() throws MathException {
UnivariateRealFunction f = new QuinticFunction();
MullerSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = -0.4; max = 0.2; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = 0.75; max = 1.5; expected = 1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = -0.9; max = -0.2; expected = -0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the exponential function.
* <p>
* It takes 10 to 15 iterations for the last two tests to converge.
* In fact, if not for the bisection alternative, the solver would
* exceed the default maximal iteration of 100.
*/
public void testExpm1Function() throws MathException {
UnivariateRealFunction f = new Expm1Function();
UnivariateRealSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = -1.0; max = 2.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -20.0; max = 10.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -50.0; max = 100.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the exponential function using solve2().
* <p>
* It takes 25 to 50 iterations for the last two tests to converge.
*/
public void testExpm1Function2() throws MathException {
UnivariateRealFunction f = new Expm1Function();
MullerSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = -1.0; max = 2.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = -20.0; max = 10.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = -50.0; max = 100.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of parameters for the solver.
*/
public void testParameters() throws Exception {
UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new MullerSolver(f);
try {
// bad interval
solver.solve(1, -1);
fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// no bracketing
solver.solve(2, 3);
fail("Expecting IllegalArgumentException - no bracketing");
} catch (IllegalArgumentException ex) {
// expected
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Muller solver.
* <p>
* Muller's method converges almost quadratically near roots, but it can
* be very slow in regions far away from zeros. Test runs show that for
* reasonably good initial values, for a default absolute accuracy of 1E-6,
* it generally takes 5 to 10 iterations for the solver to converge.
* <p>
* Tests for the exponential function illustrate the situations where
* Muller solver performs poorly.
*
* @version $Revision$ $Date$
*/
public final class MullerSolverTest extends TestCase {
/**
* Test of solver for the sine function.
*/
public void testSinFunction() throws MathException {
UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = 3.0; max = 4.0; expected = Math.PI;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -1.0; max = 1.5; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the sine function using solve2().
*/
public void testSinFunction2() throws MathException {
UnivariateRealFunction f = new SinFunction();
MullerSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = 3.0; max = 4.0; expected = Math.PI;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = -1.0; max = 1.5; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quintic function.
*/
public void testQuinticFunction() throws MathException {
UnivariateRealFunction f = new QuinticFunction();
UnivariateRealSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = -0.4; max = 0.2; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = 0.75; max = 1.5; expected = 1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -0.9; max = -0.2; expected = -0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quintic function using solve2().
*/
public void testQuinticFunction2() throws MathException {
UnivariateRealFunction f = new QuinticFunction();
MullerSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = -0.4; max = 0.2; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = 0.75; max = 1.5; expected = 1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = -0.9; max = -0.2; expected = -0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the exponential function.
* <p>
* It takes 10 to 15 iterations for the last two tests to converge.
* In fact, if not for the bisection alternative, the solver would
* exceed the default maximal iteration of 100.
*/
public void testExpm1Function() throws MathException {
UnivariateRealFunction f = new Expm1Function();
UnivariateRealSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = -1.0; max = 2.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -20.0; max = 10.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -50.0; max = 100.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the exponential function using solve2().
* <p>
* It takes 25 to 50 iterations for the last two tests to converge.
*/
public void testExpm1Function2() throws MathException {
UnivariateRealFunction f = new Expm1Function();
MullerSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = -1.0; max = 2.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = -20.0; max = 10.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = -50.0; max = 100.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of parameters for the solver.
*/
public void testParameters() throws Exception {
UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new MullerSolver(f);
try {
// bad interval
solver.solve(1, -1);
fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// no bracketing
solver.solve(2, 3);
fail("Expecting IllegalArgumentException - no bracketing");
} catch (IllegalArgumentException ex) {
// expected
}
}
}

View File

@ -1,138 +1,138 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Neville interpolator.
* <p>
* The error of polynomial interpolation is
* f(z) - p(z) = f^(n)(zeta) * (z-x[0])(z-x[1])...(z-x[n-1]) / n!
* where f^(n) is the n-th derivative of the approximated function and
* zeta is some point in the interval determined by x[] and z.
* <p>
* Since zeta is unknown, f^(n)(zeta) cannot be calculated. But we can bound
* it and use the absolute value upper bound for estimates. For reference,
* see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, chapter 2.
*
* @version $Revision$ $Date$
*/
public final class NevilleInterpolatorTest extends TestCase {
/**
* Test of interpolator for the sine function.
* <p>
* |sin^(n)(zeta)| <= 1.0, zeta in [0, 2*PI]
*/
public void testSinFunction() throws MathException {
UnivariateRealFunction f = new SinFunction();
UnivariateRealInterpolator interpolator = new NevilleInterpolator();
double x[], y[], z, expected, result, tolerance;
// 6 interpolating points on interval [0, 2*PI]
int n = 6;
double min = 0.0, max = 2 * Math.PI;
x = new double[n];
y = new double[n];
for (int i = 0; i < n; i++) {
x[i] = min + i * (max - min) / n;
y[i] = f.value(x[i]);
}
double derivativebound = 1.0;
UnivariateRealFunction p = interpolator.interpolate(x, y);
z = Math.PI / 4; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = Math.PI * 1.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
}
/**
* Test of interpolator for the exponential function.
* <p>
* |expm1^(n)(zeta)| <= e, zeta in [-1, 1]
*/
public void testExpm1Function() throws MathException {
UnivariateRealFunction f = new Expm1Function();
UnivariateRealInterpolator interpolator = new NevilleInterpolator();
double x[], y[], z, expected, result, tolerance;
// 5 interpolating points on interval [-1, 1]
int n = 5;
double min = -1.0, max = 1.0;
x = new double[n];
y = new double[n];
for (int i = 0; i < n; i++) {
x[i] = min + i * (max - min) / n;
y[i] = f.value(x[i]);
}
double derivativebound = Math.E;
UnivariateRealFunction p = interpolator.interpolate(x, y);
z = 0.0; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = 0.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = -0.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
}
/**
* Test of parameters for the interpolator.
*/
public void testParameters() throws Exception {
UnivariateRealInterpolator interpolator = new NevilleInterpolator();
try {
// bad abscissas array
double x[] = { 1.0, 2.0, 2.0, 4.0 };
double y[] = { 0.0, 4.0, 4.0, 2.5 };
UnivariateRealFunction p = interpolator.interpolate(x, y);
p.value(0.0);
fail("Expecting MathException - bad abscissas array");
} catch (MathException ex) {
// expected
}
}
/**
* Returns the partial error term (z-x[0])(z-x[1])...(z-x[n-1])/n!
*/
protected double partialerror(double x[], double z) throws
IllegalArgumentException {
if (x.length < 1) {
throw new IllegalArgumentException
("Interpolation array cannot be empty.");
}
double out = 1;
for (int i = 0; i < x.length; i++) {
out *= (z - x[i]) / (i + 1);
}
return out;
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Neville interpolator.
* <p>
* The error of polynomial interpolation is
* f(z) - p(z) = f^(n)(zeta) * (z-x[0])(z-x[1])...(z-x[n-1]) / n!
* where f^(n) is the n-th derivative of the approximated function and
* zeta is some point in the interval determined by x[] and z.
* <p>
* Since zeta is unknown, f^(n)(zeta) cannot be calculated. But we can bound
* it and use the absolute value upper bound for estimates. For reference,
* see <b>Introduction to Numerical Analysis</b>, ISBN 038795452X, chapter 2.
*
* @version $Revision$ $Date$
*/
public final class NevilleInterpolatorTest extends TestCase {
/**
* Test of interpolator for the sine function.
* <p>
* |sin^(n)(zeta)| <= 1.0, zeta in [0, 2*PI]
*/
public void testSinFunction() throws MathException {
UnivariateRealFunction f = new SinFunction();
UnivariateRealInterpolator interpolator = new NevilleInterpolator();
double x[], y[], z, expected, result, tolerance;
// 6 interpolating points on interval [0, 2*PI]
int n = 6;
double min = 0.0, max = 2 * Math.PI;
x = new double[n];
y = new double[n];
for (int i = 0; i < n; i++) {
x[i] = min + i * (max - min) / n;
y[i] = f.value(x[i]);
}
double derivativebound = 1.0;
UnivariateRealFunction p = interpolator.interpolate(x, y);
z = Math.PI / 4; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = Math.PI * 1.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
}
/**
* Test of interpolator for the exponential function.
* <p>
* |expm1^(n)(zeta)| <= e, zeta in [-1, 1]
*/
public void testExpm1Function() throws MathException {
UnivariateRealFunction f = new Expm1Function();
UnivariateRealInterpolator interpolator = new NevilleInterpolator();
double x[], y[], z, expected, result, tolerance;
// 5 interpolating points on interval [-1, 1]
int n = 5;
double min = -1.0, max = 1.0;
x = new double[n];
y = new double[n];
for (int i = 0; i < n; i++) {
x[i] = min + i * (max - min) / n;
y[i] = f.value(x[i]);
}
double derivativebound = Math.E;
UnivariateRealFunction p = interpolator.interpolate(x, y);
z = 0.0; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = 0.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
z = -0.5; expected = f.value(z); result = p.value(z);
tolerance = Math.abs(derivativebound * partialerror(x, z));
assertEquals(expected, result, tolerance);
}
/**
* Test of parameters for the interpolator.
*/
public void testParameters() throws Exception {
UnivariateRealInterpolator interpolator = new NevilleInterpolator();
try {
// bad abscissas array
double x[] = { 1.0, 2.0, 2.0, 4.0 };
double y[] = { 0.0, 4.0, 4.0, 2.5 };
UnivariateRealFunction p = interpolator.interpolate(x, y);
p.value(0.0);
fail("Expecting MathException - bad abscissas array");
} catch (MathException ex) {
// expected
}
}
/**
* Returns the partial error term (z-x[0])(z-x[1])...(z-x[n-1])/n!
*/
protected double partialerror(double x[], double z) throws
IllegalArgumentException {
if (x.length < 1) {
throw new IllegalArgumentException
("Interpolation array cannot be empty.");
}
double out = 1;
for (int i = 0; i < x.length; i++) {
out *= (z - x[i]) / (i + 1);
}
return out;
}
}

View File

@ -1,150 +1,150 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Lagrange form of polynomial function.
* <p>
* We use n+1 points to interpolate a polynomial of degree n. This should
* give us the exact same polynomial as result. Thus we can use a very
* small tolerance to account only for round-off errors.
*
* @version $Revision$ $Date$
*/
public final class PolynomialFunctionLagrangeFormTest extends TestCase {
/**
* Test of polynomial for the linear function.
*/
public void testLinearFunction() throws MathException {
PolynomialFunctionLagrangeForm p;
double c[], z, expected, result, tolerance = 1E-12;
// p(x) = 1.5x - 4
double x[] = { 0.0, 3.0 };
double y[] = { -4.0, 0.5 };
p = new PolynomialFunctionLagrangeForm(x, y);
z = 2.0; expected = -1.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 4.5; expected = 2.75; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 6.0; expected = 5.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(1, p.degree());
c = p.getCoefficients();
assertEquals(2, c.length);
assertEquals(-4.0, c[0], tolerance);
assertEquals(1.5, c[1], tolerance);
}
/**
* Test of polynomial for the quadratic function.
*/
public void testQuadraticFunction() throws MathException {
PolynomialFunctionLagrangeForm p;
double c[], z, expected, result, tolerance = 1E-12;
// p(x) = 2x^2 + 5x - 3 = (2x - 1)(x + 3)
double x[] = { 0.0, -1.0, 0.5 };
double y[] = { -3.0, -6.0, 0.0 };
p = new PolynomialFunctionLagrangeForm(x, y);
z = 1.0; expected = 4.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 2.5; expected = 22.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = -2.0; expected = -5.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(2, p.degree());
c = p.getCoefficients();
assertEquals(3, c.length);
assertEquals(-3.0, c[0], tolerance);
assertEquals(5.0, c[1], tolerance);
assertEquals(2.0, c[2], tolerance);
}
/**
* Test of polynomial for the quintic function.
*/
public void testQuinticFunction() throws MathException {
PolynomialFunctionLagrangeForm p;
double c[], z, expected, result, tolerance = 1E-12;
// p(x) = x^5 - x^4 - 7x^3 + x^2 + 6x = x(x^2 - 1)(x + 2)(x - 3)
double x[] = { 1.0, -1.0, 2.0, 3.0, -3.0, 0.5 };
double y[] = { 0.0, 0.0, -24.0, 0.0, -144.0, 2.34375 };
p = new PolynomialFunctionLagrangeForm(x, y);
z = 0.0; expected = 0.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = -2.0; expected = 0.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 4.0; expected = 360.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(5, p.degree());
c = p.getCoefficients();
assertEquals(6, c.length);
assertEquals(0.0, c[0], tolerance);
assertEquals(6.0, c[1], tolerance);
assertEquals(1.0, c[2], tolerance);
assertEquals(-7.0, c[3], tolerance);
assertEquals(-1.0, c[4], tolerance);
assertEquals(1.0, c[5], tolerance);
}
/**
* Test of parameters for the polynomial.
*/
public void testParameters() throws Exception {
PolynomialFunctionLagrangeForm p;
try {
// bad input array length
double x[] = { 1.0 };
double y[] = { 2.0 };
p = new PolynomialFunctionLagrangeForm(x, y);
fail("Expecting IllegalArgumentException - bad input array length");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// mismatch input arrays
double x[] = { 1.0, 2.0, 3.0, 4.0 };
double y[] = { 0.0, -4.0, -24.0 };
p = new PolynomialFunctionLagrangeForm(x, y);
fail("Expecting IllegalArgumentException - mismatch input arrays");
} catch (IllegalArgumentException ex) {
// expected
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Lagrange form of polynomial function.
* <p>
* We use n+1 points to interpolate a polynomial of degree n. This should
* give us the exact same polynomial as result. Thus we can use a very
* small tolerance to account only for round-off errors.
*
* @version $Revision$ $Date$
*/
public final class PolynomialFunctionLagrangeFormTest extends TestCase {
/**
* Test of polynomial for the linear function.
*/
public void testLinearFunction() throws MathException {
PolynomialFunctionLagrangeForm p;
double c[], z, expected, result, tolerance = 1E-12;
// p(x) = 1.5x - 4
double x[] = { 0.0, 3.0 };
double y[] = { -4.0, 0.5 };
p = new PolynomialFunctionLagrangeForm(x, y);
z = 2.0; expected = -1.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 4.5; expected = 2.75; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 6.0; expected = 5.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(1, p.degree());
c = p.getCoefficients();
assertEquals(2, c.length);
assertEquals(-4.0, c[0], tolerance);
assertEquals(1.5, c[1], tolerance);
}
/**
* Test of polynomial for the quadratic function.
*/
public void testQuadraticFunction() throws MathException {
PolynomialFunctionLagrangeForm p;
double c[], z, expected, result, tolerance = 1E-12;
// p(x) = 2x^2 + 5x - 3 = (2x - 1)(x + 3)
double x[] = { 0.0, -1.0, 0.5 };
double y[] = { -3.0, -6.0, 0.0 };
p = new PolynomialFunctionLagrangeForm(x, y);
z = 1.0; expected = 4.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 2.5; expected = 22.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = -2.0; expected = -5.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(2, p.degree());
c = p.getCoefficients();
assertEquals(3, c.length);
assertEquals(-3.0, c[0], tolerance);
assertEquals(5.0, c[1], tolerance);
assertEquals(2.0, c[2], tolerance);
}
/**
* Test of polynomial for the quintic function.
*/
public void testQuinticFunction() throws MathException {
PolynomialFunctionLagrangeForm p;
double c[], z, expected, result, tolerance = 1E-12;
// p(x) = x^5 - x^4 - 7x^3 + x^2 + 6x = x(x^2 - 1)(x + 2)(x - 3)
double x[] = { 1.0, -1.0, 2.0, 3.0, -3.0, 0.5 };
double y[] = { 0.0, 0.0, -24.0, 0.0, -144.0, 2.34375 };
p = new PolynomialFunctionLagrangeForm(x, y);
z = 0.0; expected = 0.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = -2.0; expected = 0.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 4.0; expected = 360.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(5, p.degree());
c = p.getCoefficients();
assertEquals(6, c.length);
assertEquals(0.0, c[0], tolerance);
assertEquals(6.0, c[1], tolerance);
assertEquals(1.0, c[2], tolerance);
assertEquals(-7.0, c[3], tolerance);
assertEquals(-1.0, c[4], tolerance);
assertEquals(1.0, c[5], tolerance);
}
/**
* Test of parameters for the polynomial.
*/
public void testParameters() throws Exception {
PolynomialFunctionLagrangeForm p;
try {
// bad input array length
double x[] = { 1.0 };
double y[] = { 2.0 };
p = new PolynomialFunctionLagrangeForm(x, y);
fail("Expecting IllegalArgumentException - bad input array length");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// mismatch input arrays
double x[] = { 1.0, 2.0, 3.0, 4.0 };
double y[] = { 0.0, -4.0, -24.0 };
p = new PolynomialFunctionLagrangeForm(x, y);
fail("Expecting IllegalArgumentException - mismatch input arrays");
} catch (IllegalArgumentException ex) {
// expected
}
}
}

View File

@ -1,149 +1,149 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Newton form of polynomial function.
* <p>
* The small tolerance number is used only to account for round-off errors.
*
* @version $Revision$ $Date$
*/
public final class PolynomialFunctionNewtonFormTest extends TestCase {
/**
* Test of polynomial for the linear function.
*/
public void testLinearFunction() throws MathException {
PolynomialFunctionNewtonForm p;
double coefficients[], z, expected, result, tolerance = 1E-12;
// p(x) = 1.5x - 4 = 2 + 1.5(x-4)
double a[] = { 2.0, 1.5 };
double c[] = { 4.0 };
p = new PolynomialFunctionNewtonForm(a, c);
z = 2.0; expected = -1.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 4.5; expected = 2.75; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 6.0; expected = 5.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(1, p.degree());
coefficients = p.getCoefficients();
assertEquals(2, coefficients.length);
assertEquals(-4.0, coefficients[0], tolerance);
assertEquals(1.5, coefficients[1], tolerance);
}
/**
* Test of polynomial for the quadratic function.
*/
public void testQuadraticFunction() throws MathException {
PolynomialFunctionNewtonForm p;
double coefficients[], z, expected, result, tolerance = 1E-12;
// p(x) = 2x^2 + 5x - 3 = 4 + 3(x-1) + 2(x-1)(x+2)
double a[] = { 4.0, 3.0, 2.0 };
double c[] = { 1.0, -2.0 };
p = new PolynomialFunctionNewtonForm(a, c);
z = 1.0; expected = 4.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 2.5; expected = 22.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = -2.0; expected = -5.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(2, p.degree());
coefficients = p.getCoefficients();
assertEquals(3, coefficients.length);
assertEquals(-3.0, coefficients[0], tolerance);
assertEquals(5.0, coefficients[1], tolerance);
assertEquals(2.0, coefficients[2], tolerance);
}
/**
* Test of polynomial for the quintic function.
*/
public void testQuinticFunction() throws MathException {
PolynomialFunctionNewtonForm p;
double coefficients[], z, expected, result, tolerance = 1E-12;
// p(x) = x^5 - x^4 - 7x^3 + x^2 + 6x
// = 6x - 6x^2 -6x^2(x-1) + x^2(x-1)(x+1) + x^2(x-1)(x+1)(x-2)
double a[] = { 0.0, 6.0, -6.0, -6.0, 1.0, 1.0 };
double c[] = { 0.0, 0.0, 1.0, -1.0, 2.0 };
p = new PolynomialFunctionNewtonForm(a, c);
z = 0.0; expected = 0.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = -2.0; expected = 0.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 4.0; expected = 360.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(5, p.degree());
coefficients = p.getCoefficients();
assertEquals(6, coefficients.length);
assertEquals(0.0, coefficients[0], tolerance);
assertEquals(6.0, coefficients[1], tolerance);
assertEquals(1.0, coefficients[2], tolerance);
assertEquals(-7.0, coefficients[3], tolerance);
assertEquals(-1.0, coefficients[4], tolerance);
assertEquals(1.0, coefficients[5], tolerance);
}
/**
* Test of parameters for the polynomial.
*/
public void testParameters() throws Exception {
PolynomialFunctionNewtonForm p;
try {
// bad input array length
double a[] = { 1.0 };
double c[] = { 2.0 };
p = new PolynomialFunctionNewtonForm(a, c);
fail("Expecting IllegalArgumentException - bad input array length");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// mismatch input arrays
double a[] = { 1.0, 2.0, 3.0, 4.0 };
double c[] = { 4.0, 3.0, 2.0, 1.0 };
p = new PolynomialFunctionNewtonForm(a, c);
fail("Expecting IllegalArgumentException - mismatch input arrays");
} catch (IllegalArgumentException ex) {
// expected
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Newton form of polynomial function.
* <p>
* The small tolerance number is used only to account for round-off errors.
*
* @version $Revision$ $Date$
*/
public final class PolynomialFunctionNewtonFormTest extends TestCase {
/**
* Test of polynomial for the linear function.
*/
public void testLinearFunction() throws MathException {
PolynomialFunctionNewtonForm p;
double coefficients[], z, expected, result, tolerance = 1E-12;
// p(x) = 1.5x - 4 = 2 + 1.5(x-4)
double a[] = { 2.0, 1.5 };
double c[] = { 4.0 };
p = new PolynomialFunctionNewtonForm(a, c);
z = 2.0; expected = -1.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 4.5; expected = 2.75; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 6.0; expected = 5.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(1, p.degree());
coefficients = p.getCoefficients();
assertEquals(2, coefficients.length);
assertEquals(-4.0, coefficients[0], tolerance);
assertEquals(1.5, coefficients[1], tolerance);
}
/**
* Test of polynomial for the quadratic function.
*/
public void testQuadraticFunction() throws MathException {
PolynomialFunctionNewtonForm p;
double coefficients[], z, expected, result, tolerance = 1E-12;
// p(x) = 2x^2 + 5x - 3 = 4 + 3(x-1) + 2(x-1)(x+2)
double a[] = { 4.0, 3.0, 2.0 };
double c[] = { 1.0, -2.0 };
p = new PolynomialFunctionNewtonForm(a, c);
z = 1.0; expected = 4.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 2.5; expected = 22.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = -2.0; expected = -5.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(2, p.degree());
coefficients = p.getCoefficients();
assertEquals(3, coefficients.length);
assertEquals(-3.0, coefficients[0], tolerance);
assertEquals(5.0, coefficients[1], tolerance);
assertEquals(2.0, coefficients[2], tolerance);
}
/**
* Test of polynomial for the quintic function.
*/
public void testQuinticFunction() throws MathException {
PolynomialFunctionNewtonForm p;
double coefficients[], z, expected, result, tolerance = 1E-12;
// p(x) = x^5 - x^4 - 7x^3 + x^2 + 6x
// = 6x - 6x^2 -6x^2(x-1) + x^2(x-1)(x+1) + x^2(x-1)(x+1)(x-2)
double a[] = { 0.0, 6.0, -6.0, -6.0, 1.0, 1.0 };
double c[] = { 0.0, 0.0, 1.0, -1.0, 2.0 };
p = new PolynomialFunctionNewtonForm(a, c);
z = 0.0; expected = 0.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = -2.0; expected = 0.0; result = p.value(z);
assertEquals(expected, result, tolerance);
z = 4.0; expected = 360.0; result = p.value(z);
assertEquals(expected, result, tolerance);
assertEquals(5, p.degree());
coefficients = p.getCoefficients();
assertEquals(6, coefficients.length);
assertEquals(0.0, coefficients[0], tolerance);
assertEquals(6.0, coefficients[1], tolerance);
assertEquals(1.0, coefficients[2], tolerance);
assertEquals(-7.0, coefficients[3], tolerance);
assertEquals(-1.0, coefficients[4], tolerance);
assertEquals(1.0, coefficients[5], tolerance);
}
/**
* Test of parameters for the polynomial.
*/
public void testParameters() throws Exception {
PolynomialFunctionNewtonForm p;
try {
// bad input array length
double a[] = { 1.0 };
double c[] = { 2.0 };
p = new PolynomialFunctionNewtonForm(a, c);
fail("Expecting IllegalArgumentException - bad input array length");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// mismatch input arrays
double a[] = { 1.0, 2.0, 3.0, 4.0 };
double c[] = { 4.0, 3.0, 2.0, 1.0 };
p = new PolynomialFunctionNewtonForm(a, c);
fail("Expecting IllegalArgumentException - mismatch input arrays");
} catch (IllegalArgumentException ex) {
// expected
}
}
}

View File

@ -1,132 +1,132 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Ridders solver.
* <p>
* Ridders' method converges superlinearly, more specific, its rate of
* convergence is sqrt(2). Test runs show that for a default absolute
* accuracy of 1E-6, it generally takes less than 5 iterations for close
* initial bracket and 5 to 10 iterations for distant initial bracket
* to converge.
*
* @version $Revision$ $Date$
*/
public final class RiddersSolverTest extends TestCase {
/**
* Test of solver for the sine function.
*/
public void testSinFunction() throws MathException {
UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new RiddersSolver(f);
double min, max, expected, result, tolerance;
min = 3.0; max = 4.0; expected = Math.PI;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -1.0; max = 1.5; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quintic function.
*/
public void testQuinticFunction() throws MathException {
UnivariateRealFunction f = new QuinticFunction();
UnivariateRealSolver solver = new RiddersSolver(f);
double min, max, expected, result, tolerance;
min = -0.4; max = 0.2; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = 0.75; max = 1.5; expected = 1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -0.9; max = -0.2; expected = -0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the exponential function.
*/
public void testExpm1Function() throws MathException {
UnivariateRealFunction f = new Expm1Function();
UnivariateRealSolver solver = new RiddersSolver(f);
double min, max, expected, result, tolerance;
min = -1.0; max = 2.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -20.0; max = 10.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -50.0; max = 100.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of parameters for the solver.
*/
public void testParameters() throws Exception {
UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new RiddersSolver(f);
try {
// bad interval
solver.solve(1, -1);
fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// no bracketing
solver.solve(2, 3);
fail("Expecting IllegalArgumentException - no bracketing");
} catch (IllegalArgumentException ex) {
// expected
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
import junit.framework.TestCase;
/**
* Testcase for Ridders solver.
* <p>
* Ridders' method converges superlinearly, more specific, its rate of
* convergence is sqrt(2). Test runs show that for a default absolute
* accuracy of 1E-6, it generally takes less than 5 iterations for close
* initial bracket and 5 to 10 iterations for distant initial bracket
* to converge.
*
* @version $Revision$ $Date$
*/
public final class RiddersSolverTest extends TestCase {
/**
* Test of solver for the sine function.
*/
public void testSinFunction() throws MathException {
UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new RiddersSolver(f);
double min, max, expected, result, tolerance;
min = 3.0; max = 4.0; expected = Math.PI;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -1.0; max = 1.5; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the quintic function.
*/
public void testQuinticFunction() throws MathException {
UnivariateRealFunction f = new QuinticFunction();
UnivariateRealSolver solver = new RiddersSolver(f);
double min, max, expected, result, tolerance;
min = -0.4; max = 0.2; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = 0.75; max = 1.5; expected = 1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -0.9; max = -0.2; expected = -0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the exponential function.
*/
public void testExpm1Function() throws MathException {
UnivariateRealFunction f = new Expm1Function();
UnivariateRealSolver solver = new RiddersSolver(f);
double min, max, expected, result, tolerance;
min = -1.0; max = 2.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -20.0; max = 10.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
min = -50.0; max = 100.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of parameters for the solver.
*/
public void testParameters() throws Exception {
UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new RiddersSolver(f);
try {
// bad interval
solver.solve(1, -1);
fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// no bracketing
solver.solve(2, 3);
fail("Expecting IllegalArgumentException - no bracketing");
} catch (IllegalArgumentException ex) {
// expected
}
}
}

View File

@ -1,97 +1,97 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
/**
* Test cases for CauchyDistribution.
* Extends ContinuousDistributionAbstractTest. See class javadoc for
* ContinuousDistributionAbstractTest for details.
*
* @version $Revision$ $Date$
*/
public class CauchyDistributionTest extends ContinuousDistributionAbstractTest {
/**
* Constructor for CauchyDistributionTest.
* @param arg0
*/
public CauchyDistributionTest(String arg0) {
super(arg0);
}
//-------------- Implementations for abstract methods -----------------------
/** Creates the default continuous distribution instance to use in tests. */
public ContinuousDistribution makeDistribution() {
return DistributionFactory.newInstance().createCauchyDistribution(1.2, 2.1);
}
/** Creates the default cumulative probability distribution test input values */
public double[] makeCumulativeTestPoints() {
// quantiles computed using Mathematica
return new double[] {-667.2485619d, -65.6230835d, -25.48302995d,
-12.05887818d, -5.263135428d, 7.663135428d, 14.45887818d,
27.88302995d, 68.0230835d, 669.6485619d};
}
/** Creates the default cumulative probability density test expected values */
public double[] makeCumulativeTestValues() {
return new double[] {0.001d, 0.01d, 0.025d, 0.05d, 0.1d, 0.900d, 0.950d,
0.975d, 0.990d, 0.999d};
}
//---------------------------- Additional test cases -------------------------
public void testInverseCumulativeProbabilityExtremes() throws Exception {
setInverseCumulativeTestPoints(new double[] {0.0, 1.0});
setInverseCumulativeTestValues(
new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY});
verifyInverseCumulativeProbabilities();
}
public void testMedian() {
CauchyDistribution distribution = (CauchyDistribution) getDistribution();
double expected = Math.random();
distribution.setMedian(expected);
assertEquals(expected, distribution.getMedian(), 0.0);
}
public void testScale() {
CauchyDistribution distribution = (CauchyDistribution) getDistribution();
double expected = Math.random();
distribution.setScale(expected);
assertEquals(expected, distribution.getScale(), 0.0);
}
public void testSetScale() {
CauchyDistribution distribution = (CauchyDistribution) getDistribution();
try {
distribution.setScale(0.0);
fail("Can not have 0.0 scale.");
} catch (IllegalArgumentException ex) {
// success
}
try {
distribution.setScale(-1.0);
fail("Can not have negative scale.");
} catch (IllegalArgumentException ex) {
// success
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
/**
* Test cases for CauchyDistribution.
* Extends ContinuousDistributionAbstractTest. See class javadoc for
* ContinuousDistributionAbstractTest for details.
*
* @version $Revision$ $Date$
*/
public class CauchyDistributionTest extends ContinuousDistributionAbstractTest {
/**
* Constructor for CauchyDistributionTest.
* @param arg0
*/
public CauchyDistributionTest(String arg0) {
super(arg0);
}
//-------------- Implementations for abstract methods -----------------------
/** Creates the default continuous distribution instance to use in tests. */
public ContinuousDistribution makeDistribution() {
return DistributionFactory.newInstance().createCauchyDistribution(1.2, 2.1);
}
/** Creates the default cumulative probability distribution test input values */
public double[] makeCumulativeTestPoints() {
// quantiles computed using Mathematica
return new double[] {-667.2485619d, -65.6230835d, -25.48302995d,
-12.05887818d, -5.263135428d, 7.663135428d, 14.45887818d,
27.88302995d, 68.0230835d, 669.6485619d};
}
/** Creates the default cumulative probability density test expected values */
public double[] makeCumulativeTestValues() {
return new double[] {0.001d, 0.01d, 0.025d, 0.05d, 0.1d, 0.900d, 0.950d,
0.975d, 0.990d, 0.999d};
}
//---------------------------- Additional test cases -------------------------
public void testInverseCumulativeProbabilityExtremes() throws Exception {
setInverseCumulativeTestPoints(new double[] {0.0, 1.0});
setInverseCumulativeTestValues(
new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY});
verifyInverseCumulativeProbabilities();
}
public void testMedian() {
CauchyDistribution distribution = (CauchyDistribution) getDistribution();
double expected = Math.random();
distribution.setMedian(expected);
assertEquals(expected, distribution.getMedian(), 0.0);
}
public void testScale() {
CauchyDistribution distribution = (CauchyDistribution) getDistribution();
double expected = Math.random();
distribution.setScale(expected);
assertEquals(expected, distribution.getScale(), 0.0);
}
public void testSetScale() {
CauchyDistribution distribution = (CauchyDistribution) getDistribution();
try {
distribution.setScale(0.0);
fail("Can not have 0.0 scale.");
} catch (IllegalArgumentException ex) {
// success
}
try {
distribution.setScale(-1.0);
fail("Can not have negative scale.");
} catch (IllegalArgumentException ex) {
// success
}
}
}

View File

@ -1,114 +1,114 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
/**
* Test cases for WeibullDistribution.
* Extends ContinuousDistributionAbstractTest. See class javadoc for
* ContinuousDistributionAbstractTest for details.
*
* @version $Revision: 1.8 $ $Date: 2004-07-24 16:41:37 -0500 (Sat, 24 Jul 2004) $
*/
public class WeibullDistributionTest extends ContinuousDistributionAbstractTest {
/**
* Constructor for CauchyDistributionTest.
* @param arg0
*/
public WeibullDistributionTest(String arg0) {
super(arg0);
}
//-------------- Implementations for abstract methods -----------------------
/** Creates the default continuous distribution instance to use in tests. */
public ContinuousDistribution makeDistribution() {
return DistributionFactory.newInstance().createWeibullDistribution(1.2, 2.1);
}
/** Creates the default cumulative probability distribution test input values */
public double[] makeCumulativeTestPoints() {
// quantiles computed using Mathematica
return new double[] {0.00664355181d, 0.04543282833d, 0.09811627374d,
0.1767135246d, 0.3219468654d, 4.207902826d, 5.23968437d,
6.232056007d, 7.497630467d, 10.51154969d};
}
/** Creates the default cumulative probability density test expected values */
public double[] makeCumulativeTestValues() {
return new double[] {0.001d, 0.01d, 0.025d, 0.05d, 0.1d, 0.900d, 0.950d,
0.975d, 0.990d, 0.999d};
}
//---------------------------- Additional test cases -------------------------
public void testInverseCumulativeProbabilityExtremes() throws Exception {
setInverseCumulativeTestPoints(new double[] {0.0, 1.0});
setInverseCumulativeTestValues(
new double[] {0.0, Double.POSITIVE_INFINITY});
verifyInverseCumulativeProbabilities();
}
public void testAlpha() {
WeibullDistribution distribution = (WeibullDistribution) getDistribution();
double expected = Math.random();
distribution.setShape(expected);
assertEquals(expected, distribution.getShape(), 0.0);
}
public void testBeta() {
WeibullDistribution distribution = (WeibullDistribution) getDistribution();
double expected = Math.random();
distribution.setScale(expected);
assertEquals(expected, distribution.getScale(), 0.0);
}
public void testSetAlpha() {
WeibullDistribution distribution = (WeibullDistribution) getDistribution();
try {
distribution.setShape(0.0);
fail("Can not have 0.0 alpha.");
} catch (IllegalArgumentException ex) {
// success
}
try {
distribution.setShape(-1.0);
fail("Can not have negative alpha.");
} catch (IllegalArgumentException ex) {
// success
}
}
public void testSetBeta() {
WeibullDistribution distribution = (WeibullDistribution) getDistribution();
try {
distribution.setScale(0.0);
fail("Can not have 0.0 beta.");
} catch (IllegalArgumentException ex) {
// success
}
try {
distribution.setScale(-1.0);
fail("Can not have negative beta.");
} catch (IllegalArgumentException ex) {
// success
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.distribution;
/**
* Test cases for WeibullDistribution.
* Extends ContinuousDistributionAbstractTest. See class javadoc for
* ContinuousDistributionAbstractTest for details.
*
* @version $Revision: 1.8 $ $Date: 2004-07-24 16:41:37 -0500 (Sat, 24 Jul 2004) $
*/
public class WeibullDistributionTest extends ContinuousDistributionAbstractTest {
/**
* Constructor for CauchyDistributionTest.
* @param arg0
*/
public WeibullDistributionTest(String arg0) {
super(arg0);
}
//-------------- Implementations for abstract methods -----------------------
/** Creates the default continuous distribution instance to use in tests. */
public ContinuousDistribution makeDistribution() {
return DistributionFactory.newInstance().createWeibullDistribution(1.2, 2.1);
}
/** Creates the default cumulative probability distribution test input values */
public double[] makeCumulativeTestPoints() {
// quantiles computed using Mathematica
return new double[] {0.00664355181d, 0.04543282833d, 0.09811627374d,
0.1767135246d, 0.3219468654d, 4.207902826d, 5.23968437d,
6.232056007d, 7.497630467d, 10.51154969d};
}
/** Creates the default cumulative probability density test expected values */
public double[] makeCumulativeTestValues() {
return new double[] {0.001d, 0.01d, 0.025d, 0.05d, 0.1d, 0.900d, 0.950d,
0.975d, 0.990d, 0.999d};
}
//---------------------------- Additional test cases -------------------------
public void testInverseCumulativeProbabilityExtremes() throws Exception {
setInverseCumulativeTestPoints(new double[] {0.0, 1.0});
setInverseCumulativeTestValues(
new double[] {0.0, Double.POSITIVE_INFINITY});
verifyInverseCumulativeProbabilities();
}
public void testAlpha() {
WeibullDistribution distribution = (WeibullDistribution) getDistribution();
double expected = Math.random();
distribution.setShape(expected);
assertEquals(expected, distribution.getShape(), 0.0);
}
public void testBeta() {
WeibullDistribution distribution = (WeibullDistribution) getDistribution();
double expected = Math.random();
distribution.setScale(expected);
assertEquals(expected, distribution.getScale(), 0.0);
}
public void testSetAlpha() {
WeibullDistribution distribution = (WeibullDistribution) getDistribution();
try {
distribution.setShape(0.0);
fail("Can not have 0.0 alpha.");
} catch (IllegalArgumentException ex) {
// success
}
try {
distribution.setShape(-1.0);
fail("Can not have negative alpha.");
} catch (IllegalArgumentException ex) {
// success
}
}
public void testSetBeta() {
WeibullDistribution distribution = (WeibullDistribution) getDistribution();
try {
distribution.setScale(0.0);
fail("Can not have 0.0 beta.");
} catch (IllegalArgumentException ex) {
// success
}
try {
distribution.setScale(-1.0);
fail("Can not have negative beta.");
} catch (IllegalArgumentException ex) {
// success
}
}
}

View File

@ -1,292 +1,292 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.fraction;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import junit.framework.TestCase;
public class FractionFormatTest extends TestCase {
FractionFormat properFormat = null;
FractionFormat improperFormat = null;
protected Locale getLocale() {
return Locale.getDefault();
}
protected void setUp() throws Exception {
properFormat = FractionFormat.getProperInstance(getLocale());
improperFormat = FractionFormat.getImproperInstance(getLocale());
}
public void testFormat() {
Fraction c = new Fraction(1, 2);
String expected = "1 / 2";
String actual = properFormat.format(c);
assertEquals(expected, actual);
actual = improperFormat.format(c);
assertEquals(expected, actual);
}
public void testFormatNegative() {
Fraction c = new Fraction(-1, 2);
String expected = "-1 / 2";
String actual = properFormat.format(c);
assertEquals(expected, actual);
actual = improperFormat.format(c);
assertEquals(expected, actual);
}
public void testFormatZero() {
Fraction c = new Fraction(0, 1);
String expected = "0 / 1";
String actual = properFormat.format(c);
assertEquals(expected, actual);
actual = improperFormat.format(c);
assertEquals(expected, actual);
}
public void testFormatImproper() {
Fraction c = new Fraction(5, 3);
String actual = properFormat.format(c);
assertEquals("1 2 / 3", actual);
actual = improperFormat.format(c);
assertEquals("5 / 3", actual);
}
public void testFormatImproperNegative() {
Fraction c = new Fraction(-5, 3);
String actual = properFormat.format(c);
assertEquals("-1 2 / 3", actual);
actual = improperFormat.format(c);
assertEquals("-5 / 3", actual);
}
public void testParse() {
String source = "1 / 2";
try {
Fraction c = properFormat.parse(source);
assertNotNull(c);
assertEquals(1, c.getNumerator());
assertEquals(2, c.getDenominator());
c = improperFormat.parse(source);
assertNotNull(c);
assertEquals(1, c.getNumerator());
assertEquals(2, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
}
public void testParseInteger() {
String source = "10";
try {
Fraction c = properFormat.parse(source);
assertNotNull(c);
assertEquals(10, c.getNumerator());
assertEquals(1, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
try {
Fraction c = improperFormat.parse(source);
assertNotNull(c);
assertEquals(10, c.getNumerator());
assertEquals(1, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
}
public void testParseInvalid() {
String source = "a";
String msg = "should not be able to parse '10 / a'.";
try {
properFormat.parse(source);
fail(msg);
} catch (ParseException ex) {
// success
}
try {
improperFormat.parse(source);
fail(msg);
} catch (ParseException ex) {
// success
}
}
public void testParseInvalidDenominator() {
String source = "10 / a";
String msg = "should not be able to parse '10 / a'.";
try {
properFormat.parse(source);
fail(msg);
} catch (ParseException ex) {
// success
}
try {
improperFormat.parse(source);
fail(msg);
} catch (ParseException ex) {
// success
}
}
public void testParseNegative() {
try {
String source = "-1 / 2";
Fraction c = properFormat.parse(source);
assertNotNull(c);
assertEquals(-1, c.getNumerator());
assertEquals(2, c.getDenominator());
c = improperFormat.parse(source);
assertNotNull(c);
assertEquals(-1, c.getNumerator());
assertEquals(2, c.getDenominator());
source = "1 / -2";
c = properFormat.parse(source);
assertNotNull(c);
assertEquals(-1, c.getNumerator());
assertEquals(2, c.getDenominator());
c = improperFormat.parse(source);
assertNotNull(c);
assertEquals(-1, c.getNumerator());
assertEquals(2, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
}
public void testParseProper() {
String source = "1 2 / 3";
try {
Fraction c = properFormat.parse(source);
assertNotNull(c);
assertEquals(5, c.getNumerator());
assertEquals(3, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
try {
improperFormat.parse(source);
fail("invalid improper fraction.");
} catch (ParseException ex) {
// success
}
}
public void testParseProperNegative() {
String source = "-1 2 / 3";
try {
Fraction c = properFormat.parse(source);
assertNotNull(c);
assertEquals(-5, c.getNumerator());
assertEquals(3, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
try {
improperFormat.parse(source);
fail("invalid improper fraction.");
} catch (ParseException ex) {
// success
}
}
public void testParseProperInvalidMinus() {
String source = "2 -2 / 3";
try {
Fraction c = properFormat.parse(source);
fail("invalid minus in improper fraction.");
} catch (ParseException ex) {
// expected
}
source = "2 2 / -3";
try {
Fraction c = properFormat.parse(source);
fail("invalid minus in improper fraction.");
} catch (ParseException ex) {
// expected
}
}
public void testNumeratorFormat() {
NumberFormat old = properFormat.getNumeratorFormat();
NumberFormat nf = NumberFormat.getInstance();
nf.setParseIntegerOnly(true);
properFormat.setNumeratorFormat(nf);
assertEquals(nf, properFormat.getNumeratorFormat());
properFormat.setNumeratorFormat(old);
old = improperFormat.getNumeratorFormat();
nf = NumberFormat.getInstance();
nf.setParseIntegerOnly(true);
improperFormat.setNumeratorFormat(nf);
assertEquals(nf, improperFormat.getNumeratorFormat());
improperFormat.setNumeratorFormat(old);
}
public void testDenominatorFormat() {
NumberFormat old = properFormat.getDenominatorFormat();
NumberFormat nf = NumberFormat.getInstance();
nf.setParseIntegerOnly(true);
properFormat.setDenominatorFormat(nf);
assertEquals(nf, properFormat.getDenominatorFormat());
properFormat.setDenominatorFormat(old);
old = improperFormat.getDenominatorFormat();
nf = NumberFormat.getInstance();
nf.setParseIntegerOnly(true);
improperFormat.setDenominatorFormat(nf);
assertEquals(nf, improperFormat.getDenominatorFormat());
improperFormat.setDenominatorFormat(old);
}
public void testWholeFormat() {
ProperFractionFormat format = (ProperFractionFormat)properFormat;
NumberFormat old = format.getWholeFormat();
NumberFormat nf = NumberFormat.getInstance();
nf.setParseIntegerOnly(true);
format.setWholeFormat(nf);
assertEquals(nf, format.getWholeFormat());
format.setWholeFormat(old);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.fraction;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;
import junit.framework.TestCase;
public class FractionFormatTest extends TestCase {
FractionFormat properFormat = null;
FractionFormat improperFormat = null;
protected Locale getLocale() {
return Locale.getDefault();
}
protected void setUp() throws Exception {
properFormat = FractionFormat.getProperInstance(getLocale());
improperFormat = FractionFormat.getImproperInstance(getLocale());
}
public void testFormat() {
Fraction c = new Fraction(1, 2);
String expected = "1 / 2";
String actual = properFormat.format(c);
assertEquals(expected, actual);
actual = improperFormat.format(c);
assertEquals(expected, actual);
}
public void testFormatNegative() {
Fraction c = new Fraction(-1, 2);
String expected = "-1 / 2";
String actual = properFormat.format(c);
assertEquals(expected, actual);
actual = improperFormat.format(c);
assertEquals(expected, actual);
}
public void testFormatZero() {
Fraction c = new Fraction(0, 1);
String expected = "0 / 1";
String actual = properFormat.format(c);
assertEquals(expected, actual);
actual = improperFormat.format(c);
assertEquals(expected, actual);
}
public void testFormatImproper() {
Fraction c = new Fraction(5, 3);
String actual = properFormat.format(c);
assertEquals("1 2 / 3", actual);
actual = improperFormat.format(c);
assertEquals("5 / 3", actual);
}
public void testFormatImproperNegative() {
Fraction c = new Fraction(-5, 3);
String actual = properFormat.format(c);
assertEquals("-1 2 / 3", actual);
actual = improperFormat.format(c);
assertEquals("-5 / 3", actual);
}
public void testParse() {
String source = "1 / 2";
try {
Fraction c = properFormat.parse(source);
assertNotNull(c);
assertEquals(1, c.getNumerator());
assertEquals(2, c.getDenominator());
c = improperFormat.parse(source);
assertNotNull(c);
assertEquals(1, c.getNumerator());
assertEquals(2, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
}
public void testParseInteger() {
String source = "10";
try {
Fraction c = properFormat.parse(source);
assertNotNull(c);
assertEquals(10, c.getNumerator());
assertEquals(1, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
try {
Fraction c = improperFormat.parse(source);
assertNotNull(c);
assertEquals(10, c.getNumerator());
assertEquals(1, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
}
public void testParseInvalid() {
String source = "a";
String msg = "should not be able to parse '10 / a'.";
try {
properFormat.parse(source);
fail(msg);
} catch (ParseException ex) {
// success
}
try {
improperFormat.parse(source);
fail(msg);
} catch (ParseException ex) {
// success
}
}
public void testParseInvalidDenominator() {
String source = "10 / a";
String msg = "should not be able to parse '10 / a'.";
try {
properFormat.parse(source);
fail(msg);
} catch (ParseException ex) {
// success
}
try {
improperFormat.parse(source);
fail(msg);
} catch (ParseException ex) {
// success
}
}
public void testParseNegative() {
try {
String source = "-1 / 2";
Fraction c = properFormat.parse(source);
assertNotNull(c);
assertEquals(-1, c.getNumerator());
assertEquals(2, c.getDenominator());
c = improperFormat.parse(source);
assertNotNull(c);
assertEquals(-1, c.getNumerator());
assertEquals(2, c.getDenominator());
source = "1 / -2";
c = properFormat.parse(source);
assertNotNull(c);
assertEquals(-1, c.getNumerator());
assertEquals(2, c.getDenominator());
c = improperFormat.parse(source);
assertNotNull(c);
assertEquals(-1, c.getNumerator());
assertEquals(2, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
}
public void testParseProper() {
String source = "1 2 / 3";
try {
Fraction c = properFormat.parse(source);
assertNotNull(c);
assertEquals(5, c.getNumerator());
assertEquals(3, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
try {
improperFormat.parse(source);
fail("invalid improper fraction.");
} catch (ParseException ex) {
// success
}
}
public void testParseProperNegative() {
String source = "-1 2 / 3";
try {
Fraction c = properFormat.parse(source);
assertNotNull(c);
assertEquals(-5, c.getNumerator());
assertEquals(3, c.getDenominator());
} catch (ParseException ex) {
fail(ex.getMessage());
}
try {
improperFormat.parse(source);
fail("invalid improper fraction.");
} catch (ParseException ex) {
// success
}
}
public void testParseProperInvalidMinus() {
String source = "2 -2 / 3";
try {
Fraction c = properFormat.parse(source);
fail("invalid minus in improper fraction.");
} catch (ParseException ex) {
// expected
}
source = "2 2 / -3";
try {
Fraction c = properFormat.parse(source);
fail("invalid minus in improper fraction.");
} catch (ParseException ex) {
// expected
}
}
public void testNumeratorFormat() {
NumberFormat old = properFormat.getNumeratorFormat();
NumberFormat nf = NumberFormat.getInstance();
nf.setParseIntegerOnly(true);
properFormat.setNumeratorFormat(nf);
assertEquals(nf, properFormat.getNumeratorFormat());
properFormat.setNumeratorFormat(old);
old = improperFormat.getNumeratorFormat();
nf = NumberFormat.getInstance();
nf.setParseIntegerOnly(true);
improperFormat.setNumeratorFormat(nf);
assertEquals(nf, improperFormat.getNumeratorFormat());
improperFormat.setNumeratorFormat(old);
}
public void testDenominatorFormat() {
NumberFormat old = properFormat.getDenominatorFormat();
NumberFormat nf = NumberFormat.getInstance();
nf.setParseIntegerOnly(true);
properFormat.setDenominatorFormat(nf);
assertEquals(nf, properFormat.getDenominatorFormat());
properFormat.setDenominatorFormat(old);
old = improperFormat.getDenominatorFormat();
nf = NumberFormat.getInstance();
nf.setParseIntegerOnly(true);
improperFormat.setDenominatorFormat(nf);
assertEquals(nf, improperFormat.getDenominatorFormat());
improperFormat.setDenominatorFormat(old);
}
public void testWholeFormat() {
ProperFractionFormat format = (ProperFractionFormat)properFormat;
NumberFormat old = format.getWholeFormat();
NumberFormat nf = NumberFormat.getInstance();
nf.setParseIntegerOnly(true);
format.setWholeFormat(nf);
assertEquals(nf, format.getWholeFormat());
format.setWholeFormat(old);
}
}

View File

@ -1,446 +1,446 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.fraction;
import org.apache.commons.math.ConvergenceException;
import junit.framework.TestCase;
/**
* @version $Revision$ $Date$
*/
public class FractionTest extends TestCase {
private void assertFraction(int expectedNumerator, int expectedDenominator, Fraction actual) {
assertEquals(expectedNumerator, actual.getNumerator());
assertEquals(expectedDenominator, actual.getDenominator());
}
public void testConstructor() {
assertFraction(0, 1, new Fraction(0, 1));
assertFraction(0, 1, new Fraction(0, 2));
assertFraction(0, 1, new Fraction(0, -1));
assertFraction(1, 2, new Fraction(1, 2));
assertFraction(1, 2, new Fraction(2, 4));
assertFraction(-1, 2, new Fraction(-1, 2));
assertFraction(-1, 2, new Fraction(1, -2));
assertFraction(-1, 2, new Fraction(-2, 4));
assertFraction(-1, 2, new Fraction(2, -4));
// overflow
try {
new Fraction(Integer.MIN_VALUE, -1);
fail();
} catch (ArithmeticException ex) {
// success
}
try {
new Fraction(1, Integer.MIN_VALUE);
fail();
} catch (ArithmeticException ex) {
// success
}
try {
assertFraction(0, 1, new Fraction(0.00000000000001));
assertFraction(2, 5, new Fraction(0.40000000000001));
assertFraction(15, 1, new Fraction(15.0000000000001));
} catch (ConvergenceException ex) {
fail(ex.getMessage());
}
}
public void testCompareTo() {
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(1, 3);
Fraction third = new Fraction(1, 2);
assertEquals(0, first.compareTo(first));
assertEquals(0, first.compareTo(third));
assertEquals(1, first.compareTo(second));
assertEquals(-1, second.compareTo(first));
}
public void testDoubleValue() {
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(1, 3);
assertEquals(0.5, first.doubleValue(), 0.0);
assertEquals(1.0 / 3.0, second.doubleValue(), 0.0);
}
public void testFloatValue() {
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(1, 3);
assertEquals(0.5f, first.floatValue(), 0.0f);
assertEquals((float)(1.0 / 3.0), second.floatValue(), 0.0f);
}
public void testIntValue() {
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(3, 2);
assertEquals(0, first.intValue());
assertEquals(1, second.intValue());
}
public void testLongValue() {
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(3, 2);
assertEquals(0L, first.longValue());
assertEquals(1L, second.longValue());
}
public void testConstructorDouble() {
try {
assertFraction(1, 2, new Fraction(0.5));
assertFraction(1, 3, new Fraction(1.0 / 3.0));
assertFraction(17, 100, new Fraction(17.0 / 100.0));
assertFraction(317, 100, new Fraction(317.0 / 100.0));
assertFraction(-1, 2, new Fraction(-0.5));
assertFraction(-1, 3, new Fraction(-1.0 / 3.0));
assertFraction(-17, 100, new Fraction(17.0 / -100.0));
assertFraction(-317, 100, new Fraction(-317.0 / 100.0));
} catch (ConvergenceException ex) {
fail(ex.getMessage());
}
}
public void testAbs() {
Fraction a = new Fraction(10, 21);
Fraction b = new Fraction(-10, 21);
Fraction c = new Fraction(10, -21);
assertFraction(10, 21, a.abs());
assertFraction(10, 21, b.abs());
assertFraction(10, 21, c.abs());
}
public void testReciprocal() {
Fraction f = null;
f = new Fraction(50, 75);
f = f.reciprocal();
assertEquals(3, f.getNumerator());
assertEquals(2, f.getDenominator());
f = new Fraction(4, 3);
f = f.reciprocal();
assertEquals(3, f.getNumerator());
assertEquals(4, f.getDenominator());
f = new Fraction(-15, 47);
f = f.reciprocal();
assertEquals(-47, f.getNumerator());
assertEquals(15, f.getDenominator());
f = new Fraction(0, 3);
try {
f = f.reciprocal();
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
// large values
f = new Fraction(Integer.MAX_VALUE, 1);
f = f.reciprocal();
assertEquals(1, f.getNumerator());
assertEquals(Integer.MAX_VALUE, f.getDenominator());
}
public void testNegate() {
Fraction f = null;
f = new Fraction(50, 75);
f = f.negate();
assertEquals(-2, f.getNumerator());
assertEquals(3, f.getDenominator());
f = new Fraction(-50, 75);
f = f.negate();
assertEquals(2, f.getNumerator());
assertEquals(3, f.getDenominator());
// large values
f = new Fraction(Integer.MAX_VALUE-1, Integer.MAX_VALUE);
f = f.negate();
assertEquals(Integer.MIN_VALUE+2, f.getNumerator());
assertEquals(Integer.MAX_VALUE, f.getDenominator());
f = new Fraction(Integer.MIN_VALUE, 1);
try {
f = f.negate();
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
}
public void testAdd() {
Fraction a = new Fraction(1, 2);
Fraction b = new Fraction(2, 3);
assertFraction(1, 1, a.add(a));
assertFraction(7, 6, a.add(b));
assertFraction(7, 6, b.add(a));
assertFraction(4, 3, b.add(b));
Fraction f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
Fraction f2 = Fraction.ONE;
Fraction f = f1.add(f2);
assertEquals(Integer.MAX_VALUE, f.getNumerator());
assertEquals(1, f.getDenominator());
f1 = new Fraction(-1, 13*13*2*2);
f2 = new Fraction(-2, 13*17*2);
f = f1.add(f2);
assertEquals(13*13*17*2*2, f.getDenominator());
assertEquals(-17 - 2*13*2, f.getNumerator());
try {
f.add(null);
fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException ex) {}
// if this fraction is added naively, it will overflow.
// check that it doesn't.
f1 = new Fraction(1,32768*3);
f2 = new Fraction(1,59049);
f = f1.add(f2);
assertEquals(52451, f.getNumerator());
assertEquals(1934917632, f.getDenominator());
f1 = new Fraction(Integer.MIN_VALUE, 3);
f2 = new Fraction(1,3);
f = f1.add(f2);
assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
assertEquals(3, f.getDenominator());
f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
f2 = Fraction.ONE;
f = f1.add(f2);
assertEquals(Integer.MAX_VALUE, f.getNumerator());
assertEquals(1, f.getDenominator());
try {
f = f.add(Fraction.ONE); // should overflow
fail("expecting ArithmeticException but got: " + f.toString());
} catch (ArithmeticException ex) {}
// denominator should not be a multiple of 2 or 3 to trigger overflow
f1 = new Fraction(Integer.MIN_VALUE, 5);
f2 = new Fraction(-1,5);
try {
f = f1.add(f2); // should overflow
fail("expecting ArithmeticException but got: " + f.toString());
} catch (ArithmeticException ex) {}
try {
f= new Fraction(-Integer.MAX_VALUE, 1);
f = f.add(f);
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
try {
f= new Fraction(-Integer.MAX_VALUE, 1);
f = f.add(f);
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
f1 = new Fraction(3,327680);
f2 = new Fraction(2,59049);
try {
f = f1.add(f2); // should overflow
fail("expecting ArithmeticException but got: " + f.toString());
} catch (ArithmeticException ex) {}
}
public void testDivide() {
Fraction a = new Fraction(1, 2);
Fraction b = new Fraction(2, 3);
assertFraction(1, 1, a.divide(a));
assertFraction(3, 4, a.divide(b));
assertFraction(4, 3, b.divide(a));
assertFraction(1, 1, b.divide(b));
Fraction f1 = new Fraction(3, 5);
Fraction f2 = Fraction.ZERO;
try {
Fraction f = f1.divide(f2);
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
f1 = new Fraction(0, 5);
f2 = new Fraction(2, 7);
Fraction f = f1.divide(f2);
assertSame(Fraction.ZERO, f);
f1 = new Fraction(2, 7);
f2 = Fraction.ONE;
f = f1.divide(f2);
assertEquals(2, f.getNumerator());
assertEquals(7, f.getDenominator());
f1 = new Fraction(1, Integer.MAX_VALUE);
f = f1.divide(f1);
assertEquals(1, f.getNumerator());
assertEquals(1, f.getDenominator());
f1 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
f2 = new Fraction(1, Integer.MAX_VALUE);
f = f1.divide(f2);
assertEquals(Integer.MIN_VALUE, f.getNumerator());
assertEquals(1, f.getDenominator());
try {
f.divide(null);
fail("IllegalArgumentException");
} catch (IllegalArgumentException ex) {}
try {
f1 = new Fraction(1, Integer.MAX_VALUE);
f = f1.divide(f1.reciprocal()); // should overflow
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
try {
f1 = new Fraction(1, -Integer.MAX_VALUE);
f = f1.divide(f1.reciprocal()); // should overflow
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
}
public void testMultiply() {
Fraction a = new Fraction(1, 2);
Fraction b = new Fraction(2, 3);
assertFraction(1, 4, a.multiply(a));
assertFraction(1, 3, a.multiply(b));
assertFraction(1, 3, b.multiply(a));
assertFraction(4, 9, b.multiply(b));
Fraction f1 = new Fraction(Integer.MAX_VALUE, 1);
Fraction f2 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
Fraction f = f1.multiply(f2);
assertEquals(Integer.MIN_VALUE, f.getNumerator());
assertEquals(1, f.getDenominator());
try {
f.multiply(null);
fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException ex) {}
}
public void testSubtract() {
Fraction a = new Fraction(1, 2);
Fraction b = new Fraction(2, 3);
assertFraction(0, 1, a.subtract(a));
assertFraction(-1, 6, a.subtract(b));
assertFraction(1, 6, b.subtract(a));
assertFraction(0, 1, b.subtract(b));
Fraction f = new Fraction(1,1);
try {
f.subtract(null);
fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException ex) {}
// if this fraction is subtracted naively, it will overflow.
// check that it doesn't.
Fraction f1 = new Fraction(1,32768*3);
Fraction f2 = new Fraction(1,59049);
f = f1.subtract(f2);
assertEquals(-13085, f.getNumerator());
assertEquals(1934917632, f.getDenominator());
f1 = new Fraction(Integer.MIN_VALUE, 3);
f2 = new Fraction(1,3).negate();
f = f1.subtract(f2);
assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
assertEquals(3, f.getDenominator());
f1 = new Fraction(Integer.MAX_VALUE, 1);
f2 = Fraction.ONE;
f = f1.subtract(f2);
assertEquals(Integer.MAX_VALUE-1, f.getNumerator());
assertEquals(1, f.getDenominator());
try {
f1 = new Fraction(1, Integer.MAX_VALUE);
f2 = new Fraction(1, Integer.MAX_VALUE - 1);
f = f1.subtract(f2);
fail("expecting ArithmeticException"); //should overflow
} catch (ArithmeticException ex) {}
// denominator should not be a multiple of 2 or 3 to trigger overflow
f1 = new Fraction(Integer.MIN_VALUE, 5);
f2 = new Fraction(1,5);
try {
f = f1.subtract(f2); // should overflow
fail("expecting ArithmeticException but got: " + f.toString());
} catch (ArithmeticException ex) {}
try {
f= new Fraction(Integer.MIN_VALUE, 1);
f = f.subtract(Fraction.ONE);
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
try {
f= new Fraction(Integer.MAX_VALUE, 1);
f = f.subtract(Fraction.ONE.negate());
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
f1 = new Fraction(3,327680);
f2 = new Fraction(2,59049);
try {
f = f1.subtract(f2); // should overflow
fail("expecting ArithmeticException but got: " + f.toString());
} catch (ArithmeticException ex) {}
}
public void testEqualsAndHashCode() {
Fraction zero = new Fraction(0,1);
Fraction nullFraction = null;
int zeroHash = zero.hashCode();
assertTrue( zero.equals(zero));
assertFalse(zero.equals(nullFraction));
assertFalse(zero.equals(new Double(0)));
Fraction zero2 = new Fraction(0,2);
assertTrue(zero.equals(zero2));
assertEquals(zero.hashCode(), zero2.hashCode());
Fraction one = new Fraction(1,1);
assertFalse((one.equals(zero) ||zero.equals(one)));
}
public void testGetReducedFraction() {
Fraction threeFourths = new Fraction(3, 4);
assertTrue(threeFourths.equals(Fraction.getReducedFraction(6, 8)));
assertTrue(Fraction.ZERO.equals(Fraction.getReducedFraction(0, -1)));
try {
Fraction f = Fraction.getReducedFraction(1, 0);
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {
// expected
}
assertEquals(Fraction.getReducedFraction
(2, Integer.MIN_VALUE).getNumerator(),-1);
assertEquals(Fraction.getReducedFraction
(1, -1).getNumerator(), -1);
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.fraction;
import org.apache.commons.math.ConvergenceException;
import junit.framework.TestCase;
/**
* @version $Revision$ $Date$
*/
public class FractionTest extends TestCase {
private void assertFraction(int expectedNumerator, int expectedDenominator, Fraction actual) {
assertEquals(expectedNumerator, actual.getNumerator());
assertEquals(expectedDenominator, actual.getDenominator());
}
public void testConstructor() {
assertFraction(0, 1, new Fraction(0, 1));
assertFraction(0, 1, new Fraction(0, 2));
assertFraction(0, 1, new Fraction(0, -1));
assertFraction(1, 2, new Fraction(1, 2));
assertFraction(1, 2, new Fraction(2, 4));
assertFraction(-1, 2, new Fraction(-1, 2));
assertFraction(-1, 2, new Fraction(1, -2));
assertFraction(-1, 2, new Fraction(-2, 4));
assertFraction(-1, 2, new Fraction(2, -4));
// overflow
try {
new Fraction(Integer.MIN_VALUE, -1);
fail();
} catch (ArithmeticException ex) {
// success
}
try {
new Fraction(1, Integer.MIN_VALUE);
fail();
} catch (ArithmeticException ex) {
// success
}
try {
assertFraction(0, 1, new Fraction(0.00000000000001));
assertFraction(2, 5, new Fraction(0.40000000000001));
assertFraction(15, 1, new Fraction(15.0000000000001));
} catch (ConvergenceException ex) {
fail(ex.getMessage());
}
}
public void testCompareTo() {
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(1, 3);
Fraction third = new Fraction(1, 2);
assertEquals(0, first.compareTo(first));
assertEquals(0, first.compareTo(third));
assertEquals(1, first.compareTo(second));
assertEquals(-1, second.compareTo(first));
}
public void testDoubleValue() {
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(1, 3);
assertEquals(0.5, first.doubleValue(), 0.0);
assertEquals(1.0 / 3.0, second.doubleValue(), 0.0);
}
public void testFloatValue() {
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(1, 3);
assertEquals(0.5f, first.floatValue(), 0.0f);
assertEquals((float)(1.0 / 3.0), second.floatValue(), 0.0f);
}
public void testIntValue() {
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(3, 2);
assertEquals(0, first.intValue());
assertEquals(1, second.intValue());
}
public void testLongValue() {
Fraction first = new Fraction(1, 2);
Fraction second = new Fraction(3, 2);
assertEquals(0L, first.longValue());
assertEquals(1L, second.longValue());
}
public void testConstructorDouble() {
try {
assertFraction(1, 2, new Fraction(0.5));
assertFraction(1, 3, new Fraction(1.0 / 3.0));
assertFraction(17, 100, new Fraction(17.0 / 100.0));
assertFraction(317, 100, new Fraction(317.0 / 100.0));
assertFraction(-1, 2, new Fraction(-0.5));
assertFraction(-1, 3, new Fraction(-1.0 / 3.0));
assertFraction(-17, 100, new Fraction(17.0 / -100.0));
assertFraction(-317, 100, new Fraction(-317.0 / 100.0));
} catch (ConvergenceException ex) {
fail(ex.getMessage());
}
}
public void testAbs() {
Fraction a = new Fraction(10, 21);
Fraction b = new Fraction(-10, 21);
Fraction c = new Fraction(10, -21);
assertFraction(10, 21, a.abs());
assertFraction(10, 21, b.abs());
assertFraction(10, 21, c.abs());
}
public void testReciprocal() {
Fraction f = null;
f = new Fraction(50, 75);
f = f.reciprocal();
assertEquals(3, f.getNumerator());
assertEquals(2, f.getDenominator());
f = new Fraction(4, 3);
f = f.reciprocal();
assertEquals(3, f.getNumerator());
assertEquals(4, f.getDenominator());
f = new Fraction(-15, 47);
f = f.reciprocal();
assertEquals(-47, f.getNumerator());
assertEquals(15, f.getDenominator());
f = new Fraction(0, 3);
try {
f = f.reciprocal();
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
// large values
f = new Fraction(Integer.MAX_VALUE, 1);
f = f.reciprocal();
assertEquals(1, f.getNumerator());
assertEquals(Integer.MAX_VALUE, f.getDenominator());
}
public void testNegate() {
Fraction f = null;
f = new Fraction(50, 75);
f = f.negate();
assertEquals(-2, f.getNumerator());
assertEquals(3, f.getDenominator());
f = new Fraction(-50, 75);
f = f.negate();
assertEquals(2, f.getNumerator());
assertEquals(3, f.getDenominator());
// large values
f = new Fraction(Integer.MAX_VALUE-1, Integer.MAX_VALUE);
f = f.negate();
assertEquals(Integer.MIN_VALUE+2, f.getNumerator());
assertEquals(Integer.MAX_VALUE, f.getDenominator());
f = new Fraction(Integer.MIN_VALUE, 1);
try {
f = f.negate();
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
}
public void testAdd() {
Fraction a = new Fraction(1, 2);
Fraction b = new Fraction(2, 3);
assertFraction(1, 1, a.add(a));
assertFraction(7, 6, a.add(b));
assertFraction(7, 6, b.add(a));
assertFraction(4, 3, b.add(b));
Fraction f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
Fraction f2 = Fraction.ONE;
Fraction f = f1.add(f2);
assertEquals(Integer.MAX_VALUE, f.getNumerator());
assertEquals(1, f.getDenominator());
f1 = new Fraction(-1, 13*13*2*2);
f2 = new Fraction(-2, 13*17*2);
f = f1.add(f2);
assertEquals(13*13*17*2*2, f.getDenominator());
assertEquals(-17 - 2*13*2, f.getNumerator());
try {
f.add(null);
fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException ex) {}
// if this fraction is added naively, it will overflow.
// check that it doesn't.
f1 = new Fraction(1,32768*3);
f2 = new Fraction(1,59049);
f = f1.add(f2);
assertEquals(52451, f.getNumerator());
assertEquals(1934917632, f.getDenominator());
f1 = new Fraction(Integer.MIN_VALUE, 3);
f2 = new Fraction(1,3);
f = f1.add(f2);
assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
assertEquals(3, f.getDenominator());
f1 = new Fraction(Integer.MAX_VALUE - 1, 1);
f2 = Fraction.ONE;
f = f1.add(f2);
assertEquals(Integer.MAX_VALUE, f.getNumerator());
assertEquals(1, f.getDenominator());
try {
f = f.add(Fraction.ONE); // should overflow
fail("expecting ArithmeticException but got: " + f.toString());
} catch (ArithmeticException ex) {}
// denominator should not be a multiple of 2 or 3 to trigger overflow
f1 = new Fraction(Integer.MIN_VALUE, 5);
f2 = new Fraction(-1,5);
try {
f = f1.add(f2); // should overflow
fail("expecting ArithmeticException but got: " + f.toString());
} catch (ArithmeticException ex) {}
try {
f= new Fraction(-Integer.MAX_VALUE, 1);
f = f.add(f);
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
try {
f= new Fraction(-Integer.MAX_VALUE, 1);
f = f.add(f);
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
f1 = new Fraction(3,327680);
f2 = new Fraction(2,59049);
try {
f = f1.add(f2); // should overflow
fail("expecting ArithmeticException but got: " + f.toString());
} catch (ArithmeticException ex) {}
}
public void testDivide() {
Fraction a = new Fraction(1, 2);
Fraction b = new Fraction(2, 3);
assertFraction(1, 1, a.divide(a));
assertFraction(3, 4, a.divide(b));
assertFraction(4, 3, b.divide(a));
assertFraction(1, 1, b.divide(b));
Fraction f1 = new Fraction(3, 5);
Fraction f2 = Fraction.ZERO;
try {
Fraction f = f1.divide(f2);
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
f1 = new Fraction(0, 5);
f2 = new Fraction(2, 7);
Fraction f = f1.divide(f2);
assertSame(Fraction.ZERO, f);
f1 = new Fraction(2, 7);
f2 = Fraction.ONE;
f = f1.divide(f2);
assertEquals(2, f.getNumerator());
assertEquals(7, f.getDenominator());
f1 = new Fraction(1, Integer.MAX_VALUE);
f = f1.divide(f1);
assertEquals(1, f.getNumerator());
assertEquals(1, f.getDenominator());
f1 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
f2 = new Fraction(1, Integer.MAX_VALUE);
f = f1.divide(f2);
assertEquals(Integer.MIN_VALUE, f.getNumerator());
assertEquals(1, f.getDenominator());
try {
f.divide(null);
fail("IllegalArgumentException");
} catch (IllegalArgumentException ex) {}
try {
f1 = new Fraction(1, Integer.MAX_VALUE);
f = f1.divide(f1.reciprocal()); // should overflow
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
try {
f1 = new Fraction(1, -Integer.MAX_VALUE);
f = f1.divide(f1.reciprocal()); // should overflow
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
}
public void testMultiply() {
Fraction a = new Fraction(1, 2);
Fraction b = new Fraction(2, 3);
assertFraction(1, 4, a.multiply(a));
assertFraction(1, 3, a.multiply(b));
assertFraction(1, 3, b.multiply(a));
assertFraction(4, 9, b.multiply(b));
Fraction f1 = new Fraction(Integer.MAX_VALUE, 1);
Fraction f2 = new Fraction(Integer.MIN_VALUE, Integer.MAX_VALUE);
Fraction f = f1.multiply(f2);
assertEquals(Integer.MIN_VALUE, f.getNumerator());
assertEquals(1, f.getDenominator());
try {
f.multiply(null);
fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException ex) {}
}
public void testSubtract() {
Fraction a = new Fraction(1, 2);
Fraction b = new Fraction(2, 3);
assertFraction(0, 1, a.subtract(a));
assertFraction(-1, 6, a.subtract(b));
assertFraction(1, 6, b.subtract(a));
assertFraction(0, 1, b.subtract(b));
Fraction f = new Fraction(1,1);
try {
f.subtract(null);
fail("expecting IllegalArgumentException");
} catch (IllegalArgumentException ex) {}
// if this fraction is subtracted naively, it will overflow.
// check that it doesn't.
Fraction f1 = new Fraction(1,32768*3);
Fraction f2 = new Fraction(1,59049);
f = f1.subtract(f2);
assertEquals(-13085, f.getNumerator());
assertEquals(1934917632, f.getDenominator());
f1 = new Fraction(Integer.MIN_VALUE, 3);
f2 = new Fraction(1,3).negate();
f = f1.subtract(f2);
assertEquals(Integer.MIN_VALUE+1, f.getNumerator());
assertEquals(3, f.getDenominator());
f1 = new Fraction(Integer.MAX_VALUE, 1);
f2 = Fraction.ONE;
f = f1.subtract(f2);
assertEquals(Integer.MAX_VALUE-1, f.getNumerator());
assertEquals(1, f.getDenominator());
try {
f1 = new Fraction(1, Integer.MAX_VALUE);
f2 = new Fraction(1, Integer.MAX_VALUE - 1);
f = f1.subtract(f2);
fail("expecting ArithmeticException"); //should overflow
} catch (ArithmeticException ex) {}
// denominator should not be a multiple of 2 or 3 to trigger overflow
f1 = new Fraction(Integer.MIN_VALUE, 5);
f2 = new Fraction(1,5);
try {
f = f1.subtract(f2); // should overflow
fail("expecting ArithmeticException but got: " + f.toString());
} catch (ArithmeticException ex) {}
try {
f= new Fraction(Integer.MIN_VALUE, 1);
f = f.subtract(Fraction.ONE);
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
try {
f= new Fraction(Integer.MAX_VALUE, 1);
f = f.subtract(Fraction.ONE.negate());
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {}
f1 = new Fraction(3,327680);
f2 = new Fraction(2,59049);
try {
f = f1.subtract(f2); // should overflow
fail("expecting ArithmeticException but got: " + f.toString());
} catch (ArithmeticException ex) {}
}
public void testEqualsAndHashCode() {
Fraction zero = new Fraction(0,1);
Fraction nullFraction = null;
int zeroHash = zero.hashCode();
assertTrue( zero.equals(zero));
assertFalse(zero.equals(nullFraction));
assertFalse(zero.equals(new Double(0)));
Fraction zero2 = new Fraction(0,2);
assertTrue(zero.equals(zero2));
assertEquals(zero.hashCode(), zero2.hashCode());
Fraction one = new Fraction(1,1);
assertFalse((one.equals(zero) ||zero.equals(one)));
}
public void testGetReducedFraction() {
Fraction threeFourths = new Fraction(3, 4);
assertTrue(threeFourths.equals(Fraction.getReducedFraction(6, 8)));
assertTrue(Fraction.ZERO.equals(Fraction.getReducedFraction(0, -1)));
try {
Fraction f = Fraction.getReducedFraction(1, 0);
fail("expecting ArithmeticException");
} catch (ArithmeticException ex) {
// expected
}
assertEquals(Fraction.getReducedFraction
(2, Integer.MIN_VALUE).getNumerator(),-1);
assertEquals(Fraction.getReducedFraction
(1, -1).getNumerator(), -1);
}
}

View File

@ -1,106 +1,106 @@
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<?xml-stylesheet type="text/xsl" href="./xdoc.xsl"?>
<!-- $Revision$ $Date$ -->
<document url="stat.html">
<properties>
<title>The Commons Math User Guide - Fractions</title>
</properties>
<body>
<section name="9 Fractions">
<subsection name="9.1 Overview" href="overview">
<p>
The fraction packages provides a fraction number type as well as
fraction number formatting.
</p>
</subsection>
<subsection name="9.2 Fraction Numbers" href="fraction">
<p>
<a href="../apidocs/org/apache/commons/math/fraction/Fraction.html">
org.apache.commons.math.fraction.Fraction</a> provides a fraction number
type that forms the basis for the fraction functionality found in
commons-math.
</p>
<p>
To create a fraction number, simply call the constructor passing in two
integer arguments, the first being the numerator of the fraction and the second being the denominator:
<source>Fraction f = new Fraction(1, 3); // 1 / 3</source>
</p>
<p>
Of special note with fraction construction, when a fraction is created it is always reduced to lowest terms.
</p>
<p>
The <code>Fraction</code> class provides many unary and binary
fraction operations. These operations provide the means to add,
subtract, multiple and, divide fractions along with other functions similar to the real number functions found in
<code>java.math.BigDecimal</code>:
<source>Fraction lhs = new Fraction(1, 3);
Fraction rhs = new Fraction(2, 5);
Fraction answer = lhs.add(rhs); // add two fractions
answer = lhs.subtract(rhs); // subtract two fractions
answer = lhs.abs(); // absolute value
answer = lhs.reciprocal(); // reciprocal of lhs</source>
</p>
<p>
Like fraction construction, for each of the fraction functions, the resulting fraction is reduced to lowest terms.
</p>
</subsection>
<subsection name="9.3 Fraction Formatting and Parsing" href="formatting">
<p>
<code>Fraction</code> instances can be converted to and from strings
using the<a href="../apidocs/org/apache/commons/math/fraction/FractionFormat.html">
org.apache.commons.math.fraction.FractionFormat</a> class.
<code>FractionFormat</code> is a <code>java.text.Format</code>
extension and, as such, is used like other formatting objects (e.g.
<code>java.text.SimpleDateFormat</code>):
<source>FractionFormat format = new FractionFormat(); // default format
Fraction f = new Fraction(2, 4);
String s = format.format(f); // s contains "1 / 2", note the reduced fraction</source>
</p>
<p>
To customize the formatting output, one or two
<code>java.text.NumberFormat</code> instances can be used to construct
a <code>FractionFormat</code>. These number formats control the
formatting of the numerator and denominator of the fraction:
<source>NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
// create fraction format with custom number format
// when one number format is used, both numerator and
// denominator are formatted the same
FractionFormat format = new FractionFormat(nf);
Fraction f = new Fraction(2000, 3333);
String s = format.format(c); // s contains "2.000 / 3.333"
NumberFormat nf2 = NumberFormat.getInstance(Locale.US);
// create fraction format with custom number formats
format = new FractionFormat(nf, nf2);
s = format.format(f); // s contains "2.000 / 3,333"</source>
</p>
<p>
Formatting's inverse operation, parsing, can also be performed by
<code>FractionFormat</code>. To parse a fraction from a string,
simply call the <code>parse</code> method:
<source>FractionFormat ff = new FractionFormat();
Fraction f = ff.parse("-10 / 21");</source>
</p>
</subsection>
</section>
</body>
</document>
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<?xml-stylesheet type="text/xsl" href="./xdoc.xsl"?>
<!-- $Revision$ $Date$ -->
<document url="stat.html">
<properties>
<title>The Commons Math User Guide - Fractions</title>
</properties>
<body>
<section name="9 Fractions">
<subsection name="9.1 Overview" href="overview">
<p>
The fraction packages provides a fraction number type as well as
fraction number formatting.
</p>
</subsection>
<subsection name="9.2 Fraction Numbers" href="fraction">
<p>
<a href="../apidocs/org/apache/commons/math/fraction/Fraction.html">
org.apache.commons.math.fraction.Fraction</a> provides a fraction number
type that forms the basis for the fraction functionality found in
commons-math.
</p>
<p>
To create a fraction number, simply call the constructor passing in two
integer arguments, the first being the numerator of the fraction and the second being the denominator:
<source>Fraction f = new Fraction(1, 3); // 1 / 3</source>
</p>
<p>
Of special note with fraction construction, when a fraction is created it is always reduced to lowest terms.
</p>
<p>
The <code>Fraction</code> class provides many unary and binary
fraction operations. These operations provide the means to add,
subtract, multiple and, divide fractions along with other functions similar to the real number functions found in
<code>java.math.BigDecimal</code>:
<source>Fraction lhs = new Fraction(1, 3);
Fraction rhs = new Fraction(2, 5);
Fraction answer = lhs.add(rhs); // add two fractions
answer = lhs.subtract(rhs); // subtract two fractions
answer = lhs.abs(); // absolute value
answer = lhs.reciprocal(); // reciprocal of lhs</source>
</p>
<p>
Like fraction construction, for each of the fraction functions, the resulting fraction is reduced to lowest terms.
</p>
</subsection>
<subsection name="9.3 Fraction Formatting and Parsing" href="formatting">
<p>
<code>Fraction</code> instances can be converted to and from strings
using the<a href="../apidocs/org/apache/commons/math/fraction/FractionFormat.html">
org.apache.commons.math.fraction.FractionFormat</a> class.
<code>FractionFormat</code> is a <code>java.text.Format</code>
extension and, as such, is used like other formatting objects (e.g.
<code>java.text.SimpleDateFormat</code>):
<source>FractionFormat format = new FractionFormat(); // default format
Fraction f = new Fraction(2, 4);
String s = format.format(f); // s contains "1 / 2", note the reduced fraction</source>
</p>
<p>
To customize the formatting output, one or two
<code>java.text.NumberFormat</code> instances can be used to construct
a <code>FractionFormat</code>. These number formats control the
formatting of the numerator and denominator of the fraction:
<source>NumberFormat nf = NumberFormat.getInstance(Locale.FRANCE);
// create fraction format with custom number format
// when one number format is used, both numerator and
// denominator are formatted the same
FractionFormat format = new FractionFormat(nf);
Fraction f = new Fraction(2000, 3333);
String s = format.format(c); // s contains "2.000 / 3.333"
NumberFormat nf2 = NumberFormat.getInstance(Locale.US);
// create fraction format with custom number formats
format = new FractionFormat(nf, nf2);
s = format.format(f); // s contains "2.000 / 3,333"</source>
</p>
<p>
Formatting's inverse operation, parsing, can also be performed by
<code>FractionFormat</code>. To parse a fraction from a string,
simply call the <code>parse</code> method:
<source>FractionFormat ff = new FractionFormat();
Fraction f = ff.parse("-10 / 21");</source>
</p>
</subsection>
</section>
</body>
</document>