desmoj.core.dist.ContDistCustom.java Source code

Java tutorial

Introduction

Here is the source code for desmoj.core.dist.ContDistCustom.java

Source

package desmoj.core.dist;

import org.apache.commons.math.analysis.BisectionSolver;
import org.apache.commons.math.analysis.UnivariateRealSolver;

import desmoj.core.simulator.Model;

/**
 * Distribution returning values according to a user-specified distribution
 * function.
 * 
 * It is important that the used function is an actual distribution function,
 * meaning it must be strictly monotonically increasing from 0 to 1. You also
 * need to specify the lower and upper bounds of the distribution, meaning the
 * values at which the cumulative probability is 0 and 1 respectively. If these
 * requirements are not fulfilled, the class might return false and/or no
 * samples.
 * 
 * 
 * @version DESMO-J, Ver. 2.3.5 copyright (c) 2013
 * @author Peter Wueppen
 * 
 *         Licensed under the Apache License, Version 2.0 (the "License"); you
 *         may not use this file except in compliance with the License. You may
 *         obtain a copy of the License at
 *         http://www.apache.org/licenses/LICENSE-2.0
 * 
 *         Unless required by applicable law or agreed to in writing, software
 *         distributed under the License is distributed on an "AS IS" BASIS,
 *         WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 *         implied. See the License for the specific language governing
 *         permissions and limitations under the License.
 * @param <N>
 * 
 */

public class ContDistCustom extends ContDist {

    /**
     * User-defined distribution function
     */
    protected Function distFunction;

    /**
     * Lower bound of possibly sampled values. This is needed for the underlying
     * zero root solving algorithms.
     */
    protected double lowerBound;

    /**
     * Upper bound of possibly sampled values. This is needed for the underlying
     * zero root solving algorithms.
     */
    protected double upperBound;

    /**
     * The current Number generated by RandomNumberGenerator.
     */
    protected double randomNumber;

    /**
     * Instantiates the CustomContDist, making it possible to get samples. The
     * user-defined CustomFunction has to be given here.
     * 
     * @param owner
     *            Model : The distribution's owner
     * @param name
     *            java.lang.String : The distribution's name
     * @param function
     *            Function: User-defined distribution Function
     * @param showInReport
     *            boolean : Flag for producing reports
     * @param showInTrace
     *            boolean : Flag for producing trace output
     */
    public ContDistCustom(Model owner, String name, Function function, double lower, double upper,
            boolean showInReport, boolean showInTrace) {
        super(owner, name, showInReport, showInTrace);
        distFunction = function;
        lowerBound = lower;
        upperBound = upper;
    }

    /**
     * Returns the lower bound of possible values of this distribution.
     * 
     * @return double : The lower bound of possible values of this distribution.
     */
    public double getLowerBound() {

        return lowerBound;
    }

    /**
     * Returns the upper bound of possible values of this distribution.
     * 
     * @return double : The upper bound of possible values of this distribution.
     */
    public double getUpperBound() {

        return upperBound;
    }

    /**
     * Returns the upper bound of possible values of this distribution.
     * 
     * @return double : The upper bound of possible values of this distribution.
     */
    public Function getFunction() {

        return distFunction;
    }

    /**
     * Creates the default reporter for the CustomContDist distribution.
     * 
     * @return Reporter : The reporter for the CustomContDist distribution
     * @see desmoj.core.report.ContDistCustomReporter
     */
    public desmoj.core.report.Reporter createReporter() {

        return new desmoj.core.report.ContDistCustomReporter(this);

    }

    /**
     * Returns the next sample from this distribution. The value depends upon
     * the seed, the number of values taken from the stream by using this method
     * before and the alpha and beta parameters specified for this distribution.
     * 
     * @return Double : The next gamma distributed sample from this
     *         distribution.
     */
    public Double sample() {

        double newSample; //

        incrementObservations(); // increase count of samples

        randomNumber = randomGenerator.nextDouble();
        if (isAntithetic()) {
            randomNumber = 1 - randomNumber;

        }

        Function functiontosolve = new Function() {

            public double value(double x) {

                return distFunction.value(x) - randomNumber;
                // Decrease input function by randomNumber to make the desired
                // sample be at a zero root.
            }

            public String getDescription() {
                return null;
            }
        };

        UnivariateRealSolver solver = new BisectionSolver(functiontosolve);
        try {
            newSample = solver.solve(lowerBound, upperBound); // Finding zero
            // root

        } catch (Exception e) {
            sendWarning("Failed to find sample, returning -1",
                    "CustomContDist : " + getName() + " Method: sample()",
                    "The solver could not deal with the distribution function specified.",
                    "Make sure the CustomFunction this Distribution is using is a proper "
                            + "distribution function and the upper and lower bounds are set accordingly");
            newSample = -1;
        }
        if (this.currentlySendTraceNotes())
            this.traceLastSample(Double.toString(newSample));
        return newSample;

    }
}