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