Created runtime sibling, but not the synapses yet
This commit is contained in:
parent
36f876c0d8
commit
04010903f5
@ -164,94 +164,117 @@ namespace NanoBrain {
|
|||||||
// clonedNeuron.AddReceiver(clonedReceiver, weight);
|
// clonedNeuron.AddReceiver(clonedReceiver, weight);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Application.isPlaying) {
|
||||||
|
// Only create cluster siblings at runtime
|
||||||
|
foreach (Nucleus clonedNucleus in clonedNuclei) {
|
||||||
|
if (clonedNucleus is not Cluster clonedCluster)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if (clonedCluster.instanceCount <= 1)
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
for (int instanceIx = 1; instanceIx < clonedCluster.instanceCount; instanceIx++) {
|
||||||
|
//ClusterPrefab prefabCluster = clonedCluster.prefab;
|
||||||
|
// Create another sibling
|
||||||
|
Debug.Log($"create {clonedCluster.prefab.name} sibling");
|
||||||
|
Cluster sibling = new(clonedCluster.prefab, this) {
|
||||||
|
name = this.name,
|
||||||
|
clusterPrefab = this.clusterPrefab,
|
||||||
|
instanceCount = this.instanceCount,
|
||||||
|
};
|
||||||
|
RestoreAllExternalReceivers(clonedCluster, clonedCluster.prefab, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
// Copy the siblings for clusters
|
for (int nucleusIx = 0; nucleusIx < clonedNuclei.Length; nucleusIx++) {
|
||||||
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
|
Nucleus prefabNucleus = prefabNuclei[nucleusIx];
|
||||||
Nucleus prefabNucleus = prefabNuclei[nucleusIx];
|
if (prefabNucleus is not Cluster prefabCluster)
|
||||||
if (prefabNucleus is not Cluster prefabCluster)
|
continue;
|
||||||
|
|
||||||
|
if (prefabCluster.instanceCount <= 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Cluster clonedNucleus = clonedNuclei[nucleusIx] as Cluster;
|
||||||
|
if (prefabCluster == prefabCluster.siblingClusters[0]) {
|
||||||
|
// We clone the array only for the first entry
|
||||||
|
//NucleusArray clonedArray = new(prefabReceptor.nucleiArray.Length);
|
||||||
|
Cluster[] clonedArray = new Cluster[prefabCluster.siblingClusters.Length];
|
||||||
|
int arrayIx = 0;
|
||||||
|
foreach (Cluster prefabArrayNucleus in prefabCluster.siblingClusters) {
|
||||||
|
int arrayNucleusIx = GetNucleusIndex(prefabNuclei, prefabArrayNucleus);
|
||||||
|
if (arrayNucleusIx >= 0) {
|
||||||
|
Cluster clonedArrayNucleus = clonedNuclei[arrayNucleusIx] as Cluster;
|
||||||
|
clonedArray[arrayIx] = clonedArrayNucleus;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Debug.LogError($" Could not find prefab nucleus {prefabNucleus.name} in the clones");
|
||||||
|
}
|
||||||
|
arrayIx++;
|
||||||
|
}
|
||||||
|
clonedNucleus.siblingClusters = clonedArray;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The others will refer to the array created for the first nucleus in the array
|
||||||
|
int firstNucleusIx = GetNucleusIndex(prefabNuclei, prefabCluster.siblingClusters[0]);
|
||||||
|
Cluster clonedFirstNucleus = clonedNuclei[firstNucleusIx] as Cluster;
|
||||||
|
clonedNucleus.siblingClusters = clonedFirstNucleus.siblingClusters;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Collect the subclusters
|
||||||
|
List<Cluster> subClusters = new();
|
||||||
|
foreach (Nucleus nucleus in prefabNuclei) {
|
||||||
|
foreach (Synapse synapse in nucleus.synapses) {
|
||||||
|
Nucleus synapseNucleus = synapse.neuron;
|
||||||
|
Cluster subCluster = synapseNucleus.parent;
|
||||||
|
if (subCluster is null ||
|
||||||
|
synapseNucleus.clusterPrefab == this.clusterPrefab) {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (prefabCluster.siblingClusters == null || prefabCluster.siblingClusters.Length == 0)
|
// if (synapseNucleus is not Cluster subCluster)
|
||||||
|
// continue;
|
||||||
|
if (subClusters.Contains(subCluster))
|
||||||
continue;
|
continue;
|
||||||
|
subClusters.Add(subCluster);
|
||||||
Cluster clonedNucleus = clonedNuclei[nucleusIx] as Cluster;
|
|
||||||
if (prefabCluster == prefabCluster.siblingClusters[0]) {
|
|
||||||
// We clone the array only for the first entry
|
|
||||||
//NucleusArray clonedArray = new(prefabReceptor.nucleiArray.Length);
|
|
||||||
Cluster[] clonedArray = new Cluster[prefabCluster.siblingClusters.Length];
|
|
||||||
int arrayIx = 0;
|
|
||||||
foreach (Cluster prefabArrayNucleus in prefabCluster.siblingClusters) {
|
|
||||||
int arrayNucleusIx = GetNucleusIndex(prefabNuclei, prefabArrayNucleus);
|
|
||||||
if (arrayNucleusIx >= 0) {
|
|
||||||
Cluster clonedArrayNucleus = clonedNuclei[arrayNucleusIx] as Cluster;
|
|
||||||
clonedArray[arrayIx] = clonedArrayNucleus;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Debug.LogError($" Could not find prefab nucleus {prefabNucleus.name} in the clones");
|
|
||||||
}
|
|
||||||
arrayIx++;
|
|
||||||
}
|
|
||||||
clonedNucleus.siblingClusters = clonedArray;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The others will refer to the array created for the first nucleus in the array
|
|
||||||
int firstNucleusIx = GetNucleusIndex(prefabNuclei, prefabCluster.siblingClusters[0]);
|
|
||||||
Cluster clonedFirstNucleus = clonedNuclei[firstNucleusIx] as Cluster;
|
|
||||||
clonedNucleus.siblingClusters = clonedFirstNucleus.siblingClusters;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/*
|
// Create the subcluster instances
|
||||||
// Collect the subclusters
|
foreach (Cluster subCluster in subClusters) {
|
||||||
List<Cluster> subClusters = new();
|
for (int ix = 0; ix < subCluster.instanceCount; ix++) {
|
||||||
foreach (Nucleus nucleus in prefabNuclei) {
|
// create the new instance
|
||||||
foreach (Synapse synapse in nucleus.synapses) {
|
Cluster clusterInstance = new(subCluster.prefab);
|
||||||
Nucleus synapseNucleus = synapse.neuron;
|
// connect it
|
||||||
Cluster subCluster = synapseNucleus.parent;
|
foreach ((Neuron sender, Nucleus receiver) in subCluster.CollectConnections()) {
|
||||||
if (subCluster is null ||
|
int receiverIx = GetNucleusIndex(prefabNuclei, receiver);
|
||||||
synapseNucleus.clusterPrefab == this.clusterPrefab) {
|
if (receiverIx < 0)
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
// if (synapseNucleus is not Cluster subCluster)
|
if (clonedNuclei[receiverIx] is not Nucleus clonedReceiver)
|
||||||
// continue;
|
|
||||||
if (subClusters.Contains(subCluster))
|
|
||||||
continue;
|
continue;
|
||||||
subClusters.Add(subCluster);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create the subcluster instances
|
|
||||||
foreach (Cluster subCluster in subClusters) {
|
|
||||||
for (int ix = 0; ix < subCluster.instanceCount; ix++) {
|
|
||||||
// create the new instance
|
|
||||||
Cluster clusterInstance = new(subCluster.prefab);
|
|
||||||
// connect it
|
|
||||||
foreach ((Neuron sender, Nucleus receiver) in subCluster.CollectConnections()) {
|
|
||||||
int receiverIx = GetNucleusIndex(prefabNuclei, receiver);
|
|
||||||
if (receiverIx < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (clonedNuclei[receiverIx] is not Nucleus clonedReceiver)
|
// Find the synapse for the weight
|
||||||
continue;
|
float weight = 1;
|
||||||
|
foreach (Synapse synapse in receiver.synapses) {
|
||||||
// Find the synapse for the weight
|
// Find the weight for this synapse
|
||||||
float weight = 1;
|
if (synapse.neuron == sender) {
|
||||||
foreach (Synapse synapse in receiver.synapses) {
|
weight = synapse.weight;
|
||||||
// Find the weight for this synapse
|
break;
|
||||||
if (synapse.neuron == sender) {
|
|
||||||
weight = synapse.weight;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clusterInstance.GetNucleus(sender.name) is not Neuron clonedSender)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
clonedSender.AddReceiver(clonedReceiver, weight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (clusterInstance.GetNucleus(sender.name) is not Neuron clonedSender)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
clonedSender.AddReceiver(clonedReceiver, weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// foreach (Nucleus nucleus in this.clusterNuclei) {
|
// foreach (Nucleus nucleus in this.clusterNuclei) {
|
||||||
// if (nucleus is Cluster clonedSubCluster)
|
// if (nucleus is Cluster clonedSubCluster)
|
||||||
@ -259,6 +282,38 @@ namespace NanoBrain {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CloneSynapses(Neuron prefabNeuron, Neuron clonedNeuron) {
|
||||||
|
foreach (Synapse prefabSynapse in prefabNeuron.synapses) {
|
||||||
|
Neuron synapseNeuron = prefabSynapse.neuron;
|
||||||
|
if (synapseNeuron.clusterPrefab != null && synapseNeuron.clusterPrefab != this.prefab) {
|
||||||
|
// Neuron is in another cluster, find the cloned cluster first
|
||||||
|
ClusterPrefab prefabCluster = synapseNeuron.clusterPrefab;
|
||||||
|
Cluster clonedCluster = this.clusterNuclei.Find(n => n.name == prefabCluster.name) as Cluster;
|
||||||
|
if (clonedCluster == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Now find the neuron in that cloned cluster
|
||||||
|
int neuronIx = GetNucleusIndex(prefabCluster.nuclei, prefabSynapse.neuron.name);
|
||||||
|
if (neuronIx < 0)
|
||||||
|
// Could not find the neuron in the prefab cluster
|
||||||
|
continue;
|
||||||
|
if (clonedCluster.clusterNuclei[neuronIx] is not Neuron clonedSender)
|
||||||
|
// Could not find the neuron in the cloned cluster
|
||||||
|
continue;
|
||||||
|
|
||||||
|
clonedSender.AddReceiver(clonedNeuron, prefabSynapse.weight);
|
||||||
|
//Debug.Log($"Add synapse {clonedCluster.name}.{clonedSender.name} -> {clonedNeuron.name} [{clonedSender.receivers.Count}]");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Neuron clonedSender = this.clusterNuclei.Find(n => n.name == prefabSynapse.neuron.name) as Neuron;
|
||||||
|
// Copy the receivers which will also create the synapse
|
||||||
|
clonedSender.AddReceiver(clonedNeuron, prefabSynapse.weight);
|
||||||
|
// Debug.Log($"Add synapse {clonedSender.name} -> {clonedNeuron.name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sort the nuclei in a correct evaluation order
|
/// Sort the nuclei in a correct evaluation order
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -349,6 +404,7 @@ namespace NanoBrain {
|
|||||||
Cluster clone = new(this.prefab, parent) {
|
Cluster clone = new(this.prefab, parent) {
|
||||||
name = this.name,
|
name = this.name,
|
||||||
clusterPrefab = this.clusterPrefab,
|
clusterPrefab = this.clusterPrefab,
|
||||||
|
instanceCount = this.instanceCount,
|
||||||
};
|
};
|
||||||
// Somehow siblingClusters should be cloned too. Believe I do this in ClonePrefab right now.
|
// Somehow siblingClusters should be cloned too. Believe I do this in ClonePrefab right now.
|
||||||
|
|
||||||
@ -356,40 +412,44 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void RestoreAllExternalReceivers(Cluster clonedCluster, ClusterPrefab prefabParent, Cluster clonedParent) {
|
private static void RestoreAllExternalReceivers(Cluster clonedCluster, ClusterPrefab prefabParent, Cluster clonedParent) {
|
||||||
int clonedClusterIx = GetNucleusIndex(clonedParent.clusterNuclei, clonedCluster);
|
|
||||||
if (prefabParent.nuclei[clonedClusterIx] is not Cluster sourceCluster)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int nucleusIx = 0; nucleusIx < sourceCluster.clusterNuclei.Count; nucleusIx++) {
|
|
||||||
Nucleus sourceNucleus = sourceCluster.clusterNuclei[nucleusIx];
|
|
||||||
if (sourceNucleus is not Neuron sourceNeuron)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (clonedCluster.clusterNuclei[nucleusIx] is not Neuron clonedNeuron)
|
// int clonedClusterIx = GetNucleusIndex(clonedParent.clusterNuclei, clonedCluster);
|
||||||
continue;
|
// if (prefabParent.nuclei[clonedClusterIx] is not Cluster sourceCluster)
|
||||||
|
// return;
|
||||||
|
|
||||||
// copy the receivers (and thus synapses) from the source to the clone
|
// for (int nucleusIx = 0; nucleusIx < sourceCluster.clusterNuclei.Count; nucleusIx++) {
|
||||||
foreach (Nucleus receiver in sourceNeuron.receivers) {
|
// Nucleus sourceNucleus = sourceCluster.clusterNuclei[nucleusIx];
|
||||||
int ix = GetNucleusIndex(prefabParent.nuclei, receiver);
|
// if (sourceNucleus is not Neuron sourceNeuron)
|
||||||
if (ix < 0 || ix >= clonedParent.clusterNuclei.Count)
|
// continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
Nucleus clonedReceiver = clonedParent.clusterNuclei[ix];
|
// if (clonedCluster.clusterNuclei[nucleusIx] is not Neuron clonedNeuron)
|
||||||
|
// continue;
|
||||||
|
|
||||||
// Find the synapse for the weight
|
// // copy the receivers (and thus synapses) from the source to the clone
|
||||||
float weight = 1;
|
// foreach (Nucleus receiver in sourceNeuron.receivers) {
|
||||||
foreach (Synapse synapse in receiver.synapses) {
|
// int ix = GetNucleusIndex(prefabParent.nuclei, receiver);
|
||||||
// Find the weight for this synapse
|
// if (ix < 0 || ix >= clonedParent.clusterNuclei.Count)
|
||||||
if (synapse.neuron == sourceNucleus) {
|
// continue;
|
||||||
weight = synapse.weight;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clonedNeuron.AddReceiver(clonedReceiver, weight);
|
// Nucleus clonedReceiver = clonedParent.clusterNuclei[ix];
|
||||||
// Debug.Log($"external: {clonedReceiver.name} receives from {clonedNeuron.name} {clonedNeuron.GetHashCode()}");
|
|
||||||
}
|
// // Find the synapse for the weight
|
||||||
}
|
// float weight = 1;
|
||||||
|
// foreach (Synapse synapse in receiver.synapses) {
|
||||||
|
// // Find the weight for this synapse
|
||||||
|
// if (synapse.neuron == sourceNucleus) {
|
||||||
|
// weight = synapse.weight;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// clonedNeuron.AddReceiver(clonedReceiver, weight);
|
||||||
|
// Debug.Log($"external: {clonedReceiver.name} receives from {clonedNeuron.name} {clonedNeuron.GetHashCode()}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int GetNucleusIndex(Nucleus[] nuclei, Nucleus nucleus) {
|
protected int GetNucleusIndex(Nucleus[] nuclei, Nucleus nucleus) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user