Centrality: private API
PortfolioOptimisers.assert_no_weight_channel_args — Function
assert_no_weight_channel_args(::Type{T}, args::Tuple, S::Type, shape::AbstractString,
channel::AbstractString) where {T}Refuse an entry of args that would reach a second weighting channel.
The one refusal both splat guards make. A Graphs.jl entry point takes its weights in a positional slot, so an entry of args with that shape is a second channel answering a question the declared one already answered. assert_centrality_args and assert_tree_args differ only in which shape reaches a channel and in which declared channel they name, so both call this with their own S, shape and channel.
The index of the offending entry is reported with its type, because args is splatted and the caller sees no argument names.
Algorithm
- Find the index of the first entry of
argsthat is anS, givingidx. - Throw a
ConflictingArgumentErrorwhenidxis an index rather thannothing. The message carriesT,shape,channel,idxand the type of the offending entry.
Arguments
T: Algorithm type, named in the error message.args: Positional arguments destined for theGraphs.jlfunction.S: The shape that reaches a weight slot, e.g.AbstractMatrix.shape: Name of that shape, used in the error message.channel: Sentence naming the declared channel the caller must use instead.
Validation
- Throws a
ConflictingArgumentErrorif any entry ofargsis anS.
Returns
nothing.
Related
PortfolioOptimisers.assert_centrality_args — Function
assert_centrality_args(::Type{T}, args::Tuple) where {T}Refuse a matrix inside a centrality algorithm's args.
args is splatted straight into the Graphs.jl centrality function, so a matrix in it is a distmx — a second, undeclared way to weight the graph. centrality_polarity is the declared one, and it picks the weights the algorithm's own mathematics needs, from the structure that was actually built. Two channels answering the same question is one too many, and this one was never safe:
Graphs.betweenness_centrality'sdistmxis its third positional argument, so a matrix inargsbinds tovsinstead and the call overflows the stack insideGraphs.degree. TheStackOverflowErroris catchable and the process survives it, so what is lost is the call and not the session.Graphs.closeness_centrality's is its second, so that one worked — silently overriding the polarity, and reporting a wrong-sized matrix as aBoundsErrorrather than aDimensionMismatch.Graphs.stress_centralityhas nodistmxat all.
Non-matrix entries are untouched: a vertex list or a sample count is a genuine positional argument of those functions and says nothing about weights.
kwargs needs no companion guard. A keyword binds by name, so a matrix there cannot reach a positional slot: none of the four functions declares a matrix-valued keyword, and every one of normalize, endpoints, rng and seed refuses a matrix on its own. The whole family fails closed with a MethodError or a TypeError.
Algorithm
- Refuse an
AbstractMatrixinargswithassert_no_weight_channel_args, namingcentrality_polarityas the declared weight channel.
Arguments
T: Centrality algorithm type, named in the error message.args: Positional arguments destined for theGraphs.jlcentrality function.
Validation
- Throws a
ConflictingArgumentErrorif any entry ofargsis anAbstractMatrix.
Returns
nothing.
Related
PortfolioOptimisers.assert_tree_args — Function
assert_tree_args(::Type{T}, args::Tuple, kwargs::NamedTuple) where {T}Refuse a second weighting channel inside a spanning-tree algorithm's args and kwargs.
Both fields are splatted straight into the Graphs.jl spanning-tree function, and every channel they can reach re-weights or re-orients a tree that calc_weighted_adjacency_graph has already weighted. The graph it hands to calc_mst carries the distances the estimator's de and ce produced, and Graphs.jl defaults distmx to exactly those weights. A caller who fills these fields therefore answers a question that was already answered, and the wrong answer is silent:
kruskal_mst,boruvka_mstandprim_mstall takedistmxas their second positional argument, so a matrix inargsreplaces the estimator's distances outright. It is correctly sized often enough to succeed, and the tree it builds is a legitimate-looking tree of the wrong graph.kruskal_mstalso takes aweight_vectorthere, which is the same override in the other shape.minimizeinkwargsinverts the sense of the search. The tree branch is defined by minimising a distance —calc_weighted_adjacency_graphandSimilarityPolarityboth say so — andminimize = falseyields a maximum spanning tree while everything downstream still reads it as a minimum one.
Non-matrix, non-vector entries are untouched, and so is every other keyword. Those reach no weighting channel, and the three functions declare none, so they fail closed at the call.
Algorithm
- Refuse an
AbstractMatrixor anAbstractVectorinargswithassert_no_weight_channel_args, naming the graphcalc_weighted_adjacency_graphbuilt as the declared weight channel. - Throw a
ConflictingArgumentErrorwhenkwargscarries the keyminimize. The message carriesTand the value of that key.
Arguments
T: Spanning-tree algorithm type, named in the error message.args: Positional arguments destined for theGraphs.jlspanning-tree function.kwargs: Keyword arguments destined for the same function.
Validation
- Throws a
ConflictingArgumentErrorif any entry ofargsis anAbstractMatrixor anAbstractVector. - Throws a
ConflictingArgumentErrorifkwargscontainsminimize.
Returns
nothing.
Related