MetalogLPSolver

class MetalogLPSolver(val initialRelativeFloor: Double = DEFAULT_INITIAL_RELATIVE_FLOOR, val maxEscalations: Int = DEFAULT_MAX_ESCALATIONS, val maxIterations: Int = DEFAULT_MAX_ITERATIONS, val constraintStep: Double = DEFAULT_CONSTRAINT_STEP, val constraintTailDecades: Int = DEFAULT_CONSTRAINT_TAIL_DECADES)(source)

Fits metalog coefficients as a linear program, minimizing the sum of absolute deviations subject to explicit monotonicity constraints.

This exists because least squares can produce coefficients whose quantile function is not strictly increasing, which is not a distribution at all. Constraining the derivative directly makes the solution valid by construction, so a term count that least squares cannot fit becomes usable rather than being discarded.

Two details matter for correctness. The constraints are imposed on the same probability grid the feasibility checker scans, because a coarser constraint grid lets the solution satisfy every constraint while still failing between grid points; measured on a case least squares could not fit, a grid ten times coarser produced a solution the checker rejected. And the floor on the derivative is expressed relative to the spread of the response rather than as a fixed number, because the derivative carries the units of the data: a fixed floor is vacuous on large-scale data and badly distorting on small-scale data. The solve is then verified and the floor raised until the checker agrees, which in testing never needed more than two attempts.

Coefficients are unrestricted in sign but the simplex solver requires non-negative variables, so each coefficient is carried as a difference of two non-negative variables, as are the residuals.

Parameters

initialRelativeFloor

the first derivative floor, as a fraction of the response spread

maxEscalations

how many times the floor may be raised before giving up

maxIterations

the iteration cap handed to the simplex solver

Constructors

Link copied to clipboard
constructor(initialRelativeFloor: Double = DEFAULT_INITIAL_RELATIVE_FLOOR, maxEscalations: Int = DEFAULT_MAX_ESCALATIONS, maxIterations: Int = DEFAULT_MAX_ITERATIONS, constraintStep: Double = DEFAULT_CONSTRAINT_STEP, constraintTailDecades: Int = DEFAULT_CONSTRAINT_TAIL_DECADES)

Types

Link copied to clipboard
object Companion

Properties

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

How many times the floor had to be raised on the most recent successful solve, which is one when no escalation was needed. Useful for diagnosing a fit that only just converged.

Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Functions

Link copied to clipboard
fun solveOrNull(probabilities: DoubleArray, z: DoubleArray, numTerms: Int, checker: MetalogFeasibilityChecker = MetalogFeasibilityChecker.defaultChecker): DoubleArray?

Coefficients that fit the response as closely as the absolute-deviation objective allows while defining a strictly increasing quantile function, or null when no such fit was found.