private static void recordOrder(double time) { // Compute and record global order parameter double globalOrder = sync.GetOrder(network.Vertices.ToArray()); foreach (Vertex v in network.Vertices) { sync.AddDataPoint(v.Label, sync.CurrentValues[sync._mapping[v]]); } if (time > 30d) { sync.Stop(); } //double avgLocalOrder = 0d; //// Compute and record cluster order parameters //foreach(int g in network.ClusterIDs) //{ // double localOrder = sync.GetOrder(network.GetNodesInCluster(g)); // _clusterOrder[g] = localOrder; // sync.AddDataPoint(string.Format("order_{0}", g), localOrder); // avgLocalOrder += localOrder; // // Switch to pacemaker mode if cluster order exceeds threshold // if(localOrder>0.95d && !pacemaker_mode[g]) // { // pacemaker_mode[g] = true; // // Probabilistically switch border nodes to pacemaker mode // // Note: CouplingStrengths[... v, w ... ] is the strength by which phase advance of v is influenced when coupling to node w // foreach(Vertex v in network.GetNodesInCluster(g)) // { // if(network.HasInterClusterConnection(v)) // foreach(Vertex w in v.Neigbors) // if(!network.HasInterClusterConnection(w)) // { // Logger.AddMessage(LogEntryType.AppMsg, string.Format("Vertex switched to pacemaker mode", g)); // sync.CouplingStrengths[new Tuple<Vertex, Vertex>(v, w)] = 0d; // } // } // } //} //avgLocalOrder /= (double) network.ClusterIDs.Length; Logger.AddMessage(LogEntryType.SimMsg, string.Format("Time = {000000}", time)); //Avg. Cluster Order = {1:0.00}, Global Order = {2:0.00}", time, avgLocalOrder, globalOrder)); }
/// <summary> /// Runs the cluster synchronization experiments, reading simulation parameters from the .config file /// </summary> public override void RunSimulation() { // Setup the experiment by creating the network and the synchronization module ClusterNetwork net = new ClusterNetwork(nodes, edges, clusters, modularity_tgt, true); Kuramoto sync = new Kuramoto(net, K); // Couple to single random neighbor in each step sync.CouplingSelector = new Func <Vertex, Vertex[]>(v => { return(new Vertex[] { v.RandomNeighbor }); }); // Keeps track whether clusters have already switched to pacemaker mode Dictionary <int, bool> pacemaker_mode = new Dictionary <int, bool>(); // Mixed distribution of natural frequencies Normal group_avgs = new Normal(global_mean, global_mean * global_mean_width_factor); foreach (int i in net.ClusterIDs) { double group_avg = group_avgs.Sample(); Normal group_dist = new Normal(group_avg, group_avg * cluster_width_factor); foreach (Vertex v in net.GetNodesInCluster(i)) { sync.NaturalFrequencies[v] = group_dist.Sample(); } pacemaker_mode[i] = false; } // Set up handler that will be called AFTER each simulation step sync.OnStep += new Kuramoto.StepHandler( delegate(double t) { // Compute global order parameter finalOrderParam = sync.GetOrder(net.Vertices.ToArray()); normalizerIntegratedOrder += finalOrderParam; // Record order evolution sync.AddDataPoint("GlobalOrder", finalOrderParam); // Stop simulation if full ordered state is reached or time exceeded if (finalOrderParam >= orderThres || t > timeThres) { sync.Stop(); } // Output will only been shown when pyspg module is started in debug mode //if(t % (sync.TimeDelta * 100d) == 0) Logger.AddMessage(LogEntryType.SimMsg, string.Format("Time {0}, Order = {1:0.00}", t, finalOrderParam)); // Compute order parameter of individual clusters foreach (int g in net.ClusterIDs) { double localOrder = sync.GetOrder(net.GetNodesInCluster(g)); sync.AddDataPoint(string.Format("ClusterOrder_{0}", g), localOrder); // Switch to pacemaker mode if cluster order exceeds threshold if (localOrder > orderThres && !pacemaker_mode[g]) { pacemaker_mode[g] = true; // Probabilistically switch border nodes to pacemaker mode // Note: CouplingStrengths[... v, w ... ] is the strength by which phase advance of v is influenced when coupling to node w foreach (Vertex v in net.GetNodesInCluster(g)) { if (net.HasInterClusterConnection(v)) { foreach (Vertex w in v.Neigbors) { if (!net.HasInterClusterConnection(w) && net.NextRandomDouble() <= pacemakerProb) { Logger.AddMessage(LogEntryType.AppMsg, string.Format("Vertex switched to pacemaker mode", g)); sync.CouplingStrengths[new Tuple <Vertex, Vertex>(v, w)] = 0d; } } } } } } }); // compute coupling density in the initial situation initialDensity = 0d; foreach (var t in sync.CouplingStrengths.Keys) { initialDensity += sync.CouplingStrengths[t]; } // Synchronously run the experiment (blocks execution until experiment is finished) sync.Run(); // compute final coupling density finalDensity = 0d; foreach (var t in sync.CouplingStrengths.Keys) { finalDensity += sync.CouplingStrengths[t]; } // Write time-series of the order parameters (global and cluster-wise) to a file sync.WriteTimeSeries(dynamics); // Set results normalizerIntegratedOrder /= sync.Time; time = sync.Time; finalOrderParam = sync.GetOrder(net.Vertices.ToArray()); modularity_real = net.NewmanModularityUndirected; }