process signal for clsuter receptor

This commit is contained in:
Pascal Serrarens 2026-03-03 11:48:16 +01:00
parent bd24e6e19b
commit 3cdca017d6

View File

@ -123,7 +123,11 @@ public class Cluster : Nucleus {
// Calculate in-degrees // Calculate in-degrees
foreach (Nucleus node in nodes) { foreach (Nucleus node in nodes) {
if (node is Neuron neuron) { if (node is Cluster cluster) {
foreach (Nucleus receiver in cluster.CollectReceivers())
inDegree[receiver]++;
}
else if (node is Neuron neuron) {
foreach (Nucleus receiver in neuron.receivers) foreach (Nucleus receiver in neuron.receivers)
inDegree[receiver]++; inDegree[receiver]++;
} }
@ -148,6 +152,13 @@ public class Cluster : Nucleus {
queue.Enqueue(receiver); queue.Enqueue(receiver);
} }
} }
else if (current is Cluster cluster) {
foreach (Nucleus receiver in cluster.CollectReceivers()) {
inDegree[receiver]--;
if (inDegree[receiver] == 0) // If all dependencies resolved
queue.Enqueue(receiver);
}
}
} }
// Check for cycles in the graph // Check for cycles in the graph
@ -279,19 +290,17 @@ public class Cluster : Nucleus {
public Dictionary<Nucleus, List<Nucleus>> computeOrders = new(); public Dictionary<Nucleus, List<Nucleus>> computeOrders = new();
private void ComputeOrders() { private void ComputeOrders() {
foreach (Nucleus input in this._inputs) { foreach (Nucleus input in this._inputs)
computeOrders[input] = TopologicalSort2(input); computeOrders[input] = TopologicalSort2(input);
} }
}
private List<Nucleus> TopologicalSort2(Nucleus startNode) { private List<Nucleus> TopologicalSort2(Nucleus startNode) {
Dictionary<Nucleus, int> inDegree = new Dictionary<Nucleus, int>(); Dictionary<Nucleus, int> inDegree = new();
HashSet<Nucleus> visited = new HashSet<Nucleus>(); HashSet<Nucleus> visited = new();
// Initialize in-degrees and mark all nodes as unvisited // Initialize in-degrees and mark all nodes as unvisited
foreach (Nucleus node in this.clusterNuclei) { foreach (Nucleus node in this.clusterNuclei)
inDegree[node] = 0; inDegree[node] = 0;
}
// Calculate in-degrees for all nodes reachable from the start node // Calculate in-degrees for all nodes reachable from the start node
Queue<Nucleus> queue = new Queue<Nucleus>(); Queue<Nucleus> queue = new Queue<Nucleus>();
@ -300,39 +309,51 @@ public class Cluster : Nucleus {
while (queue.Count > 0) { while (queue.Count > 0) {
Nucleus current = queue.Dequeue(); Nucleus current = queue.Dequeue();
if (current is Neuron neuron) { List<Nucleus> receivers = null;
foreach (Nucleus receiver in neuron.receivers) { if (current is Neuron neuron)
receivers = neuron.receivers;
else if (current is Cluster cluster)
receivers = cluster.CollectReceivers();
// if (current is Neuron neuron) {
foreach (Nucleus receiver in receivers) {
if (!visited.Contains(receiver)) { if (!visited.Contains(receiver)) {
visited.Add(receiver); visited.Add(receiver);
queue.Enqueue(receiver); queue.Enqueue(receiver);
} }
inDegree[receiver]++; inDegree[receiver]++;
} }
} // }
} }
// Perform topological sort on all reachable nodes // Perform topological sort on all reachable nodes
queue.Clear(); queue.Clear();
foreach (var node in visited) { foreach (Nucleus node in visited) {
if (inDegree[node] == 0) { if (inDegree[node] == 0)
queue.Enqueue(node); queue.Enqueue(node);
} }
}
List<Nucleus> sortedOrder = new List<Nucleus>(); List<Nucleus> sortedOrder = new List<Nucleus>();
while (queue.Count > 0) { while (queue.Count > 0) {
Nucleus current = queue.Dequeue(); Nucleus current = queue.Dequeue();
sortedOrder.Add(current); // Process the node sortedOrder.Add(current); // Process the node
if (current is Neuron neuron) { List<Nucleus> receivers = null;
foreach (Nucleus receiver in neuron.receivers) { if (current is Neuron neuron)
receivers = neuron.receivers;
else if (current is Cluster cluster)
receivers = cluster.CollectReceivers();
//if (current is Neuron neuron) {
foreach (Nucleus receiver in receivers) {
if (visited.Contains(receiver)) { if (visited.Contains(receiver)) {
inDegree[receiver]--; inDegree[receiver]--;
if (inDegree[receiver] == 0) // If all dependencies resolved if (inDegree[receiver] == 0) // If all dependencies resolved
queue.Enqueue(receiver); queue.Enqueue(receiver);
} }
} }
} //}
} }
// Check for cycles in the graph // Check for cycles in the graph
@ -342,44 +363,6 @@ public class Cluster : Nucleus {
return sortedOrder; return sortedOrder;
} }
private List<Nucleus> TopologicalSort3(Nucleus startNode) {
Dictionary<Nucleus, int> inDegree = new();
foreach (Nucleus node in this.clusterNuclei)
inDegree[node] = 0; // Initialize in-degree to zero
// Calculate in-degrees
foreach (Nucleus node in this.clusterNuclei) {
if (node is Neuron neuron) {
foreach (Nucleus receiver in neuron.receivers)
inDegree[receiver]++;
}
}
Queue<Nucleus> queue = new();
queue.Enqueue(startNode);
List<Nucleus> sortedOrder = new();
while (queue.Count > 0) {
Nucleus current = queue.Dequeue();
sortedOrder.Add(current); // Process the node
if (current is Neuron neuron) {
foreach (Nucleus receiver in neuron.receivers) {
inDegree[receiver]--;
if (inDegree[receiver] == 0) // If all dependencies resolved
queue.Enqueue(receiver);
}
}
}
Debug.Log($"Compute order for {startNode.name} length = {sortedOrder.Count}");
// Check for cycles in the graph
// if (sortedOrder.Count != this.nuclei.Count)
// throw new InvalidOperationException("Graph is not a DAG; a cycle exists.");
return sortedOrder;
}
public virtual Neuron defaultOutput {//=> this.nuclei[0] as Nucleus; public virtual Neuron defaultOutput {//=> this.nuclei[0] as Nucleus;
get { get {
if (this.clusterNuclei.Count > 0) if (this.clusterNuclei.Count > 0)
@ -469,6 +452,11 @@ public class Cluster : Nucleus {
public void UpdateFromNucleus(Nucleus startNucleus) { public void UpdateFromNucleus(Nucleus startNucleus) {
// no bias+synapse input state calculation for now... // no bias+synapse input state calculation for now...
if (this.computeOrders.ContainsKey(startNucleus) == false) {
Debug.LogError($"{this.name} compute orders does not contain an order for {startNucleus.name}");
return;
}
List<Nucleus> computeOrder = this.computeOrders[startNucleus]; List<Nucleus> computeOrder = this.computeOrders[startNucleus];
if (startNucleus.trace) if (startNucleus.trace)
Debug.Log($"Update from {startNucleus.name}"); Debug.Log($"Update from {startNucleus.name}");
@ -481,6 +469,16 @@ public class Cluster : Nucleus {
this.outputValue = this.defaultOutput.outputValue; this.outputValue = this.defaultOutput.outputValue;
this.stale = 0; this.stale = 0;
if (this.parent != null) {
// continue in parent
this.parent.UpdateFromNucleus(this);
// continue in parent with the receivers of the last nucleus in the compute order
// if (computeOrder.Last() is Neuron lastNeuron) {
// foreach (Nucleus receiver in lastNeuron.receivers)
// this.parent?.UpdateFromNucleus(this);
// }
}
UpdateNuclei(); UpdateNuclei();
} }