MetalogDistribution

abstract class MetalogDistribution(coefficients: DoubleArray, lowerBound: Double = Double.NEGATIVE_INFINITY, upperBound: Double = Double.POSITIVE_INFINITY, name: String? = null) : Distribution, ContinuousDistributionIfc, InverseCDFIfc, GetRVariableIfc, MomentsIfc(source)

Shared behavior for the metalog distributions of Keelin (2016).

A metalog is defined by its quantile function, which is a linear combination of basis terms in the cumulative probability. The coefficients of that combination are held here as an array so the basis functions can be applied without repacking on each evaluation, while the concrete subclasses expose them as individually named parameters.

Boundedness is not a property of the subclass. It follows from which of the two bounds is finite, so a single subclass per term count covers the unbounded, semi-bounded, and bounded members of the family. A bound left infinite is absent.

The coefficients must always define a strictly increasing quantile function. Construction and every mutator enforce that, and a rejected change leaves the instance untouched, so an instance of this class is always a valid probability distribution.

Two consequences of the construction are worth knowing. There is no closed-form cumulative distribution function, so the cumulative and density functions solve the quantile equation numerically; monotonicity guarantees this converges. And the semi-bounded members need not possess the moments one might assume, because they exponentiate the quantile function; the mean and variance report a non-finite value rather than a fabricated one in that case.

Because an absent bound is carried as an infinity rather than as a null, the parameters of a metalog can include a non-finite value. Everything in the KSL that transports random variable parameters accepts one: the parameter setter, the simulation database, and the JSON codecs behind the model descriptor, the fitting documents, and the servers all handle infinities, the last because they already had to for control bounds. Two places do not, and neither is reachable from a running model. A configuration file cannot author an infinite bound through RVParameterOverride, which requires a finite value — no matter, since the bound comes from the random variable itself and an override need only name what is changing. And the general purpose RVData.toJson builds its own encoder without the special floating point option, so it rejects an unbounded metalog; write such a specification as TOML, whose format admits infinities natively.

Parameters

coefficients

the metalog scaling constants, of which there must be at least two

lowerBound

the lower bound, or negative infinity when unbounded below

upperBound

the upper bound, or positive infinity when unbounded above

name

an optional name

Inheritors

Constructors

Link copied to clipboard
constructor(coefficients: DoubleArray, lowerBound: Double = Double.NEGATIVE_INFINITY, upperBound: Double = Double.POSITIVE_INFINITY, name: String? = null)

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard

Which member of the metalog family this instance represents, derived from its bounds.

Link copied to clipboard
open override val kurtosis: Double

The standardized fourth central moment. This is not available in closed form for the metalog, so it is integrated numerically and cached. It is not a number when the fourth moment does not exist.

Link copied to clipboard

The lower bound of the support, or negative infinity when unbounded below. Assigning a value that would not leave the lower bound strictly below the upper bound fails and leaves the distribution unchanged.

Link copied to clipboard
open override val mean: Double
Link copied to clipboard
Link copied to clipboard

How many metalog terms this distribution uses.

Link copied to clipboard
open override val skewness: Double

The standardized third central moment. This is not available in closed form for the metalog, so it is integrated numerically and cached. It is not a number when the third moment does not exist.

Link copied to clipboard

The upper bound of the support, or positive infinity when unbounded above. Assigning a value that would not leave the upper bound strictly above the lower bound fails and leaves the distribution unchanged.

Link copied to clipboard
open override val variance: Double

Functions

Link copied to clipboard
open override fun cdf(x: Double): Double

Returns the F(x) = Pr{X <= x} where F represents the cumulative distribution function

Link copied to clipboard
protected fun changeCoefficient(index: Int, value: Double)

Assigns one coefficient by its zero-based index. The change is rejected, leaving the distribution unchanged, when it would produce a quantile function that is not strictly increasing.

Link copied to clipboard
protected fun clearMomentCache()

Discards cached moments. Called by every mutator, since all four cached values depend on the coefficients and the bounds.

Link copied to clipboard

A defensive copy of the coefficients, in the order in which they multiply the basis terms.

Link copied to clipboard
Link copied to clipboard
open override fun domain(): Interval

The actual support of the distribution, which is not always the interval between the declared bounds.

Link copied to clipboard

Reports how much margin the current coefficients have against the feasibility boundary, and where that margin is smallest. Useful for diagnosing a fit that is only just valid.

Link copied to clipboard
open override fun invCDF(p: Double): Double

Provides the inverse cumulative distribution function for the distribution

Link copied to clipboard
open override fun mean(): Double

Returns the mean or expected value of a distribution

Link copied to clipboard
fun momentsAreReliable(order: Int = 2): Boolean

Whether the mean and variance reported by this distribution are exact or approximate, and in the approximate case whether they are trustworthy.

Link copied to clipboard
open override fun parameters(): DoubleArray

The coefficients followed by the lower and upper bounds, so the array has two more elements than the number of terms. The bounds are reported even when infinite, because they are parameters of the distribution.

open override fun parameters(params: DoubleArray)

Assigns the coefficients and both bounds from a single array laid out as the array returned by the no-argument overload. Everything is validated before anything is assigned, so a rejected array leaves the distribution unchanged.

Link copied to clipboard
open override fun pdf(x: Double): Double

Returns the f(x) where f represents the probability density function for the distribution. Note this is not a probability.

Link copied to clipboard
protected fun probabilityAt(x: Double): Double

Solves the quantile equation for the cumulative probability that produces the supplied value.

Link copied to clipboard
protected fun quantileAtLogit(logit: Double): Double

The value of the random variable at the cumulative probability with the supplied logit.

Link copied to clipboard

The value of the random variable at the supplied cumulative probability, which must lie strictly inside the unit interval.

Link copied to clipboard
open override fun toString(): String

Names each coefficient by its position and reports both bounds, so the family member is evident from the output whether or not the bounds are finite.

Link copied to clipboard
open override fun variance(): Double

Returns the variance of the distribution if defined