Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.exigen.ie.constrainer.impl.FloatCalc Maven / Gradle / Ivy
package com.exigen.ie.constrainer.impl;
import com.exigen.ie.constrainer.Constrainer;
import com.exigen.ie.constrainer.Failure;
import com.exigen.ie.constrainer.FloatExp;
// IEEE 754 NAN and inf RULES
// - result of any operation with the operand NAN = NAN
// - (-inf)+(+inf) = NAN
// - (+inf)-(+inf) = NAN
// - (-inf)-(-inf) = NAN
// - inf*0 = NAN
// - inf/inf = NAN
// - 0/0 = NAN ((!0)/0 = (+/-)inf)
//
// We have to try the rules:
// - values can be finite doubles, +inf, -inf but not NaN
/**
* A helper for the floating-point arithmetic.
*/
public final class FloatCalc
{
/**
* A Not-a-Number (NaN) value of type double
.
* @see Double#NaN
*/
static public final double NaN = Double.NaN;
/**
* The positive infinity of type double
.
* @see Double#POSITIVE_INFINITY
*/
static public final double pInf = Double.POSITIVE_INFINITY;
/**
* The negative infinity of type double
.
* @see Double#NEGATIVE_INFINITY
*/
static public final double nInf = Double.NEGATIVE_INFINITY;
/**
* Returns true if the specified numbers are equal
* with the precision
*/
public static boolean eq (double d1, double d2) {
return Math.abs (d1 - d2) < Constrainer.FLOAT_PRECISION;
}
/**
* Returns true if the first number more than the second number
* with the precision
*/
public static boolean gt (double d1, double d2) {
return (d1 - d2) > Constrainer.FLOAT_PRECISION;
}
/**
* Returns true if the first number is more or equal to the second number
* with the precision
*/
public static boolean ge (double d1, double d2) {
return d1 - d2 > - Constrainer.FLOAT_PRECISION;
}
/**
* Returns true if the specified number is the special Not-a-Number (NaN) value.
* @see Double#isNaN
*/
public static boolean isNan(double v)
{
return Double.isNaN(v);
}
/**
* Returns true if the specified number is infinitely large in magnitude.
* @see Double#isInfinite
*/
public static boolean isInf(double v)
{
return Double.isInfinite(v);
}
/**
* Returns the expression: min(1 / [min..max])
.
* Result may be finite number or -inf.
*/
public static double inverseMin(double min, double max)
{
assertMinMax(min, max);
double _min;
// strictly positive or strictly negative
if(min > 0 || max < 0)
{
_min = 1/max;
}
// [0..>0]
else if(min == 0 && max > 0)
{
_min = 1/max;
}
// [<0..0]
else if(max == 0 && min < 0)
{
_min = nInf;
}
// [<0..>0] or [0..0]
else
{
_min = nInf;
}
return _min;
}
/**
* Returns the expression: max(1 / [min..max])
.
* Result may be finite number or +inf.
*/
public static double inverseMax(double min, double max)
{
assertMinMax(min, max);
double _max;
// strictly positive or strictly negative
if(min > 0 || max < 0)
{
_max = 1/min;
}
// [0..>0]
else if(min == 0 && max > 0)
{
_max = pInf;
}
// [<0..0]
else if(max == 0 && min < 0)
{
_max = 1/min;
}
// [<0..>0] or [0..0]
else
{
_max = pInf;
}
return _max;
}
/**
* Returns the expression: min(1 / [v..v])
.
* Result may be finite number or -inf.
*/
public static double inverseMin(double v)
{
return v != 0 ? 1/v : nInf;
}
/**
* Returns the expression: max(1 / [v..v])
.
* Result may be finite number or +inf.
*/
public static double inverseMax(double v)
{
return v != 0 ? 1/v : pInf;
}
/**
* Returns the expression: log(x,base)
.
*/
public static double calc_log(double x, double base)
{
// log(x,e)=log(x,base)*log(base,e)
return Math.log(x) / Math.log(base);
}
/**
* Returns x satisfying the equation: y = pow(x,v)
.
*/
public static double solve_pow(double y, double v)
{
// y=pow(x,v) -> pow(y,1/v)=pow(pow(x,v),1/v)=x
double x = Math.pow(y,1/v);
// System.out.println(y+"=pow("+x+","+v+")["+Math.pow(x,v)+"]"); // check
return x;
}
/**
* Returns the expression: min([min1..max1]*[min2..max2])
* where [min1..max1] ge 0
.
*/
public static double productMinP(double min1, double max1, double min2)
{
if(min2 >= 0)
return min1 * min2;
else
return max1 * min2;
}
/**
* Returns the expression: max([min1..max1]*[min2..max2])
* where [min1..max1] ge 0
.
*/
public static double productMaxP(double min1, double max1, double max2)
{
if(max2 >= 0)
return max1 * max2;
else
return min1 * max2;
}
/**
* Returns the expression: min([min1..max1]*[min2..max2])
* where [min1..max1] le 0
.
*/
public static double productMinN(double min1, double max1, double max2)
{
if(max2 >= 0)
return min1 * max2;
else
return max1 * max2;
}
/**
* Returns the expression: max([min1..max1]*[min2..max2])
* where [min1..max1] le 0
.
*/
public static double productMaxN(double min1, double max1, double min2)
{
if(min2 >= 0)
return max1 * min2;
else
return min1 * min2;
}
/**
* Returns the expression: min([min1..max1]*[min2..max2])
.
*/
public static double productMin(double min1, double max1, double min2, double max2)
{
// exp1 >= 0
if(min1 >= 0)
return productMinP(min1, max1, min2);
// exp1 <= 0
else if(max1 <= 0)
return productMinN(min1, max1, max2);
// exp1 changes sign
else
{
// exp2 >= 0
if(min2 >= 0)
return min1 * max2;
// exp2 <= 0
else if(max2 <= 0)
return max1 * min2;
// exp2 changes sign
else
{
return Math.min(max1*min2,min1*max2);
}
}
}
/**
* Returns the expression: max([min1..max1]*[min2..max2])
.
*/
public static double productMax(double min1, double max1, double min2, double max2)
{
// exp1 >= 0
if(min1 >= 0)
return productMaxP(min1, max1, max2);
// exp1 <= 0
else if(max1 <= 0)
return productMaxN(min1, max1, min2);
// exp1 changes sign
else
{
// exp2 >= 0
if(min2 >= 0)
return max1 * max2;
// exp2 <= 0
else if(max2 <= 0)
return min1 * min2;
// exp2 changes sign
else
{
return Math.max(min1*min2,max1*max2);
}
}
}
/**
* Adjust the expression exp2 so that: min([min1..max1]*[min2..max2]) ge min
* where [min1..max1] ge 0
.
*/
static public void productSetMinP(double min, double min1, double max1, FloatExp exp2)
throws Failure
{
if(min == 0)
{
if(min1 > 0)
exp2.setMin(0);
}
else
{
double v = min > 0 ? max1 : min1;
if(v != 0)
{
double min2 = min / v;
exp2.setMin(min2);
}
}
}
/**
* Adjust the expression exp2 so that: min([min1..max1]*[min2..max2]) le max
* where [min1..max1] ge 0
.
*/
static public void productSetMaxP(double max, double min1, double max1, FloatExp exp2)
throws Failure
{
if(max == 0)
{
if(min1 > 0)
exp2.setMax(0);
}
else
{
double v = max > 0 ? min1 : max1;
if(v != 0)
{
double max2 = max / v;
exp2.setMax(max2);
}
}
}
/**
* Adjust the expression exp2 so that: min([min1..max1]*[min2..max2]) ge min
* where [min1..max1] le 0
.
*/
static public void productSetMinN(double min, double min1, double max1, FloatExp exp2)
throws Failure
{
if(min == 0)
{
if(max1 < 0)
exp2.setMax(0);
}
else
{
double v = min > 0 ? min1 : max1;
if(v != 0)
{
double max2 = min / v;
exp2.setMax(max2);
}
}
}
/**
* Adjust the expression exp2 so that: min([min1..max1]*[min2..max2]) le max
* where [min1..max1] le 0
.
*/
static public void productSetMaxN(double max, double min1, double max1, FloatExp exp2)
throws Failure
{
if(max == 0)
{
if(max1 < 0)
exp2.setMin(0);
}
else
{
double v = max > 0 ? max1 : min1;
if(v != 0)
{
double min2 = max / v;
exp2.setMin(min2);
}
}
}
/**
* Adjust the expression exp2 so that: min([min1..max1]*[min2..max2]) ge min
.
*/
static public void productSetMin(double min, FloatExp exp1, FloatExp exp2)
throws Failure
{
double min1, max1;
// exp1 >= 0
if((min1=exp1.min()) >= 0)
{
productSetMinP(min,min1,exp1.max(),exp2);
}
// exp1 <= 0
else if((max1=exp1.max()) <= 0)
{
productSetMinN(min,min1,max1,exp2);
}
else // exp1 changes sign
{
if(min > 0)
{
double m = min1 / min;
double M = max1 / min;
exp2.removeRange(m,M);
}
}
}
/**
* Adjust the expression exp2 so that: max([min1..max1]*[min2..max2]) le max
.
*/
static public void productSetMax(double max, FloatExp exp1, FloatExp exp2)
throws Failure
{
double min1, max1;
// exp1 >= 0
if((min1=exp1.min()) >= 0)
{
productSetMaxP(max,min1,exp1.max(),exp2);
}
// exp1 <= 0
else if((max1=exp1.max()) <= 0)
{
productSetMaxN(max,min1,max1,exp2);
}
else // exp1 changes sign
{
if(max < 0)
{
double m = max1 / max;
double M = min1 / max;
exp2.removeRange(m,M);
}
}
}
/**
* Returns the expression: max(sqr(min),sqr(max))
.
*/
public static double sqrMax(double min, double max)
{
return Math.max(min*min,max*max);
}
/**
* Returns the expression: min(sqr(min),sqr(max))
.
*/
public static double sqrMin(double min, double max)
{
// min >= 0 && max >= 0
if (min >= 0)
return min*min;
// min < 0 && max >= 0
if (max >= 0)
return 0;
// min < 0 && max < 0
return max*max;
}
public static void doAssert(boolean v, String s)
{
if(v) return;
System.out.println("Assertion failed: "+s);
}
public static void assertMinMax(double min, double max)
{
doAssert(!isNan(min),"min not NaN");
doAssert(!isNan(max),"max not NaN");
doAssert(min <= max,"min <= max");
}
} //~ FloatCalc