static public double[] Gradient(Digraph G, double[] xs) { Debug.Assert(xs.Length == G.n); var ys = Enumerable.Range(0, G.n).Select( u => xs [u] / Math.Sqrt(G.Degree(u)) ).ToArray(); var res = new double[G.n]; for (int u = 0; u < G.n; u++) { res [u] = xs [u]; foreach (var v in G.OutNeighbors[u]) { if (ys [u] > ys [v]) { res [u] -= xs [v] / Math.Sqrt(G.Degree(u) * G.Degree(v)); } else { res [u] -= xs [u] / G.Degree(u); } } foreach (var v in G.InNeighbors[u]) { if (ys [u] < ys [v]) { res [u] -= xs [v] / Math.Sqrt(G.Degree(u) * G.Degree(v)); } else { res [u] -= xs [u] / G.Degree(u); } } } for (int u = 0; u < G.n; u++) { res [u] = -res [u]; } return(res); }
static public double[] Gradient(Digraph G, double[] xs) { Debug.Assert(xs.Length == G.n); var res = new double[G.n]; for (int u = 0; u < G.n; u++) { res [u] = xs [u] * G.Degree(u); foreach (var v in G.OutNeighbors[u]) { if (xs [u] > xs [v]) { res [u] -= xs [v]; } else { res [u] -= xs [u]; } } foreach (var v in G.InNeighbors[u]) { if (xs [u] < xs [v]) { res [u] -= xs [v]; } else { res [u] -= xs [u]; } } } for (int u = 0; u < G.n; u++) { res [u] = -res [u]; } return(res); }
static public double RayleighQuotient(Digraph G, double[] xs) { Debug.Assert(xs.Length == G.n); double denominator = Vector.L2Norm(xs); double numerator = 0; var ys = Enumerable.Range(0, G.n).Select( u => xs [u] / Math.Sqrt(G.Degree(u)) ).ToArray(); for (int u = 0; u < G.n; u++) { foreach (var v in G.OutNeighbors[u]) { if (ys [u] > ys [v]) { numerator += (ys [u] - ys [v]) * (ys [u] - ys [v]); } } } return(numerator / denominator); }
static public double[] FirstEigenvector(Digraph G) { var res = Enumerable.Range(0, G.n).Select(u => Math.Sqrt(G.Degree(u))).ToArray(); return(Vector.L2Normalize(res)); }