Class TurboLog
- java.lang.Object
-
- micycle.peasygradients.utilities.fastLog.FastLog
-
- micycle.peasygradients.utilities.fastLog.TurboLog
-
public class TurboLog extends FastLog
Implementation of the ICSILog algorithm as described in O. Vinyals, G. Friedland, N. Mirghafori "Revisiting a basic function on current CPUs: A fast logarithm implementation with adjustable accuracy" (2007).This class is based on the original algorithm description.
The algorithm has been changed to detects when the unbiased exponent is zero and maintains the precision.
Using look-up table the relative error
((fastLog(x)-Math.log(x))/Math.log(x))
is large (e>>1
) when the input valuex
is close to 1. So the algorithm detects values close to 1 and usesMath.log(double)
instead.
-
-
Field Summary
Fields Modifier and Type Field Description protected static long
LOWER_BOUND_MANTISSA
The lower bound mantissa (for a double) below 1 where the function switches to use Math.logprotected static int
LOWER_BOUND_MANTISSA_F
The lower bound mantissa (for a float) below 1 where the function switches to use Math.logstatic double
LOWER_ONE_BOUND
The bounds below 1 where the function switches to use Math.log.protected static long
UPPER_BOUND_MANTISSA
The upper bound mantissa (for a double) above 1 where the function switches to use Math.logprotected static int
UPPER_BOUND_MANTISSA_F
The upper bound mantissa (for a float) above 1 where the function switches to use Math.logstatic double
UPPER_ONE_BOUND
The bounds above 1 where the function switches to use Math.log.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected float
computeSubnormal(int mantissa)
Compute the log for a subnormal float-point number, i.e.protected double
computeSubnormal(long mantissa)
Compute the log for a subnormal float-point number, i.e.protected float
computeSubnormalF(long mantissa)
Compute the log for a subnormal float-point number, i.e.float
fastLog(double x)
Calculate the natural logarithm.float
fastLog(float x)
Calculate the natural logarithm.float
fastLog2(double x)
Calculate the logarithm to base 2.float
fastLog2(float x)
Calculate the logarithm to base 2.double
fastLog2D(double x)
Calculate the logarithm to base 2.double
fastLogD(double x)
Calculate the natural logarithm.double
getBase()
Gets the base.int
getN()
Gets the number of most significant bits to keep from the mantissa, i.e.double
getScale()
Gets the scale to convert from log2 to logB (the base given byFastLog.getBase()
) by multiplication.float
log(double x)
Calculate the logarithm to the configured base, handling special cases.float
log(float x)
Calculate the logarithm to the configured base, handling special cases.float
log2(double x)
Calculate the logarithm to base 2, handling special cases.float
log2(float x)
Calculate the logarithm to base 2, handling special cases.double
log2D(double x)
Calculate the logarithm to base 2, handling special cases.double
logD(double x)
Calculate the logarithm to the configured base, handling special cases.-
Methods inherited from class micycle.peasygradients.utilities.fastLog.FastLog
computeScale, exactLog2
-
-
-
-
Field Detail
-
LOWER_ONE_BOUND
public static final double LOWER_ONE_BOUND
The bounds below 1 where the function switches to use Math.log. This results in a maximum relative error of 7.95e-4 for x below 1.- See Also:
- Constant Field Values
-
UPPER_ONE_BOUND
public static final double UPPER_ONE_BOUND
The bounds above 1 where the function switches to use Math.log. This results in a maximum relative error of 7.09e-4 for x above 1.- See Also:
- Constant Field Values
-
LOWER_BOUND_MANTISSA
protected static final long LOWER_BOUND_MANTISSA
The lower bound mantissa (for a double) below 1 where the function switches to use Math.log
-
UPPER_BOUND_MANTISSA
protected static final long UPPER_BOUND_MANTISSA
The upper bound mantissa (for a double) above 1 where the function switches to use Math.log
-
LOWER_BOUND_MANTISSA_F
protected static final int LOWER_BOUND_MANTISSA_F
The lower bound mantissa (for a float) below 1 where the function switches to use Math.log
-
UPPER_BOUND_MANTISSA_F
protected static final int UPPER_BOUND_MANTISSA_F
The upper bound mantissa (for a float) above 1 where the function switches to use Math.log
-
-
Constructor Detail
-
TurboLog
public TurboLog()
Create a new natural logarithm calculation instance. This will hold the pre-calculated log values for base E and the default table size.
-
TurboLog
public TurboLog(int n)
Create a new natural logarithm calculation instance. This will hold the pre-calculated log values for base E and a table size depending on a given mantissa precision.- Parameters:
n
- The number of bits to keep from the mantissa. Table storage = 2^n * 4 bytes, e.g. 32Kb for n=13.
-
-
Method Detail
-
getN
public int getN()
Description copied from class:FastLog
Gets the number of most significant bits to keep from the mantissa, i.e. the binary precision of the floating point number before computing the log.
-
getScale
public double getScale()
Description copied from class:FastLog
Gets the scale to convert from log2 to logB (the base given byFastLog.getBase()
) by multiplication.
-
getBase
public double getBase()
Description copied from class:FastLog
Gets the base.
-
log
public float log(float x)
Description copied from class:FastLog
Calculate the logarithm to the configured base, handling special cases.Special cases:
- If the argument is NaN or less than zero, then the result is NaN.
- If the argument is positive infinity, then the result is positive infinity.
- If the argument is positive zero or negative zero, then the result is negative infinity.
- Specified by:
log
in classFastLog
- Parameters:
x
- the argument- Returns:
- log(x)
- See Also:
FastLog.getBase()
-
log
public float log(double x)
Description copied from class:FastLog
Calculate the logarithm to the configured base, handling special cases.Special cases:
- If the argument is NaN or less than zero, then the result is NaN.
- If the argument is positive infinity, then the result is positive infinity.
- If the argument is positive zero or negative zero, then the result is negative infinity.
- Specified by:
log
in classFastLog
- Parameters:
x
- the argument- Returns:
- log(x)
- See Also:
FastLog.getBase()
-
computeSubnormal
protected float computeSubnormal(int mantissa)
Compute the log for a subnormal float-point number, i.e. where the exponent is 0 then there is no assumed leading 1.Note that if the mantissa is zero this will fail!
No rounding to be done on sub-normal as the mantissa is shifted
<< 1
so the least significant digit is always 0.- Parameters:
mantissa
- the mantissa (already bit shifted by 1)- Returns:
- the log(x)
-
computeSubnormal
protected double computeSubnormal(long mantissa)
Compute the log for a subnormal float-point number, i.e. where the exponent is 0 then there is no assumed leading 1.Note that if the mantissa is zero this will fail!
No rounding to be done on sub-normal as the mantissa is shifted
<< 1
so the least significant digit is always 0.- Parameters:
mantissa
- the mantissa (already bit shifted by 1)- Returns:
- the log(x)
-
computeSubnormalF
protected float computeSubnormalF(long mantissa)
Compute the log for a subnormal float-point number, i.e. where the exponent is 0 then there is no assumed leading 1.Note that if the mantissa is zero this will fail!
No rounding to be done on sub-normal as the mantissa is shifted
<< 1
so the least significant digit is always 0.- Parameters:
mantissa
- the mantissa (already bit shifted by 1)- Returns:
- the log(x)
-
fastLog
public float fastLog(float x)
Calculate the natural logarithm. Requires the argument be finite and positive.Special cases:
- If the argument is NaN, then the result is incorrect
(
>fastLog(Float.MAX_VALUE)
). - If the argument is negative, then the result is incorrect
(
fastLog(-x)
). - If the argument is positive infinity, then the result is incorrect
(
>fastLog(Float.MAX_VALUE)
). - If the argument is positive zero or negative zero, then the result is negative infinity.
- Specified by:
fastLog
in classFastLog
- Parameters:
x
- the argument (must be strictly positive)- Returns:
- log(x)
- See Also:
FastLog.getBase()
- If the argument is NaN, then the result is incorrect
(
-
fastLog
public float fastLog(double x)
Calculate the natural logarithm. Requires the argument be finite and positive.Special cases:
- If the argument is NaN, then the result is incorrect
(
>fastLog(Double.MAX_VALUE)
). - If the argument is negative, then the result is incorrect
(
fastLog(-x)
). - If the argument is positive infinity, then the result is incorrect
(
>fastLog(Double.MAX_VALUE)
). - If the argument is positive zero or negative zero, then the result is negative infinity.
- Specified by:
fastLog
in classFastLog
- Parameters:
x
- the argument (must be strictly positive)- Returns:
- log(x)
- See Also:
FastLog.getBase()
- If the argument is NaN, then the result is incorrect
(
-
logD
public double logD(double x)
Description copied from class:FastLog
Calculate the logarithm to the configured base, handling special cases.Special cases:
- If the argument is NaN or less than zero, then the result is NaN.
- If the argument is positive infinity, then the result is positive infinity.
- If the argument is positive zero or negative zero, then the result is negative infinity.
This can be re-implemented if
FastLog.log(double)
can be returned in double precision.- Overrides:
logD
in classFastLog
- Parameters:
x
- the argument- Returns:
- log(x)
- See Also:
FastLog.getBase()
-
fastLogD
public double fastLogD(double x)
Calculate the natural logarithm. Requires the argument be finite and positive.Special cases:
- If the argument is NaN, then the result is incorrect
(
>fastLog(Double.MAX_VALUE)
). - If the argument is negative, then the result is incorrect
(
fastLog(-x)
). - If the argument is positive infinity, then the result is incorrect
(
>fastLog(Double.MAX_VALUE)
). - If the argument is positive zero or negative zero, then the result is negative infinity.
- Overrides:
fastLogD
in classFastLog
- Parameters:
x
- the argument (must be strictly positive)- Returns:
- log(x)
- See Also:
FastLog.getBase()
- If the argument is NaN, then the result is incorrect
(
-
log2
public float log2(float x)
Calculate the logarithm to base 2, handling special cases.Special cases:
- If the argument is NaN or less than zero, then the result is NaN.
- If the argument is positive infinity, then the result is positive infinity.
- If the argument is positive zero or negative zero, then the result is negative infinity.
Non-specialised version which calls the corresponding log function and divides by
Math.log(2)
.
-
log2
public float log2(double x)
Calculate the logarithm to base 2, handling special cases.Special cases:
- If the argument is NaN or less than zero, then the result is NaN.
- If the argument is positive infinity, then the result is positive infinity.
- If the argument is positive zero or negative zero, then the result is negative infinity.
Non-specialised version which calls the corresponding log function and divides by
Math.log(2)
.
-
fastLog2
public float fastLog2(float x)
Calculate the logarithm to base 2. Requires the argument be finite and strictly positive.Special cases:
- If the argument is NaN, then the result is incorrect.
- If the argument is negative, then the result is incorrect.
- If the argument is positive infinity, then the result is incorrect.
- If the argument is positive zero or negative zero, then the result is incorrect.
Sub-classes may handle some of the special cases.
Non-specialised version which calls the corresponding log function and divides by
Math.log(2)
.
-
fastLog2
public float fastLog2(double x)
Calculate the logarithm to base 2. Requires the argument be finite and strictly positive.Special cases:
- If the argument is NaN, then the result is incorrect.
- If the argument is negative, then the result is incorrect.
- If the argument is positive infinity, then the result is incorrect.
- If the argument is positive zero or negative zero, then the result is incorrect.
Sub-classes may handle some of the special cases.
Non-specialised version which calls the corresponding log function and divides by
Math.log(2)
.
-
log2D
public double log2D(double x)
Calculate the logarithm to base 2, handling special cases.Special cases:
- If the argument is NaN or less than zero, then the result is NaN.
- If the argument is positive infinity, then the result is positive infinity.
- If the argument is positive zero or negative zero, then the result is negative infinity.
This can be re-implemented if
FastLog.fastLog(double)
can be returned in double precision.Non-specialised version which calls the corresponding log function and divides by
Math.log(2)
.
-
fastLog2D
public double fastLog2D(double x)
Calculate the logarithm to base 2. Requires the argument be finite and strictly positive.Special cases:
- If the argument is NaN, then the result is incorrect.
- If the argument is negative, then the result is incorrect.
- If the argument is positive infinity, then the result is incorrect.
- If the argument is positive zero or negative zero, then the result is incorrect.
Sub-classes may handle some of the special cases.
This can be re-implemented if
FastLog.fastLog(double)
can be returned in double precision.Non-specialised version which calls the corresponding log function and divides by
Math.log(2)
.
-
-