Fix Cluster array extension
This commit is contained in:
parent
02047a4bd9
commit
c2e4e1b33f
@ -197,9 +197,9 @@ namespace NanoBrain {
|
|||||||
if (this.currentNucleus is Cluster cluster) {
|
if (this.currentNucleus is Cluster cluster) {
|
||||||
EditorGUILayout.BeginHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
||||||
if (cluster.siblingClusters != null && cluster.siblingClusters.Length > 1)
|
if (cluster.siblingClusters != null && cluster.siblingClusters.Length > 1)
|
||||||
EditorGUILayout.IntField("Array size", cluster.siblingClusters.Count());
|
EditorGUILayout.IntField("Array size", cluster.siblingClusters.Count(), GUILayout.MinWidth(150));
|
||||||
else
|
else
|
||||||
EditorGUILayout.IntField("Array size", 1);
|
EditorGUILayout.IntField("Array size", 1, GUILayout.MinWidth(150));
|
||||||
if (GUILayout.Button("Add")) {
|
if (GUILayout.Button("Add")) {
|
||||||
Undo.RecordObject(prefabAsset, "Array add " + prefabAsset.name);
|
Undo.RecordObject(prefabAsset, "Array add " + prefabAsset.name);
|
||||||
cluster.AddInstance(this.prefab);
|
cluster.AddInstance(this.prefab);
|
||||||
@ -224,10 +224,13 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EditorGUIUtility.wideMode = true;
|
EditorGUIUtility.wideMode = true;
|
||||||
|
float previousLabelWidth = EditorGUIUtility.labelWidth;
|
||||||
EditorGUIUtility.labelWidth = 100;
|
EditorGUIUtility.labelWidth = 100;
|
||||||
|
|
||||||
Vector3 newBias = EditorGUILayout.Vector3Field("Bias", this.currentNucleus.bias);
|
Vector3 newBias = EditorGUILayout.Vector3Field("Bias", this.currentNucleus.bias);
|
||||||
anythingChanged |= newBias != this.currentNucleus.bias;
|
anythingChanged |= newBias != this.currentNucleus.bias;
|
||||||
this.currentNucleus.bias = newBias;
|
this.currentNucleus.bias = newBias;
|
||||||
|
EditorGUIUtility.labelWidth = previousLabelWidth;
|
||||||
|
|
||||||
Nucleus[] array = null;
|
Nucleus[] array = null;
|
||||||
int elementIx = -1;
|
int elementIx = -1;
|
||||||
|
|||||||
@ -189,11 +189,9 @@ namespace NanoBrain {
|
|||||||
if (nucleus == null)
|
if (nucleus == null)
|
||||||
return;
|
return;
|
||||||
layer.neuroids.Add(nucleus);
|
layer.neuroids.Add(nucleus);
|
||||||
//nucleus.layerIx = layer.ix;
|
|
||||||
// Store its position
|
// Store its position
|
||||||
Vector2Int neuroidPosition = new(layer.ix, layer.neuroids.Count - 1);
|
Vector2Int neuroidPosition = new(layer.ix, layer.neuroids.Count - 1);
|
||||||
neuroidPositions[nucleus] = neuroidPosition;
|
neuroidPositions[nucleus] = neuroidPosition;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnIMGUI() {
|
public void OnIMGUI() {
|
||||||
@ -224,9 +222,9 @@ namespace NanoBrain {
|
|||||||
Dag dag = GenerateGraph(this.selectedOutput);
|
Dag dag = GenerateGraph(this.selectedOutput);
|
||||||
Dag.ComputeLayout(dag);
|
Dag.ComputeLayout(dag);
|
||||||
// Draw edges
|
// Draw edges
|
||||||
foreach (DagEdge e in dag.edges) {
|
foreach (Dag.Edge e in dag.edges) {
|
||||||
DagNode from = dag.nodes.FirstOrDefault(x => x.id == e.fromId);
|
Dag.Node from = dag.nodes.FirstOrDefault(x => x.id == e.fromId);
|
||||||
DagNode to = dag.nodes.FirstOrDefault(x => x.id == e.toId);
|
Dag.Node to = dag.nodes.FirstOrDefault(x => x.id == e.toId);
|
||||||
if (from == null || to == null)
|
if (from == null || to == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -236,13 +234,13 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw nodes
|
// Draw nodes
|
||||||
foreach (DagNode n in dag.nodes)
|
foreach (Dag.Node n in dag.nodes)
|
||||||
DrawNucleus(n.nucleus, n.position, 1, n.radius);
|
DrawNucleus(n.nucleus, n.position, 1, n.radius);
|
||||||
|
|
||||||
// Determine graph width
|
// Determine graph width
|
||||||
float width = 0;
|
float width = 0;
|
||||||
float currentNucleusPosition = 0;
|
float currentNucleusPosition = 0;
|
||||||
foreach (DagNode node in dag.nodes) {
|
foreach (Dag.Node node in dag.nodes) {
|
||||||
if (node.position.x > width)
|
if (node.position.x > width)
|
||||||
width = node.position.x;
|
width = node.position.x;
|
||||||
if (node.nucleus == currentNucleus)
|
if (node.nucleus == currentNucleus)
|
||||||
@ -271,7 +269,7 @@ namespace NanoBrain {
|
|||||||
return dag;
|
return dag;
|
||||||
|
|
||||||
int ix = 0;
|
int ix = 0;
|
||||||
DagNode receiver = new() {
|
Dag.Node receiver = new() {
|
||||||
id = ix,
|
id = ix,
|
||||||
//title = nucleus.name,
|
//title = nucleus.name,
|
||||||
nucleus = rootNucleus
|
nucleus = rootNucleus
|
||||||
@ -282,9 +280,9 @@ namespace NanoBrain {
|
|||||||
return dag;
|
return dag;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DescendGraph(DagNode receiver, ref int ix, Dag dag) {
|
private void DescendGraph(Dag.Node receiver, ref int ix, Dag dag) {
|
||||||
foreach (Synapse synapse in receiver.nucleus.synapses) {
|
foreach (Synapse synapse in receiver.nucleus.synapses) {
|
||||||
DagNode synapseNode = dag.FindNode(synapse.neuron.name);
|
Dag.Node synapseNode = dag.FindNode(synapse.neuron.name);
|
||||||
if (synapseNode == null) {
|
if (synapseNode == null) {
|
||||||
synapseNode = new() {
|
synapseNode = new() {
|
||||||
id = ix,
|
id = ix,
|
||||||
@ -292,7 +290,7 @@ namespace NanoBrain {
|
|||||||
};
|
};
|
||||||
dag.nodes.Add(synapseNode);
|
dag.nodes.Add(synapseNode);
|
||||||
}
|
}
|
||||||
DagEdge edge = new() {
|
Dag.Edge edge = new() {
|
||||||
fromId = synapseNode.id,
|
fromId = synapseNode.id,
|
||||||
toId = receiver.id
|
toId = receiver.id
|
||||||
};
|
};
|
||||||
@ -480,6 +478,11 @@ namespace NanoBrain {
|
|||||||
// continue;
|
// continue;
|
||||||
// drawnArrays.Add(clusterReceptor.nucleiArray);
|
// drawnArrays.Add(clusterReceptor.nucleiArray);
|
||||||
// }
|
// }
|
||||||
|
if (synapse.neuron.parent is Cluster cluster) {
|
||||||
|
if (drawnArrays.Contains(cluster.siblingClusters))
|
||||||
|
continue;
|
||||||
|
drawnArrays.Add(cluster.siblingClusters);
|
||||||
|
}
|
||||||
Vector3 pos = new(250, margin + row * spacing, 0.0f);
|
Vector3 pos = new(250, margin + row * spacing, 0.0f);
|
||||||
Handles.color = Color.white;
|
Handles.color = Color.white;
|
||||||
Handles.DrawLine(parentPos, pos);
|
Handles.DrawLine(parentPos, pos);
|
||||||
@ -679,13 +682,13 @@ namespace NanoBrain {
|
|||||||
else
|
else
|
||||||
expandArray = false;
|
expandArray = false;
|
||||||
}
|
}
|
||||||
// else if (nucleus.parent != this.currentNucleus.parent) {
|
else if (nucleus.parent != this.currentNucleus.parent) {
|
||||||
// // We go to a different cluster
|
// We go to a different cluster
|
||||||
// // select the cluster, not the neuron in the cluster
|
// select the cluster, not the neuron in the cluster
|
||||||
// this.currentNucleus = nucleus.parent;
|
this.currentNucleus = nucleus.parent;
|
||||||
// expandArray = false;
|
expandArray = false;
|
||||||
// BuildLayers();
|
BuildLayers();
|
||||||
// }
|
}
|
||||||
else {
|
else {
|
||||||
this.currentNucleus = nucleus;
|
this.currentNucleus = nucleus;
|
||||||
expandArray = false;
|
expandArray = false;
|
||||||
@ -729,37 +732,37 @@ namespace NanoBrain {
|
|||||||
public List<Nucleus> neuroids = new();
|
public List<Nucleus> neuroids = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
[System.Serializable]
|
|
||||||
public class DagNode {
|
|
||||||
public int id;
|
|
||||||
public Vector2 position;
|
|
||||||
public float radius = 20f; // circle radius
|
|
||||||
public Nucleus nucleus;
|
|
||||||
}
|
|
||||||
|
|
||||||
[System.Serializable]
|
|
||||||
public class DagEdge {
|
|
||||||
public int fromId;
|
|
||||||
public int toId;
|
|
||||||
}
|
|
||||||
public class Dag {
|
public class Dag {
|
||||||
public List<DagNode> nodes = new();
|
|
||||||
public List<DagEdge> edges = new();
|
|
||||||
|
|
||||||
public DagNode FindNode(string name) {
|
public class Node {
|
||||||
foreach (DagNode node in this.nodes) {
|
public int id;
|
||||||
|
public Vector2 position;
|
||||||
|
public float radius = 20f; // circle radius
|
||||||
|
public Nucleus nucleus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Edge {
|
||||||
|
public int fromId;
|
||||||
|
public int toId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Node> nodes = new();
|
||||||
|
public List<Edge> edges = new();
|
||||||
|
|
||||||
|
public Node FindNode(string name) {
|
||||||
|
foreach (Node node in this.nodes) {
|
||||||
if (node.nucleus.name == name)
|
if (node.nucleus.name == name)
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DagNode GetNodeById(Dag dag, int id) => dag.nodes.FirstOrDefault(x => x.id == id);
|
public static Node GetNodeById(Dag dag, int id) => dag.nodes.FirstOrDefault(x => x.id == id);
|
||||||
|
|
||||||
public static void ComputeLayout(Dag dag) {
|
public static void ComputeLayout(Dag dag) {
|
||||||
Dictionary<int, List<int>> adjacency = dag.nodes.ToDictionary(n => n.id, n => new List<int>());
|
Dictionary<int, List<int>> adjacency = dag.nodes.ToDictionary(n => n.id, n => new List<int>());
|
||||||
Dictionary<int, int> outdegree = dag.nodes.ToDictionary(node => node.id, n => 0);
|
Dictionary<int, int> outdegree = dag.nodes.ToDictionary(node => node.id, n => 0);
|
||||||
foreach (DagEdge edge in dag.edges) {
|
foreach (Edge edge in dag.edges) {
|
||||||
if (!adjacency.ContainsKey(edge.fromId) || !adjacency.ContainsKey(edge.toId))
|
if (!adjacency.ContainsKey(edge.fromId) || !adjacency.ContainsKey(edge.toId))
|
||||||
continue;
|
continue;
|
||||||
adjacency[edge.fromId].Add(edge.toId);
|
adjacency[edge.fromId].Add(edge.toId);
|
||||||
@ -771,7 +774,7 @@ namespace NanoBrain {
|
|||||||
Dictionary<int, List<int>> parents = dag.nodes.ToDictionary(n => n.id, _ => new List<int>());
|
Dictionary<int, List<int>> parents = dag.nodes.ToDictionary(n => n.id, _ => new List<int>());
|
||||||
Dictionary<int, int> childCount = dag.nodes.ToDictionary(n => n.id, _ => 0);
|
Dictionary<int, int> childCount = dag.nodes.ToDictionary(n => n.id, _ => 0);
|
||||||
|
|
||||||
foreach (DagEdge edge in dag.edges) {
|
foreach (Edge edge in dag.edges) {
|
||||||
if (!adjacency.ContainsKey(edge.fromId) || !adjacency.ContainsKey(edge.toId)) continue;
|
if (!adjacency.ContainsKey(edge.fromId) || !adjacency.ContainsKey(edge.toId)) continue;
|
||||||
adjacency[edge.fromId].Add(edge.toId);
|
adjacency[edge.fromId].Add(edge.toId);
|
||||||
parents[edge.toId].Add(edge.fromId); // parent of 'to' is 'from'
|
parents[edge.toId].Add(edge.fromId); // parent of 'to' is 'from'
|
||||||
@ -798,7 +801,7 @@ namespace NanoBrain {
|
|||||||
|
|
||||||
// Any unreachable nodes -> assign next layers
|
// Any unreachable nodes -> assign next layers
|
||||||
int maxLayer = layer.Count > 0 ? layer.Values.Max() : 0;
|
int maxLayer = layer.Count > 0 ? layer.Values.Max() : 0;
|
||||||
foreach (DagNode node in dag.nodes) {
|
foreach (Node node in dag.nodes) {
|
||||||
if (!layer.ContainsKey(node.id)) {
|
if (!layer.ContainsKey(node.id)) {
|
||||||
maxLayer++;
|
maxLayer++;
|
||||||
layer[node.id] = maxLayer;
|
layer[node.id] = maxLayer;
|
||||||
@ -846,7 +849,7 @@ namespace NanoBrain {
|
|||||||
float margin = 10 + spacing / 2;
|
float margin = 10 + spacing / 2;
|
||||||
for (int i = 0; i < nodeList.Count; i++) {
|
for (int i = 0; i < nodeList.Count; i++) {
|
||||||
int index = nodeList[i];
|
int index = nodeList[i];
|
||||||
DagNode node = GetNodeById(dag, index);
|
Node node = GetNodeById(dag, index);
|
||||||
if (node == null)
|
if (node == null)
|
||||||
continue;
|
continue;
|
||||||
float x = hSpacing + layerIx * hSpacing;
|
float x = hSpacing + layerIx * hSpacing;
|
||||||
|
|||||||
@ -281,7 +281,8 @@ namespace NanoBrain {
|
|||||||
|
|
||||||
public void AddInstance(ClusterPrefab prefab) {
|
public void AddInstance(ClusterPrefab prefab) {
|
||||||
// Ensure siblingClusters exists
|
// Ensure siblingClusters exists
|
||||||
this.siblingClusters ??= new Cluster[1] { this };
|
if (this.siblingClusters == null || this.siblingClusters.Length == 0)
|
||||||
|
this.siblingClusters = new Cluster[1] { this };
|
||||||
|
|
||||||
// Prepare the new array
|
// Prepare the new array
|
||||||
int newLength = this.siblingClusters.Length + 1;
|
int newLength = this.siblingClusters.Length + 1;
|
||||||
@ -299,7 +300,7 @@ namespace NanoBrain {
|
|||||||
newSiblings[newLength - 1] = newCluster;
|
newSiblings[newLength - 1] = newCluster;
|
||||||
|
|
||||||
// All siblingClusters need to user this array!
|
// All siblingClusters need to user this array!
|
||||||
foreach (Cluster sibling in this.siblingClusters)
|
foreach (Cluster sibling in newSiblings)
|
||||||
sibling.siblingClusters = newSiblings;
|
sibling.siblingClusters = newSiblings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +350,7 @@ namespace NanoBrain {
|
|||||||
if (this.siblingClusters[ix].defaultOutput.lastUpdate < unusedCluster.defaultOutput.lastUpdate)
|
if (this.siblingClusters[ix].defaultOutput.lastUpdate < unusedCluster.defaultOutput.lastUpdate)
|
||||||
unusedCluster = this.siblingClusters[ix];
|
unusedCluster = this.siblingClusters[ix];
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveThingCluster(unusedCluster);
|
RemoveThingCluster(unusedCluster);
|
||||||
return unusedCluster;
|
return unusedCluster;
|
||||||
}
|
}
|
||||||
@ -534,7 +535,10 @@ namespace NanoBrain {
|
|||||||
|
|
||||||
public virtual List<Nucleus> CollectReceivers() {
|
public virtual List<Nucleus> CollectReceivers() {
|
||||||
List<Nucleus> receivers = new();
|
List<Nucleus> receivers = new();
|
||||||
foreach (Neuron output in this.outputs) {
|
foreach (Nucleus outputNucleus in this.clusterNuclei) {
|
||||||
|
if (outputNucleus is not Neuron output)
|
||||||
|
continue;
|
||||||
|
|
||||||
foreach (Nucleus receiver in output.receivers) {
|
foreach (Nucleus receiver in output.receivers) {
|
||||||
// Only add receivers outside this cluster
|
// Only add receivers outside this cluster
|
||||||
if (receiver.clusterPrefab != this.prefab)
|
if (receiver.clusterPrefab != this.prefab)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user