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.