/*
* Copyright (c) 2016 Martin Davis.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.locationtech.jts.math;
import junit.framework.TestCase;
import junit.textui.TestRunner;
/**
* Various tests involving computing known mathematical quantities
* using the basic {@link DD} arithmetic operations.
*
* @author Martin Davis
*
*/
public class DDComputeTest
extends TestCase
{
public static void main(String args[]) {
TestRunner.run(DDComputeTest.class);
}
public DDComputeTest(String name) { super(name); }
public void testEByTaylorSeries()
{
//System.out.println("--------------------------------");
//System.out.println("Computing e by Taylor series");
DD testE = computeEByTaylorSeries();
double err = Math.abs(testE.subtract(DD.E).doubleValue());
//System.out.println("Difference from DoubleDouble.E = " + err);
assertTrue(err < 64 * DD.EPS);
}
/**
* Uses Taylor series to compute e
*
* e = 1 + 1 + 1/2! + 1/3! + 1/4! + ...
*
* @return an approximation to e
*/
private DD computeEByTaylorSeries()
{
DD s = DD.valueOf(2.0);
DD t = DD.valueOf(1.0);
double n = 1.0;
int i = 0;
while (t.doubleValue() > DD.EPS) {
i++;
n += 1.0;
t = t.divide(DD.valueOf(n));
s = s.add(t);
//System.out.println(i + ": " + s);
}
return s;
}
public void testPiByMachin()
{
//System.out.println("--------------------------------");
//System.out.println("Computing Pi by Machin's rule");
DD testE = computePiByMachin();
double err = Math.abs(testE.subtract(DD.PI).doubleValue());
//System.out.println("Difference from DoubleDouble.PI = " + err);
assertTrue(err < 8 * DD.EPS);
}
/**
* Uses Machin's arctangent formula to compute Pi:
*
* Pi / 4 = 4 arctan(1/5) - arctan(1/239)
*
* @return an approximation to Pi
*/
private DD computePiByMachin()
{
DD t1 = DD.valueOf(1.0).divide(DD.valueOf(5.0));
DD t2 = DD.valueOf(1.0).divide(DD.valueOf(239.0));
DD pi4 = (DD.valueOf(4.0)
.multiply(arctan(t1)))
.subtract(arctan(t2));
DD pi = DD.valueOf(4.0).multiply(pi4);
//System.out.println("Computed value = " + pi);
return pi;
}
/**
* Computes the arctangent based on the Taylor series expansion
*
* arctan(x) = x - x^3 / 3 + x^5 / 5 - x^7 / 7 + ...
*
* @param x the argument
* @return an approximation to the arctangent of the input
*/
private DD arctan(DD x)
{
DD t = x;
DD t2 = t.sqr();
DD at = new DD(0.0);
DD two = new DD(2.0);
int k = 0;
DD d = new DD(1.0);
int sign = 1;
while (t.doubleValue() > DD.EPS) {
k++;
if (sign < 0)
at = at.subtract(t.divide(d));
else
at = at.add(t.divide(d));
d = d.add(two);
t = t.multiply(t2);
sign = -sign;
}
//System.out.println("Computed DD.atan(): " + at
// + " Math.atan = " + Math.atan(x.doubleValue()));
return at;
}
}