Development Class Java

/*
 * 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    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;
  }
}