Observation weights
PortfolioOptimisers.get_observation_weights — Function
get_observation_weights(
w::Option{<:ObsWeights},
args...;
kwargs...
) -> Option{<:VecNum}Get the observation weights for statistical estimation.
nothing is returned only when w === nothing, and means no weights were requested — every isnothing branch downstream reads it that way and computes an unweighted result. It never means weights were unavailable: a DynamicAbstractWeights with no method for the given input shape throws ObservationWeightsError rather than resolving to nothing, because returning nothing there would silently yield an unweighted answer that looks plausible.
This is why call sites need no strictness check of their own. A DynamicAbstractWeights is resolved before dispatch (see average_drawdown for the pattern), so the estimator downstream only ever sees a concrete weight vector or a deliberate nothing.
The returned vector is borrowed, not owned
For a StatsBase.AbstractWeights this returns the stored object itself, not a copy — an estimator's w field is handed straight back. So the caller may read it but must never mutate it: writing through it permutes the estimator's own configuration, and every later evaluation of that estimator is then wrong.
This is the same obligation the rest of src/ already meets: a reverse! or a sort! is applied only to a vector the surrounding expression has just allocated. Beware the indirect route in particular — view(w, order) is a view, so reverse! on the view writes through into w just as surely as reverse!(w) would. Reverse the permutation instead, or sort into a fresh vector.
A defensive copy here was considered and rejected: it would cost an allocation on every evaluation of every weighted estimator, and the obligation is cheap to keep.
Algorithm
The method Julia selects on the type of w is the algorithm. Three methods share the name, and a fourth is written by the caller.
w === nothingselects the method that returnsnothing, which is the deliberate request for an unweighted result.- A
StatsBase.AbstractWeights, which is aVecNum, selects the method that returns the stored object itself. It allocates nothing, which is why the returned vector is borrowed. - A
DynamicAbstractWeightsfor which the caller wrote no method selects the fallback, which raises. The fallback buildsshapefrom the first positional argument, naming its dimension count and its size when that argument is an array and naming it as "the given input" otherwise, then raisesObservationWeightsErrorcarryingshapeand the two method signatures to write. - A
DynamicAbstractWeightsfor which the caller wrote a method selects that method instead, because it is more specific than the fallback of step 3.
Arguments
w: Optional observation weights vectorobservations × 1, or a concrete subtype ofDynamicAbstractWeights. Ifnothing, the computation is unweighted.args: Additional positional arguments (ignored).kwargs: Additional keyword arguments (ignored).
Validation
wisnothing, aStatsBase.AbstractWeights, or aDynamicAbstractWeightsthat has a method for the shape of the given input. ADynamicAbstractWeightswith no such method raisesObservationWeightsError, which names the two signatures to write. It never resolves tonothing, because that would silently give an unweighted answer that looks plausible.
Returns
w::Option{<:VecNum}: The observation weights, ornothingwhenwisnothing.
Related