package cz.cuni.lf1.lge.ThunderSTORM.util;
import org.apache.commons.math3.util.FastMath;
/**
* This class wraps mathematical functions used in ThunderSTORM.
*
* The reason for this is that the common java.lang.Math class is missing some
* of the methods we need to use. Also the methods in the class are a bit slow
* for our needs. So it is more convenient to have this class (Adapter pattern)
* to not need to commit changes inside the application code and instead of that
* use methods in this class to globaly change the methods we want to use. Our
* decision was to use highly optimized FastMath class from Apache Commons Math3
* library, which performs much better in our scenario (many calls to
* {@code exp}) than the general Java Math class.
*/
public class MathProxy {
/**
* PI constant ({@mathjax \pi}).
*/
public static final double PI = org.apache.commons.math3.util.FastMath.PI;
/**
* Raise a double to an int power.
*
* @param x number to raise
* @param n exponent
* @return {@mathjax x^n}
*/
public static double pow(double x, int n) {
return org.apache.commons.math3.util.FastMath.pow(x, n);
}
/**
* Raise a double to a double power.
*
* @param x number to raise
* @param n exponent
* @return {@mathjax x^n}
*/
public static double pow(double x, double n) {
return org.apache.commons.math3.util.FastMath.pow(x, n);
}
/**
* Exponential function.
*
* @param x a value
* @return {@mathjax \mathrm{e}^x}
*/
public static double exp(double x) {
return org.apache.commons.math3.util.FastMath.exp(x);
}
/**
* Natural logarithm.
*
* @param x a value
* @return {@mathjax \mathrm{log}(x)}
*/
public static double log(double x) {
return org.apache.commons.math3.util.FastMath.log(x);
}
/**
* Get the smallest whole number larger than x.
*
* @param x number from which ceil is requested
* @return {@mathjax \lceil x \rceil}
*/
public static double ceil(double x) {
return org.apache.commons.math3.util.FastMath.ceil(x);
}
/**
* Compute the maximum of two values.
*
* @param a first value
* @param b second value
* @return b if a is lesser or equal to b, a otherwise
*/
public static int max(int a, int b) {
return org.apache.commons.math3.util.FastMath.max(a, b);
}
/**
* Get the closest long to x.
*
* @param x number from which closest long is requested
* @return closest long to x
*/
public static long round(double x) {
return org.apache.commons.math3.util.FastMath.round(x);
}
/**
* Get the closest int to x.
*
* @param x number from which closest int is requested
* @return closest int to x
*/
public static int round(float x) {
return org.apache.commons.math3.util.FastMath.round(x);
}
/**
* Compute the square root of a number.
*
* @param x number on which evaluation is done
* @return {@mathjax \sqrt{a}}
*/
public static double sqrt(double x) {
return org.apache.commons.math3.util.FastMath.sqrt(x);
}
/**
* Compute the square of a number.
*
* @param x a number
* @return {@mathjax x^2}
*/
public static double sqr(double x) {
return x * x;
}
public static Double abs(double val) { return java.lang.Math.abs(val); }
public static Double abs(Double val) {
return new Double(java.lang.Math.abs(val.doubleValue()));
}
public static double sin(double radians) {
return FastMath.sin(radians);
}
public static double cos(double radians) {
return FastMath.cos(radians);
}
public static double atan2(double y, double x) {
return FastMath.atan2(y, x);
}
public static int min(int a, int b) {
return FastMath.min(a, b);
}
public static double min(double a, double b) {
return FastMath.min(a, b);
}
public static double max(double a, double b) {
return FastMath.max(a, b);
}
public static double max(double... values) {
double max = values[0];
for(int i = 1; i < values.length; i++) {
if(values[i] > max) {
max = values[i];
}
}
return max;
}
public static int [] genIntSequence(int from, int length) {
int [] seq = new int[length];
for(int i = 0; i < length; i++) {
seq[i] = from + i;
}
return seq;
}
public static int nextPowerOf2(int num) {
int powof2 = 1;
while(powof2 < num) {
powof2 <<= 1;
}
return powof2;
}
public static double euclidDist2(double[] a, double[] b) {
double dist2 = 0.0;
int i = 0, im = min(a.length, b.length);
for ( ; i < im; i++) {
dist2 += sqr(a[i] - b[i]);
}
if (a.length > b.length) {
for ( ; i < a.length; i++) {
dist2 += sqr(a[i]);
}
} else if (b.length > a.length) {
for ( ; i < b.length; i++) {
dist2 += sqr(b[i]);
}
}
return dist2;
}
public static double euclidDist(double[] a, double[] b) {
return sqrt(euclidDist2(a, b));
}
}