Applied Brent Wardens Bug fixes to Complex implementation and tests.

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@141022 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Dirk Verbeeck 2003-11-15 18:52:31 +00:00
parent d916ecceb2
commit 8864381a96
6 changed files with 399 additions and 42 deletions

View File

@ -62,7 +62,7 @@ import org.apache.commons.math.util.MathUtils;
* Reference:
* http://myweb.lmu.edu/dmsmith/ZMLIB.pdf
*
* @version $Revision: 1.3 $ $Date: 2003/11/14 22:22:22 $
* @version $Revision: 1.4 $ $Date: 2003/11/15 18:52:31 $
*/
public class ComplexMath {
@ -105,9 +105,10 @@ public class ComplexMath {
return Complex.NaN;
}
return Complex.I.multiply(
log(Complex.I.add(z).divide(Complex.I.subtract(z))))
.multiply(new Complex(2.0, 0.0));
.divide(new Complex(2.0, 0.0));
}
/**
@ -219,8 +220,8 @@ public class ComplexMath {
if (a >= 0.0) {
return new Complex(t, b / (2.0 * t));
} else {
double s = (b > 0.0 ? 1.0 : (b < 0.0 ? -1.0 : 0.0));
return new Complex(Math.abs(z.getImaginary()) / (2.0 * t), s * t);
return new Complex(Math.abs(z.getImaginary()) / (2.0 * t),
MathUtils.sign(b) * t);
}
}
@ -244,7 +245,7 @@ public class ComplexMath {
double b2 = 2.0 * z.getImaginary();
double d = Math.cos(a2) + MathUtils.cosh(b2);
return new Complex(Math.sin(a2) / d, MathUtils.sinh(b2) / 2);
return new Complex(Math.sin(a2) / d, MathUtils.sinh(b2) / d);
}
/**
@ -259,6 +260,6 @@ public class ComplexMath {
double b2 = 2.0 * z.getImaginary();
double d = MathUtils.cosh(a2) + Math.cos(b2);
return new Complex(MathUtils.sinh(a2) / d, Math.sin(b2) / 2);
return new Complex(MathUtils.sinh(a2) / d, Math.sin(b2) / d);
}
}

View File

@ -58,6 +58,7 @@ import org.apache.commons.math.stat.univariate.moment.Mean;
import org.apache.commons.math.stat.univariate.moment.Variance;
import org.apache.commons.math.stat.univariate.rank.Max;
import org.apache.commons.math.stat.univariate.rank.Min;
import org.apache.commons.math.stat.univariate.rank.Percentile;
import org.apache.commons.math.stat.univariate.summary.Product;
import org.apache.commons.math.stat.univariate.summary.Sum;
import org.apache.commons.math.stat.univariate.summary.SumOfLogs;
@ -67,34 +68,37 @@ import org.apache.commons.math.stat.univariate.summary.SumOfSquares;
* StatUtils provides easy static implementations of common double[] based
* statistical methods. These return a single result value or in some cases, as
* identified in the javadoc for each method, Double.NaN.
* @version $Revision: 1.21 $ $Date: 2003/11/14 22:22:18 $
* @version $Revision: 1.22 $ $Date: 2003/11/15 18:52:31 $
*/
public final class StatUtils {
/** sum */
private static UnivariateStatistic sum = new Sum();
/** sumSq */
private static UnivariateStatistic sumSq = new SumOfSquares();
/** prod */
private static UnivariateStatistic prod = new Product();
/** sumLog */
private static UnivariateStatistic sumLog = new SumOfLogs();
/** min */
private static UnivariateStatistic min = new Min();
/** max */
private static UnivariateStatistic max = new Max();
/** mean */
private static UnivariateStatistic mean = new Mean();
/** variance */
private static UnivariateStatistic variance = new Variance();
/** sum */
private static UnivariateStatistic sum = new Sum();
/** sumSq */
private static UnivariateStatistic sumSq = new SumOfSquares();
/** prod */
private static UnivariateStatistic prod = new Product();
/** sumLog */
private static UnivariateStatistic sumLog = new SumOfLogs();
/** min */
private static UnivariateStatistic min = new Min();
/** max */
private static UnivariateStatistic max = new Max();
/** mean */
private static UnivariateStatistic mean = new Mean();
/** variance */
private static UnivariateStatistic variance = new Variance();
/** variance */
private static Percentile percentile = new Percentile();
/**
* Private Constructor
*/
@ -107,7 +111,7 @@ public final class StatUtils {
* @return the sum of the values or Double.NaN if the array is empty
*/
public static double sum(final double[] values) {
return sum.evaluate(values);
return sum.evaluate(values);
}
/**
@ -130,7 +134,7 @@ public final class StatUtils {
* @return the sum of the squared values or Double.NaN if the array is empty
*/
public static double sumSq(final double[] values) {
return sumSq.evaluate(values);
return sumSq.evaluate(values);
}
/**
@ -176,7 +180,7 @@ public final class StatUtils {
* @return the sumLog value or Double.NaN if the array is empty
*/
public static double sumLog(final double[] values) {
return sumLog.evaluate(values);
return sumLog.evaluate(values);
}
/**
@ -190,7 +194,7 @@ public final class StatUtils {
final double[] values,
final int begin,
final int length) {
return sumLog.evaluate(values, begin, length);
return sumLog.evaluate(values, begin, length);
}
/**
@ -200,7 +204,7 @@ public final class StatUtils {
* @return the mean of the values or Double.NaN if the array is empty
*/
public static double mean(final double[] values) {
return mean.evaluate(values);
return mean.evaluate(values);
}
/**
@ -232,7 +236,7 @@ public final class StatUtils {
* or 0.0 for a single value set.
*/
public static double variance(final double[] values) {
return variance.evaluate(values);
return variance.evaluate(values);
}
/**
@ -263,7 +267,7 @@ public final class StatUtils {
* @return the maximum of the values or Double.NaN if the array is empty
*/
public static double max(final double[] values) {
return max.evaluate(values);
return max.evaluate(values);
}
/**
@ -286,7 +290,7 @@ public final class StatUtils {
* @return the minimum of the values or Double.NaN if the array is empty
*/
public static double min(final double[] values) {
return min.evaluate(values);
return min.evaluate(values);
}
/**
@ -302,5 +306,52 @@ public final class StatUtils {
final int length) {
return min.evaluate(values, begin, length);
}
/**
* Returns an estimate for the pth percentile of the stored values.
* This estimate follows the interpolation-adjusted defintion presented
* <a href="http://www.utdallas.edu/~ammann/stat5311/node8.html">here</a>
* <p/>
* <strong>Preconditions</strong>:<ul>
* <li><code>0 &lt; p &lt; 100</code> (otherwise an
* <code>IllegalArgumentException</code> is thrown)</li>
* <li>at least one value must be stored (returns <code>Double.NaN
* </code> otherwise)</li>
* </ul>
*
* @param values Is a double[] containing the values
* @param p the requested percentile (scaled from 0 - 100)
* @return An estimate for the pth percentile of the data values
*/
public static double percentile(final double[] values, final double p) {
return percentile.evaluate(values,p);
}
/**
* Returns an estimate for the pth percentile of the stored values.
* This estimate follows the interpolation-adjusted defintion presented
* <a href="http://www.utdallas.edu/~ammann/stat5311/node8.html">here</a>
* <p/>
* <strong>Preconditions</strong>:<ul>
* <li><code>0 &lt; p &lt; 100</code> (otherwise an
* <code>IllegalArgumentException</code> is thrown)</li>
* <li>at least one value must be stored (returns <code>Double.NaN
* </code> otherwise)</li>
* </ul>
*
* @param values Is a double[] containing the values
* @param begin processing at this point in the array
* @param length processing at this point in the array
* @param p the requested percentile (scaled from 0 - 100)
* @return An estimate for the pth percentile of the data values
*/
public static double percentile(
final double[] values,
final int begin,
final int length,
final double p) {
return percentile.evaluate(values, begin, length, p);
}
}

View File

@ -54,10 +54,12 @@
package org.apache.commons.math;
import org.apache.commons.math.complex.Complex;
import junit.framework.Assert;
/**
* @version $Revision: 1.6 $ $Date: 2003/11/14 22:22:23 $
* @version $Revision: 1.7 $ $Date: 2003/11/15 18:52:31 $
*/
public class TestUtils {
/**
@ -75,4 +77,12 @@ public class TestUtils {
Assert.assertEquals(expected, actual, delta);
}
}
/**
*
*/
public static void assertEquals(Complex expected, Complex actual, double delta) {
assertEquals(expected.getReal(), actual.getReal(), delta);
assertEquals(expected.getImaginary(), actual.getImaginary(), delta);
}
}

View File

@ -0,0 +1,236 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowledgement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgement may appear in the software itself,
* if and wherever such third-party acknowledgements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their name without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.math.complex;
import org.apache.commons.math.TestUtils;
import junit.framework.TestCase;
/**
* @version $Revision: 1.1 $ $Date: 2003/11/15 18:52:31 $
*/
public class ComplexMathTest extends TestCase {
public void testAcos() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(0.936812, -2.30551);
TestUtils.assertEquals(expected, ComplexMath.acos(z), 1.0e-5);
}
public void testAcosNaN() {
assertTrue(ComplexMath.acos(Complex.NaN).isNaN());
}
public void testAsin() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(0.633984, 2.30551);
TestUtils.assertEquals(expected, ComplexMath.asin(z), 1.0e-5);
}
public void testAsinNaN() {
assertTrue(ComplexMath.asin(Complex.NaN).isNaN());
}
public void testAtan() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(1.44831, 0.158997);
TestUtils.assertEquals(expected, ComplexMath.atan(z), 1.0e-5);
}
public void testAtanNaN() {
assertTrue(ComplexMath.atan(Complex.NaN).isNaN());
}
public void testCos() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(-27.03495, -3.851153);
TestUtils.assertEquals(expected, ComplexMath.cos(z), 1.0e-5);
}
public void testCosh() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(-6.58066, -7.58155);
TestUtils.assertEquals(expected, ComplexMath.cosh(z), 1.0e-5);
}
public void testCoshNaN() {
assertTrue(ComplexMath.cosh(Complex.NaN).isNaN());
}
public void testCosNaN() {
assertTrue(ComplexMath.cos(Complex.NaN).isNaN());
}
public void testExp() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(-13.12878, -15.20078);
TestUtils.assertEquals(expected, ComplexMath.exp(z), 1.0e-5);
}
public void testExpNaN() {
assertTrue(ComplexMath.exp(Complex.NaN).isNaN());
}
public void testLog() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(1.60944, 0.927295);
TestUtils.assertEquals(expected, ComplexMath.log(z), 1.0e-5);
}
public void testLogNaN() {
assertTrue(ComplexMath.log(Complex.NaN).isNaN());
}
public void testPow() {
Complex x = new Complex(3, 4);
Complex y = new Complex(5, 6);
Complex expected = new Complex(-1.860893, 11.83677);
TestUtils.assertEquals(expected, ComplexMath.pow(x, y), 1.0e-5);
}
public void testPowNaNBase() {
Complex x = new Complex(3, 4);
assertTrue(ComplexMath.pow(Complex.NaN, x).isNaN());
}
public void testPowNaNExponent() {
Complex x = new Complex(3, 4);
assertTrue(ComplexMath.pow(x, Complex.NaN).isNaN());
}
public void testSin() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(3.853738, -27.01681);
TestUtils.assertEquals(expected, ComplexMath.sin(z), 1.0e-5);
}
public void testSinh() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(-6.54812, -7.61923);
TestUtils.assertEquals(expected, ComplexMath.sinh(z), 1.0e-5);
}
public void testSinhNaN() {
assertTrue(ComplexMath.sinh(Complex.NaN).isNaN());
}
public void testSinNaN() {
assertTrue(ComplexMath.sin(Complex.NaN).isNaN());
}
public void testSqrtRealPositive() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(2, 1);
TestUtils.assertEquals(expected, ComplexMath.sqrt(z), 1.0e-5);
}
public void testSqrtRealZero() {
Complex z = new Complex(0.0, 4);
Complex expected = new Complex(1.41421, 1.41421);
TestUtils.assertEquals(expected, ComplexMath.sqrt(z), 1.0e-5);
}
public void testSqrtRealNegative() {
Complex z = new Complex(-3.0, 4);
Complex expected = new Complex(1, 2);
TestUtils.assertEquals(expected, ComplexMath.sqrt(z), 1.0e-5);
}
public void testSqrtImaginaryZero() {
Complex z = new Complex(-3.0, 0.0);
Complex expected = new Complex(0.0, 1.73205);
TestUtils.assertEquals(expected, ComplexMath.sqrt(z), 1.0e-5);
}
public void testSqrtImaginaryNegative() {
Complex z = new Complex(-3.0, -4.0);
Complex expected = new Complex(1.0, -2.0);
TestUtils.assertEquals(expected, ComplexMath.sqrt(z), 1.0e-5);
}
public void testSqrt1z() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(4.08033, -2.94094);
TestUtils.assertEquals(expected, ComplexMath.sqrt1z(z), 1.0e-5);
}
public void testSqrt1zNaN() {
assertTrue(ComplexMath.sqrt1z(Complex.NaN).isNaN());
}
public void testSqrtNaN() {
assertTrue(ComplexMath.sqrt(Complex.NaN).isNaN());
}
public void testTan() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(-0.000187346, 0.999356);
TestUtils.assertEquals(expected, ComplexMath.tan(z), 1.0e-5);
}
public void testTanh() {
Complex z = new Complex(3, 4);
Complex expected = new Complex(1.00071, 0.00490826);
TestUtils.assertEquals(expected, ComplexMath.tanh(z), 1.0e-5);
}
public void testTanhNaN() {
assertTrue(ComplexMath.tanh(Complex.NaN).isNaN());
}
public void testTanNaN() {
assertTrue(ComplexMath.tan(Complex.NaN).isNaN());
}
}

View File

@ -59,7 +59,7 @@ package org.apache.commons.math.complex;
import junit.framework.TestCase;
/**
* @version $Revision: 1.3 $ $Date: 2003/11/14 22:22:24 $
* @version $Revision: 1.4 $ $Date: 2003/11/15 18:52:31 $
*/
public class ComplexTest extends TestCase {
@ -85,6 +85,10 @@ public class ComplexTest extends TestCase {
assertEquals(5.0, z.abs(), 1.0e-5);
}
public void testAbsNaN() {
assertTrue(Double.isNaN(Complex.NaN.abs()));
}
public void testAdd() {
Complex x = new Complex(3.0, 4.0);
Complex y = new Complex(5.0, 6.0);
@ -164,4 +168,37 @@ public class ComplexTest extends TestCase {
Complex z = x.subtract(Complex.NaN);
assertTrue(z.isNaN());
}
public void testEqualsNull() {
Complex x = new Complex(3.0, 4.0);
assertFalse(x.equals(null));
}
public void testEqualsClass() {
Complex x = new Complex(3.0, 4.0);
assertFalse(x.equals(this));
}
public void testEqualsSame() {
Complex x = new Complex(3.0, 4.0);
assertTrue(x.equals(x));
}
public void testEqualsTrue() {
Complex x = new Complex(3.0, 4.0);
Complex y = new Complex(3.0, 4.0);
assertTrue(x.equals(y));
}
public void testEqualsRealDifference() {
Complex x = new Complex(0.0, 0.0);
Complex y = new Complex(0.0 + Double.MIN_VALUE, 0.0);
assertFalse(x.equals(y));
}
public void testEqualsImaginaryDifference() {
Complex x = new Complex(0.0, 0.0);
Complex y = new Complex(0.0, 0.0 + Double.MIN_VALUE);
assertFalse(x.equals(y));
}
}

View File

@ -53,6 +53,8 @@
*/
package org.apache.commons.math.util;
import org.apache.commons.math.TestUtils;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
@ -60,7 +62,7 @@ import junit.framework.TestSuite;
/**
* Test cases for the MathUtils class.
*
* @version $Revision: 1.6 $ $Date: 2003/11/14 22:22:23 $
* @version $Revision: 1.7 $ $Date: 2003/11/15 18:52:31 $
*/
public final class MathUtilsTest extends TestCase {
@ -349,4 +351,24 @@ public final class MathUtilsTest extends TestCase {
assertEquals( 1L, MathUtils.sign( 2L ) ) ;
assertEquals( -1L, MathUtils.sign( -2L ) ) ;
}
public void testCosh() {
double x = 3.0;
double expected = 10.06766;
assertEquals(expected, MathUtils.cosh(x), 1.0e-5);
}
public void testSinh() {
double x = 3.0;
double expected = 10.01787;
assertEquals(expected, MathUtils.sinh(x), 1.0e-5);
}
public void testCoshNaN() {
assertTrue(Double.isNaN(MathUtils.cosh(Double.NaN)));
}
public void testSinhNaN() {
assertTrue(Double.isNaN(MathUtils.sinh(Double.NaN)));
}
}