package umontreal.iro.lecuyer.util;
/**
* Represents a function computing a ratio of two values.
*
*/
public class RatioFunction implements MultivariateFunction {
private double zeroOverZero = Double.NaN;
/**
* Constructs a new ratio function.
*
*/
public RatioFunction() {}
/**
* Constructs a new ratio function that returns
* zeroOverZero for the special case of 0/0.
* See the {@link #getZeroOverZeroValue getZeroOverZeroValue} method for more information.
* The default value of zeroOverZero is Double.NaN.
*
* @param zeroOverZero the value for 0/0.
*
*
*/
public RatioFunction (double zeroOverZero) {
this.zeroOverZero = zeroOverZero;
}
/**
* Returns the value returned by {@link #evaluate((double[])) evaluate} in the
* case where the 0/0 function is calculated.
* The default value for 0/0 is Double.NaN.
*
*
* Generally, 0/0 is undefined, and therefore associated with the Double.NaN
* constant, meaning not-a-number.
* However, in certain applications, it can be defined differently to accomodate some special cases.
* For exemple, in a queueing system, if there are no arrivals, no customers are served,
* lost, queued, etc. As a result, many performance measures of interest turn out to be
* 0/0. Specifically, the loss probability, i.e., the ratio of
* lost customers over the number of arrivals, should be 0 if there is no arrival;
* in this case, 0/0 means 0.
* On the other hand, the service level, i.e., the fraction of customers waiting less than
* a fixed threshold, could be fixed to 1 if there is no arrival.
*
* @return the value for 0/0.
*
*/
public double getZeroOverZeroValue() {
return zeroOverZero;
}
/**
* Sets the value returned by {@link #evaluate((double[])) evaluate} for
* the undefined function 0/0 to zeroOverZero.
* See {@link #getZeroOverZeroValue getZeroOverZeroValue} for more information.
*
* @param zeroOverZero the new value for 0/0.
*
*
*/
public void setZeroOverZeroValue (double zeroOverZero) {
this.zeroOverZero = zeroOverZero;
}
public int getDimension() {
return 2;
}
public double evaluate (double... x) {
if (x.length != 2)
throw new IllegalArgumentException
("Invalid length of x");
if (x[0] == 0 && x[1] == 0)
return zeroOverZero;
return x[0]/x[1];
}
public double evaluateGradient (int i, double... x) {
if (x.length != 2)
throw new IllegalArgumentException
("Invalid length of x");
switch (i) {
case 0: return 1.0/x[1];
case 1: return -x[0]/(x[1]*x[1]);
default: throw new IndexOutOfBoundsException
("Invalid value of i: " + i);
}
}
}
Ads help maintain this website.