Centrality Queries: private API

PortfolioOptimisers.centrality_graphFunction
centrality_graph(pl::ClE_Cl, ct::AbstractCentralityAlgorithm, X::MatNum;
                 dims::Int = 1, kwargs...)
centrality_graph(nte::AbstractNetworkEstimator, ct::AbstractCentralityAlgorithm,
                 X::MatNum; dims::Int = 1, kwargs...)
centrality_graph(polarity::Option{<:AbstractCentralityPolarity},
                 nte::AbstractNetworkEstimator, X::MatNum; dims::Int = 1, kwargs...)

Build the graph calc_centrality runs on, weighted in the polarity centrality_polarity answers for ct.

The one place where the source and the algorithm are both in scope, so it is the one place the pairing can be resolved. centrality_polarity says which quantity ct needs; the source says which quantities it has.

The routing

sourcepolaritygraph
AbstractNetworkEstimatorDistancePolaritycalc_distance_weighted_graph — distances, on either branch
NetworkEstimator on the similarity branchSimilarityPolaritycalc_weighted_adjacency_graph — the similarities that selected the edges
any sourcenothingplain Graphs.SimpleGraph of phylogeny_matrix
a clustering estimator or Clustersanyplain Graphs.SimpleGraph of phylogeny_matrix
AbstractNetworkEstimator on a tree branchSimilarityPolarityplain Graphs.SimpleGraph of phylogeny_matrix

The similarity route is narrower than the distance route on purpose. calc_distance_weighted_graph carries distances on both branches, but only the similarity branch is selected by a similarity — a tree is selected by calc_mst minimising a distance, and manufacturing a similarity from it would weight the structure with a quantity that did not choose it.

A partition carries no weights, and does not borrow any

A clustering source could reach a distance estimator through its own de, and does not. The triangulated maximally filtered graph selects each edge by a pairwise quantity, so a distance orders that selection; a partition selects by a dendrogram and a cut, and two assets in the same cluster may sit far apart in the distance. Co-membership is not ordered by the distance, so there is no quantity to borrow.

The separation is read on the unweighted route only

The unweighted route goes through phylogeny_matrix, so it sees the AbstractSeparationAlgorithm on the estimator — a HopCount of n = 2 gives centrality on the two-hop closure. The weighted routes bypass it and read the structure itself, because a closure is built by summing matrix powers and a power of a weighted matrix sums products of distances, which is not a separation. So the sep field is inert on the weighted routes. At the default HopCount(; n = 1) there is nothing to notice: the closure of a graph at one hop is the graph.

Two entry points, because the polarity is resolved once

The three-argument methods taking ct resolve centrality_polarity and forward to the methods taking the polarity itself, which is the same shape separation_matrix uses: the deciding algorithm comes first, and the estimator only supplies the graph.

Algorithm

  1. Answer the plain Graphs.SimpleGraph of phylogeny_matrix at once when the source is a clustering estimator or a Clusters. A partition carries no edge weights, so no polarity is read.

  2. Resolve the effective polarity of ct with centrality_polarity. The methods that take the polarity itself are handed it and start at step 3.

  3. Build the graph, through the branch the polarity and the source name together.

Arguments

  • pl: Network estimator, phylogeny result, clustering estimator, or clustering result.
  • ct: Centrality algorithm.
  • polarity: Effective polarity of ct, from centrality_polarity.
  • nte: Network estimator.
  • X: Data matrix (observations × assets).
  • dims: Dimension along which to perform the computation.
  • kwargs...: Additional keyword arguments.

Returns

  • g::Graphs.AbstractGraph: A SimpleWeightedGraphs.SimpleWeightedGraph on a weighted route, a Graphs.SimpleGraph otherwise.

Related

source