From 38e342a700c4b833e404e54131284881a2d8bdcd Mon Sep 17 00:00:00 2001 From: Martin Goik <goik@hdm-stuttgart.de> Date: Mon, 13 Apr 2015 23:06:55 +0200 Subject: [PATCH] loop.xml --> objectsClasses.xml --- Doc/Sd1/objectsClasses.xml | 2468 ++++++++++++++++++++++++++++++++++++ P/Sd1/Gcd/V1/pom.xml | 1 - 2 files changed, 2468 insertions(+), 1 deletion(-) diff --git a/Doc/Sd1/objectsClasses.xml b/Doc/Sd1/objectsClasses.xml index c81798f2e..a1cb61f7f 100644 --- a/Doc/Sd1/objectsClasses.xml +++ b/Doc/Sd1/objectsClasses.xml @@ -1619,6 +1619,122 @@ Is 2016 a leap year? true</programlisting> </qandaset> </section> + <section xml:id="sd1MathTable"> + <title>A mathematical table.</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaSinTable"> + <title>Nicely formatting sine values.</title> + + <qandadiv> + <qandaentry> + <question> + <para>We are interested in the following output presenting the + sine function rounded to three decimal places:</para> + + <programlisting language="ignore"> x | sin(x) +----+------ + 0 | 0.000 + 5 | 0.087 + 10 | 0.174 + 15 | 0.259 + 20 | 0.342 +----+------- + 25 | 0.423 + 30 | 0.500 + 35 | 0.574 + 40 | 0.643 +----+------- +... (left out for brevity's sake) +----+------- +325 |-0.574 +330 |-0.500 +335 |-0.423 +340 |-0.342 +----+------- +345 |-0.259 +350 |-0.174 +355 |-0.087</programlisting> + + <para>You may also generate HTML output.</para> + + <para>Write a corresponding Java application producing this + output. You will have to deal with alignment problems, leading + spaces, padding zeros and so on. Though more sophisticated + support exists the following hints will fully suffice:</para> + + <orderedlist> + <listitem> + <para>Consider the <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#sin-double-">sin(...)</link> + function. The documentation will tell you that the argument + to sin(...) is expected to be in radians rather than common + degree values from [0,360[ being expected on output. So you + will have to transform degree values to radians.</para> + </listitem> + + <listitem> + <para>Depending on the angle's value you may want to add one + or two leading spaces to keep the first column right + aligned.</para> + </listitem> + + <listitem> + <para>Depending on the sign you may want to add leading + spaces to the second column.</para> + </listitem> + + <listitem> + <para>Rounding the sine's value is the crucial part here. + The function <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#round-double-">round()</link> + is quite helpful. Consider the following example rounding + 23.22365 to four decimal places:</para> + + <orderedlist> + <listitem> + <para>Multiplication by 10000 results in 232236.5</para> + </listitem> + + <listitem> + <para><link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#round-double-">round(232236.5)</link> + results in 232237 (long).</para> + </listitem> + + <listitem> + <para>Integer division by 10000 yields 23</para> + </listitem> + + <listitem> + <para>The remainder (by 10000) is 2237</para> + </listitem> + + <listitem> + <para>So you may print 23.2237 this way</para> + </listitem> + </orderedlist> + </listitem> + + <listitem> + <para>You'll need padding zero values to transform e.g. + <quote>0.4</quote> to <quote>0.400</quote>.</para> + </listitem> + </orderedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/rounding</para> + </annotation> + + <para>See <link + xlink:href="Ref/api/P/rounding/de/hdm_stuttgart/de/sd1/rounding/MathTable.html">MathTable</link>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + <section xml:id="sd1InterestCalculator"> <title>Interest calculations</title> @@ -1984,5 +2100,2357 @@ long sum = (long)a + b;</programlisting> </qandaset> </section> </section> + + <section xml:id="sd1Gcd"> + <title>The greatest common divisor and the common multiple</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaGcd"> + <title>Finding the greatest common divisor of two integer + values</title> + + <qandadiv> + <qandaentry> + <question> + <para>We recall <xref linkend="sde1QandaFraction"/>. So far no + one demands reducing fractions. Yet calling <code>new + Fraction(4,8)</code> will create an instance internally being + represented by <inlineequation> + <m:math display="inline"> + <m:mfrac> + <m:mi>4</m:mi> + + <m:mi>8</m:mi> + </m:mfrac> + </m:math> + </inlineequation> rather than by <inlineequation> + <m:math display="inline"> + <m:mfrac> + <m:mi>1</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:math> + </inlineequation>.</para> + + <para>Reducing fractions requires implementing e.g. the <link + xlink:href="http://www.math.rutgers.edu/~greenfie/gs2004/euclid.html">Euclidean + algorithm</link> in order to find the greatest common divisor + (<acronym>GCD</acronym>) of two non-zero integer values.</para> + + <para>Read the above link and implement a private class method + getGcd(long, long) inside a class + <classname>Math</classname>:</para> + + <programlisting language="java"> public static long getGcd(long a, long b) <co + xml:id="sd1ListEuclidNeg"/> { + // Following http://www.math.rutgers.edu/~greenfie/gs2004/euclid.html + return ??; + }</programlisting> + + <para>With respect to fractions one or both parameters + <code>a</code> and <code>b</code> <coref + linkend="sd1ListEuclidNeg"/> may zero or negative. So we do have + several special cases to handle:</para> + + <glosslist> + <glossentry> + <glossterm>a == 0 and b == 0</glossterm> + + <glossdef> + <para>Return 1.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>a == 0 and b != 0</glossterm> + + <glossdef> + <para>Return absolute value of b.</para> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>a != 0 and b != 0</glossterm> + + <glossdef> + <para>Return the <acronym>gcd</acronym> of the absolute + values of a and b</para> + </glossdef> + </glossentry> + </glosslist> + + <para>Based on <methodname>getGcd(...)</methodname> implement + the common multiple of two long values:</para> + + <tip> + <para>Follow the test driven approach: Provide dummy methods + and write tests prior to implementation of + <methodname>getGcd()</methodname>.</para> + </tip> + + <programlisting language="java">public static long getCommonMultiple(long a, long b) {...}</programlisting> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/Gcd/V1</para> + </annotation> + + <para>Implementing <methodname + xlink:href="Ref/api/P/Gcd/V1/de/hdm_stuttgart/mi/sd1/gcd/Math.html#getGcd-long-long-">getGcd(</methodname>...):</para> + + <programlisting language="java"> public static long <link + xlink:href="Ref/api/P/Gcd/V1/de/hdm_stuttgart/mi/sd1/gcd/Math.html#getCommonMultiple-long-long-">getGcd(long a, long b)</link> { + + // Following http://www.math.rutgers.edu/~greenfie/gs2004/euclid.html + if (a < b) { // Swap the values of a and b + long tmp = a; + a = b; + b = tmp; + } + while (0 != b) { + long r = a % b; + a = b; + b = r; + } + return a; + }</programlisting> + + <para>Knowing the the <acronym>gcd</acronym> of two values a and + b the common multiple may be obtained by <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mfrac> + <m:mi>a</m:mi> + + <m:mi>gcd</m:mi> + </m:mfrac> + + <m:mo></m:mo> + + <m:mfrac> + <m:mi>b</m:mi> + + <m:mi>gcd</m:mi> + </m:mfrac> + + <m:mo></m:mo> + + <m:mi>gcd</m:mi> + + <m:mo>=</m:mo> + + <m:mfrac> + <m:mrow> + <m:mi>a</m:mi> + + <m:mo></m:mo> + + <m:mi>b</m:mi> + </m:mrow> + + <m:mi>gcd</m:mi> + </m:mfrac> + </m:mrow> + </m:math> + </inlineequation>. Thus we have:</para> + + <programlisting language="java"> public static long <link + xlink:href="Ref/api/P/Gcd/V1/de/hdm_stuttgart/mi/sd1/gcd/Math.html#getGcd-long-long-">getCommonMultiple(long a, long b)</link> { + final long gcd = getGcd(a, b); + if (1 == gcd) { + return a * b; + } else { + return (a / gcd) * b; + } + }</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="ed1FractionCancel"> + <title>Reducing fractions</title> + + <para>The following exercise requires the import of the previous Maven + based exercise <xref linkend="sd1QandaGcd"/>. The import may be effected + by:</para> + + <orderedlist> + <listitem> + <para>Creating a local Maven jar archive export by executing + <quote><command>mvn</command> <option>install</option></quote> in + project <xref linkend="sd1QandaGcd"/> at the command line. + Alternatively you may right click on your <xref + linkend="glo_pom.xml"/> file in <xref linkend="glo_Eclipse"/> + hitting <quote>Run as Maven build</quote> using + <parameter>install</parameter> as goal.</para> + </listitem> + + <listitem> + <para>Defining <xref linkend="sd1QandaGcd"/> as a dependency <coref + linkend="mvnGcdDep"/> in your current project:</para> + + <programlisting language="none"><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>de.hdm-stuttgart.de.sd1</groupId> + <artifactId>fraction</artifactId> + <version>1.0</version> + <packaging>jar</packaging> + + <name>fraction</name> + ... + <dependencies> + <emphasis role="bold"><dependency></emphasis> <co xml:id="mvnGcdDep"/> + <emphasis role="bold"><groupId>de.hdm-stuttgart.de.sd1</groupId> + <artifactId>gcd</artifactId> + <version>1.0</version> + <scope>compile</scope> + </dependency></emphasis> + <dependency> + <groupId>junit</groupId> + ... + </dependency> + </dependencies> +</project></programlisting> + </listitem> + </orderedlist> + + <figure xml:id="figMavenProjectDependency"> + <title>Defining a dependency to another Maven artifact.</title> + + <mediaobject> + <imageobject> + <imagedata fileref="Ref/Svg/mavenPrjRef.svg"/> + </imageobject> + </mediaobject> + </figure> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaFractionCancel"> + <title>Implementing reducing of fractions</title> + + <qandadiv> + <qandaentry> + <question> + <para>We have implemented <acronym>GCD</acronym> computation in + <xref linkend="sd1QandaGcd"/>. The current exercises idea is to + implement reducing of fractions by using the method + <methodname>long getGcd(long a, long b)</methodname>. Change the + following implementation items:</para> + + <itemizedlist> + <listitem> + <para>The constructor should reduce a fraction if required, + see introductory remark.</para> + </listitem> + + <listitem> + <para>The Methods <methodname>mult(...)</methodname> and + <methodname>add(...)</methodname> should reduce any + resulting Fraction instance. It might be worth to consider a + defensive strategy to avoid unnecessary overflow + errors.</para> + </listitem> + </itemizedlist> + + <para>Test your results.</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/fraction/V2</para> + </annotation> + + <para>Modifying the constructor is straightforward: On creating + a fraction we simply divide both numerator and denominator by + the <acronym>GCD</acronym> value:</para> + + <programlisting language="java"> <link + xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html#Fraction-long-long-">public Fraction(long numerator, long denominator)</link> { + final long gcd = Math.getGcd(numerator, denominator); + + setNumerator(numerator / gcd); + setDenominator(denominator / gcd); + }</programlisting> + + <para>Its tempting to implement + <methodname>mult(...)</methodname> in a simple fashion:</para> + + <programlisting language="java"> public Fraction mult2(Fraction f) { + return new Fraction(numerator * f.numerator, + denominator * f.denominator); + }</programlisting> + + <para>This is however too shortsighted. Consider the example + <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mfrac> + <m:mi>4</m:mi> + + <m:mi>7</m:mi> + </m:mfrac> + + <m:mo></m:mo> + + <m:mfrac> + <m:mi>3</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + </m:math> + </inlineequation>. Our simple implementation proposal would + call <code>new Fraction(12, 14)</code> only to discover a + <acronym>GCD</acronym> value of 4. Having larger argument values + this might cause an unnecessary overflow. Moreover the + <acronym>GCD</acronym> calculation will take longer than + needed.</para> + + <para>We may instead transform the term in question by + exchanging the numerators like <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mfrac> + <m:mi>3</m:mi> + + <m:mi>7</m:mi> + </m:mfrac> + + <m:mo></m:mo> + + <m:mfrac> + <m:mi>4</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + </m:math> + </inlineequation> to enable reducing <emphasis + role="bold">prior</emphasis> to multiplying. Now the call + <code>new Fraction(4,2)</code> will construct the representation + <inlineequation> + <m:math display="inline"> + <m:mfrac> + <m:mi>2</m:mi> + + <m:mi>1</m:mi> + </m:mfrac> + </m:math> + </inlineequation> and finishing the computation will yield the + correct result <inlineequation> + <m:math display="inline"> + <m:mfrac> + <m:mi>6</m:mi> + + <m:mi>7</m:mi> + </m:mfrac> + </m:math> + </inlineequation>. We should thus implement:</para> + + <programlisting language="java"> public Fraction <link + xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html#mult-de.hdm_stuttgart.mi.sd1.fraction.Fraction-">mult(Fraction f)</link> { + final Fraction f1 = new Fraction(f.numerator, denominator), + f2 = new Fraction(numerator, f.denominator); + + return new Fraction(f1.numerator * f2.numerator, + f1.denominator * f2.denominator); + }</programlisting> + + <para>Similar reflections lead to the clue decomposing the + denominators when implementing + <methodname>add(...)</methodname>. This is what you'd do as well + if your task was adding two fractions by hand trying to avoid + large numbers:</para> + + <programlisting language="java"> public Fraction <link + xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html#add-de.hdm_stuttgart.mi.sd1.fraction.Fraction-">add(Fraction f)</link> { + + final long gcd = Math.getGcd(denominator, f.denominator); + + return new Fraction( numerator * (f.denominator / gcd) + (denominator / gcd) * f.numerator, + (denominator / gcd) * f.denominator); + }</programlisting> + + <para>See complete <link + xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Fraction.html">implementation + here</link>. We may re-use out test:</para> + + <programlisting language="java"> public static void <link + xlink:href="Ref/api/P/fraction/V2/de/hdm_stuttgart/mi/sd1/fraction/Driver.html#main-java.lang.String:A-">main(String[] args)</link> { + + // Input + final Fraction + twoThird = new Fraction(2, 3), // Construct a fraction object (2/3) + threeSeven = new Fraction(3, 7); // Construct a fraction object (3/7) + + // Computed results + final Fraction + sum = twoThird.add(threeSeven), // (2/3) + (3/7) + product = twoThird.mult(threeSeven); // (2/3) * (3/7) + + System.out.println("(2/3) + (3/7) = (23/21) = " + sum.getValue()); + System.out.println("(2/3) * (3/7) = (2/7) = " + product.getValue()); + }</programlisting> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1MathMaxAbs"> + <title>Building a private library of mathematical functions.</title> + + <para>The following sections provide exercises on implementing + mathematical functions. We start with an easy one.</para> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaMaxAbs"> + <title>Maximum and absolute value</title> + + <qandadiv> + <qandaentry> + <question> + <para>Implement two class methods double abs(double) and double + max(double, double, double) in a class math living in a package + of your choice:</para> + + <programlisting language="java">package de.hdm_stuttgart.de.sd1.math; + +/** + * Some class methods. + */ +public class Math { + + /** + * Return the absolute value of a given argument + * @param value The argument to be considered + * @return the argument's absolute (positive) value. + */ + public static double abs(double value) { + ... return ??; + } + + /** + * The maximum of two arguments + * @param a First argument + * @param b Second argument + * @return The maximum of a and b + */ + public static double max(double a, double b) { + ... return ??; + } + + /** + * The maximum of three arguments + * + * @param a First argument + * @param b Second argument + * @param c Third argument + * @return The maximum of a, b and c + */ + public static double max(double a, double b, double c) { + ... return ??; + } +}</programlisting> + + <para>Test these functions using appropriate data.</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/math/V0_5</para> + </annotation> + + <para>See <link + xlink:href="Ref/api/P/math/V0_5/de/hdm_stuttgart/de/sd1/math/Math.html">implementation + here.</link></para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + + <section xml:id="sd1SecExp"> + <title>Implementing the exponential function.</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaMath"> + <title>The exponential <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>f</m:mi> + + <m:mo></m:mo> + + <m:mfenced> + <m:mi>x</m:mi> + </m:mfenced> + </m:mrow> + + <m:mo>=</m:mo> + + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + </m:mrow> + </m:math> + </inlineequation></title> + + <qandadiv> + <qandaentry> + <question> + <para>The exponential <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>f</m:mi> + + <m:mo></m:mo> + + <m:mfenced> + <m:mi>x</m:mi> + </m:mfenced> + </m:mrow> + + <m:mo>=</m:mo> + + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + </m:mrow> + </m:math> + </inlineequation> is being defined by a power series:</para> + + <equation xml:id="sd1EqnDefExp"> + <title>Power series definition of <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>f</m:mi> + + <m:mo></m:mo> + + <m:mfenced> + <m:mi>x</m:mi> + </m:mfenced> + </m:mrow> + + <m:mo>=</m:mo> + + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + </m:mrow> + </m:math> + </inlineequation></title> + + <m:math display="block"> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mrow> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>1</m:mi> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>1</m:mi> + </m:msup> + + <m:mrow> + <m:mi>1</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>2</m:mi> + </m:msup> + + <m:mrow> + <m:mi>2</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>3</m:mi> + </m:msup> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mi>...</m:mi> + </m:mrow> + </m:mrow> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mrow> + <m:mo>=</m:mo> + + <m:mrow> + <m:munderover> + <m:mo>∑</m:mo> + + <m:mrow> + <m:mi>i</m:mi> + + <m:mo>=</m:mo> + + <m:mi>0</m:mi> + </m:mrow> + + <m:mi mathvariant="normal">∞</m:mi> + </m:munderover> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>i</m:mi> + </m:msup> + + <m:mrow> + <m:mi>i</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + </m:mrow> + </m:mrow> + </m:mtd> + </m:mtr> + </m:mtable> + </m:math> + </equation> + + <para>Implement a class method <methodname>double + exp(double)</methodname> inside a class + <package>Math</package> choosing a package of your choice. The + name clash with the Java standard class <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html">java.lang.Math</link> + is intended: You'll learn how to resolve naming + conflicts.</para> + + <para>Regarding practical calculations we replace the above + infinite series by a limited one. So the number of terms to be + considered will become a parameter which shall be + configurable. Continue the implementation of the following + skeleton:</para> + + <figure xml:id="sd1FigExpSketch"> + <title>An implementation sketch for the exponential</title> + + <programlisting language="java">public class Math { + ... + + /** + * @param seriesLimit The last term's index of a power series to be included, + */ + public static void setSeriesLimit(int seriesLimit) {...} + + /** + * Approximating the natural exponential function by a finite + * number of terms from the corresponding power series. + * + * A power series implementation has to be finite since an + * infinite number of terms requires infinite execution time. + * + * The number of terms to be considered can be set by {@link #setSeriesLimit(int)}} + * + * @param x + * @return + */ + public static double exp(double x) {...} +}</programlisting> + </figure> + + <para>Compare your results using <code>seriesLimit=8</code> + terms and the corresponding values from the professional + implementation <link + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#exp-double">java.lang.Math.exp</link> + by calculating <inlineequation> + <m:math display="inline"> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>1</m:mi> + </m:msup> + </m:math> + </inlineequation>, <inlineequation> + <m:math display="inline"> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>2</m:mi> + </m:msup> + </m:math> + </inlineequation> and <inlineequation> + <m:math display="inline"> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>3</m:mi> + </m:msup> + </m:math> + </inlineequation>. What do you observe? Can you explain this + result?</para> + + <para>Do not forget to provide suitable + <command>Javadoc</command> comments and watch the generated + documentation.</para> + + <para>Hints:</para> + + <itemizedlist> + <listitem> + <para>You should only use basic arithmetic operations like + +, - * and /. Do not use <link + xlink:href="https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#pow-double-double-">Math.pow(double + a, double b)</link> and friends! Their implementations use + power series expansions as well and are designed for a + different purpose like having fractional exponent + values.</para> + </listitem> + + <listitem> + <para>The power series' elements may be obtained in a + recursive fashion like e.g.:</para> + + <informalequation> + <m:math display="block"> + <m:mrow> + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>3</m:mi> + </m:msup> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mfrac> + <m:mi>x</m:mi> + + <m:mn>3</m:mn> + </m:mfrac> + + <m:mo></m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>2</m:mi> + </m:msup> + + <m:mrow> + <m:mi>2</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + </m:mrow> + </m:mrow> + </m:math> + </informalequation> + </listitem> + </itemizedlist> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/math/V1</para> + </annotation> + + <para>Regarding the finite number of terms we provide a class + variable <coref linkend="sd1ListingSeriesLimit"/> having + default value of 5 corresponding to just the first 1 + 5 = 6 + terms:</para> + + <informalequation> + <m:math display="block"> + <m:mrow> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + + <m:mo>≈</m:mo> + + <m:mrow> + <m:mi>1</m:mi> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>1</m:mi> + </m:msup> + + <m:mrow> + <m:mi>1</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mi>...</m:mi> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>5</m:mi> + </m:msup> + + <m:mrow> + <m:mi>5</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + </m:mrow> + </m:mrow> + </m:math> + </informalequation> + + <para>We also provide a corresponding setter method <coref + linkend="sd1ListingSeriesLimitSetter"/> enabling users of our + class to choose a different value:</para> + + <programlisting language="java">public class Math { + + static int <emphasis role="bold">seriesLimit = 5</emphasis>; <co + xml:id="sd1ListingSeriesLimit"/> + + /** + * + * @param seriesLimit The last term's index of a power series to be included, + * {@link }}. + */ + public static void setSeriesLimit(int seriesLimit) { <co + xml:id="sd1ListingSeriesLimitSetter"/> + Math.seriesLimit = seriesLimit; + } ...</programlisting> + + <para>Calculating values by a finite series requires a + loop:</para> + + <programlisting language="java"> public static double exp(double x) { + double currentTerm = 1., // the first (i == 0) term x^0/0! + sum = currentTerm; // initialize to the power series' first term + + for (int i = 1; i <= seriesLimit; i++) { // i = 0 has already been completed. + currentTerm *= x / i; + sum += currentTerm; + } + return sum; + }</programlisting> + + <para>You may also view the <productname>Javadoc</productname> + and the implementation of <link + xlink:href="Ref/api/P/math/V1/de/hdm_stuttgart/de/sd1/math/Math.html#exp-double-">double + Math.exp(double)</link>. We may use the subsequent code + snippet for testing and comparing our implementation:</para> + + <programlisting language="java"> Math.setSeriesLimit(6); + + double byPowerSeries = Math.exp(1.); + System.out.println("e^1=" + byPowerSeries + ", difference=" + (byPowerSeries - java.lang.Math.exp(1.))); + + byPowerSeries = Math.exp(2.); + System.out.println("e^2=" + byPowerSeries + ", difference=" + (byPowerSeries - java.lang.Math.exp(2.))); + + byPowerSeries = Math.exp(3.); + System.out.println("e^3=" + byPowerSeries + ", difference=" + (byPowerSeries - java.lang.Math.exp(3.)));</programlisting> + + <para>In comparison with a professional implementation we have + the following results:</para> + + <programlisting language="unknown">e^1=2.7180555555555554, difference=-2.262729034896438E-4 +e^2=7.355555555555555, difference=-0.033500543375095226 +e^3=19.412499999999998, difference=-0.67303692318767</programlisting> + + <para>Our implementation based on just 6 terms is quite good + for small values of x. Larger values however exhibit growing + differences.</para> + + <para>This is due to the fact that our approximation is in + fact just a polynomial of degree 6.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1MathSin"> + <title>Adding sine</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaSin"> + <title>Implementing <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>.</title> + + <qandadiv> + <qandaentry> + <question> + <para>We may implement <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> in a similar fashion to <xref + linkend="sd1EqnDefExp"/>:</para> + + <equation xml:id="sd1EqnDefSin"> + <title>Power series definition of <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>f</m:mi> + + <m:mo></m:mo> + + <m:mfenced> + <m:mi>x</m:mi> + </m:mfenced> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation></title> + + <m:math display="block"> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>-</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>3</m:mi> + </m:msup> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>5</m:mi> + </m:msup> + + <m:mrow> + <m:mi>5</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>-</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>7</m:mi> + </m:msup> + + <m:mrow> + <m:mi>7</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mi>...</m:mi> + </m:mrow> + </m:mrow> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mrow> + <m:mo>=</m:mo> + + <m:mrow> + <m:munderover> + <m:mo>∑</m:mo> + + <m:mrow> + <m:mi>k</m:mi> + + <m:mo>=</m:mo> + + <m:mi>0</m:mi> + </m:mrow> + + <m:mi mathvariant="normal">∞</m:mi> + </m:munderover> + + <m:mrow> + <m:msup> + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>-1</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + + <m:mi>k</m:mi> + </m:msup> + + <m:mo>∙</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mrow> + <m:mi>2</m:mi> + + <m:mo>k</m:mo> + + <m:mo>+</m:mo> + + <m:mi>1</m:mi> + </m:mrow> + </m:msup> + + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>2</m:mi> + + <m:mi>k</m:mi> + + <m:mo>+</m:mo> + + <m:mi>1</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + </m:mrow> + </m:mrow> + </m:mrow> + </m:mtd> + </m:mtr> + </m:mtable> + </m:math> + </equation> + + <para>Extend <xref linkend="sd1FigExpSketch"/> by adding a + second method <methodname>double sin(double)</methodname>. Do + not forget to add suitable <command>Javadoc</command> comments + and watch the generated documentation.</para> + + <para>Test your implementation by calculating the known values + <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>, <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>π</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> and <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>4</m:mi> + + <m:mi>π</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> using <varname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#PI">java.lang.Math.PI</varname>. + Explain your results</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/math/V2</para> + </annotation> + + <para>Taking seven terms into account we have the following + results:</para> + + <programlisting language="unknown">sin(pi/2)=0.9999999999939768, difference=-6.023181953196399E-12 +sin(pi)=-7.727858895155385E-7, difference=-7.727858895155385E-7 +sin(4 * PI)=-9143.306026012957, <emphasis role="bold">difference=-9143.306026012957</emphasis></programlisting> + + <para>As with the implementation of <inlineequation> + <m:math display="inline"> + <m:msup> + <m:mi>e</m:mi> + + <m:mi>x</m:mi> + </m:msup> + </m:math> + </inlineequation> larger (positive or negative) argument + values show growing differences. On the other hand the + approximation is remarkably precise for smaller arguments. The + reason again is the fact that our power series is just a + polynomial approximation.</para> + + <para>You may also view the <link + xlink:href="Ref/api/P/math/V2/de/hdm_stuttgart/de/sd1/math/Math.html#sin-double-">Javadoc</link> + and the implementation of <link + xlink:href="Ref/api/P/math/V2/de/hdm_stuttgart/de/sd1/math/Math.html#sin-double-">double + Math.sin(double)</link>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sdnSecSinRoundingErrors"> + <title>Strange things happen</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaReorderSin"> + <title>Summing up in a different order.</title> + + <qandadiv> + <qandaentry> + <question> + <para>We may reorder summing up within our power series + defining<inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>:</para> + + <equation xml:id="sde1MathReorderSumming"> + <title>Reordering of terms with respect to an + implementation.</title> + + <m:math display="block"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>+</m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mo>-</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>3</m:mi> + </m:msup> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>5</m:mi> + </m:msup> + + <m:mrow> + <m:mi>5</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>)</m:mo> + </m:mrow> + + <m:mo>+</m:mo> + + <m:mo>(</m:mo> + + <m:mo>-</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>7</m:mi> + </m:msup> + + <m:mrow> + <m:mi>7</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>9</m:mi> + </m:msup> + + <m:mrow> + <m:mi>9</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>)</m:mo> + + <m:mo>+</m:mo> + + <m:mo>...</m:mo> + </m:mrow> + </m:math> + </equation> + + <para>From a mathematical point of view there is no difference + to <xref linkend="sd1EqnDefSin"/>. Nevertheless:</para> + + <itemizedlist> + <listitem> + <para>Rename your current sine implementation to + <methodname>double sinOld(double)</methodname>.</para> + </listitem> + + <listitem> + <para>Implement a new method <methodname>double + sin(double)</methodname> using the above summing + reordering.</para> + </listitem> + </itemizedlist> + + <para>Compare the results of <methodname>double + sinOld(double)</methodname> and <methodname>double + sin(double)</methodname> for seven terms. What do you observe? + Do you have an explanation?</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/math/V3</para> + </annotation> + + <para>The following results result from <link + xlink:href="Ref/api/P/math/V3/de/hdm_stuttgart/de/sd1/math/Driver.html">this + test</link>:</para> + + <programlisting language="unknown">Old Implementation:+++++++++++++++++++++++++++++++++++++++ + +sinOld(pi/2)=0.9999999999939768, difference=-6.023181953196399E-12 +sinOld(pi)=-7.727858895155385E-7, difference=-7.727858895155385E-7 +sinOld(4 * PI)=-9143.306026012957, difference=-9143.306026012957 + +New reorder Implementation:+++++++++++++++++++++++++++++++++++++ + +sin(pi/2)=1.0000000000000435, difference=4.3520742565306136E-14 +sin(pi)=2.2419510618081458E-8, difference=2.2419510618081458E-8 +sin(4 * PI)=4518.2187229323445, difference=4518.2187229323445</programlisting> + + <para>Comparing corresponding values our reordered + implementation is more than 100 times more precise. For larger + values we still have a factor of two.</para> + + <para>This is due to limited arithmetic precision: Each double + value can only be approximated by an in memory representation + of eight bytes. Consider the following example:</para> + + <programlisting language="java"> double one = 1., + a = 0.000000000000200, + b = 0.000000000000201; + + System.out.println("(1 + (a - b)) - 1:" + ((one + (a - b)) - one)); + System.out.println("((1 + a) - b) - 1:" + (((one + a) - b) - one));</programlisting> + + <para>This produces the following output:</para> + + <programlisting language="unknown">(1 + (a - b)) - 1:-9.992007221626409E-16 +((1 + a) - b) - 1:-8.881784197001252E-16</programlisting> + + <para>Errors like this one sum up in a power series to + reasonable values especially if higher powers are + involved.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + + <section xml:id="sd1SinComplete"> + <title>Completing sine implementation</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaSinMapArguments"> + <title>Transforming arguments.</title> + + <qandadiv> + <qandaentry> + <question> + <para>We've reached an implementation offering good results + for <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> if <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>∈</m:mo> + + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mrow> + <m:mo>-</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>]</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>. The following rules may be used to retain + precision for arbitrary argument values:</para> + + <orderedlist> + <listitem> + <informalequation> + <m:math display="block"> + <m:mrow> + <m:msub> + <m:mo>∀</m:mo> + + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>∈</m:mo> + + <m:mi mathvariant="normal">ℝ</m:mi> + </m:mrow> + </m:msub> + + <m:mo>,</m:mo> + + <m:msub> + <m:mo>∀</m:mo> + + <m:mrow> + <m:mi>n</m:mi> + + <m:mo>∈</m:mo> + + <m:mi mathvariant="normal">ℤ</m:mi> + </m:mrow> + </m:msub> + + <m:mo>:</m:mo> + + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>n</m:mi> + + <m:mo></m:mo> + + <m:mi>2</m:mi> + + <m:mo></m:mo> + + <m:mi>π</m:mi> + + <m:mo>+</m:mo> + + <m:mi>x</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </informalequation> + + <para>This rule of periodicity allows us to consider only + the interval <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mo>-</m:mo> + + <m:mi>π</m:mi> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mi>π</m:mi> + + <m:mo>[</m:mo> + </m:mrow> + </m:math> + </inlineequation> like e.g. <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>21</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>21</m:mi> + + <m:mo>-</m:mo> + + <m:mrow> + <m:mi>3</m:mi> + + <m:mo>∙</m:mo> + + <m:mi>2</m:mi> + + <m:mo>∙</m:mo> + + <m:mi>π</m:mi> + </m:mrow> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>≈</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>2.15</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>.</para> + </listitem> + + <listitem> + <informalequation> + <m:math display="block"> + <m:mrow> + <m:msub> + <m:mo>∀</m:mo> + + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>∈</m:mo> + + <m:mi mathvariant="normal">ℝ</m:mi> + </m:mrow> + </m:msub> + + <m:mo>:</m:mo> + + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>π</m:mi> + + <m:mo>-</m:mo> + + <m:mi>x</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </informalequation> + + <para>This rule allows us to narrow down values from + <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mo>-</m:mo> + + <m:mi>π</m:mi> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mi>π</m:mi> + + <m:mo>[</m:mo> + </m:mrow> + </m:math> + </inlineequation> to <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mrow> + <m:mo>-</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>[</m:mo> + </m:mrow> + </m:math> + </inlineequation> like e.g. <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(2</m:mo> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mi>π</m:mi> + + <m:mo>-</m:mo> + + <m:mi>2</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>≈</m:mo> + + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>1.14</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>.</para> + </listitem> + + <listitem> + <informalequation> + <m:math display="block"> + <m:mrow> + <m:msub> + <m:mo>∀</m:mo> + + <m:mrow> + <m:mi>x</m:mi> + + <m:mo>∈</m:mo> + + <m:mi mathvariant="normal">ℝ</m:mi> + </m:mrow> + </m:msub> + + <m:mo>:</m:mo> + + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>cos</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + + <m:mo>-</m:mo> + + <m:mi>x</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </informalequation> + + <para>This rule allows us to further narrow down values + from <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mrow> + <m:mo>-</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>[</m:mo> + </m:mrow> + </m:math> + </inlineequation> to <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mrow> + <m:mo>-</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>4</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>4</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>[</m:mo> + </m:mrow> + </m:math> + </inlineequation> like e.g. <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(1.1</m:mo> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>cos</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>2</m:mi> + </m:mfrac> + + <m:mo>-</m:mo> + + <m:mi>1.1</m:mi> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>≈</m:mo> + + <m:mrow> + <m:mi>cos</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>0.471</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>. We must however implement the + corresponding power series of <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>cos</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>:</para> + + <equation xml:id="sd1EqnDefCos"> + <title>Power series definition of <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>cos</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation></title> + + <m:math display="block"> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mrow> + <m:mrow> + <m:mi>cos</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mrow> + <m:mi>1</m:mi> + + <m:mo>-</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>2</m:mi> + </m:msup> + + <m:mrow> + <m:mi>2</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>4</m:mi> + </m:msup> + + <m:mrow> + <m:mi>4</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>-</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mi>6</m:mi> + </m:msup> + + <m:mrow> + <m:mi>6</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + + <m:mo>+</m:mo> + + <m:mi>...</m:mi> + </m:mrow> + </m:mrow> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mrow> + <m:mo>=</m:mo> + + <m:mrow> + <m:munderover> + <m:mo>∑</m:mo> + + <m:mrow> + <m:mi>k</m:mi> + + <m:mo>=</m:mo> + + <m:mi>0</m:mi> + </m:mrow> + + <m:mi mathvariant="normal">∞</m:mi> + </m:munderover> + + <m:mrow> + <m:msup> + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>-1</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + + <m:mi>k</m:mi> + </m:msup> + + <m:mo>∙</m:mo> + + <m:mfrac> + <m:msup> + <m:mi>x</m:mi> + + <m:mrow> + <m:mi>2</m:mi> + + <m:mo>k</m:mo> + </m:mrow> + </m:msup> + + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>2</m:mi> + + <m:mi>k</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + + <m:mo>!</m:mo> + </m:mrow> + </m:mfrac> + </m:mrow> + </m:mrow> + </m:mrow> + </m:mtd> + </m:mtr> + </m:mtable> + </m:math> + </equation> + </listitem> + </orderedlist> + + <para>The above rules allow for computation of arbitrary + <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mi>sin</m:mi> + + <m:mo></m:mo> + + <m:mrow> + <m:mo>(</m:mo> + + <m:mi>x</m:mi> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> values by means of power series expansion + limited to the interval <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mo>[</m:mo> + + <m:mrow> + <m:mrow> + <m:mo>-</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>4</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>,</m:mo> + + <m:mfrac> + <m:mi>π</m:mi> + + <m:mi>4</m:mi> + </m:mfrac> + </m:mrow> + + <m:mo>]</m:mo> + </m:mrow> + </m:math> + </inlineequation> thereby gaining high precision results. + Extend your current implementation by mapping arbitrary + arguments to this interval appropriately.</para> + + <para>Hint: The standard function <methodname + xlink:href="http://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floor-double-">Math.rint(double)</methodname> + could be helpful: It may turn e.g. 4.47 (<code>double</code>) + to 4 (<code>long</code>).</para> + </question> + + <answer> + <annotation role="make"> + <para role="eclipse">Sd1/math/V4</para> + </annotation> + + <para>For convenience reasons we start defining PI within our + class:</para> + + <programlisting language="java">public class Math { + + private static final double PI = java.lang.Math.PI; + ...</programlisting> + + <para>Now we need two steps mapping our argument:</para> + + <programlisting language="java"> public static double sin(double x) { + // Step 1: Normalize x to [-PI, +PI[ + final long countTimes2PI = (long) java.lang.Math.rint(x / 2 / PI); + if (countTimes2PI != 0) { + x -= 2 * PI * countTimes2PI; + } + + // Step 2: Normalize x to [-PI/2, +PI/2] + // Since sin(x) = sin (PI - x) we continue to normalize + // having x in [-PI/2, +PI/2] + if (PI/2 < x) { + x = PI - x; + } else if (x < -PI/2) { + x = -x - PI; + } + + // Step 3: Continue with business as usual + ...</programlisting> + + <para>This yet sows only the result from applying the first + two rules. You may also view the + <productname>Javadoc</productname> and the implementation of + <link + xlink:href="Ref/api/P/math/V4/de/hdm_stuttgart/de/sd1/math/Math.html#sin-double-">double + Math.sin(double)</link>.</para> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + </section> </section> </chapter> diff --git a/P/Sd1/Gcd/V1/pom.xml b/P/Sd1/Gcd/V1/pom.xml index 7a915ece4..62cd648e6 100644 --- a/P/Sd1/Gcd/V1/pom.xml +++ b/P/Sd1/Gcd/V1/pom.xml @@ -12,7 +12,6 @@ <groupId>de.hdm-stuttgart.de.sd1</groupId> <artifactId>gcd</artifactId> - <version>1.0</version> <packaging>jar</packaging> <name>gcd</name> -- GitLab