Vector to scalar measures

Summary statistics

PortfolioOptimisers.VectorToScalarMeasure — Type
abstract type VectorToScalarMeasure <: AbstractAlgorithm

Abstract supertype for algorithms mapping a vector of real values to a single real value.

VectorToScalarMeasure provides a unified interface for algorithms that reduce a vector of real numbers to a scalar, such as minimum, mean, median, or maximum. These are used in constraint generation and centrality-based portfolio constraints to aggregate asset-level metrics.

Interfaces

In order to implement a new vector-to-scalar measure that works seamlessly with the library, subtype VectorToScalarMeasure and implement the following method:

Reduction method

  • vec_to_real_measure(measure::VectorToScalarMeasure, val::VecNum) -> Number: Reduces val to a single scalar.

Arguments

  • measure: Concrete subtype instance.
  • val: Vector of real values to reduce.

Returns

  • score::Number: Computed scalar.

Related

source
PortfolioOptimisers.MinValue — Type
struct MinValue <: VectorToScalarMeasure

Algorithm for reducing a vector of real values to its minimum.

Mathematical definition

\[\begin{align} \mathrm{MinValue}(\boldsymbol{v}) &= \underset{i}{\min}\ v_{i}\,. \end{align}\]

Where:

  • $\boldsymbol{v}$: The vector to reduce, of length $n$.
  • $v_{i}$: Its $i$-th entry, $i = 1,\ldots,n$.

The reduction carries no weights, so a weighted call gives the same value as an unweighted one.

Constructors

MinValue() -> MinValue

Examples

julia> PortfolioOptimisers.vec_to_real_measure(MinValue(), [1.2, 3.4, 0.7])0.7

Related

source
PortfolioOptimisers.MeanValue — Type
struct MeanValue{__T_w} <: VectorToScalarMeasure

Algorithm for reducing a vector of real values to its optionally weighted mean.

Mathematical definition

\[\begin{align} \mathrm{MeanValue}(\boldsymbol{v}) &= \frac{1}{n} \sum_{i=1}^{n} v_{i}\,, &&w = \mathrm{nothing}\,, \\ \mathrm{MeanValue}(\boldsymbol{v}) &= \frac{\sum_{i=1}^{n} w_{i} v_{i}}{\sum_{i=1}^{n} w_{i}}\,, &&\mathrm{otherwise}\,. \end{align}\]

Where:

  • $\boldsymbol{v}$: The vector to reduce, of length $n$.
  • $v_{i}$: Its $i$-th entry, $i = 1,\ldots,n$.
  • $w_{i}$: The $i$-th observation weight, from the field w.

The weighted form normalises by the total weight, so a weight vector scaled by a positive constant gives the same value. w must carry one entry per entry of $\boldsymbol{v}$.

Fields

  • w: Optional observation weights vector observations × 1, or a concrete subtype of DynamicAbstractWeights. If nothing, the computation is unweighted.

Constructors

MeanValue(;    w::Option{<:ObsWeights} = nothing,) -> MeanValue

Keywords correspond to the struct's fields.

Validation

  • If w is not nothing, !isempty(w).

Propagated parameters

When factory is called on this type, the following @wprop-tagged field is automatically propagated:

Observation weight parameters

When obs_weights_view is called on this type, the following fields are automatically indexed to the selected observations:

Examples

julia> PortfolioOptimisers.vec_to_real_measure(MeanValue(), [1.2, 3.4, 0.7])1.7666666666666666

Related

source
PortfolioOptimisers.MedianValue — Type
struct MedianValue{__T_w} <: VectorToScalarMeasure

Algorithm for reducing a vector of real values to its optionally weighted median.

Mathematical definition

\[\begin{align} \mathrm{MedianValue}(\boldsymbol{v}) &= Q_{\boldsymbol{v}}(0.5)\,, \\ \mathrm{MedianValue}(\boldsymbol{v}) &= Q_{\boldsymbol{v}, \boldsymbol{w}}(0.5)\,. \end{align}\]

Where:

  • $\boldsymbol{v}$: The vector to reduce, of length $n$.
  • $\boldsymbol{w}$: The observation weights, from the field w. The first line is the case w = nothing.
  • $Q_{\boldsymbol{v}}(p)$: The $p$-quantile of $\boldsymbol{v}$.
  • $Q_{\boldsymbol{v}, \boldsymbol{w}}(p)$: The weighted $p$-quantile of $\boldsymbol{v}$, as StatsBase defines it.

Both forms are quantiles, and both interpolate. Neither is an order statistic, so the result need not be an entry of $\boldsymbol{v}$. On a vector of even length the unweighted form averages the two middle entries, and the weighted form interpolates between the two entries that bracket half the weight mass.

Fields

  • w: Optional observation weights vector observations × 1, or a concrete subtype of DynamicAbstractWeights. If nothing, the computation is unweighted.

Constructors

MedianValue(;    w::Option{<:ObsWeights} = nothing,) -> MedianValue

Keywords correspond to the struct's fields.

Validation

  • If w is not nothing, !isempty(w).

Propagated parameters

When factory is called on this type, the following @wprop-tagged field is automatically propagated:

Observation weight parameters

When obs_weights_view is called on this type, the following fields are automatically indexed to the selected observations:

Examples

julia> PortfolioOptimisers.vec_to_real_measure(MedianValue(), [1.2, 3.4, 0.7])1.2

Related

source
PortfolioOptimisers.MaxValue — Type
struct MaxValue <: VectorToScalarMeasure

Algorithm for reducing a vector of real values to its maximum.

Mathematical definition

\[\begin{align} \mathrm{MaxValue}(\boldsymbol{v}) &= \underset{i}{\max}\ v_{i}\,. \end{align}\]

Where:

  • $\boldsymbol{v}$: The vector to reduce, of length $n$.
  • $v_{i}$: Its $i$-th entry, $i = 1,\ldots,n$.

The reduction carries no weights, so a weighted call gives the same value as an unweighted one.

Constructors

MaxValue() -> MaxValue

Examples

julia> PortfolioOptimisers.vec_to_real_measure(MaxValue(), [1.2, 3.4, 0.7])3.4

Related

source
PortfolioOptimisers.StdValue — Type
struct StdValue{__T_w, __T_corrected} <: VectorToScalarMeasure

Algorithm for reducing a vector of real values to its optionally weighted standard deviation. The unweighted default is safe and the weighted default is not: corrected = true under a plain StatsBase.Weights raises an ArgumentError, because that type declares no bias correction. Pass an AnalyticWeights, a FrequencyWeights or a ProbabilityWeights, or set corrected = false.

Mathematical definition

\[\begin{align} \mathrm{StdValue}(\boldsymbol{v}) &= \sqrt{\mathrm{VarValue}(\boldsymbol{v})}\,. \end{align}\]

Where:

  • $\boldsymbol{v}$: The vector to reduce, of length $n$.
  • $\mathrm{VarValue}(\boldsymbol{v})$: The variance under the same w and the same corrected, whose four denominators VarValue states.

corrected selects the denominator of the variance, and the square root carries that choice through. The unweighted default corrected = true divides by $n - 1$.

Fields

  • w: Optional observation weights vector observations × 1, or a concrete subtype of DynamicAbstractWeights. If nothing, the computation is unweighted.
  • corrected: Whether to apply Bessel's correction.

Constructors

StdValue(;    w::Option{<:ObsWeights} = nothing,    corrected::Bool = true,) -> StdValue

Keywords correspond to the struct's fields.

Validation

  • If w is not nothing, !isempty(w).

Propagated parameters

When factory is called on this type, the following @wprop-tagged field is automatically propagated:

Observation weight parameters

When obs_weights_view is called on this type, the following fields are automatically indexed to the selected observations:

Examples

julia> PortfolioOptimisers.vec_to_real_measure(StdValue(), [1.2, 3.4, 0.7])1.4364307617610164

Related

source
PortfolioOptimisers.VarValue — Type
struct VarValue{__T_w, __T_corrected} <: VectorToScalarMeasure

Algorithm for reducing a vector of real values to its optionally weighted variance. The weighted default raises: a plain StatsBase.Weights declares no bias correction, so corrected = true under it raises an ArgumentError rather than returning a value. Pass one of the three corrected weight types below, or set corrected = false.

Mathematical definition

\[\begin{align} \mathrm{VarValue}(\boldsymbol{v}) &= \frac{1}{d} \sum_{i=1}^{n} w_{i} \left(v_{i} - \bar{v}\right)^{2}\,, \\ \bar{v} &= \frac{\sum_{i=1}^{n} w_{i} v_{i}}{\sum_{i=1}^{n} w_{i}}\,. \end{align}\]

Where:

  • $\boldsymbol{v}$: The vector to reduce, of length $n$.
  • $w_{i}$: The $i$-th observation weight. The unweighted case is $w_{i} = 1$.
  • $\bar{v}$: The mean of $\boldsymbol{v}$ under those weights.
  • $d$: The denominator, which corrected and the type of w together select.

$d$ takes one of four values:

  • w = nothing: $d = n - 1$ when corrected is true, and $d = n$ when it is false.
  • w::AnalyticWeights: $d = \sum w_{i} - \sum w_{i}^{2} / \sum w_{i}$ when corrected is true.
  • w::FrequencyWeights: $d = \sum w_{i} - 1$ when corrected is true.
  • w::ProbabilityWeights: $d = \left(\sum w_{i}\right)(m - 1) / m$ when corrected is true, where $m$ is the count of non-zero weights.

With corrected = false every weighted case takes $d = \sum w_{i}$.

$d$ is selected by the type of $\boldsymbol{w}$ and not by its values, so two numerically identical weight vectors of different types give different variances.

Fields

  • w: Optional observation weights vector observations × 1, or a concrete subtype of DynamicAbstractWeights. If nothing, the computation is unweighted.
  • corrected: Whether to apply Bessel's correction.

Constructors

VarValue(;    w::Option{<:ObsWeights} = nothing,    corrected::Bool = true,) -> VarValue

Keywords correspond to the struct's fields.

Validation

  • If w is not nothing, !isempty(w).

Propagated parameters

When factory is called on this type, the following @wprop-tagged field is automatically propagated:

Observation weight parameters

When obs_weights_view is called on this type, the following fields are automatically indexed to the selected observations:

Examples

julia> PortfolioOptimisers.vec_to_real_measure(VarValue(), [1.2, 3.4, 0.7])2.0633333333333335

Related

source
PortfolioOptimisers.SumValue — Type
struct SumValue <: VectorToScalarMeasure

Algorithm for reducing a vector of real values to its sum.

Mathematical definition

\[\begin{align} \mathrm{SumValue}(\boldsymbol{v}) &= \sum_{i=1}^{n} v_{i}\,. \end{align}\]

Where:

  • $\boldsymbol{v}$: The vector to reduce, of length $n$.
  • $v_{i}$: Its $i$-th entry, $i = 1,\ldots,n$.

The reduction carries no weights. MeanValue is the weighted sum normalised by the total weight, so a weighted sum is that value multiplied by the total weight.

Constructors

SumValue() -> SumValue

Examples

julia> PortfolioOptimisers.vec_to_real_measure(SumValue(), [1.2, 3.4, 0.7])5.3

Related

source
PortfolioOptimisers.ProdValue — Type
struct ProdValue <: VectorToScalarMeasure

Algorithm for reducing a vector of real values to its product.

Mathematical definition

\[\begin{align} \mathrm{ProdValue}(\boldsymbol{v}) &= \prod_{i=1}^{n} v_{i}\,. \end{align}\]

Where:

  • $\boldsymbol{v}$: The vector to reduce, of length $n$.
  • $v_{i}$: Its $i$-th entry, $i = 1,\ldots,n$.

The reduction carries no weights. One zero entry gives zero, and the product of many entries below one underflows, so this reduction is for a short vector of values near one.

Constructors

ProdValue() -> ProdValue

Examples

julia> PortfolioOptimisers.vec_to_real_measure(ProdValue(), [1.2, 3.4, 0.7])2.856

Related

source
PortfolioOptimisers.ModeValue — Type
struct ModeValue <: VectorToScalarMeasure

Algorithm for reducing a vector of real values to its mode.

Mathematical definition

\[\begin{align} \mathrm{ModeValue}(\boldsymbol{v}) &= \underset{u \in \boldsymbol{v}}{\arg\max}\ \left| \left\{ i : v_{i} = u \right\} \right|\,. \end{align}\]

Where:

  • $\boldsymbol{v}$: The vector to reduce, of length $n$.
  • $u$: A value that $\boldsymbol{v}$ carries.
  • $\left| \cdot \right|$: The count of a set.

StatsBase.mode breaks a tie by the first value that reaches the highest count, so the result is a value of the input and never an average of two. The comparison is exact equality, so this reduction is for a vector of repeated exact values and not for a continuous one.

Constructors

ModeValue() -> ModeValue

Examples

julia> PortfolioOptimisers.vec_to_real_measure(ModeValue(), [1.2, 3.4, 0.7, 1.2])1.2

Related

source
PortfolioOptimisers.StandardisedValue — Type
struct StandardisedValue{__T_mv, __T_sv} <: VectorToScalarMeasure

Algorithm for reducing a vector of real values to its optionally weighted mean divided by its optionally weighted standard deviation. A weighted factory call can make the reduction raise: factory replaces the w field of both mv and sv with the incoming ObsWeights, and sv keeps its default corrected = true, which raises an ArgumentError under a plain StatsBase.Weights. Thread an AnalyticWeights, a FrequencyWeights or a ProbabilityWeights, or declare sv = StdValue(; corrected = false).

Mathematical definition

\[\begin{align} z &= \frac{\hat{\mu}}{\tilde{\sigma}}\,, \\ \tilde{\sigma} &= \begin{cases} 1 & \hat{\sigma} \ \mathrm{undefined} \\ \sqrt{\varepsilon} & \hat{\sigma} = 0 \\ \hat{\sigma} & \mathrm{otherwise} \end{cases}\,. \end{align}\]

Where:

  • $z$: Standardised value.
  • $\hat{\mu}$: The value computed by mv.
  • $\hat{\sigma}$: The value computed by sv, taken about $\hat{\mu}$.
  • $\tilde{\sigma}$: The guarded denominator.
  • $\varepsilon$: Machine epsilon of the element type of $\hat{\sigma}$.

$\hat{\sigma}$ is undefined on a vector of one entry, because a corrected standard deviation needs two. The first case then gives $\tilde{\sigma} = 1$ and $z = \hat{\mu}$, so the reduction is defined on every non-empty vector.

Algorithm

  1. Reduce val with mv, giving m.
  2. Reduce val with sv, and pass m as the mean keyword, giving s. The deviation is therefore always taken about the mean that step 1 produced, so weighting mv without weighting sv changes the denominator too.
  3. Guard s:
    1. s is NaN: replace it with one(s).
    2. s is an exact zero: replace it with sqrt(eps(eltype(s))). The test is an equality, so a small s is not guarded: on the constant vector [2.0, 2.0, 2.0] the result is 1.342e8, which is 2 / sqrt(eps(Float64)).
    3. Otherwise: keep s.
  4. Return m / s.

Fields

  • mv: The mean value measure used for the numerator.
  • sv: The standard deviation measure used for the denominator.

Constructors

StandardisedValue(;    mv::MeanValue = MeanValue(),    sv::StdValue = StdValue(),) -> StandardisedValue

Keywords correspond to the struct's fields.

Propagated parameters

When factory is called on this type, the following @fprop-tagged fields are automatically propagated:

  • mv: Recursively updated via factory.
  • sv: Recursively updated via factory.

Examples

julia> PortfolioOptimisers.vec_to_real_measure(StandardisedValue(), [1.2, 3.4, 0.7])1.2299003291330186julia> PortfolioOptimisers.vec_to_real_measure(StandardisedValue(), [0.37])0.37

Related

source
PortfolioOptimisers.vec_to_real_measure — Function
vec_to_real_measure(
    measure::Num_VecToScaM,
    val::Union{<:VecNum, NTuple{N, <:Number} where {N}};
    kwargs...
) -> Number

Reduce a vector of real values to a single real value using a specified measure.

vec_to_real_measure applies a reduction algorithm (such as minimum, mean, median, or maximum) to a vector of real numbers, as specified by the concrete subtype of VectorToScalarMeasure. This is used in constraint generation and centrality-based portfolio constraints to aggregate asset-level metrics.

Algorithm

The method that Julia selects is the algorithm. measure names the reduction, and the type parameter of a weighted measure names the branch, MeanValue{Nothing} against MeanValue{<:ObsWeights}, so the branch is chosen at compile time and the field is never tested at run time.

  1. measure is a Number: return it, and read nothing of val.
  2. measure is a Function: return measure(val).
  3. measure is a MinValue, a MaxValue, a SumValue or a ProdValue: return minimum, maximum, sum or prod of val.
  4. measure is a ModeValue: return StatsBase.mode of val.
  5. measure is a MeanValue or a MedianValue: return Statistics.mean or Statistics.median of val, with the weights measure.w when the measure carries them. A tuple is collected first on the weighted branch.
  6. measure is a StdValue or a VarValue: return Statistics.std or Statistics.var of val, with corrected = measure.corrected, with the weights measure.w when the measure carries them, and with kwargs... forwarded. A tuple is collected first on the weighted branch.
  7. measure is a StandardisedValue: follow that type's own algorithm, which reduces twice and guards the denominator.

Step 1 is the case that makes a plain number a legal measure: a caller that already holds the value writes it where a reduction goes, and the seam needs no second signature.

Arguments

  • measure: One of three things.

    • ::VectorToScalarMeasure: The reduction to apply to val.
    • ::Number: The value to return, whatever val holds.
    • ::Function: Applied to val directly, as measure(val).
  • val: A vector or tuple of real values to be reduced. A tuple is accepted wherever a vector is, and the weighted reductions collect it first, because Statistics needs an AbstractVector beside its weights. It is ignored when measure is a Number.

  • kwargs...: Forwarded to the underlying reduction. Only the StdValue and VarValue reductions read them.

Returns

  • score::Number: Computed value according to measure.

Examples

julia> PortfolioOptimisers.vec_to_real_measure(MaxValue(), [1.2, 3.4, 0.7])3.4julia> PortfolioOptimisers.vec_to_real_measure(0.9, [1.2, 3.4, 0.7])0.9

Related

source