All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.finmath.stochastic.RandomVariable Maven / Gradle / Ivy

/*
 * (c) Copyright Christian P. Fries, Germany. Contact: [email protected].
 *
 * Created on 21.10.2007
 * Created on 02.02.2014
 */
package net.finmath.stochastic;

import java.io.Serializable;
import java.util.List;
import java.util.function.DoubleBinaryOperator;
import java.util.function.DoubleUnaryOperator;
import java.util.function.IntToDoubleFunction;
import java.util.stream.DoubleStream;

import net.finmath.functions.DoubleTernaryOperator;

/**
 * This interface describes the methods implemented by an immutable random variable.
 *
 * The random variable is immutable, i.e. method calls like add, sub, mult will return
 * a new instance and leave the method receiver random variable unchanged (immutable).
 * This is used to ensure that arguments or return values are not changed.
 *
 * @author Christian Fries
 * @version 1.6
 */
public interface RandomVariable extends Serializable {

	/**
	 * Compare this random variable with a given one
	 *
	 * @param randomVariable Random variable to compare with.
	 * @return True if this random variable and the given one are equal, otherwise false
	 */
	boolean equals(RandomVariable randomVariable);

	/**
	 * Returns the filtration time.
	 *
	 * @return The filtration time.
	 */
	double getFiltrationTime();

	/**
	 * Returns the type priority.
	 *
	 * @return The type priority.
	 * @see ssrn abstract 3246127
	 */
	int getTypePriority();

	/**
	 * Evaluate at a given path or state.
	 *
	 * @param pathOrState Index of the path or state.
	 * @return Value of this random variable at the given path or state.
	 */
	double get(int pathOrState);

	/**
	 * Returns the number of paths or states.
	 *
	 * @return Number of paths or states.
	 */
	int size();

	/**
	 * Check if this random variable is deterministic in the sense that it is represented by a single double value.
	 * Note that the methods returns false, if the random variable is represented by a vector where each element has the same value.
	 *
	 * @return True if this random variable is deterministic.
	 */
	boolean isDeterministic();

	/**
	 * Returns the underlying values and a random variable.
	 *
	 * If the implementation supports an "inner representation", returns the inner representation. Otherwise just returns this.
	 *
	 * @return The underling values.
	 */
	default RandomVariable getValues() { return this; }

	/**
	 * Returns a vector representing the realization of this random variable.
	 * This method is merely useful for analysis. Its interpretation depends on the context (Monte-Carlo or lattice).
	 * The method does not expose an internal data model.
	 *
	 * @return Vector of realizations of this random variable.
	 */
	double[] getRealizations();

	/**
	 * Returns the double value if isDeterministic() is true. otherwise throws an {@link UnsupportedOperationException}.
	 *
	 * @return The double value if isDeterministic() is true, otherwise throws an  an {@link UnsupportedOperationException}.
	 */
	Double doubleValue();

	/**
	 * Returns the operator path → this.get(path) corresponding to this random variable.
	 *
	 * @return The operator path → this.get(path) corresponding to this random variable.
	 */
	IntToDoubleFunction getOperator();

	/**
	 * Returns a stream of doubles corresponding to the realizations of this random variable.
	 *
	 * @return A stream of doubles corresponding to the realizations of this random variable.
	 */
	DoubleStream getRealizationsStream();

	/**
	 * Returns the minimum value attained by this random variable.
	 *
	 * @return The minimum value.
	 */
	double getMin();

	/**
	 * Returns the maximum value attained by this random variable.
	 *
	 * @return The maximum value.
	 */
	double getMax();

	/**
	 * Returns the expectation of this random variable.
	 * The result of this method has to agrees with average().doubleValue().
	 *
	 * @return The average assuming equi-distribution.
	 */
	double getAverage();

	/**
	 * Returns the expectation of this random variable for a given probability measure (weight).
	 *
	 * The result of this method is (mathematically) equivalent to
	 * 
* this.mult(probabilities).getAverage() / probabilities.getAverage() *
* while the internal implementation may differ, e.g. being more efficient by performing multiplication and summation in the same loop. * * @param probabilities The probability weights. * @return The average assuming the given probability weights. */ double getAverage(RandomVariable probabilities); /** * Returns the variance of this random variable, i.e., * V where V = ((X-m)^2).getAverage() and X = this and m = X.getAverage(). * * @return The average assuming equi-distribution. */ double getVariance(); /** * Returns the variance of this random variable, i.e., * V where V = ((X-m)^2).getAverage(probabilities) and X = this and m = X.getAverage(probabilities). * * @param probabilities The probability weights. * @return The average assuming the given probability weights. */ double getVariance(RandomVariable probabilities); /** * Returns the sample variance of this random variable, i.e., * V * size()/(size()-1) where V = getVariance(). * * @return The sample variance. */ double getSampleVariance(); /** * Returns the standard deviation of this random variable, i.e., * sqrt(V) where V = ((X-m)^2).getAverage() and X = this and m = X.getAverage(). * * @return The standard deviation assuming equi-distribution. */ double getStandardDeviation(); /** * Returns the standard deviation of this random variable, i.e., * sqrt(V) where V = ((X-m)^2).getAverage(probabilities) and X = this and m = X.getAverage(probabilities). * * @param probabilities The probability weights. * @return The standard error assuming the given probability weights. */ double getStandardDeviation(RandomVariable probabilities); /** * Returns the standard error (discretization error) of this random variable. * For a Monte-Carlo simulation this is 1/Math.sqrt(n) * {@link #getStandardDeviation() }. * * @return The standard error assuming equi-distribution. */ double getStandardError(); /** * Returns the standard error (discretization error) of this random variable. * For a Monte-Carlo simulation this is 1/Math.sqrt(n) * {@link #getStandardDeviation(RandomVariable) }. * * @param probabilities The probability weights. * @return The standard error assuming the given probability weights. */ double getStandardError(RandomVariable probabilities); /** * Returns the quantile value for this given random variable, i.e., the value x such that P(this < x) = quantile, * where P denotes the probability measure. * The method will consider picewise constant values (with constant extrapolation) in the random variable. * That is getQuantile(0) wiil return the smallest value and getQuantile(1) will return the largest value. * * @param quantile The quantile level. * @return The quantile value assuming equi-distribution. */ double getQuantile(double quantile); /** * Returns the quantile value for this given random variable, i.e., the value x such that P(this < x) = quantile, * where P denotes the probability measure. * * @param quantile The quantile level. * @param probabilities The probability weights. * @return The quantile value assuming the given probability weights. */ double getQuantile(double quantile, RandomVariable probabilities); /** * Returns the expectation over a quantile for this given random variable. * The method will consider picewise constant values (with constant extrapolation) in the random variable. * For a ≤ b the method returns (Σa ≤ i ≤ b x[i]) / (b-a+1), where *
    *
  • a = min(max((n+1) * quantileStart - 1, 0, 1);
  • *
  • b = min(max((n+1) * quantileEnd - 1, 0, 1);
  • *
  • n = this.size();
  • *
* For quantileStart > quantileEnd the method returns getQuantileExpectation(quantileEnd, quantileStart). * * @param quantileStart Lower bound of the integral. * @param quantileEnd Upper bound of the integral. * @return The (conditional) expectation of the values between two quantile levels assuming equi-distribution. */ double getQuantileExpectation(double quantileStart, double quantileEnd); /** * Generates a Histogram based on the realizations stored in this random variable. * The returned result array's length is intervalPoints.length+1. *
    *
  • The value result[0] equals the relative frequency of values observed in the interval ( -infinity, intervalPoints[0] ].
  • *
  • The value result[i] equals the relative frequency of values observed in the interval ( intervalPoints[i-1], intervalPoints[i] ].
  • *
  • The value result[n] equals the relative frequency of values observed in the interval ( intervalPoints[n-1], infinity ).
  • *
* where n = intervalPoints.length. Note that the intervals are open on the left, closed on the right, i.e., * result[i] contains the number of elements x with intervalPoints[i-1] < x ≤ intervalPoints[i]. * * Thus, is you have a random variable which only takes values contained in the (sorted) array * possibleValues, then result = getHistogram(possibleValues) returns an * array where result[i] is the relative frequency of occurrence of possibleValues[i]. * * The sum of result[i] over all i is equal to 1, except for uninitialized random * variables where all values are 0. * * @param intervalPoints Array of ascending values defining the interval boundaries. * @return A histogram with respect to a provided interval. */ double[] getHistogram(double[] intervalPoints); /** * Generates a histogram based on the realizations stored in this random variable * using interval points calculated from the arguments, see also {@link #getHistogram(double[])}. * The interval points are * set with equal distance over an the interval of the specified standard deviation. * * The interval points used are * x[i] = mean + alpha[i] * standardDeviations * sigma * where *
    *
  • i = 0,..., numberOfPoints-1,
  • *
  • alpha[i] = (i - (numberOfPoints-1)/2.0) / ((numberOfPoints-1)/2.0),
  • *
  • mean = {@link #getAverage()},
  • *
  • sigma = {@link #getStandardDeviation()}.
  • *
* * The methods result is an array of two vectors, where result[0] are the * intervals center points ('anchor points') and result[1] contains the relative frequency for the interval. * The 'anchor point' for the interval (-infinity, x[0]) is x[0] - 1/2 (x[1]-x[0]) * and the 'anchor point' for the interval (x[n], infinity) is x[n] + 1/2 (x[n]-x[n-1]). * Here n = numberOfPoints is the number of interval points. * * @param numberOfPoints The number of interval points. * @param standardDeviations The number of standard deviations defining the discretization radius. * @return A histogram, given as double[2][], where result[0] are the center point of the intervals and result[1] is the value of {@link #getHistogram(double[])} for the given the interval points. The length of result[0] and result[1] is numberOfPoints+1. */ double[][] getHistogram(int numberOfPoints, double standardDeviations); /** * Return a cacheable version of this object (often a self-reference). * This method should be called when you store the object for later use, * i.e., assign it, or when the object is consumed in a function, but later * used also in another function. * * @return A cacheable version of this object (often a self-reference). */ RandomVariable cache(); /** * Applies x → operator(x) to this random variable. * It returns a new random variable with the result. * * @param operator An unary operator/function, mapping RandomVariable to RandomVariable. * @return New random variable with the result of the function. */ default RandomVariable appy(RandomOperator operator) { return operator.apply(this); } /** * Applies x → operator(x) to this random variable. * It returns a new random variable with the result. * * @param operator An unary operator/function, mapping double to double. * @return New random variable with the result of the function. */ RandomVariable apply(DoubleUnaryOperator operator); /** * Applies x → operator(x,y) to this random variable, where x is this random variable and y is a given random variable. * It returns a new random variable with the result. * * @param operator A binary operator/function, mapping (double,double) to double. * @param argument A random variable. * @return New random variable with the result of the function. */ RandomVariable apply(DoubleBinaryOperator operator, RandomVariable argument); /** * Applies x → operator(x,y,z) to this random variable, where x is this random variable and y and z are given random variable. * It returns a new random variable with the result. * * @param operator A ternary operator/function, mapping (double,double,double) to double. * @param argument1 A random variable representing y. * @param argument2 A random variable representing z. * @return New random variable with the result of the function. */ RandomVariable apply(DoubleTernaryOperator operator, RandomVariable argument1, RandomVariable argument2); /** * Applies x → min(x,cap) to this random variable. * It returns a new random variable with the result. * * @param cap The cap. * @return New random variable with the result of the function. */ RandomVariable cap(double cap); /** * Applies x → max(x,floor) to this random variable. * It returns a new random variable with the result. * * @param floor The floor. * @return New random variable with the result of the function. */ RandomVariable floor(double floor); /** * Applies x → x + value to this random variable. * It returns a new random variable with the result. * * @param value The value to add. * @return New random variable with the result of the function. */ RandomVariable add(double value); /** * Applies x → x - value to this random variable. * @param value The value to subtract. * @return New random variable with the result of the function. */ RandomVariable sub(double value); /** * Applies x → value - x to this random variable. * @param value The value from which this is subtracted. * @return New random variable with the result of the function. */ default RandomVariable bus(double value) { return this.mult(-1).add(value); } /** * Applies x → x * value to this random variable. * @param value The value to multiply. * @return New random variable with the result of the function. */ RandomVariable mult(double value); /** * Applies x → x / value to this random variable. * @param value The value to divide. * @return New random variable with the result of the function. */ RandomVariable div(double value); /** * Applies x → value / x to this random variable. * @param value The numerator of the ratio where this is the denominator. * @return New random variable with the result of the function. */ default RandomVariable vid(double value) { return invert().mult(value); } /** * Applies x → pow(x,exponent) to this random variable. * @param exponent The exponent. * @return New random variable with the result of the function. */ RandomVariable pow(double exponent); /** * Returns a random variable which is deterministic and corresponds * the expectation of this random variable. * * @return New random variable being the expectation of this random variable. */ RandomVariable average(); /** * Returns a random variable which is deterministic and corresponds * the expectation of this random variable. * * @return New random variable being the expectation of this random variable. */ default RandomVariable expectation() { return average(); } /** * Returns a random variable which is deterministic and corresponds * the variance of this random variable. * * Note: The default implementation is a biased estimator. Use the factor n/(n-1) to convert to an unbiased estimator. * * @return New random variable being the variance of this random variable and the argument. */ default RandomVariable variance() { final RandomVariable meanDeviation = this.sub(average()); return meanDeviation.squared().average(); } /** * Returns a random variable which is deterministic and corresponds * the covariance of this random variable and the argument. * * Note: The default implementation is a biased estimator. Use the factor n/(n-1) to convert to an unbiased estimator. * * @param value The random variable Y to be used in Cov(X,Y) with X being this. * @return New random variable being the covariance of this random variable and the argument. */ default RandomVariable covariance(RandomVariable value) { return this.sub(average()).mult(value.sub(value.average())).average(); } /** * Returns the conditional expectation using a given conditional expectation estimator. * * @param conditionalExpectationOperator A given conditional expectation estimator. * @return The conditional expectation of this random variable (as a random variable) */ default RandomVariable getConditionalExpectation(final ConditionalExpectationEstimator conditionalExpectationOperator) { return conditionalExpectationOperator.getConditionalExpectation(this); } /** * Applies x → x * x to this random variable. * @return New random variable with the result of the function. */ RandomVariable squared(); /** * Applies x → sqrt(x) to this random variable. * @return New random variable with the result of the function. */ RandomVariable sqrt(); /** * Applies x → exp(x) to this random variable. * @return New random variable with the result of the function. */ RandomVariable exp(); /** * Applies x → expm1(x) (that is x → exp(x)-1.0) to this random variable. * @return New random variable with the result of the function. */ default RandomVariable expm1() { return this.exp().sub(1.0); } /** * Applies x → log(x) to this random variable. * @return New random variable with the result of the function. */ RandomVariable log(); /** * Applies x → sin(x) to this random variable. * @return New random variable with the result of the function. */ RandomVariable sin(); /** * Applies x → cos(x) to this random variable. * @return New random variable with the result of the function. */ RandomVariable cos(); /** * Applies x → x+randomVariable to this random variable. * @param randomVariable A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable add(RandomVariable randomVariable); /** * Applies x → x-randomVariable to this random variable. * @param randomVariable A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable sub(RandomVariable randomVariable); /** * Applies x → randomVariable-x to this random variable. * @param randomVariable A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable bus(RandomVariable randomVariable); /** * Applies x → x*randomVariable to this random variable. * @param randomVariable A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable mult(RandomVariable randomVariable); /** * Applies x → x/randomVariable to this random variable. * @param randomVariable A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable div(RandomVariable randomVariable); /** * Applies x → randomVariable/x to this random variable. * @param randomVariable A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable vid(RandomVariable randomVariable); /** * Applies x → min(x,cap) to this random variable. * @param cap The cap. A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable cap(RandomVariable cap); /** * Applies x → max(x,floor) to this random variable. * @param floor The floor. A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable floor(RandomVariable floor); /** * Applies x → x * (1.0 + rate * periodLength) to this random variable. * @param rate The accruing rate. A random variable (compatible with this random variable). * @param periodLength The period length * @return New random variable with the result of the function. */ RandomVariable accrue(RandomVariable rate, double periodLength); /** * Applies x → x / (1.0 + rate * periodLength) to this random variable. * @param rate The discounting rate. A random variable (compatible with this random variable). * @param periodLength The period length * @return New random variable with the result of the function. */ RandomVariable discount(RandomVariable rate, double periodLength); /** * Applies x → (x ≥ 0 ? valueIfTriggerNonNegative : valueIfTriggerNegative) * @param valueIfTriggerNonNegative The value used if this is greater or equal 0 * @param valueIfTriggerNegative The value used if the this is less than 0 * @return New random variable with the result of the function. */ RandomVariable choose(RandomVariable valueIfTriggerNonNegative, RandomVariable valueIfTriggerNegative); /** * Applies x → 1/x to this random variable. * @return New random variable with the result of the function. */ RandomVariable invert(); /** * Applies x → Math.abs(x), i.e. x → |x| to this random variable. * @return New random variable with the result of the function. */ RandomVariable abs(); /** * Applies x → x + factor1 * factor2 * @param factor1 The factor 1. A random variable (compatible with this random variable). * @param factor2 The factor 2. * @return New random variable with the result of the function. */ RandomVariable addProduct(RandomVariable factor1, double factor2); /** * Applies x → x + factor1 * factor2 * @param factor1 The factor 1. A random variable (compatible with this random variable). * @param factor2 The factor 2. A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable addProduct(RandomVariable factor1, RandomVariable factor2); /** * Applies x → x + numerator / denominator * * @param numerator The numerator of the ratio to add. A random variable (compatible with this random variable). * @param denominator The denominator of the ratio to add. A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable addRatio(RandomVariable numerator, RandomVariable denominator); /** * Applies x → x - numerator / denominator * * @param numerator The numerator of the ratio to sub. A random variable (compatible with this random variable). * @param denominator The denominator of the ratio to sub. A random variable (compatible with this random variable). * @return New random variable with the result of the function. */ RandomVariable subRatio(RandomVariable numerator, RandomVariable denominator); /** * Applies \( x \mapsto x + \sum_{i=0}^{n-1} factor1_{i} * factor2_{i} * @param factor1 The factor 1. A list of random variables (compatible with this random variable). * @param factor2 The factor 2. A list of random variables (compatible with this random variable). * @return New random variable with the result of the function. */ default RandomVariable addSumProduct(final RandomVariable[] factor1, final RandomVariable[] factor2) { RandomVariable result = this; for(int i=0; i factor1, final List factor2) { RandomVariable result = this; for(int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy