package mikera.util;
/**
* Helpful maths functions
*
* Focus on using floats rather than doubles for speed
*
* @author Mike
*
*/
public final class Maths {
public static final double ROOT_TWO = Math.sqrt(2);
public static final double ROOT_THREE = Math.sqrt(3);
/** mathematical constant e */
public static final double E = java.lang.Math.E;
/** Mathematical constant Pi = 3.1415926... */
public static final double PI = Math.PI;
public static final double TWO_PI = 2.0 * PI;
/** Mathematical constant Tau = 2 * Pi */
public static final double TAU = TWO_PI;
public static final double HALF_PI = 0.5 * PI;
public static final double QUARTER_PI = 0.25 * PI;
private static final double EPSILON = 0.00001;
public static float sqrt(float a) {
return (float) Math.sqrt(a);
}
public static double sqrt(double a) {
return Math.sqrt(a);
}
/**
* Clamp a double value to an integer range
*/
public static int clampToInteger(double value, int min, int max) {
int v = (int) value;
if (v < min) return min;
if (v > max) return max;
return v;
}
/**
* Clamp a float value to an integer range
*/
public static int clampToInteger(float value, int min, int max) {
int v = (int) value;
if (v < min) return min;
if (v > max) return max;
return v;
}
/** Linear interpolation between a and b */
public static final double lerp(double t, double a, double b) {
return (1 - t) * a + t * b;
}
/**
* Return the middle value of 3 numbers
*
* Can use faster "bound" method if first and last parameters are in order
*/
public static int middle(int a, int b, int c) {
if (a < b) {
if (b < c) { return b; }
return (a < c) ? c : a;
}
if (a < c) { return a; }
return (b < c) ? c : b;
}
/**
* Return the middle value of 3 numbers
*
* Can use faster "bound" method if parameters 2 and 3 are known to be in
* order
*/
public static float middle(float a, float b, float c) {
if (a < b) {
if (b < c) { return b; }
return (a < c) ? c : a;
}
if (a < c) { return a; }
return (b < c) ? c : b;
}
/**
* Return the sign of a double value
*/
public static int sign(double x) {
if (x == 0.0) return 0;
return (x > 0) ? 1 : -1;
}
/**
* Return the sign of a float value
*/
public static int sign(float x) {
if (x == 0.0f) return 0;
return (x > 0) ? 1 : -1;
}
/**
* Return the sign of an int value
*/
public static final int sign(int a) {
return (a == 0) ? 0 : ((a > 0) ? 1 : -1);
}
/** Return the sign of a long value */
public static int sign(long a) {
if (a == 0) return 0;
return (a > 0) ? 1 : -1;
}
/**
* Integer modulus function
*
* @param n
* number
* @param d
* divisor
* @return
*/
public static int mod(int number, int divisor) {
int r = (number % divisor);
if (r < 0) r += divisor;
return r;
}
/**
* Long modulus function
*
* @param n
* number
* @param d
* divisor
* @return
*/
public static long mod(long number, long divisor) {
long r = (number % divisor);
if (r < 0) r += divisor;
return r;
}
/**
* Detects the number of times that boundary is passed when adding increase
* to base
*
* @param increase
* @param boundary
* @param base
* @return
*/
public static long quantize(long increase, long boundary, long base) {
return ((base + increase) / boundary) - (base / boundary);
}
/** Return the minimum of three values */
public static double min(double a, double b, double c) {
double result = a;
if (b < result) result = b;
if (c < result) result = c;
return result;
}
/** Return the maximum of three values */
public static double max(double a, double b, double c) {
double result = a;
if (b > result) result = b;
if (c > result) result = c;
return result;
}
/** Return the minimum of three values */
public static float min(float a, float b, float c) {
float result = a;
if (b < result) result = b;
if (c < result) result = c;
return result;
}
/** Return the maximum of three values */
public static float max(float a, float b, float c) {
float result = a;
if (b > result) result = b;
if (c > result) result = c;
return result;
}
/** Return the minimum of four values */
public static final float min(float a, float b, float c, float d) {
float result = a;
if (result > b) result = b;
if (result > c) result = c;
if (result > d) result = d;
return result;
}
/** Return the maximum of four values */
public static final float max(float a, float b, float c, float d) {
float result = a;
if (result < b) result = b;
if (result < c) result = c;
if (result < d) result = d;
return result;
}
/** Return the minimum of two numbers */
public static int min(final int a, final int b) {
// oddly, this seems to outperform java.lang.Math.min by about 10% on
// caliper tests.....
return (a < b) ? a : b;
}
/** Return the maximum of two numbers */
public static int max(final int a, final int b) {
return (a > b) ? a : b;
}
/** Return the minimum of two numbers */
public static float min(float a, float b) {
return (a < b) ? a : b;
}
/** Return the maximum of two numbers */
public static float max(float a, float b) {
return (a > b) ? a : b;
}
/** Return the minimum of three numbers */
public static int min(int a, int b, int c) {
int result = a;
if (b < result) result = b;
if (c < result) result = c;
return result;
}
/** Return the maximum of three numbers */
public static int max(int a, int b, int c) {
int result = a;
if (b > result) result = b;
if (c > result) result = c;
return result;
}
/**
* Standard logistic function
*
* @param x
* @return
*/
public static double logistic(double x) {
double ea = Math.exp(-x);
double df = (1 / (1.0f + ea));
if (Double.isNaN(df)) return (x > 0) ? 1 : 0;
return df;
}
public static double softplus(double x) {
if (x > 100) return x;
if (x < -100) return 0.0;
return Math.log(1 + Math.exp(x));
}
public static double tanhScaled(double x) {
return 1.7159 * Math.tanh((2.0 / 3.0) * x);
}
public static double tanhScaledDerivative(double x) {
double ta = Math.tanh((2.0 / 3.0) * x);
return (1.7159 * (2.0 / 3.0)) * (ta * (1 - ta));
}
public static double inverseLogistic(double y) {
if (y >= 1) return 800;
if (y <= 0) return -800;
double ea = y / (1.0 - y);
return Math.log(ea);
}
public static double logisticDerivative(double x) {
double sa = logistic(x);
return sa * (1 - sa);
}
public static double tanhDerivative(double x) {
double sa = Math.tanh(x);
return 1.0 - (sa * sa);
}
/** Return the (always non-negative) fractional part of a number */
public static float frac(float a) {
return a - roundDown(a);
}
/** Return the (always non-negative) fractional part of a number */
public static double frac(double a) {
return a - Math.floor(a);
}
/** Return the square of a number */
public static int square(byte b) {
return b * b;
}
/** Return the square of a number */
public static int square(int x) {
return x * x;
}
/** Return the square of a number */
public static float square(float x) {
return x * x;
}
/** Return the square of a number */
public static double square(double x) {
return x * x;
}
/** Round up to next integer */
public static int roundUp(double x) {
int i = (int) x;
return (i == x) ? i : (i + 1);
}
/** Round up to next integer */
public static int roundUp(Number x) {
return roundUp(x.doubleValue());
}
/** Round up to next integer */
public static int roundUp(float x) {
int i = (int) x;
return (i == x) ? i : (i + 1);
}
/** Rounds down (integer floor) of a double value */
public static int roundDown(double x) {
if (x >= 0) return (int) x;
int r = (int) x;
return (x == r) ? r : r - 1;
}
/** Round down to next smallest integer (towards negative infinity) */
public static int roundDown(float x) {
if (x >= 0) return (int) x;
int r = (int) x;
return (x == r) ? r : r - 1;
}
/**
* Soft maximum function
*/
public static double softMaximum(double x, double y) {
double max = Math.max(x, y);
double min = Math.min(x, y);
return max + Math.log(1.0 + Math.exp(max - min));
}
/** Bound a value within a given range */
public static final double bound(double v, double min, double max) {
if (v < min) return min;
if (v > max) return max;
return v;
}
/** Bound a value within a given range */
public static final float bound(float v, float min, float max) {
if (v < min) return min;
if (v > max) return max;
return v;
}
/** Bound a value within a given range */
public static final int bound(int v, int min, int max) {
if (v < min) return min;
if (v > max) return max;
return v;
}
/**
* Returns (x^pow) mod (2^32) as an int
*/
public static int modPower32Bit(int x, int pow) {
int result = 1;
for (int n = pow; n > 0; n >>>= 1) {
if ((n & 1) != 0) {
result *= x;
}
x *= x;
}
return result;
}
/** Tests whether a value is near zero, to a default tolerance level */
public static boolean notNearZero(double x) {
return (x < -EPSILON) || (x > EPSILON);
}
/** Double mod function with fractional divisor */
public static double mod(double num, double div) {
double result = num % div;
if (result < 0) result += div;
return result;
}
/** Triangle wave with wavelength 1.0, and range 0.0 - 1.0 */
public static double triangleWave(double x) {
x -= Math.floor(x);
return (x < 0.5) ? x * 2 : (2 - x * 2);
}
}
Ads help maintain this website.