/// <summary> /// This routine simply tests for robustness of the ToString function. /// </summary> private static void WriteRepeatedSqrt(DD xdd) { int count = 0; while (xdd.ToDoubleValue() > 1e-300) { count++; // if (count == 100) // count = count; double x = xdd.ToDoubleValue(); var xSqrt = xdd.Sqrt(); string s = xSqrt.ToString(); // System.Console.WriteLine((count + ": " + s); var xSqrt2 = DD.Parse(s); var xx = xSqrt2.Multiply(xSqrt2); double err = Math.Abs(xx.ToDoubleValue() - x); // assertTrue(err < 1e-10); xdd = xSqrt; // square roots converge on 1 - stop when very close var distFrom1DD = xSqrt.Subtract(DD.ValueOf(1.0)); double distFrom1 = distFrom1DD.ToDoubleValue(); if (Math.Abs(distFrom1) < 1.0e-40) { break; } } }
/// <summary> /// Tests if a point is inside the circle defined by /// the triangle with vertices a, b, c (oriented counter-clockwise). /// </summary> /// <remarks> /// The computation uses <see cref="DD"/> arithmetic for robustness. /// </remarks> /// <param name="a">A vertex of the triangle</param> /// <param name="b">A vertex of the triangle</param> /// <param name="c">A vertex of the triangle</param> /// <param name="p">The point to test</param> /// <returns>true if this point is inside the circle defined by the points a, b, c</returns> public static bool IsInCircleDDSlow( Coordinate a, Coordinate b, Coordinate c, Coordinate p) { DD px = DD.ValueOf(p.X); DD py = DD.ValueOf(p.Y); DD ax = DD.ValueOf(a.X); DD ay = DD.ValueOf(a.Y); DD bx = DD.ValueOf(b.X); DD by = DD.ValueOf(b.Y); DD cx = DD.ValueOf(c.X); DD cy = DD.ValueOf(c.Y); DD aTerm = (ax.Multiply(ax).Add(ay.Multiply(ay))) .Multiply(TriAreaDDSlow(bx, by, cx, cy, px, py)); DD bTerm = (bx.Multiply(bx).Add(by.Multiply(by))) .Multiply(TriAreaDDSlow(ax, ay, cx, cy, px, py)); DD cTerm = (cx.Multiply(cx).Add(cy.Multiply(cy))) .Multiply(TriAreaDDSlow(ax, ay, bx, by, px, py)); DD pTerm = (px.Multiply(px).Add(py.Multiply(py))) .Multiply(TriAreaDDSlow(ax, ay, bx, by, cx, cy)); DD sum = aTerm.Subtract(bTerm).Add(cTerm).Subtract(pTerm); bool isInCircle = sum.ToDoubleValue() > 0; return(isInCircle); }
private static void CheckErrorBound(String tag, DD x, DD y, double errBound) { DD err = x.Subtract(y).Abs(); Console.WriteLine(tag + " err=" + err); var isWithinEps = err.ToDoubleValue() <= errBound; Assert.True(isWithinEps); }
private static void CheckParse(String str, DD expectedVal, double relErrBound) { DD xdd = DD.Parse(str); double err = xdd.Subtract(expectedVal).ToDoubleValue(); double relErr = err / xdd.ToDoubleValue(); Console.WriteLine("Parsed= " + xdd + " rel err= " + relErr); Assert.IsTrue(err <= relErrBound); }
/// <summary> /// This routine simply tests for robustness of the toString function. /// </summary> static void WriteRepeatedSqr(DD xdd) { if (xdd.GreaterOrEqualThan(DD.ValueOf(1))) { throw new ArgumentException("Argument must be < 1"); } int count = 0; while (xdd.ToDoubleValue() > 1e-300) { count++; double x = xdd.ToDoubleValue(); var xSqr = xdd.Sqr(); string s = xSqr.ToString(); // System.Console.WriteLine(count + ": " + s); var xSqr2 = DD.Parse(s); xdd = xSqr; } }
/// <summary> /// Tests if a point is inside the circle defined by /// the triangle with vertices a, b, c (oriented counter-clockwise). /// </summary> /// <remarks> /// The computation uses <see cref="DD"/> arithmetic for robustness, but a faster approach. /// </remarks> /// <param name="a">A vertex of the triangle</param> /// <param name="b">A vertex of the triangle</param> /// <param name="c">A vertex of the triangle</param> /// <param name="p">The point to test</param> /// <returns>true if this point is inside the circle defined by the points a, b, c</returns> public static bool IsInCircleDDFast( Coordinate a, Coordinate b, Coordinate c, Coordinate p) { DD aTerm = (DD.Sqr(a.X) + DD.Sqr(a.Y)) * TriAreaDDFast(b, c, p); DD bTerm = (DD.Sqr(b.X) + DD.Sqr(b.Y)) * TriAreaDDFast(a, c, p); DD cTerm = (DD.Sqr(c.X) + DD.Sqr(c.Y)) * TriAreaDDFast(a, b, p); DD pTerm = (DD.Sqr(p.X) + DD.Sqr(p.Y)) * TriAreaDDFast(a, b, c); DD sum = aTerm - bTerm + cTerm - pTerm; bool isInCircle = sum.ToDoubleValue() > 0; return(isInCircle); }
/// <summary> /// Tests that printing values with many decimal places works. /// This tests the correctness and robustness of both output and input. /// </summary> static void WriteAndReadSqrt(double x) { DD xdd = DD.ValueOf(x); DD xSqrt = xdd.Sqrt(); String s = xSqrt.ToString(); // System.out.println(s); DD xSqrt2 = DD.Parse(s); DD xx = xSqrt2 * xSqrt2; String xxStr = xx.ToString(); // System.out.println("==> " + xxStr); DD xx2 = DD.Parse(xxStr); double err = Math.Abs(xx2.ToDoubleValue() - x); Assert.IsTrue(err < 1e-10); }
/// <summary> /// Computes the arctangent based on the Taylor series expansion /// <para/> /// arctan(x) = x - x^3 / 3 + x^5 / 5 - x^7 / 7 + ... /// </summary> /// <param name="x">The argument</param> /// <returns>An approximation to the arctangent of the input</returns> private static DD ArcTan(DD x) { var t = x; var t2 = t.Sqr(); var at = new DD(0.0); var two = new DD(2.0); var k = 0; var d = new DD(1.0); var sign = 1; while (t.ToDoubleValue() > DD.Epsilon) { k++; at = sign < 0 ? at.Subtract(t.Divide(d)) : at.Add(t.Divide(d)); d = d.Add(two); t = t.Multiply(t2); sign = -sign; } Console.WriteLine("Computed DD.atan(): " + at + " Math.atan = " + Math.Atan(x.ToDoubleValue())); return(at); }
/// <summary> /// /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="c"></param> /// <param name="p"></param> /// <returns></returns> public static bool IsInCircleDDNormalized( Coordinate a, Coordinate b, Coordinate c, Coordinate p) { DD adx = DD.ValueOf(a.X) - p.X; DD ady = DD.ValueOf(a.Y) - p.Y; DD bdx = DD.ValueOf(b.X) - p.X; DD bdy = DD.ValueOf(b.Y) - p.Y; DD cdx = DD.ValueOf(c.X) - p.X; DD cdy = DD.ValueOf(c.Y) - p.Y; DD abdet = adx * bdy - bdx * ady; DD bcdet = bdx * cdy - cdx * bdy; DD cadet = cdx * ady - adx * cdy; DD alift = adx * adx + ady * ady; DD blift = bdx * bdx + bdy * bdy; DD clift = cdx * cdx + cdy * cdy; DD sum = alift * bcdet + blift * cadet + clift * abdet; bool isInCircle = sum.ToDoubleValue() > 0; return(isInCircle); }
/// <summary> /// Tests if a point is inside the circle defined by the points a, b, c. /// The computation uses <see cref="NetTopologySuite.Mathematics.DD"/> arithmetic for robustness. /// </summary> /// <param name="a">A vertex of the triangle</param> /// <param name="b">A vertex of the triangle</param> /// <param name="c">A vertex of the triangle</param> /// <param name="p">The point to test</param> /// <returns><value>true</value> if this point is inside the circle defined by the points a, b, c</returns> public static bool IsInCircleDD3( Coordinate a, Coordinate b, Coordinate c, Coordinate p) { DD adx = DD.ValueOf(a.X) - (p.X); DD ady = DD.ValueOf(a.Y) - (p.Y); DD bdx = DD.ValueOf(b.X) - (p.X); DD bdy = DD.ValueOf(b.Y) - (p.Y); DD cdx = DD.ValueOf(c.X) - (p.X); DD cdy = DD.ValueOf(c.Y) - (p.Y); DD abdet = adx * bdy - (bdx * ady); DD bcdet = bdx * cdy - (cdx * bdy); DD cadet = cdx * ady - (adx * cdy); DD alift = adx * adx - (ady * ady); DD blift = bdx * bdx - (bdy * bdy); DD clift = cdx * cdx - (cdy * cdy); DD sum = alift * bcdet + blift * cadet + clift * abdet; var isInCircle = sum.ToDoubleValue() > 0; return(isInCircle); }
/// <summary> /// Computes the arctangent based on the Taylor series expansion /// <para/> /// arctan(x) = x - x^3 / 3 + x^5 / 5 - x^7 / 7 + ... /// </summary> /// <param name="x">The argument</param> /// <returns>An approximation to the arctangent of the input</returns> private static DD ArcTan(DD x) { var t = x; var t2 = t.Sqr(); var at = new DD(0.0); var two = new DD(2.0); var k = 0; var d = new DD(1.0); var sign = 1; while (t.ToDoubleValue() > DD.Epsilon) { k++; at = sign < 0 ? at.Subtract(t.Divide(d)) : at.Add(t.Divide(d)); d = d.Add(two); t = t.Multiply(t2); sign = -sign; } Console.WriteLine("Computed DD.atan(): " + at + " Math.atan = " + Math.Atan(x.ToDoubleValue())); return at; }
/** * This routine simply tests for robustness of the toString function. * * @param xdd */ static void WriteRepeatedSqr(DD xdd) { if (xdd.GreaterOrEqualThan(DD.ValueOf(1))) throw new ArgumentException("Argument must be < 1"); int count = 0; while (xdd.ToDoubleValue() > 1e-300) { count++; double x = xdd.ToDoubleValue(); DD xSqr = xdd.Sqr(); String s = xSqr.ToString(); Console.WriteLine(count + ": " + s); DD xSqr2 = DD.Parse(s); xdd = xSqr; } }
/** * This routine simply tests for robustness of the toString function. * * @param xdd */ private static void WriteRepeatedSqrt(DD xdd) { int count = 0; while (xdd.ToDoubleValue() > 1e-300) { count++; //if (count == 100) // count = count; double x = xdd.ToDoubleValue(); DD xSqrt = xdd.Sqrt(); String s = xSqrt.ToString(); // System.out.println(count + ": " + s); DD xSqrt2 = DD.Parse(s); DD xx = xSqrt2.Multiply(xSqrt2); double err = Math.Abs(xx.ToDoubleValue() - x); //assertTrue(err < 1e-10); xdd = xSqrt; // square roots converge on 1 - stop when very close DD distFrom1DD = xSqrt.Subtract(DD.ValueOf(1.0)); double distFrom1 = distFrom1DD.ToDoubleValue(); if (Math.Abs(distFrom1) < 1.0e-40) break; } }