001package de.hdm_stuttgart.sd1.math;
002
003/**
004 * <p>This class implements a subset of functions from class
005 * {@link java.lang.Math} using power series expansions.</p>
006 *
007 */
008public class Math {
009  
010  static int seriesLimit = 5;
011  
012  /**
013   *  
014   * @param seriesLimit The number of terms of a power series to be included.
015   * 
016   */
017  public static void setSeriesLimit(int seriesLimit) {
018    Math.seriesLimit = seriesLimit;
019  }
020  
021  /**
022   * <p>Approximating the natural exponential function by a finite
023   * number of terms using power series expansion.</p>
024   *
025   * \[ \begin{aligned}
026   *   e^x ={} &amp; 1 + {x\over 1!} + {x^2\over 2!} + {x^3\over 3!} + \dots \\
027   *       ={} &amp; \sum_{i = 0}^\infty {x^i\over i!}
028   * \end{aligned} \]
029   *
030   * A power series implementation has to be finite since an
031   * infinite number of terms requires infinite execution time.
032   *
033   * The number of terms to be considered can be set by {@link #setSeriesLimit(int)}}
034   *
035   * @param x The exponential's argument as in  \( e^x \)
036
037   * @return The value \( e^x \) itself.
038   */
039  public static double exp(double x) {
040    double currentTerm = 1.,  // the first (i == 0) term x^0/0!
041        sum = currentTerm;    // initialize to the power series' first term
042    
043    for (int i = 1; i <= seriesLimit; i++) { // i = 0 has already been completed.
044      currentTerm *= x / i;
045      sum += currentTerm;
046    }
047    return sum;
048  }
049  
050  /**
051   * <p>Calculating the sine by means of the corresponding power series.</p>
052   *
053   \[
054   \begin{aligned}
055   \text{sin}(x) ={} &amp; x - {x^3\over 3!} + {x^5\over 5!} - {x^7\over 7!} + \dots \\
056   ={} &amp; \sum_{i = 0}^\infty {(-1)^i  {x^{2i+1}\over (2i+1)!}}
057   \end{aligned}
058   \]
059   *
060   * @param x The sine's argument as in \( \text{sin}(x) \).
061   *
062   * @return The value \( \text{sin}(x) \) itself.
063   */
064  public static double sinOld(double x) {
065    double currentTerm = x,  // the first (i == 0) term x^1/1!
066        sum = currentTerm;    // initialize to the power series' first term
067
068    for (int i = 1; i <= seriesLimit; i++) {
069      currentTerm *= -1 * x * x / (2 * i) / (2 * i + 1);
070      sum += currentTerm;
071    }
072    return sum;
073  }
074  /**
075   * Implementing sine slightly different by reordering terms.
076   * @param x See {@link #sinOld(double)}}
077   * @return See {@link #sinOld(double)}}
078   * 
079   */
080  public static double sin(double x) {
081    double currentTerm = x,   // the first (i == 0) term x^1/1!
082        sum = currentTerm;    // initialize to the power series' first term
083
084    // Slightly incorrect if seriesLimit is even
085    for (int i = 1; i <= seriesLimit; i += 2) { // Caution: Steps of two!!
086      final double previousTerm =               // save the current term
087          currentTerm *= x * x / (2 * i) / (2 * i + 1) ;
088      currentTerm *= x * x / (2 * i + 2) / (2 * i + 3);
089      sum += currentTerm - previousTerm;      //Summing up reordered
090    }
091    return sum;
092  }
093}