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:
parent
2fe2d9a4aa
commit
2b25d6352a
108
src/java/org/apache/commons/math/analysis/NevilleInterpolator.java
Executable file → Normal file
108
src/java/org/apache/commons/math/analysis/NevilleInterpolator.java
Executable file → Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
430
src/java/org/apache/commons/math/analysis/PolynomialFunctionNewtonForm.java
Executable file → Normal file
430
src/java/org/apache/commons/math/analysis/PolynomialFunctionNewtonForm.java
Executable file → Normal 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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 < <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 < 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 < 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 < <i>lower bound</i>) < <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 < <i>upper bound</i>) > <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 < <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 < 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 < 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 < <i>lower bound</i>) < <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 < <i>upper bound</i>) > <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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 < <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 < 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 < 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 < <i>lower bound</i>) < <code>p</code>
|
||||
*/
|
||||
protected double getDomainLowerBound(double p) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the domain value upper bound, based on <code>p</code>, used to
|
||||
* bracket a CDF root. This method is used by
|
||||
* {@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 < <i>upper bound</i>) > <code>p</code>
|
||||
*/
|
||||
protected double getDomainUpperBound(double p) {
|
||||
return Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the initial domain value, based on <code>p</code>, used to
|
||||
* bracket a CDF root. This method is used by
|
||||
* {@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 < <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 < 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 < 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 < <i>lower bound</i>) < <code>p</code>
|
||||
*/
|
||||
protected double getDomainLowerBound(double p) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the domain value upper bound, based on <code>p</code>, used to
|
||||
* bracket a CDF root. This method is used by
|
||||
* {@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 < <i>upper bound</i>) > <code>p</code>
|
||||
*/
|
||||
protected double getDomainUpperBound(double p) {
|
||||
return Double.MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the initial domain value, based on <code>p</code>, used to
|
||||
* bracket a CDF root. This method is used by
|
||||
* {@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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
276
src/test/org/apache/commons/math/analysis/DividedDifferenceInterpolatorTest.java
Executable file → Normal file
276
src/test/org/apache/commons/math/analysis/DividedDifferenceInterpolatorTest.java
Executable file → Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
276
src/test/org/apache/commons/math/analysis/NevilleInterpolatorTest.java
Executable file → Normal file
276
src/test/org/apache/commons/math/analysis/NevilleInterpolatorTest.java
Executable file → Normal 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;
|
||||
}
|
||||
}
|
||||
|
|
300
src/test/org/apache/commons/math/analysis/PolynomialFunctionLagrangeFormTest.java
Executable file → Normal file
300
src/test/org/apache/commons/math/analysis/PolynomialFunctionLagrangeFormTest.java
Executable file → Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
298
src/test/org/apache/commons/math/analysis/PolynomialFunctionNewtonFormTest.java
Executable file → Normal file
298
src/test/org/apache/commons/math/analysis/PolynomialFunctionNewtonFormTest.java
Executable file → Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue