/* 
 * MathUtil.java 
 * 
 * Copyright (C) 2005-2008 Tommi Laukkanen 
 * http://www.substanceofcode.com 
 * 
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version. 
 * 
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 * GNU General Public License for more details. 
 * 
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 * 
 */ 
 
//package com.substanceofcode.util; 
 
/** 
 * Utility methods for mathematical problems. 
 *  
 * @author Tommi Laukkanen 
 */ 
public class MathUtil { 
 
  /** Square root from 3 */ 
  final static public double SQRT3 = 1.732050807568877294; 
  /** Log10 constant */ 
  final static public double LOG10 = 2.302585092994045684; 
  /** ln(0.5) constant */ 
  final static public double LOGdiv2 = -0.6931471805599453094; 
  public final static double EVal = 2.718281828459045235; 
 
  /** Creates a new instance of MathUtil */ 
  private MathUtil() { 
  } 
 
  /** 
   * Returns the value of the first argument raised to the power of the second 
   * argument. 
   *  
   * @author Mario Sansone 
   */ 
  public static int pow(int base, int exponent) { 
    boolean reciprocal = false; 
    if (exponent < 0) { 
      reciprocal = true; 
    } 
    int result = 1; 
    while (exponent-- > 0) { 
      result *= base; 
    } 
    return reciprocal ? 1 / result : result; 
  } 
 
  public static double pow(double base, int exponent) { 
    boolean reciprocal = false; 
    if (exponent < 0) { 
      reciprocal = true; 
    } 
    double result = 1; 
    while (exponent-- > 0) { 
      result *= base; 
    } 
    return reciprocal ? 1 / result : result; 
  } 
 
  /** Arcus cos */ 
  static public double acos(double x) { 
    double f = asin(x); 
    if (f == Double.NaN) { 
      return f; 
    } 
    return Math.PI / 2 - f; 
  } 
 
  /** Arcus sin */ 
  static public double asin(double x) { 
    if (x < -1. || x > 1.) { 
      return Double.NaN; 
    } 
    if (x == -1.) { 
      return -Math.PI / 2; 
    } 
    if (x == 1) { 
      return Math.PI / 2; 
    } 
    return atan(x / Math.sqrt(1 - x * x)); 
  } 
 
  /** Arcus tan */ 
  static public double atan(double x) { 
    boolean signChange = false; 
    boolean Invert = false; 
    int sp = 0; 
    double x2, a; 
    // check up the sign change 
    if (x < 0.) { 
      x = -x; 
      signChange = true; 
    } 
    // check up the invertation 
    if (x > 1.) { 
      x = 1 / x; 
      Invert = true; 
    } 
    // process shrinking the domain until x<PI/12 
    while (x > Math.PI / 12) { 
      sp++; 
      a = x + SQRT3; 
      a = 1 / a; 
      x = x * SQRT3; 
      x = x - 1; 
      x = x * a; 
    } 
    // calculation core 
    x2 = x * x; 
    a = x2 + 1.4087812; 
    a = 0.55913709 / a; 
    a = a + 0.60310579; 
    a = a - (x2 * 0.05160454); 
    a = a * x; 
    // process until sp=0 
    while (sp > 0) { 
      a = a + Math.PI / 6; 
      sp--; 
    } 
    // invertation took place 
    if (Invert) { 
      a = Math.PI / 2 - a; 
    } 
    // sign change took place 
    if (signChange) { 
      a = -a; 
    } 
    // 
    return a; 
  } 
 
  public static double log(double x) { 
    if (x < 0) { 
      return Double.NaN; 
    } 
    // 
    if (x == 1) { 
      return 0d; 
    } 
 
    if (x == 0) { 
      return Double.NEGATIVE_INFINITY; 
    } 
    // 
    if (x > 1) { 
      x = 1 / x; 
      return -1 * _log(x); 
    } 
    return _log(x); 
  } 
 
  public static double _log(double x) { 
 
    double f = 0.0; 
    // Make x to close at 1 
    int appendix = 0; 
    while (x > 0 && x < 1) { 
      x = x * 2; 
      appendix++; 
    } 
    // 
    x = x / 2; 
    appendix--; 
    // 
    double y1 = x - 1; 
    double y2 = x + 1; 
    double y = y1 / y2; 
    // 
    double k = y; 
    y2 = k * y; 
    // 
    for (long i = 1; i < 50; i += 2) { 
      f = f + (k / i); 
      k = k * y2; 
    } 
    // 
    f = f * 2; 
    for (int i = 0; i < appendix; i++) { 
      f = f + (LOGdiv2); 
    } 
    // 
    return f; 
  } 
 
  /** 
   * Replacement for missing Math.pow(double, double) 
   *  
   * @param x 
   * @param y 
   * @return 
   */ 
  public static double pow(double x, double y) { 
    // Convert the real power to a fractional form 
    int den = 1024; // declare the denominator to be 1024 
 
    /* 
     * Conveniently 2^10=1024, so taking the square root 10 times will yield 
     * our estimate for n. In our example n^3=8^2 n^1024 = 8^683. 
     */ 
 
    int num = (int) (y * den); // declare numerator 
 
    int iterations = 10; /* 
               * declare the number of square root iterations 
               * associated with our denominator, 1024. 
               */ 
 
    double n = Double.MAX_VALUE; /* 
                   * we initialize our estimate, setting it to 
                   * max 
                   */ 
 
    while (n >= Double.MAX_VALUE && iterations > 1) { 
      /* 
       * We try to set our estimate equal to the right hand side of the 
       * equation (e.g., 8^2048). If this number is too large, we will 
       * have to rescale. 
       */ 
 
      n = x; 
 
      for (int i = 1; i < num; i++) { 
        n *= x; 
      } 
 
      /* 
       * here, we handle the condition where our starting point is too 
       * large 
       */ 
      if (n >= Double.MAX_VALUE) { 
        iterations--; /* reduce the iterations by one */ 
 
        den = (int) (den / 2); /* redefine the denominator */ 
 
        num = (int) (y * den); // redefine the numerator 
      } 
    } 
 
    /************************************************* 
     ** We now have an appropriately sized right-hand-side. Starting with 
     * this estimate for n, we proceed. 
     **************************************************/ 
    for (int i = 0; i < iterations; i++) { 
      n = Math.sqrt(n); 
    } 
 
    // Return our estimate 
    return n; 
  } 
 
  public final static int abs(int in) { 
    if (in < 0.0) { 
      return in * -1; 
    } 
    return in; 
  } 
 
  public final static long abs(long in) { 
    if (in < 0.0) { 
      return in * -1; 
    } 
    return in; 
  } 
 
  public final static double abs(double in) { 
    if (in < 0.0) { 
      return in * -1.0; 
    } 
    return in; 
  } 
} 
 
    
     
     
     
     
     
  
  |