Cleanup
This commit is contained in:
parent
c8f0f0c9da
commit
75d9d1cd5c
@ -117,44 +117,6 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Copy nucleus arrays for receptors
|
|
||||||
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
|
|
||||||
Nucleus prefabNucleus = prefabNuclei[nucleusIx];
|
|
||||||
if (prefabNucleus is not IReceptor prefabReceptor)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (prefabReceptor.nucleiArray == null || prefabReceptor.nucleiArray.Length == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
IReceptor clonedNucleus = clonedNuclei[nucleusIx] as IReceptor;
|
|
||||||
if (prefabReceptor == prefabReceptor.nucleiArray[0]) {
|
|
||||||
// We clone the array only for the first entry
|
|
||||||
NucleusArray clonedArray = new(prefabReceptor.nucleiArray.Length);
|
|
||||||
int arrayIx = 0;
|
|
||||||
foreach (Nucleus prefabArrayNucleus in prefabReceptor.nucleiArray) {
|
|
||||||
int arrayNucleusIx = GetNucleusIndex(prefabNuclei, prefabArrayNucleus);
|
|
||||||
if (arrayNucleusIx >= 0) {
|
|
||||||
Nucleus clonedArrayNucleus = clonedNuclei[arrayNucleusIx];
|
|
||||||
clonedArray.nuclei[arrayIx] = clonedArrayNucleus;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Debug.LogError($" Could not find prefab nucleus {prefabNucleus.name} in the clones");
|
|
||||||
}
|
|
||||||
arrayIx++;
|
|
||||||
}
|
|
||||||
//clonedNucleus.array = clonedArray;
|
|
||||||
clonedNucleus.nucleiArray = clonedArray.nuclei;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// The others will refer to the array created for the first nucleus in the array
|
|
||||||
int firstNucleusIx = GetNucleusIndex(prefabNuclei, prefabReceptor.nucleiArray[0]);
|
|
||||||
IReceptor clonedFirstNucleus = clonedNuclei[firstNucleusIx] as IReceptor;
|
|
||||||
clonedNucleus.nucleiArray = clonedFirstNucleus.nucleiArray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
foreach (Nucleus nucleus in this.clusterNuclei) {
|
foreach (Nucleus nucleus in this.clusterNuclei) {
|
||||||
if (nucleus is Cluster clonedSubCluster)
|
if (nucleus is Cluster clonedSubCluster)
|
||||||
RestoreAllExternalReceivers(clonedSubCluster, this.prefab, this);
|
RestoreAllExternalReceivers(clonedSubCluster, this.prefab, this);
|
||||||
@ -381,13 +343,6 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise find the stalest cluster?
|
|
||||||
// Cluster stalestCluster = this.siblingClusters[0];
|
|
||||||
// for (int ix = 1; ix < this.siblingClusters.Length; ix++) {
|
|
||||||
// if (this.siblingClusters[ix].defaultOutput.stale > stalestCluster.defaultOutput.stale)
|
|
||||||
// stalestCluster = this.siblingClusters[ix];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Otherwise find longest unused cluster
|
// Otherwise find longest unused cluster
|
||||||
Cluster unusedCluster = this.siblingClusters[0];
|
Cluster unusedCluster = this.siblingClusters[0];
|
||||||
for (int ix = 1; ix < this.siblingClusters.Length; ix++) {
|
for (int ix = 1; ix < this.siblingClusters.Length; ix++) {
|
||||||
@ -575,11 +530,6 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [Obsolete("Use GetNucleus instead")]
|
|
||||||
// public IReceptor GetReceptor(string receptorName) {
|
|
||||||
// return GetNucleus(receptorName) as IReceptor;
|
|
||||||
// }
|
|
||||||
|
|
||||||
#region Receivers
|
#region Receivers
|
||||||
|
|
||||||
public virtual List<Nucleus> CollectReceivers() {
|
public virtual List<Nucleus> CollectReceivers() {
|
||||||
@ -589,7 +539,6 @@ namespace NanoBrain {
|
|||||||
// Only add receivers outside this cluster
|
// Only add receivers outside this cluster
|
||||||
if (receiver.clusterPrefab != this.prefab)
|
if (receiver.clusterPrefab != this.prefab)
|
||||||
receivers.Add(receiver);
|
receivers.Add(receiver);
|
||||||
//receivers.AddRange(output.receivers);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return receivers;
|
return receivers;
|
||||||
@ -626,19 +575,6 @@ namespace NanoBrain {
|
|||||||
|
|
||||||
public override void UpdateStateIsolated() {
|
public override void UpdateStateIsolated() {
|
||||||
throw new Exception("Cluster should not be updated!");
|
throw new Exception("Cluster should not be updated!");
|
||||||
// float3 sum = this.bias;
|
|
||||||
|
|
||||||
// //Applying the weight factors
|
|
||||||
// foreach (Synapse synapse in this.synapses) {
|
|
||||||
// if (lengthsq(synapse.neuron.outputValue) > 0) {
|
|
||||||
// sum += synapse.weight * synapse.neuron.outputValue;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// foreach (Nucleus nucleus in this.sortedNuclei)
|
|
||||||
// nucleus.UpdateStateIsolated();
|
|
||||||
|
|
||||||
// UpdateNuclei();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void UpdateNuclei() {
|
public override void UpdateNuclei() {
|
||||||
|
|||||||
@ -1,145 +0,0 @@
|
|||||||
/*
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace NanoBrain {
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class ClusterArray : Nucleus {
|
|
||||||
|
|
||||||
public ClusterPrefab prefab;
|
|
||||||
[SerializeReference]
|
|
||||||
public Cluster[] clusters;
|
|
||||||
|
|
||||||
public Dictionary<int, Cluster> thingClusters = new();
|
|
||||||
|
|
||||||
public ClusterArray(ClusterPrefab prefab, Cluster parent, int size, Nucleus receiver = null) {
|
|
||||||
this.prefab = prefab;
|
|
||||||
this.name = prefab.name;
|
|
||||||
this.clusters = new Cluster[size];
|
|
||||||
for (int ix = 0; ix < size; ix++) {
|
|
||||||
Cluster cluster = new(prefab, parent);
|
|
||||||
cluster.defaultOutput.AddReceiver(receiver);
|
|
||||||
//cluster.clusterArray = this;
|
|
||||||
this.clusters[ix] = cluster;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClusterArray(ClusterPrefab prefab, ClusterPrefab parent, int size, Nucleus receiver = null) {
|
|
||||||
this.prefab = prefab;
|
|
||||||
this.name = prefab.name;
|
|
||||||
this.clusters = new Cluster[size];
|
|
||||||
for (int ix = 0; ix < size; ix++) {
|
|
||||||
Cluster cluster = new(prefab, parent);
|
|
||||||
cluster.defaultOutput.AddReceiver(receiver);
|
|
||||||
//cluster.clusterArray = this;
|
|
||||||
this.clusters[ix] = cluster;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Nucleus ShallowCloneTo(Cluster parent) {
|
|
||||||
ClusterArray clone = new(this.prefab, parent, this.clusters.Length) {
|
|
||||||
clusterPrefab = this.clusterPrefab,
|
|
||||||
};
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Nucleus Clone(ClusterPrefab parent) {
|
|
||||||
ClusterArray clone = new(this.prefab, parent, this.clusters.Length) {
|
|
||||||
};
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Add(ClusterPrefab prefab) {
|
|
||||||
if (this.clusters.Length == 0) {
|
|
||||||
Debug.LogError("Empty perceptoid array, cannot add");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int newLength = this.clusters.Length + 1;
|
|
||||||
Cluster[] newClusters = new Cluster[newLength];
|
|
||||||
|
|
||||||
string baseName = this.name;
|
|
||||||
int colonPos = baseName.IndexOf(":");
|
|
||||||
if (colonPos > 0)
|
|
||||||
baseName = baseName[..colonPos];
|
|
||||||
|
|
||||||
for (int i = 0; i < this.clusters.Length; i++)
|
|
||||||
newClusters[i] = this.clusters[i];
|
|
||||||
Cluster sourceCluster = this.clusters[0];
|
|
||||||
Cluster newCluster = sourceCluster.Clone(prefab) as Cluster;
|
|
||||||
newCluster.name = $"{baseName}: {newLength - 1}";
|
|
||||||
//newCluster.clusterArray = this;
|
|
||||||
newClusters[newLength - 1] = newCluster;
|
|
||||||
this.clusters = newClusters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Remove() {
|
|
||||||
int newLength = this.clusters.Length - 1;
|
|
||||||
if (newLength == 0) {
|
|
||||||
Debug.LogWarning("Perceptoid array cannot be empty");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Cluster[] newClusters = new Cluster[newLength];
|
|
||||||
for (int i = 0; i < newLength; i++)
|
|
||||||
newClusters[i] = this.clusters[i];
|
|
||||||
// Delete the last perception
|
|
||||||
//Cluster.Delete(nucleus);
|
|
||||||
this.clusters = newClusters;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void UpdateStateIsolated() {
|
|
||||||
// Clusters don't do anything,
|
|
||||||
// The nuclei in them do the work
|
|
||||||
// and should be called directly, not from the cluster
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual Cluster GetThingCluster() {
|
|
||||||
Cluster selectedCluster = SelectCluster();
|
|
||||||
return selectedCluster;
|
|
||||||
}
|
|
||||||
public virtual Cluster GetThingCluster(int thingId, string thingName = null) {
|
|
||||||
if (thingClusters.TryGetValue(thingId, out Cluster cluster))
|
|
||||||
return cluster;
|
|
||||||
|
|
||||||
Cluster selectedCluster = SelectCluster();
|
|
||||||
thingClusters[thingId] = selectedCluster;
|
|
||||||
return selectedCluster;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Cluster SelectCluster() {
|
|
||||||
// Find a sleeping cluster
|
|
||||||
foreach (Cluster cluster in clusters) {
|
|
||||||
if (cluster.defaultOutput.isSleeping) {
|
|
||||||
RemoveThingCluster(cluster);
|
|
||||||
return cluster;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise find the stalest cluster?
|
|
||||||
Cluster stalestCluster = clusters[0];
|
|
||||||
for (int ix = 1; ix < clusters.Length; ix++) {
|
|
||||||
if (clusters[ix].defaultOutput.stale > stalestCluster.defaultOutput.stale)
|
|
||||||
stalestCluster = clusters[ix];
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveThingCluster(stalestCluster);
|
|
||||||
return stalestCluster;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RemoveThingCluster(Cluster cluster) {
|
|
||||||
List<int> keysToRemove = new();
|
|
||||||
foreach (KeyValuePair<int, Cluster> kvp in thingClusters) {
|
|
||||||
if (kvp.Value == cluster)
|
|
||||||
keysToRemove.Add(kvp.Key);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (int thingId in keysToRemove)
|
|
||||||
thingClusters.Remove(thingId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 837dfcffeb99804479a0887cbfc33372
|
|
||||||
@ -1,280 +0,0 @@
|
|||||||
/*
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
#if UNITY_MATHEMATICS
|
|
||||||
using Unity.Mathematics;
|
|
||||||
using static Unity.Mathematics.math;
|
|
||||||
#endif
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace NanoBrain {
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class ClusterReceptor : Cluster, IReceptor {
|
|
||||||
public ClusterReceptor(ClusterPrefab prefab, Cluster parent, string name) : base(prefab, parent) {
|
|
||||||
this.name = name;
|
|
||||||
this.array = new NucleusArray(this);
|
|
||||||
if (this.name.IndexOf(":") < 0)
|
|
||||||
this.name += ": 0";
|
|
||||||
|
|
||||||
}
|
|
||||||
public ClusterReceptor(ClusterPrefab prefab, ClusterPrefab parent, string name) : base(prefab, parent) {
|
|
||||||
this.name = name;
|
|
||||||
this.array = new NucleusArray(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Nucleus ShallowCloneTo(Cluster parent) {
|
|
||||||
ClusterReceptor clone = new(this.prefab, parent, this.name) {
|
|
||||||
clusterPrefab = this.clusterPrefab,
|
|
||||||
};
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override Nucleus Clone(ClusterPrefab parent) {
|
|
||||||
ClusterReceptor clone = new(prefab, parent, this.name) {
|
|
||||||
array = this._array
|
|
||||||
};
|
|
||||||
|
|
||||||
foreach (Synapse synapse in this.synapses) {
|
|
||||||
Synapse clonedSynapse = clone.AddSynapse(synapse.neuron);
|
|
||||||
clonedSynapse.weight = synapse.weight;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._outputs = null; // Make sure the output are regenerated
|
|
||||||
foreach (Neuron output in this.outputs) {
|
|
||||||
int ix = GetNucleusIndex(this.clusterNuclei, output);
|
|
||||||
if (ix < 0 || clone.clusterNuclei[ix] is not Neuron clonedOutput)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
foreach (Nucleus receiver in output.receivers)
|
|
||||||
clonedOutput.AddReceiver(receiver);
|
|
||||||
}
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override List<Nucleus> CollectReceivers() {
|
|
||||||
List<Nucleus> receivers = new();
|
|
||||||
foreach (Nucleus element in this.nucleiArray) {
|
|
||||||
if (element is not Cluster clusterElement)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
foreach (Nucleus outputNucleus in clusterElement.clusterNuclei) {
|
|
||||||
if (outputNucleus is not Neuron output)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// this should be clusterElement.outputs,
|
|
||||||
// but outputs is not updated when correctly and may contain old data...
|
|
||||||
foreach (Nucleus receiver in output.receivers) {
|
|
||||||
// Only add receivers outside clusterElement cluster
|
|
||||||
if (receiver.clusterPrefab != clusterElement.prefab &&
|
|
||||||
receivers.Contains(receiver) == false)
|
|
||||||
receivers.Add(receiver);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return receivers;
|
|
||||||
}
|
|
||||||
|
|
||||||
[SerializeReference]
|
|
||||||
private NucleusArray _array;
|
|
||||||
public NucleusArray array {
|
|
||||||
set { _array = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Nucleus[] nucleiArray {
|
|
||||||
get { return _array.nuclei; }
|
|
||||||
set { _array.nuclei = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddReceptorElement(ClusterPrefab prefab) {
|
|
||||||
IReceptorHelpers.AddReceptorElement(this, prefab);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveReceptorElement() {
|
|
||||||
IReceptorHelpers.RemoveReceptorElement(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddArrayReceiver(Nucleus receiverToAdd, float weight = 1) {
|
|
||||||
IReceptorHelpers.AddArrayReceiver(this, receiverToAdd, weight);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void UpdateStateIsolated() {
|
|
||||||
// Clusters don't do anything,
|
|
||||||
// The nuclei in them do the work
|
|
||||||
// and should be called directly, not from the cluster
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void UpdateNuclei() {
|
|
||||||
foreach (Nucleus nucleus in this.clusterNuclei)
|
|
||||||
nucleus.UpdateNuclei();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
|
||||||
Debug.LogError("Process Stimulus was called on clusterreceptor without a neuron specified");
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly Dictionary<int, ClusterReceptor> thingReceivers = new();
|
|
||||||
|
|
||||||
public virtual void ProcessStimulus(Neuron input, Vector3 inputValue, int thingId = 0, string thingName = null) {
|
|
||||||
CleanupReceivers();
|
|
||||||
|
|
||||||
if (!thingReceivers.TryGetValue(thingId, out ClusterReceptor selectedReceiver))
|
|
||||||
selectedReceiver = FindReceiver2(thingId, inputValue, input);
|
|
||||||
if (selectedReceiver == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (thingName != null) {
|
|
||||||
string baseName = selectedReceiver.name;
|
|
||||||
int colonPos = selectedReceiver.name.IndexOf(":");
|
|
||||||
if (colonPos > 0)
|
|
||||||
baseName = selectedReceiver.name[..colonPos];
|
|
||||||
selectedReceiver.name = baseName + ": " + thingName;
|
|
||||||
}
|
|
||||||
|
|
||||||
int inputIx = GetNucleusIndex(this.clusterNuclei, input);
|
|
||||||
if (inputIx < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (selectedReceiver.clusterNuclei[inputIx] is Neuron selectedNeuron)
|
|
||||||
selectedNeuron.ProcessStimulusDirect(inputValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_MATHEMATICS
|
|
||||||
|
|
||||||
private ClusterReceptor FindReceiver2(int thingId, float3 inputValue, Neuron input) {
|
|
||||||
// No existing nucleus for this thing
|
|
||||||
ClusterReceptor selectedReceiver = null;
|
|
||||||
float selectedMagnitude = 0;
|
|
||||||
foreach (ClusterReceptor receiver in this.nucleiArray.Cast<ClusterReceptor>()) {
|
|
||||||
if (thingReceivers.ContainsValue(receiver) == false) {
|
|
||||||
// We found an unusued receiver
|
|
||||||
thingReceivers.Add(thingId, receiver);
|
|
||||||
return receiver;
|
|
||||||
}
|
|
||||||
else if (receiver.defaultOutput.isSleeping) {
|
|
||||||
// A sleeping receiver is not active and can therefore always be used
|
|
||||||
thingReceivers.Add(thingId, receiver);
|
|
||||||
receiver.bias = float3(0, 0, 0);
|
|
||||||
return receiver;
|
|
||||||
}
|
|
||||||
else if (selectedReceiver == null) {
|
|
||||||
// If we haven't found a receiver yet, just start by taking the first
|
|
||||||
selectedReceiver = receiver;
|
|
||||||
selectedMagnitude = length(selectedReceiver.defaultOutput.outputValue);
|
|
||||||
}
|
|
||||||
// Look for the receiver with the lowest output magnitude
|
|
||||||
else {
|
|
||||||
float magnitude = length(receiver.defaultOutput.outputValue);
|
|
||||||
|
|
||||||
if (length(receiver.defaultOutput.outputValue) < selectedMagnitude) {
|
|
||||||
selectedReceiver = receiver;
|
|
||||||
selectedMagnitude = length(selectedReceiver.defaultOutput.outputValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selectedReceiver != null) {
|
|
||||||
// To re-initialize the cluster (esp. memory cells)
|
|
||||||
// we update the cluster neuron twice.
|
|
||||||
// Bit of a hack.....
|
|
||||||
int inputIx = GetNucleusIndex(this.clusterNuclei, input);
|
|
||||||
if (inputIx >= 0) {
|
|
||||||
if (selectedReceiver.clusterNuclei[inputIx] is Neuron selectedNeuron)
|
|
||||||
selectedNeuron.ProcessStimulusDirect(inputValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the receiver
|
|
||||||
// Find the thingId current associated with the receiver
|
|
||||||
int keyToRemove = thingReceivers.FirstOrDefault(r => r.Value.Equals(selectedReceiver)).Key;
|
|
||||||
if (keyToRemove != 0 || thingReceivers.ContainsKey(keyToRemove))
|
|
||||||
thingReceivers.Remove(keyToRemove);
|
|
||||||
// And add the new association
|
|
||||||
thingReceivers.Add(thingId, selectedReceiver);
|
|
||||||
}
|
|
||||||
return selectedReceiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
private ClusterReceptor FindReceiver2(int thingId, Vector3 inputValue, Neuron input) {
|
|
||||||
// No existing nucleus for this thing
|
|
||||||
ClusterReceptor selectedReceiver = null;
|
|
||||||
float selectedMagnitude = 0;
|
|
||||||
foreach (ClusterReceptor receiver in this.nucleiArray.Cast<ClusterReceptor>()) {
|
|
||||||
if (thingReceivers.ContainsValue(receiver) == false) {
|
|
||||||
// We found an unusued receiver
|
|
||||||
thingReceivers.Add(thingId, receiver);
|
|
||||||
return receiver;
|
|
||||||
}
|
|
||||||
else if (receiver.defaultOutput.isSleeping) {
|
|
||||||
// A sleeping receiver is not active and can therefore always be used
|
|
||||||
thingReceivers.Add(thingId, receiver);
|
|
||||||
receiver.bias = new Vector3(0, 0, 0);
|
|
||||||
return receiver;
|
|
||||||
}
|
|
||||||
else if (selectedReceiver == null) {
|
|
||||||
// If we haven't found a receiver yet, just start by taking the first
|
|
||||||
selectedReceiver = receiver;
|
|
||||||
selectedMagnitude = selectedReceiver.defaultOutput.outputValue.magnitude;
|
|
||||||
}
|
|
||||||
// Look for the receiver with the lowest output magnitude
|
|
||||||
else {
|
|
||||||
float magnitude = receiver.defaultOutput.outputValue.magnitude;
|
|
||||||
|
|
||||||
if (receiver.defaultOutput.outputValue.magnitude < selectedMagnitude) {
|
|
||||||
selectedReceiver = receiver;
|
|
||||||
selectedMagnitude = selectedReceiver.defaultOutput.outputValue.magnitude;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selectedReceiver != null) {
|
|
||||||
// To re-initialize the cluster (esp. memory cells)
|
|
||||||
// we update the cluster neuron twice.
|
|
||||||
// Bit of a hack.....
|
|
||||||
int inputIx = GetNucleusIndex(this.clusterNuclei, input);
|
|
||||||
if (inputIx >= 0) {
|
|
||||||
if (selectedReceiver.clusterNuclei[inputIx] is Neuron selectedNeuron)
|
|
||||||
selectedNeuron.ProcessStimulusDirect(inputValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Replace the receiver
|
|
||||||
// Find the thingId current associated with the receiver
|
|
||||||
int keyToRemove = thingReceivers.FirstOrDefault(r => r.Value.Equals(selectedReceiver)).Key;
|
|
||||||
if (keyToRemove != 0 || thingReceivers.ContainsKey(keyToRemove))
|
|
||||||
thingReceivers.Remove(keyToRemove);
|
|
||||||
// And add the new association
|
|
||||||
thingReceivers.Add(thingId, selectedReceiver);
|
|
||||||
}
|
|
||||||
return selectedReceiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private void CleanupReceivers() {
|
|
||||||
// Remove a thing-receiver connection when the nucleus is inactive
|
|
||||||
List<int> receiversToRemove = new();
|
|
||||||
foreach (KeyValuePair<int, ClusterReceptor> item in thingReceivers) {
|
|
||||||
if (item.Value != null && item.Value.defaultOutput.isSleeping)
|
|
||||||
receiversToRemove.Add(item.Key);
|
|
||||||
}
|
|
||||||
foreach (int thingId in receiversToRemove) {
|
|
||||||
Nucleus selectedReceiver = thingReceivers[thingId];
|
|
||||||
|
|
||||||
thingReceivers.Remove(thingId);
|
|
||||||
|
|
||||||
int colonPos = selectedReceiver.name.IndexOf(":");
|
|
||||||
if (colonPos > 0)
|
|
||||||
selectedReceiver.name = selectedReceiver.name[..colonPos];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 4f64f5d72a422a7c8bb9ace598432aad
|
|
||||||
@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace NanoBrain {
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A Receptor is a Nucleus which can receive input (called Stimulus) from outside the the cluster/brain
|
|
||||||
/// </summary>
|
|
||||||
/// It has the ability to distinguish stimuli from different things using an array of Nuclei
|
|
||||||
public interface IReceptor {
|
|
||||||
/// <summary>
|
|
||||||
/// Get the name of the receptor
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>The name of the receptor</returns>
|
|
||||||
public string GetName();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The array of nuclei used to track multiple things sending stimuli
|
|
||||||
/// </summary>
|
|
||||||
/// The size of the array determines the maximum number of things which can be distinguished
|
|
||||||
// public Nucleus[] nucleiArray { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Extends the nucleiArray with an additional element
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="prefab">A prefab of the nucleus to add?</param>
|
|
||||||
// public void AddReceptorElement(ClusterPrefab prefab);
|
|
||||||
/// <summary>
|
|
||||||
/// Removes the last element from the nucleiArray
|
|
||||||
/// </summary>
|
|
||||||
// public void RemoveReceptorElement();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Add a receiver for this receptor array
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="receiverToAdd">The receiving Nucleus</param>
|
|
||||||
/// <param name="weight">The initial weight to use for the synapses</param>
|
|
||||||
/// This function will add a synapse to the receiver for each element in the nucleiArray.
|
|
||||||
// public void AddArrayReceiver(Nucleus receiverToAdd, float weight = 1);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Process an external stimulus
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="inputValue">The value of the stimulus</param>
|
|
||||||
/// <param name="thingId">The id of the thing causing the stimulus</param>
|
|
||||||
/// <param name="thingName">The name of the thing causing the stimulus</param>
|
|
||||||
public void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class IReceptorHelpers {
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Implementation for the NanoBrain::IReceptor::AddReceptorElement which can be used for all implementations of IReceptor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="receptor">The IReceptor which needs to extend its nucleiArray</param>
|
|
||||||
/// <param name="prefab">A prefab of the nucleus to add?</param>
|
|
||||||
public static void AddReceptorElement(IReceptor receptor, ClusterPrefab prefab) {
|
|
||||||
if (receptor.nucleiArray.Length == 0) {
|
|
||||||
Debug.LogError("Empty perceptoid array, cannot add");
|
|
||||||
}
|
|
||||||
int newLength = receptor.nucleiArray.Length + 1;
|
|
||||||
Nucleus[] newArray = new Nucleus[newLength];
|
|
||||||
|
|
||||||
string baseName = receptor.GetName();
|
|
||||||
int colonPos = baseName.IndexOf(":");
|
|
||||||
if (colonPos > 0)
|
|
||||||
baseName = baseName[..colonPos];
|
|
||||||
|
|
||||||
for (int i = 0; i < receptor.nucleiArray.Length; i++)
|
|
||||||
newArray[i] = receptor.nucleiArray[i];
|
|
||||||
if (receptor.nucleiArray[0] is Nucleus nucleus) {
|
|
||||||
newArray[newLength - 1] = nucleus.Clone(prefab);
|
|
||||||
newArray[newLength - 1].name = $"{baseName}: {newLength - 1}";
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (Nucleus element in receptor.nucleiArray) {
|
|
||||||
if (element is IReceptor receptorElement) {
|
|
||||||
receptorElement.nucleiArray = newArray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Implementation for the NanoBrain::IReceptor::RemoteReceptorElement which can be used for all implementations of IReceptor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="receptor">The IReceptor which needs to shorten its nucleiArray</param>
|
|
||||||
public static void RemoveReceptorElement(IReceptor receptor) {
|
|
||||||
int newLength = receptor.nucleiArray.Length - 1;
|
|
||||||
if (newLength == 0) {
|
|
||||||
Debug.LogWarning("Perceptoid array cannot be empty");
|
|
||||||
}
|
|
||||||
Nucleus[] newArray = new Nucleus[newLength];
|
|
||||||
for (int i = 0; i < newLength; i++)
|
|
||||||
newArray[i] = receptor.nucleiArray[i];
|
|
||||||
// Delete the last perception
|
|
||||||
if (receptor.nucleiArray[newLength] is Nucleus nucleus)
|
|
||||||
Neuron.Delete(nucleus);
|
|
||||||
|
|
||||||
foreach (Nucleus element in receptor.nucleiArray) {
|
|
||||||
if (element is IReceptor receptorElement) {
|
|
||||||
receptorElement.nucleiArray = newArray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Implementation for the NanoBreain::IRceptor::AddArrayReceiver which can be used for all implementations of IReceptor
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="receptor">The IReceptor for which a receiving nuclues needs to be added</param>
|
|
||||||
/// <param name="receiverToAdd">The nucleus to receive input from the receptor</param>
|
|
||||||
/// <param name="weight">The initial weight for the synapses</param>
|
|
||||||
public static void AddArrayReceiver(IReceptor receptor, Nucleus receiverToAdd, float weight = 1) {
|
|
||||||
foreach (Nucleus element in receptor.nucleiArray) {
|
|
||||||
if (element is Cluster cluster)
|
|
||||||
cluster.defaultOutput.AddReceiver(receiverToAdd, weight);
|
|
||||||
if (element is Neuron neuron)
|
|
||||||
neuron.AddReceiver(receiverToAdd, weight);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 73f052292ad16bb53a3c07aa1694c705
|
|
||||||
@ -521,32 +521,14 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public virtual void RemoveReceiver(Nucleus receiverToRemove) {
|
public virtual void RemoveReceiver(Nucleus receiverToRemove) {
|
||||||
// if (this is IReceptor receptor) {
|
|
||||||
// foreach (Nucleus element in receptor.nucleiArray) {
|
|
||||||
// if (element is Neuron neuron) {
|
|
||||||
// neuron._receivers.RemoveAll(receiver => receiver == receiverToRemove);
|
|
||||||
// receiverToRemove.synapses.RemoveAll(synapse => synapse.neuron == neuron);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
this._receivers.RemoveAll(receiver => receiver == receiverToRemove);
|
this._receivers.RemoveAll(receiver => receiver == receiverToRemove);
|
||||||
receiverToRemove.synapses.RemoveAll(synapse => synapse.neuron == this);
|
receiverToRemove.synapses.RemoveAll(synapse => synapse.neuron == this);
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion Receivers
|
#endregion Receivers
|
||||||
|
|
||||||
public override void ProcessStimulus(Vector3 inputValue) { //, int thingId = 0, string thingName = null) {
|
public override void ProcessStimulus(Vector3 inputValue) {;
|
||||||
// if (this.parent is ClusterReceptor clusterReceptor)
|
|
||||||
// clusterReceptor.ProcessStimulus(this, inputValue, thingId, thingName);
|
|
||||||
// else
|
|
||||||
ProcessStimulusDirect(inputValue); //, thingId, thingName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ProcessStimulusDirect(Vector3 inputValue) { //}, int thingId = 0, string thingName = null) {
|
|
||||||
// this.stale = 0;
|
|
||||||
this.lastUpdate = Time.time;
|
this.lastUpdate = Time.time;
|
||||||
this.bias = inputValue;
|
this.bias = inputValue;
|
||||||
this.parent.UpdateFromNucleus(this);
|
this.parent.UpdateFromNucleus(this);
|
||||||
|
|||||||
@ -1,199 +0,0 @@
|
|||||||
/*
|
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
#if UNITY_MATHEMATICS
|
|
||||||
using Unity.Mathematics;
|
|
||||||
using static Unity.Mathematics.math;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace NanoBrain {
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Class to manage an array of nuclei for an IReceptor
|
|
||||||
/// </summary>
|
|
||||||
/// Would love to get rid of this class.
|
|
||||||
[System.Serializable]
|
|
||||||
public class NucleusArray {
|
|
||||||
/// <summary>
|
|
||||||
/// The nuclei in this array
|
|
||||||
/// </summary>
|
|
||||||
[SerializeReference]
|
|
||||||
private Nucleus[] _nuclei;
|
|
||||||
public Nucleus[] nuclei {
|
|
||||||
get {
|
|
||||||
return _nuclei;
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
_nuclei = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new NucleusArray with the given nucleus
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="nucleus">The Nucleus to put in the NucleusArray</param>
|
|
||||||
/// This results in an nucleus array of size 1
|
|
||||||
public NucleusArray(Nucleus nucleus) {
|
|
||||||
this._nuclei = new Nucleus[1];
|
|
||||||
this._nuclei[0] = nucleus;
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new NucleusArray of the given size
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="size">The size of the nucluesArray</param>
|
|
||||||
public NucleusArray(int size) {
|
|
||||||
this._nuclei = new Nucleus[size];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// public void AddNucleus(ClusterPrefab prefab) {
|
|
||||||
// if (this._nuclei.Length == 0) {
|
|
||||||
// Debug.LogError("Empty perceptoid array, cannot add");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// int newLength = this._nuclei.Length + 1;
|
|
||||||
// Nucleus[] newArray = new Nucleus[newLength];
|
|
||||||
|
|
||||||
// for (int i = 0; i < this._nuclei.Length; i++)
|
|
||||||
// newArray[i] = this._nuclei[i];
|
|
||||||
// if (this._nuclei[0] is Nucleus nucleus) {
|
|
||||||
// newArray[newLength - 1] = nucleus.Clone(prefab);
|
|
||||||
// newArray[newLength - 1].name += $": {newLength - 1}";
|
|
||||||
// }
|
|
||||||
|
|
||||||
// this._nuclei = newArray;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public void RemoveNucleus() {
|
|
||||||
// int newLength = this._nuclei.Length - 1;
|
|
||||||
// if (newLength == 0) {
|
|
||||||
// Debug.LogWarning("Perceptoid array cannot be empty");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// Nucleus[] newPerceptei = new Nucleus[newLength];
|
|
||||||
// for (int i = 0; i < newLength; i++)
|
|
||||||
// newPerceptei[i] = this._nuclei[i];
|
|
||||||
// // Delete the last perception
|
|
||||||
// if (this._nuclei[newLength] is Nucleus nucleus)
|
|
||||||
// Neuron.Delete(nucleus); //this._nuclei[newLength]);
|
|
||||||
|
|
||||||
// this._nuclei = newPerceptei;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public Dictionary<int, Nucleus> thingReceivers = new();
|
|
||||||
|
|
||||||
#if UNITY_MATHEMATICS
|
|
||||||
|
|
||||||
private Nucleus FindReceiver(int thingId, float3 inputValue) {
|
|
||||||
float inputMagnitude = length(inputValue);
|
|
||||||
return FindReceiverMagnitude(thingId, inputMagnitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
private Nucleus FindReceiver(int thingId, Vector3 inputValue) {
|
|
||||||
float inputMagnitude = inputValue.magnitude;
|
|
||||||
return FindReceiverMagnitude(thingId, inputMagnitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private Nucleus FindReceiverMagnitude(int thingId, float inputMagnitude) {
|
|
||||||
Neuron selectedReceiver = null;
|
|
||||||
float selectedMagnitude = 0;
|
|
||||||
foreach (Nucleus nucleusReceiver in this._nuclei) {
|
|
||||||
if (nucleusReceiver is not Neuron receiver)
|
|
||||||
continue;
|
|
||||||
if (thingReceivers.ContainsValue(receiver) == false) {
|
|
||||||
// We found an unusued receiver
|
|
||||||
thingReceivers.Add(thingId, receiver);
|
|
||||||
return receiver;
|
|
||||||
}
|
|
||||||
else if (receiver.isSleeping) {
|
|
||||||
// A sleeping receiver is not active and can therefore always be used
|
|
||||||
thingReceivers.Add(thingId, receiver);
|
|
||||||
return receiver;
|
|
||||||
}
|
|
||||||
else if (selectedReceiver == null) {
|
|
||||||
// If we haven't found a receiver yet, just start by taking the first
|
|
||||||
selectedReceiver = receiver;
|
|
||||||
selectedMagnitude = selectedReceiver.outputMagnitude;
|
|
||||||
}
|
|
||||||
// Look for the receiver with the lowest magnitude
|
|
||||||
else {
|
|
||||||
float magnitude = receiver.outputMagnitude;
|
|
||||||
|
|
||||||
if (magnitude < inputMagnitude && receiver.outputMagnitude < selectedMagnitude) {
|
|
||||||
selectedReceiver = receiver;
|
|
||||||
selectedMagnitude = selectedReceiver.outputMagnitude;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (selectedReceiver != null) {
|
|
||||||
// Replace the receiver
|
|
||||||
// Find the thingId current associated with the receiver
|
|
||||||
int keyToRemove = thingReceivers.FirstOrDefault(r => r.Value.Equals(selectedReceiver)).Key;
|
|
||||||
if (keyToRemove != 0 || thingReceivers.ContainsKey(keyToRemove))
|
|
||||||
thingReceivers.Remove(keyToRemove);
|
|
||||||
// And add the new association
|
|
||||||
thingReceivers.Add(thingId, selectedReceiver);
|
|
||||||
}
|
|
||||||
return selectedReceiver;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Process an external stimulus
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="inputValue">The value of the stimulus</param>
|
|
||||||
/// <param name="thingId">The id of the thing causing the stimulus</param>
|
|
||||||
/// <param name="thingName">The name of the thing causing the stimulus</param>
|
|
||||||
public virtual void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
|
|
||||||
CleanupReceivers();
|
|
||||||
|
|
||||||
if (this._nuclei[0] is Neuron neuron)
|
|
||||||
inputValue = neuron.Activator(inputValue);
|
|
||||||
|
|
||||||
if (!thingReceivers.TryGetValue(thingId, out Nucleus selectedReceiver)) {
|
|
||||||
// No existing nucleus for this thing
|
|
||||||
selectedReceiver = FindReceiver(thingId, inputValue);
|
|
||||||
}
|
|
||||||
if (selectedReceiver == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (thingName != null) {
|
|
||||||
string baseName = selectedReceiver.name;
|
|
||||||
int colonPos = selectedReceiver.name.IndexOf(":");
|
|
||||||
if (colonPos > 0)
|
|
||||||
baseName = selectedReceiver.name[..colonPos];
|
|
||||||
selectedReceiver.name = baseName + ": " + thingName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedReceiver is Neuron selectedNucleus)
|
|
||||||
selectedNucleus.ProcessStimulusDirect(inputValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Remove a thing-receiver connection when the nucleus is inactive
|
|
||||||
/// </summary>
|
|
||||||
private void CleanupReceivers() {
|
|
||||||
List<int> receiversToRemove = new();
|
|
||||||
foreach (KeyValuePair<int, Nucleus> item in thingReceivers) {
|
|
||||||
if (item.Value != null && item.Value is Neuron neuron && neuron.isSleeping)
|
|
||||||
receiversToRemove.Add(item.Key);
|
|
||||||
}
|
|
||||||
foreach (int thingId in receiversToRemove) {
|
|
||||||
Nucleus selectedReceiver = thingReceivers[thingId];
|
|
||||||
|
|
||||||
thingReceivers.Remove(thingId);
|
|
||||||
|
|
||||||
int colonPos = selectedReceiver.name.IndexOf(":");
|
|
||||||
if (colonPos > 0)
|
|
||||||
selectedReceiver.name = selectedReceiver.name[..colonPos];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: f8cac60bd79854595a8571c042f77998
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
/*
|
|
||||||
using UnityEngine;
|
|
||||||
#if UNITY_MATHEMATICS
|
|
||||||
using Unity.Mathematics;
|
|
||||||
using static Unity.Mathematics.math;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace NanoBrain {
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Basic IReceptor to receive external input
|
|
||||||
/// </summary>
|
|
||||||
[System.Serializable]
|
|
||||||
public class Receptor : Neuron { //}, IReceptor {
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new Receptor in a Cluster instance
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="parent">The Cluster in which the Receptor is created</param>
|
|
||||||
/// <param name="name">The name of the new Receptor</param>
|
|
||||||
public Receptor(Cluster parent, string name) : base(parent, name) {
|
|
||||||
//this.array = new NucleusArray(this);
|
|
||||||
// if (this.name.IndexOf(":") < 0)
|
|
||||||
// this.name += ": 0";
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Create a new Receptor in a Cluster Prefab
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="prefab">The Cluster Prefab in which the Receptor is created</param>
|
|
||||||
/// <param name="name">The name of the new Receptor</param>
|
|
||||||
public Receptor(ClusterPrefab prefab, string name) : base(prefab, name) {
|
|
||||||
//this.array = new NucleusArray(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string GetName() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \copydoc NanoBrain::Neuron::ShallowCloneTo
|
|
||||||
public override Nucleus ShallowCloneTo(Cluster parent) {
|
|
||||||
Receptor clone = new(parent, name) {
|
|
||||||
|
|
||||||
};
|
|
||||||
CloneFields(clone);
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
/// \copydoc NanoBrain::Neuron::Clone
|
|
||||||
public override Nucleus Clone(ClusterPrefab prefab) {
|
|
||||||
Receptor clone = new(prefab, name) {
|
|
||||||
//array = this._array
|
|
||||||
};
|
|
||||||
CloneFields(clone);
|
|
||||||
// Adding receivers will also add synapses to the receivers
|
|
||||||
foreach (Nucleus receiver in this.receivers.ToArray())
|
|
||||||
clone.AddReceiver(receiver);
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[SerializeReference]
|
|
||||||
private NucleusArray _array;
|
|
||||||
public NucleusArray array {
|
|
||||||
set { _array = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public Nucleus[] nucleiArray {
|
|
||||||
get { return _array.nuclei; }
|
|
||||||
set { _array.nuclei = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void AddReceptorElement(ClusterPrefab prefab) {
|
|
||||||
IReceptorHelpers.AddReceptorElement(this, prefab);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveReceptorElement() {
|
|
||||||
IReceptorHelpers.RemoveReceptorElement(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void AddArrayReceiver(Nucleus receiverToAdd, float weight = 1) {
|
|
||||||
IReceptorHelpers.AddArrayReceiver(this, receiverToAdd, weight);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override void UpdateStateIsolated() {
|
|
||||||
this.outputValue = this.bias;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_MATHEMATICS
|
|
||||||
|
|
||||||
public override void UpdateNuclei() {
|
|
||||||
this.stale++;
|
|
||||||
if (this.stale > staleValueForSleep && lengthsq(this.bias) > 0) {
|
|
||||||
this.bias = new float3(0, 0, 0);
|
|
||||||
this.parent.UpdateFromNucleus(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
public override void UpdateNuclei() {
|
|
||||||
this.stale++;
|
|
||||||
if (this.stale > staleValueForSleep && this.bias.sqrMagnitude > 0) {
|
|
||||||
this.bias = new Vector3(0, 0, 0);
|
|
||||||
this.parent.UpdateFromNucleus(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
public override void ProcessStimulus(Vector3 inputValue) { //}, int thingId = 0, string thingName = null) {
|
|
||||||
// this._array ??= new NucleusArray(this.parent);
|
|
||||||
// this._array.ProcessStimulus(thingId, inputValue, thingName);
|
|
||||||
|
|
||||||
this.stale = 0;
|
|
||||||
this.bias = inputValue;
|
|
||||||
this.parent.UpdateFromNucleus(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: cfb9734aebc3ab85aacf87d26fb92e55
|
|
||||||
Loading…
x
Reference in New Issue
Block a user