Bakry-\'Emery curvature sharpness and curvature flow in finite weighted graphs. II. Implementation

In this second part of a sequence of two papers, we discuss the implementation of a curvature flow on weighted graphs based on the Bakry-\'Emery calculus. This flow can be adapted to preserve the Markovian property and its limits as time goes to infinity turn out to be curvature sharp weighted graphs. After reviewing some of the main results of the first paper concerned with the theoretical aspects, we present various examples (random graphs, paths, cycles, complete graphs, wedge sums and Cartesian products of complete graphs, hypercubes) and exhibit further properties of this flow. One particular aspect in our investigations is asymptotic stability and instability of curvature flow equilibria. The paper ends with a description of the available Python functions and routines available in the ancillary file. We hope that the explanations of the Python implementation via examples will help users to carry out their own curvature flow experiments.


Introduction
This paper is concerned with computational aspects of a curvature flow on weighted graphs based on the Bakry-Émery calculus.This curvature flow was intoduced in our first paper [CKL + 22a].A weighted graph in this paper is a finite simple mixed combinatorial graph G = (V, E) with vertex set V and edge set E = E 1 ∪ E 2 of one-and two-sided edges, together with a weighting scheme of transition rates p xy ≥ 0 for x, y ∈ V (which can be represened by a generally non-symmetric matrix P after an enumeration of the vertices).Transition rates p xy can only be positive if x = y or if there is a one-oder two-sided edge from x to y. One-sided edges are denoted by ordered pairs (x, y) ∈ E 1 ⊂ V 2 , and two-sided edges are denoted by sets {x, y} ∈ E 2 .One-or two-sided edges (x, y) ∈ E 1 or {x, y} ∈ E 2 with vanishing transition rates p xy = 0 are called degenerate and a weighted graph (G, P ) is called non-degenerate if it does not have degenerate edges.A weighted graph (G, P ) is called Markovian, if we have y∈V p xy = 1 for all x ∈ V .In this case, P is a stochastic matrix and we can view the transition rates p xy as transition probabilities of a lazy random walk (with non-zero laziness if there exists a vertex x ∈ V with p xx > 0).Our curvature flow does not affect the underlying combinatorial graph G, but it changes the weighting scheme.We will focus on a version of our flow which preserves the Markovian property.In other words, starting with an initial Markovian weighted graph (G, P 0 ), this flow will provide a family of Markovian weighting schemes {P (t)} t≥0 with P (0) = P 0 , depending smoothly on the continuous time parameter t.Before we introduce our curvature flow, we need to briefly discuss the relevant Bakry-Émery curvature background.This curvature notion is based on the weighted Laplacian ∆ = ∆ P , acting on functions f : V → R as follows: The Laplacian gives rise to the following symmetric bilinear "carré du champ operators" Γ and Γ 2 : 2Γ(f, g) = ∆(f g) − f ∆g − g∆f, 2Γ 2 (f, g) = ∆Γ(f, g) − Γ(f, ∆g) − Γ(g, ∆f ).
1.1.Bakry-Émery curvature and curvature sharpness.Bakry-Emery curvature depends on a dimension parameter N and is well-defined at every vertex x ∈ V which is not isolated, that is, there exists another vertex y ∈ V with p xy > 0. For isolated vertices, there is some ambiguity how to define its curvature, and we decided to assign to such a vertex the curvature value 0. 1 The definition of Bakry-Émery curvature reads as follows: Definition 1.1 (Bakry-Émery curvature).The Bakry-Émery curvature of a non-isolated vertex x ∈ V for a fixed dimension N ∈ (0, ∞] is the supremum of all values K ∈ R, satisfying the curvature-dimension inequality for all functions f : V → R. We use the simplified notation Γ(f ) = Γ(f, f ) and Γ 2 (f ) = Γ 2 (f, f ).We denote the curvature at x ∈ V by K N (x) = K P,N (x).If x ∈ V is isolated, that is, we have p xy = 0 for all y ∈ V \ {x}, we set K N (x) = K P,N (x) = 0 for all N ∈ (0, ∞].
1 Another natural choice of curvature for an isolated vertex x ∈ V would be KN (x) = ∞ for all N ∈ (0, ∞].An argument for that choice is that an isolated vertex can be viewed as a discrete analogue of a limit of round spheres with radii shrinking to 0, whose curvatures would diverge to infinity. This curvature notion is motivated by Bochner's identity (see, e.g., [GHL04,Prop. 4.15]), a fundamental pointwise formula in the smooth setting of n-dimensional Riemannian manifolds involving gradients, Laplacians, Hessians and Ricci curvature.We refer readers to [BE85,Elw91,Sch99,LY10] for the Bakry-Émery calculus and its application in the graph theoretic setting.By the definition, the inequality holds for every function f , and therefore also for the combinatorial distance function d(x, •).Here, d(x, y) is the length of a shortest directed path from x to y (if there is no such path, we set d(x, y) = ∞).If we have equality at x in (2) for this particular function f = d(x, •), we say that the vertex x ∈ V is N -curvature sharp.Curvature sharpness will be particularly important in our considerations.Curvature sharpness was originally introduced in [CLP20 for the distance function f = d(x, •).Moreover, a vertex x ∈ V is curvature sharp if it is curvature sharp for some dimension N ∈ (0, ∞].A weighted graph (G, P ) is called curvature sharp, if every vertex of G is curvature sharp.
Note that each function f : V → R with Γ(f )(x) = 0 gives rise to an upper curvature bound K f P,N (x) via the inequality (2).Namely, we have (4) A vertex x ∈ V is therefore N -curvature sharp if its Bakry-Émery curvature K N (x) agrees with the specific upper curvature bound K d(x,•) P,N (x).We also like to mention the following monotonicity property of curvature sharpness: If x ∈ V is N -curvature sharp that this vertex is also curvature sharp for any dimension ≤ N (see [CKL + 22a, Prop.3.1]).In the next subsection, we present an important reformulation of Bakry-Émery curvature at x ∈ V using a specific matrix Q(x), which will be important in the definition of the curvature flow.
1.2.Reformulation of curvature via a Schur complement.The combinatorial distance function allows us to define distance spheres and distance balls, S r (x) = {z ∈ V : d(x, z) = r}, B r (x) = {z ∈ V : d(x, z) ≤ r}.
Let x ∈ V be a non-isolated vertex.It turns out that the Bakry-Émery curvature K N (x) is determined locally, that is, can be derived solely from the information about the 2-ball B 2 (x) = {x} ∪ S 1 (x) ∪ S 2 (x).More precisely, denoting S 1 (x) = {y 1 , . . ., y m } and S 2 (x) = {z 1 , . . ., z n }, there exist a column vector ∆(x) and a symmetric matrix Γ(x) of size m and a symmetric matrix Γ 2 (x) of size m + n such that, for functions f, g : where f m = (f (y 1 ), . . ., f (y m )) and f m+n = (f (y 1 ), . . ., f (y m ), f (z 1 ), . . ., f (z n )) , and g n , g m+n , accordingly.Using the (n + m)-block decomposition and employing the Schur complement for matrices Γ 2 (x) with positive semidefinite Γ 2 (x) S 2 -blocks with A † the pseudoinverse 2 of A, we can reformulate Bakry-Émery curvature at where A B means that A − B is positive semidefinite.
This curvature translation was motivated originally by the aim to reformulate the computation of Bakry-Émery curvature as an eigenvalue problem (see [Sic20,Sic21] and [CKLP22]).
The symmetric matrix Q(x) of a non-isolated vertex x ∈ V is of size m and is -in the nondegenerate case -closely related to another symmetric matrix A ∞ (x) which, in turn, can be viewed as a discrete counterpart of the Ricci curvature tensor at a point x ∈ M of a Riemannian manifold (M, g) (see formula (1.2) and Section 7 in [CKLP22]).In the case of a Markovian weighted graph, curvature sharpness at a vertex x ∈ V can also be alternatively expressed with the help of the matrix Q(x) as follows.
Let (G, P ) be a Markovian weighted graph and x ∈ V be a non-isolated vertex with S 1 (x) = {y 1 , . . ., y m }.Then the following statements are equivalent: (1) x is curvature sharp, (2) x is curvature sharp for dimension N = 2, (3) We have where p x = (p xy 1 , . . ., p xym ) and 1 m is the all-one column vector of size m.
2 For a given matrix A ∈ R N ×M , its pseudoinverse A † ∈ R M ×N is defined by the following conditions: Note that the term 5) is the upper curvature bound introduced in (4) (in the special case N = ∞), that is, .
1.3.Curvature flow.Let (G, P 0 ) be a fixed initial weighted graph with N = |V |.For every nonisolated vertex x ∈ V , the size of the corresponding symmetric matrix Q(x) agrees with the degree of the vertex x, that is, the number of one-and two-sided edges emanating from x, and the entries of Q(x) are determined by the transition rates of edges of the 2-ball B 2 (x).Our curvature flow associates to this initial data a smooth matrix valued function P : [0, ∞) → R N ×N with P (0) = P 0 .The corresponding symmetric Q-matrices at time t ∈ [0, ∞) depend on the weighting schemes P (t), and we denote them henceforth by Q x (t) for all x ∈ V .Our curvature flow is now defined as follows.
Definition 1.4 (Curvature flow).Let (G, P 0 ) be a finite weighted graph.The associated curvature flow is given by the following differential equations for all non-isolated vertices x ∈ V and all t ≥ 0: where S 1 (x) = {y 1 , . . ., y m } and In the case of an isolated vertex x ∈ V , its curvature flow is given by the simple equation We note that the curvature flow equation (6) guarantees that the diagonal entries of the weighting scheme do not change.The functions C x (t) in the curvature flow equation (7) play the role of a normalisation since, for the choice C x ≡ 0, various transition rates will be unbounded as the time parameter t ≥ 0 increases.Note that in the smooth case of closed Riemannian manifolds (M, g 0 ), a suitable normalization leads to volume preservance of (M, g t ) under the Ricci curvature flow.Our aim is to preserve the Markovian property, and it was shown in our first paper that the curvature flow preserves this property if we choose the normalization functions Let us give the explicit formulas for the curvature flow equation (7) for this particular choice of C x (t), where y, y , y always represent vertices in S 1 (x) (see . Here we use D x = y p xy (t) = 1 − p xx (t).note that (6) guarantees that D x ≤ 1 is independent of the time parameter t.
The following theorem collects some fundamental properties of the normalized curvature flow.
Theorem 1.5 (see Theorem 1.5 and Prop.1.6 in [CKL + 22a]).Let (G, P 0 ) be a Markovian weighted graph.Then the curvature flow (G, P (t)) t≥0 associated to (G, P 0 ) with normalization (8) is well defined for all t ≥ 0 and preserves the Markovian property.If (G, P 0 ) is non-degenerate, then (G, P (t)) is also non-degenerate for all t ≥ 0.Moreover, if the flow converges for t → ∞ to P ∞ = lim t→∞ P (t), then the weighted graph (G, P ∞ ) is curvature sharp.
We like to emphasize that, even in the Markovian case, a flow limit P ∞ = lim t→∞ P (t) of a nondegenerate weighted graph (G, P 0 ) is in most cases no longer non-degenerate, despite the fact that all weighting schemes P (t) for finite t ≥ 0 are non-degenerate.In other words, some transition probabilities converge to zero under our normalized curvature flow, as time tends to infinity.

Curvature flow examples
In this section, we investigate normalized curvature flows on some unmixed combinatorial graphs G = (V, E).By unmixed we mean that G does not have one-sided edges.We assume in all examples and statements in this section that our graphs G = (V, E) are finite, simple, unmixed and connected and that our initial weighting schemes P 0 = P (0) = (p xy (0)) Let us now address some practical aspects of the curvature flow implementation.The solution of the curvature flow is computed numerically by the Runge-Kutta (RK4) method, which is based on a time discretization with time increments dt > 0. In the following examples we choose the step sizes dt = 0.1 and dt = 0.3.In order to distinguish between the theoretical curvature flow and its implementation, we refer to the latter as the numerical curvature flow.Since a numerical curvature flow cannot run forever, a suitable numerical convergence criterion needs to be introduced.Our convergence criterion is based on the parameter lim tolerance > 0. We say that a numerical curvature flow solution (P (t)) t≥0 has converged numerically at time t (with respect to the parameter lim tolerance ), if all the entries of P (t) differ from the corresponding entries of P (t + 10) and P (t + 20) by less than lim tolerance .The numerical flow limit is then defined to be P (t).In all examples to follow we set lim tolerance = 0.001.In this section, we are particularly interested in numerical flow limits which are not numerically totally degenerate.An unmixed weighted graph (G, P ) is called numerically totally degenerate if there are no edges with numerical non-zero transition rates in both directions, where we consider a transition rate p xy as numerically non-zero (with respect to a parameter threshold > 0), if and only if p xy ≥ threshold.In all examples to follow we set threshold = 0.001.
2.1.Random graphs.In this subsection we investigate the numerical curvature flow for random weighted graphs (G, P 0 ) with vertex set V .The edge set E of G is generated by an Erdös-Renyi process, that is, any pair of vertices is independently and randomly connected by a two-sided edge with a probability p ∈ [0, 1].Similarly, we choose a random initial weigthing scheme P 0 with the property that all non-zero transition rates p vv (0) lie in the interval [threshold, 1], for some positive parameter threshold > 0. We are interested in properties of numerical flow limits of these graphs.If the parameter p > 0 in the Erdös-Renyi process is too small, these flow limits are always numerically totally degenerate.A reasonable choice to obtain not numerically totally degenerate flow limits for such random graphs with, say, 10 vertices in roughly half of the cases, is p = 0.7.
Example 2.2 (A random graph with 10 vertices).Let (G, P 0 ) be the unmixed weighted Markovian graph with vertex set V = {v 0 , . . ., v 9 } and This randomly generated initial graph is illustrated on the left hand side of Figure 1.The numerical curvature flow of (G, P 0 ) has numerical convergence time t max = 20.7 (with respect to lim tolerance = 0.001).The numerical flow limit (G, P (t max )) is presented on the right hand side of Figure 1.Let us briefly explain the illustration of the edges of this flow limit: Edges with numerical non-zero transition rates in both directions are displayed in green.Edges with only one-sided numerical non-zero transition rates are displayed as dashed red lines with arrows.Edges whose transition rates shrink in both directions numerically to zero under the curvature flow are displayed as dotted black lines.The corresponding non-zero transition rates are written along these edges.The vertices of the green edges of the flow limit in Figure 1 are given by Since there are no numerical non-zero transition rates from these vertices to the other vertices v 2 , v 4 , v 8 , v 9 ∈ V \ W , the vertex set W together with the green edges and their transition rates represent a highly connected non-degenerate Markovian weigthed subgraph (G W , P W ). The combinatorial graph G W with vertex set W can be viewed as a double cone over the complete graph K 4 of the four vertices v 0 , v 1 , v 3 , v 6 with the vertices v 5 , v 7 as its cone tips.The transition rates of the weighting scheme P W towards all vertices in K 4 are 0.25 = 1/4, all transition rates towards v 5 are x = 0.05 and all transition rates towards v 7 are y = 0.2.Note that such a weighted double cone over K 4 with these transition rates for any choice of x, y > 0 satisfying x + y = 1/4 is curvature sharp (this follows readily from the geometric criterion in [CKL + 22a, Theorem 3.15], since the weighting scheme is volume homogeneous in all vertices and reversible with π(v 5 ) = 4x/5, π(v 7 ) = 4y/5 and π| K 4 ≡ 1/5).Therefore, not only the flow limit itself is curvature sharp by Theorem 1.5 but also the highly connected non-degenerate weighted subgraph (G W , P W ). Figure 2 presents the transition rates of the vertices v 3 , v 7 under the curvature flow as functions over the interval [0, t max ].While most transition rates converge to strictly positive limits, the transition rates p v 3 v 4 (t) and p v 8 v 9 (t) shrink to zero.Consequently, the corresponding edges on the right hand side of Figure 1 are represented by a dashed red line and a black dotted line, respectively.Let us finally, consider the curvatures t → K P (t),N (v j ) of the vertices v j under the curvature flow.We focus exemplary on the vertices v 1 and v 9 and the dimension parameter N = ∞.Figure 3 presents the ∞-curvature (in blue) and upper curvature bound K d(v,•) P (t),∞ (v) (in orange) of v ∈ {v 1 , v 9 } as functions over the interval [0, t max ].Note that the absence of laziness implies that the upper curvature bounds K d(v,•) P (t),∞ (v) are all ≥ 0 (see [CKL + 22a, (19)]).For both vertices, the curvature and upper curvature bound functions are numerically asymptotic as t → t max , indicating that v 1 and v 9 of the flow limit are ∞-curvature sharp.(In fact, all vertices in this example are ∞-curvature sharp with respect to the flow limit.)This is not always the case, but Theorem 1.3 confirms that all vertices of a flow limit (G, P ∞ ) are at least N -curvature sharp for dimension N = 2.Moreover, the initial and final ∞-curvatures of all vertices under the curvature flow are presented in Table 1.The final curvatures of all vertices in K 4 assume the highest values 0.875, followed by the final curvature values 0.773 and 0.476 of the vertices v 7 and v 5 , respectively.All other vertices in V \ V 0 have much lower final curvatures with values ≤ 0.125.Let us explain the commands of this program in detail.After initializing various parameters in lines 1-11, a random graph G = (V, E) is generated in line 13 via an Erdös-Renyi process with probability p = 0.7.A corresponding random non-degenerate Markovian weigthing scheme without laziness is generated in line 14, with each non-zero transition rate satisfying p vv (0) ∈ [threshold, 1].The numerical convergence time t max ≥ 0 is determined in lines 16-17.In most cases, the convergence time does not exceed 100.(If convergence is not achieved by t lim = 10000, the curvature flow computation stops at that time and notifies the user.)The numerical curvature flow on the interval [0, t max ] is solved again in line 21.Initial and final weighting schemes are displayed by the commands in lines 23 and 24, respectively, providing the illustrations given in Figure 1.The transition rates of the vertices v 3 and v 8 are displayed by the command in line 25, providing the illustrations given in Figure 2 The curvatures and upper curvature bounds at time steps j • k•tmax dt , j = 0, 1, . . ., are computed in lines 27 and 28, respectively, with the choice k = 1.They are displayed for the vertices v 1 and v 9 via the command in line 29, providing the illustrations given in Figure 3.
When running this program, users may be faced with the following message: 'norm_tolerance' has been exceeded at one or more vertices, at time t = ... Would you like to: A = Stop calculation and return list of P-matrices so far B = Apply manual normalization now, and apply it again when necessary without asking (you will still be notified when it is applied) C = Apply manual normalization now, and ask again before reapplying it Please enter A, B or C here: The reason behind this message is the following.The computation of the numerical curvature flow is based on a time discretization.Therefore, the solution will increasingly depart from the Markovian property after each time increment dt = 0.1.If the sum of entries of one of the rows of P (t) at time t differs from one by more than norm tolerance = 0.001, the program informs the user that a normalization of the weighting scheme is needed for the continuation of the flow calculations.After choosing the option 'B', the program will continue with its flow calculations without further interruptions, and the user is simply notified about the times at which the program applies further artificial normalizations of the transition rates.The user can suppress this message entirely by changing line 2 of the program into "stoch_corr = True", in which case the program applies stochastic corrections automatically, each time with the message Transition rates have been artificially normalized at time t = ... The numerical observations of Example 2.2 suggest that similar properties may also hold in general in the theoretical setting.Firstly, we call an edge {x, y} ∈ E in an unmixed weighted graph (G, P ) non-degenerate if p xy , p yx > 0. An unmixed weighted graph (G, P ) is called totally degenerate if it does not have any non-degenerate edges.Secondly, we denote the vertices of all non-degenerate edges of a flow limit (G, P ∞ ) by W ⊂ V , and G W denotes the subgraph of G consisting of the vertices W and all non-degenerate edges of (G, P ∞ ).Moreover, P W denotes the restriction of the weigthing scheme P ∞ to the vertex set W .We call G W the non-degenerate subgraph of (G, P ∞ ) and we conjecture the following: Conjecture 2.3.If the normalized curvature flow of a nondegenerate unmixed Markovian weighted graph (G, P 0 ) converges to a not totally degenerate limit (G, P ∞ ), then the non-degenerate subgraph G W coincides with the induced subgraph (of G) of the subset W ⊂ V and all transition rates from W to V \ W are zero.(G W , P W ) is a non-degenerate Markovian weighted graph which is itself curvature sharp.
Figuratively speaking, the curvature flow converges towards the non-degenerate Markovian subgraph (G W , P W ) consisting of highly connected components.Moreover, each vertex of V \ W is usually connected to the set W by a sequence of edges with one-sided non-zero transition rates pointing towards the set W , and we generally expect that the ∞-curvature values of the vertex set W in (G, P ∞ ) are significantly larger than the ∞-curvature values of the set V \ W in (G, P ∞ ).
In Example 2.2, the weighted Markovian subgraph (G W , P W ) has only one connected component, but we will see in the next subsection in the case of paths and cycles that (G W , P W ) may be composed of more than just one connected component.

Paths and cycles. Let
is a trivial case of a star graph and any Markovian weigthing scheme satisfying p 01 = p 21 = 1 and p 10 + p 12 = 1 is curvature sharp (see [CKL + 22a, Example 4.3].For that reason we consider only paths of lengths N ≥ 3. A cycle of length 3 is the complete graph K 3 , and a full list of all curvature sharp weighting schemes was given in [CKL + 22a, Prop.1.9], so we consider only cycles of length N ≥ 4. The following example provides some insights into some features of curvature flow limits of weighted paths and cycles. Example 2.4 (A path and a cycle of length 12). Figure 4 presents numerical curvature flow limits of a Markovian weighted path with vertices 12 vertices (left hand side) and of a weighed cycle with 12 vertices (right hand side).The non-zero transition rates of the initial weighting scheme P 0 = (p ji ) 0≤i,j≤11 for the path limit in Figure 4 were chosen as follows: The non-degenerate subgraph G W of the path limit consists of W = {v 1 , v 2 , v 3 , v 9 , v 10 , v 11 } as its vertex set together with the four green edges.Moreover, G W has two paths of length 2 as its connected components.For each vertex v ∈ V \W there exists a directed path to one of the components of G W via a sequence of one-sided transition rates.For example the vertices v 5 , v 6 , v 7 , v 8 are connected to the vertex v 9 ∈ W via such one-sided paths and v 4 , v 5 are connected to the vertex v 3 via such one-sided paths.
The cycle limit on the right hand side of Figure 4 is totally degenerate with no green edges, and all one-sided non-zero transition rates are oriented in a clockwise direction.Experiments show that Figure 4 exhibit generic limit properties: flow limits of weighted paths are never totally degenerate and their non-degenerate subgraphs G W consist of disjoint paths of length ≤ 2. Such types of limits appear also in the case of weighted cycles.However, in contrast to the path case, sometimes a cycle limit is totally degenerate with all its one-sided transition rates oriented either clockwise or anti-clockwise.The code for running the curvature flow for paths and cycles of length n reads as follows: Before we provide the following result about path limits, let us first introduce the notion of a twosided degenerate edge of a weighted graphs (G, P ): An edge {x, y} ∈ E of G is called two-sided degenerate if its transition rates vanish in both directions, that is, p xy = p yx = 0. Similarly, an edge is called numericall two-sided degenerate, if its transition rates in both directions are < threshold.Such edges are displayed in the routine display_weighted_graph as dotted black lines (see, e.g., the edges {v 2 , v 9 } and {v 8 , v 9 } on the right hand side of Figure 1).
Proposition 2.5 (Flow limits of paths of length ≥ 3).Let (G, P 0 ) be a weighted path of length N ≥ 3 with consecutive vertices v 0 , . . ., v N −1 .Let P (t) be its corresponding curvature flow converging to a limit P ∞ = lim t→∞ P (t), such that (G, P ∞ ) does not have two-sided degenerate edges.Then this limit is neither totally degenerate nor is it not non-degenerate (that is, it contains both green and dashed red edges).Moreover, the components of the non-degenerate subgraph G W are paths of lengths ≤ 2 and they are separated from each other by at least two degenerate edges.If a component of G W is a path of length 1, that is, just one edge {v j , v j+1 }, then we have p ∞ j,j+1 = p ∞ j+1,j = 1.Proof.By the last statement of Theorem 1.5, we only need to prove these statements for curvature sharp weighting schemes P = (p ij ) 0≤i,j≤N of paths of length N ≥ 3.Such weighting schemes can never be non-degenerate by [CKL + 22a, Prop.1.11].
For the proof that curvature sharp weighting schemes can never be totally degenerate, we note that we cannot have two consecutive degenerate edges {v j , v j+1 }, {v j+1 , v j+2 } ∈ E with p j,j+1 = 1 = p j+2,j+1 (since this would imply p j+1,j = p j+1,j+2 = 0, contradicting to p j+1,j + p j+1,j+2 = 1).Therefore, since p 01 = 1, any totally degenerate weighting scheme would require p j,j+1 = 1 for any j ≥ 0, in particular, p N −2,N −1 = 1, but this contradicts to the fact that we also have p N −1,N −2 = 1 and that the edge {v N −1 , v N −2 } needs to be degenerate.A curvature sharp weighting scheme cannot have more than two consecutive non-degenerate edges.This can be seen as follows: At any vertex v j with p j,j−1 , p j,j+1 > 0 we must have p j−1,j = p j+1,j .This follows from the arguments in the proof of [CKL + 22a, Lemma 4.1] (namely, since the vertex v j is not contained in any triangle, we have p j−1,j = p y+1,j = p j,j−1 p j−1,j + p j,j+1 p j+1,j .)If 0 < p j−1,j = p j+1,j < 1, we could iterate this argument backward and forward and would end up with the fact that all entries of the matrix P above the diagonal and below the diagonal would lie in (0, 1), which is a contradiction to p 01 = 1.So we must have p j−1,j = p j+1,j ∈ {0, 1}.Therefore, we cannot have two consecutive indices j ∈ {0, . . ., N − 1} with 0 < p j−1,j = p j+1,j < 1 which would exist in the case of three consecutive non-degenerate edges.So the components of G W are paths of length ≤ 2.Moreover, any gap between two consecutive non-degenerate edges must be at least two edges: this follows from the fact that if a non-degenerate edge {v j , v j+1 } is followed by a degenerate edge {v j+1 , v j+2 }, then we must have p j+1,j+2 = 0: if we had p j+1,j+2 > 0, then we had p j+1,j , p j+1,j+2 > 0 and, therefore 0 < p j+1,j = p j+2,j+1 and {v j+1 , v j+2 } would be non-degenerate, which is a contradiction.Similarly, if a degenerate edge {v k , v k+1 } is followed by a non-degenerate edge {v k+1 , v k+2 }, we must have p k+1,k = 0. Combining both facts implies that there cannot be a single degenerate edge separating two components of G W .These arguments show also that components of G W which are single edges {v j , v j+1 } must satisfy p j,j+1 = p j+1,j = 1 since the adjacent degenerate edges have one-sided transition rates pointing towards this component.Similar arguments as above can be used to prove for cycles that the components of any flow limit of a weighted cycle are again paths of length ≤ 2, unless the limit is non-degenerate.Such non-degenerate limits exist for cycles, namely, the simple random walks, but experiments show that simple random walks are very unstable stationary solutions of the curvature flow.Small perturbations of simple random walks do not converge back to the simple random walk (unless our cycle is K 3 ) but converge usually to a degenerate limit.Finally, if a totally degenerate cycle limit does not have two-sided degenerate edges, then its transition rates must all be either oriented clockwise or anti-clockwise for, otherwise, we would necessarily have a vertex with transition rates of both incident degenerate edges pointing towards this vertex.This would fail to satisfy the Markovian condition at this vertex.
Paths and cycles of length N ≥ 3 have the property that no edge is contained in a triangle.We like to finish section by a general statement about the curvature flow for edges not contained in triangles.
Proposition 2.6.Let (G, P 0 ) be a weighted Markovian graph without laziness and (P (t)) t≥0 be its associated normalized curvature flow.If we have, for some t 0 ≥ 0 and an edge e = {x, y} ∈ E, p xy (t 0 ) = 0 and e is not contained in a triangle of G, then we have p xy (t) = 0 for all t ≥ t 0 .
Proof.This proposition is an easy consequence of the flow equation (9).Since we assume no laziness, we have p yy (t) = 0, and since e is not contained in a triangle, the last term of (9), denoted by ( * ), is zero and the statement follows now from the uniqueness of the solution satisfying p xy (t 0 ) = 0. 2.3.Complete graphs.The simple random walk on any complete graph is a non-degenerate curvature sharp Markovian weighting scheme.Our experiments show that any non-degenerate initial weighting scheme P 0 on K n converges to the simple random walk, that is p ∞ jk = 1 n−1 .The following example shows that convergence to the simple random walk appears even if the initial weighting scheme is degenerate.This is not in contradiction ot Proposition 2.6 since, in a complete graph K n , n ≥ 3, every edge is contained in a triangle.Example 2.7 is the only exception in this section where we allow an initial weighting scheme to have degenerate edges.
Example 2.7 (A degenerate weighted complete graph with 6 vertices).Let (G, P 0 ) be the complete weighted Markovian graph with vertex set V = {v 0 , . . ., v 5 } and   Conjecture 2.8 (Curvature flow of complete graphs).Let P 0 be a Markovian weighting scheme without laziness on a complete graph K n = (V, E) with n ≥ 2 such that, for every proper subset W ⊂ V , there exist x, x ∈ W and y, y ∈∈ V \ W with p xy > 0 and p y x > 0. Then the curvature flow has a limit P ∞ which is the simple random walk.
2 ) be two combinatorial graphs and x 1 ∈ V 1 and x 2 ∈ V 2 .By merging the vertices x 1 and x 2 into one new vertex x which inherits the incident edges of both vertices x 1 and x 2 , we obtain a new combinatorial graph, which we denote the wedge sum of G 1 and G 2 .In this subsection, we consider flow limits of wedge sums of complete graphs.
Example 2.9 (A wedge sum of a K 4 , K 5 , K 2 and K 3 ).We consider the curvature flow on the wedge sum G = (V, E) of complete graphs presented in Figure 7 with random initial weighting schemes P = P 0 .The adjacency matrix A of this graph is generated with our code in the following way: A1 = wedge_sum ( complete (4) , complete (5) , 2 , 1) A2 = wedge_sum ( A1 , complete (2) , 6 , 0) A = wedge_sum ( A2 , complete (3) , 8 , 0) Figure 7.A wedge sum of a K 4 , K 5 , K 2 and a K 3 . Initial weighting scheme (left) and numerical flow limit a simple random walk on K 3 (right) . Initial weighting scheme (left) and numerical flow limit a simple random walk on K 4 (right) Our experiments show that, depending on the initial weighting scheme P 0 , the curvature flow converges to a limit which is concentrated in one of the complete graphs.More precisely, the limit weighting scheme P ∞ represents a simple random walk on one of the complete graphs while, from all other vertices, there is a directed path of {0, 1} transition rates towards this particular complete graph.Figures 8, 9 and 10 show the numerical curvature flow limits of various random initial . Initial weighting scheme (left) and numerical flow limit a simple random walk on K 5 (right) weighting schemes.We carried out several runs of 100000 numerical curvature flows with random initial weighting schemes to describe the limit behaviour of these flows quantitatively.The results are presented in Table 2.While more than 80% of limits concentrate on the largest clique K 5 , it is somewhat surprising that more limits concentrate on K 3 than on the larger subgraph K 4 .Not a single flow limit ended up concentrating on K 2 .The mean numerical convergence time is shortest for K 3 , followed by K 4 and K 5 (with respect to lim tolerance = 0.001).While most convergence times are below 100, there were maximal numerical convergence times well above 500.
concentration of flow limits 8.7% 80.5% 0% 10.8% mean convergence time 18.9 24.7 -17.7 Table 2. Statistics of flow limit concentrations on the complete subgraphs K 4 , K 5 , K 2 and K 3 of their wedge sum, together with mean convergence times The limit behaviour described in the above example seems to be common for many wedge sums of complete graphs.It is, however, not always true that flow limits concentrate on just one of the constituents of a wedge sum.A path of length ≥ 2 can be viewed as a wedge sum of consecutive K 2 's, and we have seen in Subsection 2.2 that flow limits will concentrate on more than only one of these K 2 's (see left hand side of Figure 4).Another special case of a wedge sum is a dumbbell which is our next example.
Example 2.10 (A symmetric weighted dumbbell).The weighted graph (G, P 0 ) in this example is a wedge sum of a K 5 , K 2 and another K 5 , together with a simple random walk as initial weighting scheme (see line 4 in the code).This situation can be set up by the following code: The numerical convergence time is 79 and the limit of the numerical curvature flow concentrates on the "bridge" K 2 between the two K 5 's, as illustrated in Figure 11.(To obtain the flow limit illustrated at the right hand side of this figure, users should choose lim tolerance = 0.0001.) Figure 11.Curvature flow of a dumbbell as a wedge sum of a K 5 , K 2 and another K 5 with simple random walk initial weighting scheme P 0 (left hand side) and numerical flow limit concentrated on K 2 (right hand side) This limit could have been predicted assuming that the initial weighted graph symmetry across the "bridge" is preserved under the curvature flow and that the limit concentrates on only one of the complete graphs K 5 , K 2 , K 5 .If instead of the simple random walk, a random initial weighting scheme would have been chosen on the dumbbell G, the limit would have usually concentrated on one of the two K 5 's.
2.5.Cartesian products of complete graphs.We have the following result for Cartesian products of complete graphs: Theorem 2.11.Let G be the Cartesian product of two complete graphs K n+1 and K m+1 with the non-lazy simple random walk P as initial weighting scheme.Then the curvature flow P (t) converges to a limit as t → ∞ with limit transition rates , where a ∞ are the transition rates along edges between (x, x ) and (y, x ) with x, y ∈ K n+1 , x ∼ y and x ∈ K m+1 ("horizontal edges"), and b ∞ are the transition rates along edges between (x, x ) and (x, y ) with x ∈ K n+1 and x , y ∈ K m+1 , x ∼ y ("vertical edges").
Proof.By symmetry of the configuration, we have only two types a(t) and b(t) of transition rates for the curvature flow at time t ≥ 0 (for horizontal and vertical edges, respectively) with due to the Markovian property.This implies that b(t) = 1−na(t) m and b (t) = − −na (t) m , and we only need to consider an ordinary differential equation for a with initial condition a(0) = 1 n+m .We can also assume without loss of generality that n ≤ m.We derive from the explicit description (9) of the curvature flow that If this differential equation converges as t → ∞, its limit a ∞ must satisfy Our assumption n ≤ m implies that we have and that the right hand side of (10) is strictly positive for (at) in the interval 2nm+3n+3m , and strictly negative for a(t) on the interval m + 3 2nm + 3n + 3m , 1 n .
These monotonicity properties force the function a(t) to converge to the limit a ∞ = m+3 2nm+3n+3m .Example 2.12 (Flow limit of K 3 × K 4 with simple random walk).The following code computes the numerical flow limit for K 3 × K 4 with the simple random walk as initial weigthing scheme.
2.6.Totally degenerate flow limits.As mentioned before, many curvature limits are totally degenerate.Therefore, it is worth to investigate properties of those particular limits.
Example 2.13 (The octahedron with a totally degenerate flow limit).Let G = (V, E) with V = {v 0 , . . ., v 5 } be the unmixed graph representing the octahedron, as illustrated in Figure 12 (left hand side).While the simple random walk without laziness is a stationary solution of the normalised curvature flow, any small perturbation of this initial weighting scheme leads to another curvature sharp limit, which is totally degenerate.For example, the initial weighting scheme Figure 12.Left hand side: An octahedron with vertices v 0 , . . ., v 5 .Right hand side: A numerical flow limit of the octahedron with a small perturbation of simple random walk as initial weighing scheme The following considerations show that the limit in Example 2.13 is essentially the only totally degenerate curvature sharp weighting scheme without two-sided degenerate edges for the octahedron (see Proposition 2.15 below).We start with a general unmixed combinatorial graph G = (V, E) without isolated vertices.A totally degenerate weighting scheme P assigns to each edge {x, y} ∈ E either a direction (x → y if p xy > 0 and y → x if p yx > 0, illustrated by a red dashed line with an arrow) or the edge is two-sided degenerate (that is p xy = p yx = 0, illustrated by a black dotted line).
A first observation is that none of the vertices x ∈ V can be a sink: the Markovian property requires that at least one edge incident to x must be outward directed.The following lemma presents a useful property of triangles.
Lemma 2.14.Let (G, P ) be a totally degenerate curvature sharp Markovian weighted graph without laziness.Then the directions of a triangle T = {x, y, z} ⊂ V without two-sided degenerate edges cannot be oriented, that is, its edges cannot have the orientations Proof.Assume that a totally degenerate curvature sharp Markovian weigthing scheme without laziness contains a triangle T = {x, y, z} with p xz , p zy , p yx > 0, that is, we have an orientation x → z → y → x.This means, in particular, that p xy = 0. We can read off the flow equation ( 9) that curvature sharpness of a totally degenerate Markovian weighting scheme means The main tool in the proof of the following proposition can be found in [Pak10, Exercise 25.14]: Assume a tessellation of the 2-dimensional sphere carries an orientation along all its edges.For every vertex v of the tessellation let ind(v) = 1 − c(v)/2, where c(v) is the number of changes in the orientation of edges adjacent to v (in cyclic order).For a face f , let ind(f ) = 1 − c(f )/2, where c(f ) is the number of changes in the orientation (clockwise vs. anti-clockwise) of edges of f .Then we have Proposition 2.15.Let G = (V, E) be the octahedron, as illustrated in Figure 12 (left hand side).Then G has essentially only one totally degenerate non-lazy curvature sharp Markovian weighting scheme without two-sided degenerate edges, namely, we have (up to a permutation of the vertices corresponding to a graph automorphism) Proof.We can think of the octahedron as a tessellation of the sphere by 8 triangles, all of them not oriented, by Lemma 2.14.This means that ind(f ) = 0 for all faces of the octahedron.Therefore, we must have that is, at least two vertices of the octahedron must have ind(v) = 1, which means that each of them must be a source or a sink.The Markovian property rules out sinks, and two sources cannot be adjacent (otherwise they would be connected by a non-degenerate edge).So the octahedron must have two sources at distance 2, which we denote by v 4 , v 5 .Their edges are all directed towards a cycle of length 4. The directions of the edges in this cycle must be directed, for otherwise there would be a sink in this cycle which is not possible.We denote this oriented cycle by Conjecture 2.16 (Flow limits of the octahedron).The normalized curvature flow on the octahedron for any non-degenerate initial weighting scheme without laziness different from the simple random walk converges always to a limit described in Proposition 2.15.

Asymptotically stable and unstable curvature sharp Markovian weighting schemes
Recall that every curvature sharp Markovian weighting scheme on a given combinatorial graph is a stationary solution of the normalized curvature flow.It is natural to ask whether such a stationary solution P s is asymptotically stable, that is, whether any closeby Markovian weigthing scheme P converges back to this equilibrium P s as t → ∞.This can be decided via the linearization of the curvature flow equations around such an equilibrium.In the next subsection, we will describe this linearization in full detail before we consider various examples in the following subsection.
3.1.Linearization of the curvature flow equations at equilibria.Let P s be a curvature sharp Markovian weighting scheme of a finite simple mixed combinatorial graph G = (V, E).We consider Markovian weighting schemes P near P s with the same laziness, that is The linearization of F at the equilibrium P s of the normalized curvature flow is given for each component function F xy , (x, y) ∈ E dir , by B xy (y z)q y z .
To end up with a uniquely defined Jacobi matric of F , we need to restrict to transition probabilities which are independent.For that we introduce the subset E ess ⊂ E dir of "essential" transition probabilities by removing, for each x ∈ V with outgoing directed edges, that is S 1 (x) = ∅, one pair (x, y) from E dir .The cardinality of E ess is M : , where V 0 ⊂ V is the subset of vertices x ∈ V for which we have S 1 (x) = ∅.Any choice (p uv ) (u,v)∈E ess determines then a weighting scheme P by setting p uv = D u − v ∈S 1 (u)\{v} p uv for the directed edge (u, v) ∈ E ess .Similarly, any choice (q uv ) (u,v)∈E ess determines also the parameters q uv with (u, v) ∈ E ess by setting q uv = − v ∈S 1 (u)\{v} q uv .Then DF ((p s uv ) (u,v)∈E ess ) is a square matrix of size M , and the weighting scheme P s corresponding to (p s uv ) (u,v)∈E ess is asymptotically stable if and only if the real parts of all eigenvalues of this square matrix are negative, and the weighting scheme P s is unstable if and only if at least one of the real parts of these eigenvalues is positive.Let us reformulate this restriction in terms of matrix multiplications.We start by enumerating the vertices of the graph G = (V, E): V = {v 0 , . . ., v N }.We also introduce the following enumeration on the directed edges in E dir : Let 1 = j 0 and a j 0 , . . ., a k 0 be the edges of the type (v 0 , * ) (where second vertices are chosen with increasing indices) in E dir , j 1 = k 0 + 1 and a j 1 , . . ., a k 1 be the edges of the type (v 1 , * ) in E dir , and so on.For all vertices v l ∈ V with S 1 (v l ) = ∅, we set j l = k l−1 + 1 and k l = k l−1 .We remove the edges a k 0 , a k 1 , . . ., a k N from E dir to obtain E ess .For simplicity, we use the notation p s j and q j for p s a j and q a j , and we can write for all a j ∈ E ess , where the last expression involves only parameters q k corresponding to essential directed edges a k ∈ E ess .Consequently, the Jacobi matrix DF ((p s k ) a k ∈E ess )((q k ) a k ∈E ess ) can be written as where B is the square matrix of size k N with B jk = B a j (a k ) for a j , a k ∈ E dir , P 1 is obtained from the identity matrix I k N by removing the rows k 0 , k 1 , . . ., k N , and P 2 = P 1 − P 3 with P 3 a k N × M matrix whose first k 0 − 1 columns are all the standard basis vector e k 0 , the next k 1 − j 1 columns are all the standard basis vector e k 1 , and so on.

Examples of asymptotically stable and unstable equilibria.
In this subsection we investigate curvature sharp weighting schemes of various examples of unmixed combinatorial graphs.
Example 3.2 (Curvature sharp weighting schemes on a cycle).Let For simplicity, we refer to vertex v i henceforth as i.We assume P s to be a non-lazy curvature sharp weighting scheme on C N , and we remove the directed edges (i, i + 1) ∈ E dir to obtain E ess , and the only coefficients B a j (a k ) with a j ∈ E ess and a k ∈ E dir , which may be potentially non-zero are (see (13), ( 14), ( 15) and ( 16)),

This implies
In the case of the simple random walk p s i,i 1 = p s i,i+1 = 1/2, i ∈ {0, . . ., N − 1}, this simplifies to , and the corresponding matrix DF ((p s k ) a k ∈E ess ) coincides with the adjacency matrix of C N whose largest eigenvalue is 2. Therefore the simple random walk on C N , N ≥ 4, is an unstable equilibrium.This is in contrast to the simple random walk on C 3 = K 3 , which is asymptotically stable, as we will see in Example 3.4.In the case of the totally degenerate clockwise weighting scheme p i,i−1 = 1 and p i,i+1 = 0 (see right hand side of Figure 4), we have and this curvature sharp Markovian weigthing scheme is asymptotically stable.This agrees with the fact that many initial weighting schemes end up in this limit under the curvature flow.The same holds true for the corresponding totally degenerate anticlockwise weighting scheme with p i,i+1 = 1 and p i,i−1 = 0.
Example 3.3 (Flow limits of the octahedron).We know from Example 2.13 that stationary solutions of the normalized curvature flow on the octahedron are the simple random walk without laziness as well as the totally degenerate weighting scheme given as matrix P s in the following code (see also the right hand side of Figure 12).The linearization DF (P s ) is analyzed in line 10 of the program, and the function equilibrium_type with the parameters chosen in lines 6 and 7 returns one of the values −1, 0, 1 (corresponding to "asymtotically stable", "undecided", "unstable", respectively), following by a list of its eigenvalues.That is, after execution of line 10, result[0] is one of the values −1, 0, 1 and result[1] is a list of the 18 eigenvalues λ j of DF (P s ).
Its eigenvalues are − 2 3 with multiplicity 6 and −2 with multiplicity 2. This shows that the simple random walk on K 4 is again an asymptotically stable equilibrium.
Since numerical experiments show that all non-degenerate Markovian weighting schemes without laziness on K n+1 converge to the simple random walk, we expect that the simple random walk on K n+1 is an asymptotically stable equilibrium for all n ≥ 2 (see also our Conjecture 2.8, which an is even stronger statement).To this end, our code provides the following numerical results: The eigenvalues of DF (P s ) for the simple random walk without laziness on the complete graph K n+1 are real valued and given by • − 7 16 with multiplicity 4, − 3 4 with multiplicity 6, and − 7 4 with multiplicity 5 for n = 4, • − 8 25 with multiplicity 5, − 4 5 with multiplicity 10, and − 8 5 with multiplicity 9 for n = 5, • − 1 4 with multiplicity 6, − 5 6 with multiplicity 15, and − 3 2 with multiplicity 14 for n = 6, and • − 10 49 with multiplicity 7, − 6 7 with multiplicity 21, and − 10 7 with multiplicity 20 for n = 7.These results give rise to the following conjecture: Conjecture 3.5.The non-lazy simple random walk P s on the unmixed complete graph K n+1 , n ≥ 2, is asymptotically stable and the eigenvalues of DF (P s ) are given by As n → ∞, we have Example 3.6 (Simple random walks on hypercubes).We know from [CKL + 22a, Corollary 1.14] that the simple random walk without laziness on a hypercube Q d = (K 2 ) d is curvature sharp, and it is the only non-degenerate curvature sharp weigthing schemes without laziness if and only if d is odd.For d = 2, a non-degenerate curvature sharp weigthing scheme on Q 2 different from the simple random walk is given in line 4 of the following code: A = hypercube (2) p = rand () q = 1 -p P = [[0 , p ,q ,0] ,[ p ,0 ,0 , q ] ,[p ,0 ,0 , q ] ,[0 ,p ,q ,0]] result = equilibrium_type (A ,P , True ) print ( " flow dynamics eigenvalues : " , result [1]) All eigenvalues λ j of the corresponding linearized flow matrix provided by this code via line 6 seem to be real.Two of them are numerically zero and the other two are given by ±λ with a non-zero real λ.So this equilibrium is unstable.Our experiments for arbitrary weighting schemes on Q d , d ≥ 2, close to the simple random walk show that the numerical flow converges usually to a degenerate limit.This agrees with our observation that the linearized flow matrix at the simple random walk seems always to have real eigenvalues with some of them being positive.These eigenvalues can be obtained via the following code: Let us finish this section with a conjecture which we verified numerically for d = 2, 3, . . ., 9: Conjecture 3.7.The non-lazy simple random walk P s on the hypercube Q d , d ≥ 2, is unstable and the eigenvalues of the corresponding linearized curvature flow matrix are all real with the largest eigenvalue λ max equals

Implementation of the curvature flow and useful tools
This section provides a short description of a program, written in Python, which allows users to carry out their own curvature flow experiments.This program is provided as an ancillary file and can be used in combination with the "Graph Curvature Calculator", which can be freely accessed at http://www.mas.ncl.ac.uk/graph-curvatureThe Graph Curvature Calculator is a powerful but easy to use interactive Web tool to draw graphs and to compute various types of curvatures like Bakry-Émery curvature on its vertices or Ollivier Ricci curvature on its edges (for details see [CKL + 22b]).This Web tool allows users to obtain the adjacency matrix of the graph under consideration which can then be used as input for the curvature flow code.The curvature flow code provides functions and routines which can be divided into six categories: (1) Functions related to graphs and their adjacency matrices (2) Functions related to weighting schemes (3) Functions testing combinatorial and weighted graphs (4) Curvature flow computation routines (5) Curvature computation routines (6) Display routines Each category is discussed in one of the following subsections.4.1.Functions related to graphs and their adjacency matrices.Recall that the topology of a given Markov chain (G, P ) is contained in the combinatorial graph G = (V, E).This information is provided by the adjacency matrix A = A G of the graph.Firstly, we go through some useful functions performing operations with these adjacency matrices.Every graph generated by one of The function cart_prod_prob(P, Q, p ,q) is a "weighted" analogue of the function cart_prod from the previous subsection for the Cartesian product of two weighting schemes P, Q with weights p, q, with p + q = 1.If P and Q are of size n and m, respectively, this function returns the matrix pP ⊗ I n + qI m ⊗ Q of size nm, where I n is the identity matrix of size n and A ⊗ B is the Kronecker product of A and B. 4.3.Functions testing combinational and weighted graphs.For combinatorial graphs given by their adjacency matrices A and weighted graphs given additionally by their weighting scheme P, we have the following test functions: • is_connected(A), • is_weakly_connected(A, threshold=0.001), • is_totally_degenerate(A, P, threshold=0.001), • is_markovian(P, norm_tolerance=0.001), • is_curvature_sharp(A, P, norm_tolerance=0.001,threshold=0.001), • equilibrium_type(A, P, eigenvalues=False, jacobi_matrix=False, norm_tolerance=0.001,threshold=0.001).The function is_connected(A) returns True if and only if the adjacency matrix A represents a connected graph.The function is_weakly_connected(P) is a "weighted" analogue, which returns True if and only if the weighted matrix P represents a weakly connected graph.It does this by forming an adjacency matrix with a 1 in the (i, j)th entry if and only if P[i, j] > threshold or P[j, i] > threshold and then testing for connectedness.Recall that a weighted graph (G, P ) is called numerically totally degenerate if there are no twosided edges with numerical non-zero transition rates in both directions and no one-sided edges with numerical non-zero transition rate, where we consider a transition rate p xy as numerically non-zero if and only if p xy ≥ threshold.The function is_totally_degenerate(A,P) tests this property.The function is_markovian(P) tests whether the entries of each of the columns of P add up numerically to 1 up to an error ≤ norm_tolerance.Numerical curvature sharpness (up to an error ≤ threshold) of Markovian weighted graphs given by (A,P) is tested by is_curvature_sharp(A,P).If (A,P) fails to be Markovian (with respect to norm_tolerance), this function returns NONE and gives notice to the user by an error message.For dynamical investigations of curvature flow equilibria, we have the function equilibrium_type(A,P) which always returns a list of length three.The function checks first whether (A,P) satisfies the Markovian property and is numerically curvature sharp.If this is not the case, it returns a list of three NONE values.Otherwise, the function investigates the real parts of the eigenvalues λ j of the linearized curvature flow matrix at the equilibrium P. The first entry of the return list is −1, 0 or 1 depending on the maximum max j Re(λ j ).If this maximum is ≥ threshold, the return value is 1 (for "unstable") and if this maximum is ≤ −threshold, the return value is −1 (for "asymptotically stable").Otherwise, the dynamical nature of the equilibrium cannot be numerically decided and the function returns the value 0. The following two entries of the return list are usually NONE unless the user made the choices eigenvalues=True or jacobi_matrix=True.In the first case, the second entry of the return list is a list of all eigenvalues of the linearized curvature flow matrix, and in the second case the third entry of the return is is the linearized curvature flow matrix itself.4.4.Curvature flow computation routines.At the heart of the program are the curvature flow routines solving the initial value ordinary differential equations ( 6) and (7).The relevant routines are the following: • curv_flow(A, P, t_max, dt=0.3,C=zeroes), • norm_curv_flow(A, P, t_max, dt=0.3,stoch_corr=True, norm_tolerance=0.001), • norm_curv_flow_lim(A, P, dt=0.3, stoch_corr=True, norm_tolerance=0.001,lim_tolerance=0.001,t_lim=10000).There are two internal subroutines involved which we would like to mention briefly.Pvecs_to_P translates a weighting scheme given by a list of lists (where each inner list contains the transition rates of the corresponding vertex) into the corresponding NumPy array.Pvecs_prime computes, for a given weighting scheme P, the right hand side of the ordinary differential equations describing the curvature flow.The representation of this right hand side is again a list of lists, as described before.The computation stops just before the discrete time steps exceed the limit time t_max and the routine returns P_list.Note that in this general setting, transition rates can assume arbitrary values and even negative ones or diverge to infinity in finite time which may lead to system error messages.Users need to be aware of this possibility.The normalized curvature flow, using the coefficients C x (t) = K d(x,•) P (t),∞ (x) (see (8)), is numerically computed by the routine norm_curv_flow(A,P).This special flow is the main focus of this paper and could also be mimicked by choosing C=K_inf in curv_flow.The function K_inf(A,P) returns a list of upper curvature bounds for all vertices of the Markovian weighted graph represented by (A,P) (see [CKL + 22a, formula (66)] for an explicit expression of this function in terms of transition rates).During the numerical computations of subsequent time steps, the Markovian property of the corresponding weighting schemes may be slightly violated.If this violation exceeds the threshold norm_tolerance, the routine prepares for a potential correction according to the Boolean variable stoch_corr.If stoch_corr=False, the program stops with a message to the user as discussed in Example 2.2.Otherwise the program carries out the following automatic Markovian renormalization of the currently considered weighting scheme: while the diagonal entries (the laziness values) are unchanged, the off-diagonal entries of every row are rescaled by the same factor to guarantee that the resulting matrix becomes stochastic again.As before, this routine returns a list P_list of consecutive weighting schemes up to the time limit t_max.While the user needs to specify the time limit t_max in the above two routines, the third routine norm_curv_flow_lim(A,P) continues computing the normalized numerical curvature flow until a numerical flow limit is reached.This limit is determined by the parameter lim_tolerance.The details for this numerical limit are explained in the introductory part of Section 2. This routine returns a list of length two: the limiting weighting scheme as a NumPy array followed by the numerical convergence time.Since it may happen that a normalized numerical flow does not converge at all (even though we are not aware of any such example), the parameter t_lim provides an upper time limit beyond which the routine will not continue.The parameters stoch_corr and norm_tolerance play the same role as in the routine norm_curv_flow.4.5.Curvature computation routines.The functions in this section calculate Bakry-Émery curvatures and curvature upper bounds of graphs with given weighting schemes at all vertices.
• curvatures(A, P, N=inf, onesps=[], q=None), • calc_curvatures(A, P_list, N=inf, k=1), • K_inf(A, P), • calc_curv_upper_bound(A, P_list, N=inf, k=1).The routine curvatures(A,P) computes, for a weighted graph (G, P ) with G = (V, E) and represented by (A,P), the curvatures of all vertices for dimension N = ∞ and returns them as a list of length |V |.If users are interested in curvatures for other dimensions, they need to change the parameter N=inf.There are two other inputs which can speed up the curvature calculations: if the number q of vertices in V is given, it can be specified to avoid its repeated recalculation, for example during a curvature flow process.Similarly, if onespheres(A) has already be calculated earlier, this information can be communicated to the routine via the input variable onesps.After a curvature flow computation with corresponding list P_list of consecutive weighting schemes, the routine calc_curvatures(A,P_list) computes the corresponding evolution of vertex curvatures by calling curvatures(A,P_list[j]) and returns it as a list of lists.Here the j-th inner list contains the curvature evolution of the j-th vertex of the graph G = (V, E) represented by A. The dimension parameter N=inf plays the same role as before.calc_curvatures computes curvatures only of each k-th weighting scheme provided by P_list.Where appropriate, this can help to reduce computation time.The routine K_inf(A,P) was already discussed in the previous subsection and provides a list of upper curvature bounds for all vertices of the weighted graph (G, P ) represented by (A,P).calc_curv_upper_bound is completely analogous to calc_curvatures, but it calls K_inf instead of curvatures.4.6.Display routines.The main display routines for users are the evolution of curvatures at various vertices during the curvature flow, the evolution of transition rates of edges emanating from vertices and the display of individual weighted graphs with vertices arranged in a circle.The relevant routines are the following: • display_curvatures(curv, dt=0.3,is_Markovian=True, N=inf, k=1, curv_bound=[], vertex_list=[]), • display_trans_rates(A, P_list, dt=0.3, vertex_list=[]), • display_weighted_graph(A, P, title=None, threshold=10**(-3), display_options=[10, True, 2, []], laziness=False).Given the evolution of vertex curvatures during a curvature flow process via a list of lists, where the j-th inner list is the curvature evolution of the j-th vertex, display_curvatures(curv) displays the curvature evolution for each consecutive vertex separately, as illustated for example, in Figure 3.If this information should be only given for specific vertices, this can be specified by the input parameter vertex_list.The time step dt=0.3 and the value of k together determine the labelling of the horizontal time axis.For the role of k we refer readers to our explanation about the routine calc_curvatures.Upper curvature bounds can be inserted into the displays by the input parameter curv_bound, which needs to be given in the same format as the vertex curvatures.Constant lower and upper curvature bounds −1 and 2 are plotted alongside if the Boolean is_Markovian is chosen to be True and if the dimension parameter N is ≥ 2. These bounds appear, for example, in the illustrations given in Figure 3.Given the evolution of weighting schemes during a curvature flow process on a graph with adjacency matrix A by a list P_list of NumPy arrays, display_trans_rates(A,P_list) displayes the evolution of transition rates of emanating edges for each consecutive vertex separately, as illustrated for example, in Figure 2. The input parameters dt and vertex_list play the same role as in the previous routine.Finally, there is the routine display_graph(A,P) with input parameters A and P representing a weighted graph (G, P ).This routine produces a MatPlotLib plot of this weighted graph, with the vertices arranged counter-clockwise in a circle.The plot uses the following convention to illustrate different types of edges: • green, solid lines represent numerically non-degenerate edges, that is {x, y} ∈ E with both p xy , p yx ≥ threshold, • red, dashed lines with an arrow represent numerically degenerate edges, that is {x, y} ∈ E with exactly one of p xy and p yx strictly less than threshold.• black, dotted lines represent edges with numerically vanishing transition rates in both directions, that is {x, y} ∈ E with both p xy , p yx strictly less than threshold.
Users can add a title into the display by specifying the input parameter title.For Markovian weighted graphs with non-vanishing laziness, the option laziness=True labels each vertex with its corresponding laziness.It remains to discuss the input parameter display_options of the display_graph routine.This parameter is a list of four entries.The first entry determines the size of the plot.Usually, the transition rates are printed above the edges, but if the second entry is chosen to be False, this information about the transition rates is omitted.Otherwise, the transition rates are given to a number of decimal places determined by the third entry.The default positions of these transition rates are 1 6 of the way along the edges, with the number closest to the vertex x in the edge (x, y) being p xy , but this can be altered manually to avoid overlapping by specification in the fourth entry of display_options.For example, if one wishes the p 45 label to be moved to a position 1 4 of the way from vertex 4 to vertex 5 and the p 62 label to be moved to a position 1 5 of the way from vertex 6 to vertex 2, this fourth entry should be chosen to be [[4, 5, 1/4, 1/6], [6, 2, 1/5, 1/6]].This completes the description of the functions and routines in the accompanying Python program to this article.

Figure 1 .Figure 2 .
Figure 1.Curvature flow of a random graph with 10 vertices with initial weighting scheme P 0 (left hand side) and final weighting scheme P (t max ) (right hand side)

Figure 4 .
Figure 4. Examples of numerical curvature flow limits of a path and of a cycle of length 12.

,
as illustrated in Figure5.Note that the edges {v 0 , v 4 }, {v 1 , v 2 }, {v 3 , v 5 } and {v 4 , v 5 } of this initial weighting scheme are degenerate, with the latter being two-sided degenerate.The numerical curvature flow has numerical convergence time t max = 18.5 (with respect to lim tolerance = 0.001) with the simple random walk as its numerical flow limit.Figure6presents the transition rates of the vertices v 2 and v 5 .Particular interesting are the functions p 2,1 (t) and p 5,4 (t) for t ∈ [0, t max ], since their initial values are zero.

Figure 5 .
Figure5.Curvature flow of a complete graph with 6 vertices with degenerate initial weighting scheme P 0 (left hand side) and numerical flow limit P (t max ), the simple random walk (right hand side)

Figure 6 .
Figure 6.Transition rates of vertices v 2 and v 5 of a complete graph with 6 vertices under the curvature flow totally degenerate limit illustrated in Figure12(right hand side) under the numerical curvature flow.

p
xy p y y ) + y =y p xy p y y = 0. Since we have p xy = 0, this means 0 ≤ p xz p zy ≤ y =y p xy p y y = 0, in contradiction to p xz , p zy > 0. The orientation x → y → z → x can be ruled out similarly.
( A ) result = equilibrium_type (A ,P , True ) print ( " Flow dynamics eigenvalues at the simple random walk : " ) for j in range (( d -1) *(2** d ) ) : print ( np .around ( result [1][ j ] ,4) ) The initial Markov chain (G, P 0 ) with G = (V, E) is entered by the adjacency matrix A describing the topology of the graph G and the weighting scheme P containing the initial probability transitions p xy (0).The first routine curv_flow(A,P) computes the non-normalized numerical curvature flow with coefficients C x (t) = 0 in (7).If users decide to choose other coefficient functions, they need to modify the input parameter C=zeroes.Note that zeroes(A,P) is a function returning simply a list of zeroes of length |V |.Users can investigate modifications of the curvature flow by choosing their own coefficient functions with input values (A,P) and returning a list of length |V | of real values.Using the discretization parameter dt=0.3 for the discrete time steps starting at t=0, the curvature flow routine creates a list P_list of weighting schemes (represented by NumPy arrays of size |V | × |V |) at each time increment using the Runge-Kutta algorithms RK4.
, Definition 1.4].The (equivalent) definition given in this paper is inspired by [KKRT16, Proof of Theorem 1.2].For more details about relations between different curvature sharpness definitions see Section 3 of our first paper [CKL + 22a].
Definition 1.2 (Curvature sharpness).Let (G, P ) be a weighted graph and N

Table 1 .
Vertex curvatures for the dimension ∞ of a random graph with 10 vertices at the beginning and the end of the curvature flow Example 2.2 and its illustrations was generated by the following code.