NucleusArray cloning seems to work
This commit is contained in:
parent
3cc5f56f61
commit
16f0c3d3bf
86
Cluster.cs
86
Cluster.cs
@ -61,8 +61,8 @@ public class Cluster : INucleus {
|
||||
// Now clone the connections
|
||||
for (int nucleusIx = 0; nucleusIx < nuclei.Length; nucleusIx++) {
|
||||
IReceptor receptor = nuclei[nucleusIx];
|
||||
IReceptor clonedSender = clonedNuclei[nucleusIx];
|
||||
if (clonedSender == null)
|
||||
IReceptor clonedReceptor = clonedNuclei[nucleusIx];
|
||||
if (clonedReceptor == null)
|
||||
continue;
|
||||
|
||||
// Copy the receivers, which will also create the synapses
|
||||
@ -76,27 +76,49 @@ public class Cluster : INucleus {
|
||||
|
||||
// Find the synapse for the weight
|
||||
float weight = 1;
|
||||
NucleusArray nucleusArray = null;
|
||||
//NucleusArray clonedNucleusArray = null;
|
||||
foreach (Synapse synapse in receiver.synapses) {
|
||||
// Find the weight for this synapse
|
||||
if (synapse.nucleus == receptor)
|
||||
weight = synapse.weight;
|
||||
if (synapse.nucleus is INucleus synapseNucleus) {
|
||||
if (synapseNucleus.array != null && synapseNucleus.array.nuclei.Length > 0) {
|
||||
if (nucleusArray == null) {
|
||||
// copy the array
|
||||
nucleusArray = new NucleusArray(synapseNucleus.array.nuclei.Length, "array");
|
||||
for (int arrayIx = 0; arrayIx < synapseNucleus.array.nuclei.Length; arrayIx++) {
|
||||
IReceptor arrayNucleus = synapseNucleus.array.nuclei[arrayIx];
|
||||
int ix2 = GetNucleusIndex(nuclei, arrayNucleus);
|
||||
nucleusArray.nuclei[arrayIx] = clonedNuclei[ix2];
|
||||
}
|
||||
}
|
||||
synapseNucleus.array = nucleusArray;
|
||||
}
|
||||
}
|
||||
|
||||
// if (synapse.nucleus is INucleus synapseNucleus) {
|
||||
// if (synapseNucleus.array != null && synapseNucleus.array.nuclei.Length > 0) {
|
||||
// Debug.Log("Clone: Nucleus array");
|
||||
// if (clonedNucleusArray == null) {
|
||||
// // copy the array
|
||||
// clonedNucleusArray = new NucleusArray(synapseNucleus.array.nuclei.Length, "array");
|
||||
// for (int arrayIx = 0; arrayIx < synapseNucleus.array.nuclei.Length; arrayIx++) {
|
||||
// IReceptor arrayNucleus = synapseNucleus.array.nuclei[arrayIx];
|
||||
// int ix2 = GetNucleusIndex(nuclei, arrayNucleus);
|
||||
// clonedNucleusArray.nuclei[arrayIx] = clonedNuclei[ix2];
|
||||
// }
|
||||
// }
|
||||
// synapseNucleus.array = clonedNucleusArray;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
clonedSender.AddReceiver(clonedReceiver, weight);
|
||||
clonedReceptor.AddReceiver(clonedReceiver, weight);
|
||||
// Nucleus clonedNucleus = clonedReceptor as Nucleus;
|
||||
// if (clonedNucleus is not null) {
|
||||
// Synapse clonedSynapse = clonedNucleus.GetSynapse(clonedReceiver);
|
||||
// if (clonedSynapse.nucleus is INucleus synapseNucleus) {
|
||||
// if (synapseNucleus.array != null && synapseNucleus.array.nuclei.Length > 0) {
|
||||
// Debug.Log("Clone: Nucleus array");
|
||||
// if (clonedNucleusArray == null) {
|
||||
// // copy the array
|
||||
// clonedNucleusArray = new NucleusArray(synapseNucleus.array.nuclei.Length, "array");
|
||||
// for (int arrayIx = 0; arrayIx < synapseNucleus.array.nuclei.Length; arrayIx++) {
|
||||
// IReceptor arrayNucleus = synapseNucleus.array.nuclei[arrayIx];
|
||||
// int ix2 = GetNucleusIndex(nuclei, arrayNucleus);
|
||||
// clonedNucleusArray.nuclei[arrayIx] = clonedNuclei[ix2];
|
||||
// }
|
||||
// }
|
||||
// synapseNucleus.array = clonedNucleusArray;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// if (receptor is INucleus nucleus) {
|
||||
@ -113,6 +135,34 @@ public class Cluster : INucleus {
|
||||
// }
|
||||
// }
|
||||
}
|
||||
for (int nucleusIx = 0; nucleusIx < nuclei.Length; nucleusIx++) {
|
||||
IReceptor prefabReceptor = nuclei[nucleusIx];
|
||||
if (prefabReceptor is not INucleus prefabNucleus)
|
||||
continue;
|
||||
|
||||
if (prefabNucleus.array == null || prefabNucleus.array.nuclei == null || prefabNucleus.array.nuclei.Length == 0)
|
||||
continue;
|
||||
|
||||
INucleus clonedNucleus = clonedNuclei[nucleusIx] as INucleus;
|
||||
if (prefabNucleus == prefabNucleus.array.nuclei[0]) {
|
||||
// We clone the array only for the first entry
|
||||
NucleusArray clonedArray = new(prefabNucleus.array.nuclei.Length, "array");
|
||||
int arrayIx = 0;
|
||||
foreach (IReceptor prefabArrayNucleus in prefabNucleus.array.nuclei) {
|
||||
int arrayNucleusIx = GetNucleusIndex(nuclei, prefabArrayNucleus);
|
||||
IReceptor clonedArrayNucleus = clonedNuclei[arrayNucleusIx];
|
||||
clonedArray.nuclei[arrayIx] = clonedArrayNucleus;
|
||||
arrayIx++;
|
||||
}
|
||||
clonedNucleus.array = clonedArray;
|
||||
}
|
||||
else {
|
||||
// The others will refer to the array created for the first nucleus in the array
|
||||
int firstNucleusIx = GetNucleusIndex(nuclei, prefabNucleus.array.nuclei[0]);
|
||||
INucleus clonedFirstNucleus = clonedNuclei[firstNucleusIx] as INucleus;
|
||||
clonedNucleus.array = clonedFirstNucleus.array;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the nuclei in a correct evaluation order
|
||||
|
||||
128
Neuron.cs
128
Neuron.cs
@ -7,7 +7,7 @@ using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
|
||||
[Serializable]
|
||||
public class Neuron : INucleus {
|
||||
public class Neuron : Nucleus, INucleus {
|
||||
|
||||
public Neuron(Cluster parent, string name) {
|
||||
this.parent = parent;
|
||||
@ -24,30 +24,30 @@ public class Neuron : INucleus {
|
||||
// Debug.LogError("No neuroid network");
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
protected string _name;
|
||||
public virtual string name {
|
||||
get => _name;
|
||||
set => _name = value;
|
||||
}
|
||||
// [SerializeField]
|
||||
// protected string _name;
|
||||
// public virtual string name {
|
||||
// get => _name;
|
||||
// set => _name = value;
|
||||
// }
|
||||
|
||||
[SerializeField]
|
||||
private List<Synapse> _synapses = new();
|
||||
public List<Synapse> synapses => _synapses;
|
||||
// [SerializeField]
|
||||
// private List<Synapse> _synapses = new();
|
||||
// public List<Synapse> synapses => _synapses;
|
||||
|
||||
[SerializeReference]
|
||||
private List<INucleus> _receivers = new();
|
||||
public List<INucleus> receivers {
|
||||
get { return _receivers; }
|
||||
set { _receivers = value; }
|
||||
}
|
||||
// [SerializeReference]
|
||||
// private List<INucleus> _receivers = new();
|
||||
// public List<INucleus> receivers {
|
||||
// get { return _receivers; }
|
||||
// set { _receivers = value; }
|
||||
// }
|
||||
|
||||
[SerializeReference]
|
||||
private NucleusArray _array;
|
||||
public NucleusArray array {
|
||||
get { return _array; }
|
||||
set { _array = value; }
|
||||
}
|
||||
// [SerializeReference]
|
||||
// private NucleusArray _array;
|
||||
// public NucleusArray array {
|
||||
// get { return _array; }
|
||||
// set { _array = value; }
|
||||
// }
|
||||
|
||||
#region Serialization
|
||||
|
||||
@ -102,8 +102,8 @@ public class Neuron : INucleus {
|
||||
|
||||
#region Runtime state (not serialized)
|
||||
|
||||
public ClusterPrefab cluster { get; set; }
|
||||
public Cluster parent { get; set; }
|
||||
// public ClusterPrefab cluster { get; set; }
|
||||
// public Cluster parent { get; set; }
|
||||
|
||||
#region Activation
|
||||
|
||||
@ -153,35 +153,35 @@ public class Neuron : INucleus {
|
||||
|
||||
#endregion Activation
|
||||
|
||||
protected float3 _outputValue;
|
||||
public virtual float3 outputValue {
|
||||
get { return _outputValue; }
|
||||
set {
|
||||
this.stale = 0;
|
||||
// this._isSleeping = false;
|
||||
_outputValue = value;
|
||||
}
|
||||
}
|
||||
// protected float3 _outputValue;
|
||||
// public virtual float3 outputValue {
|
||||
// get { return _outputValue; }
|
||||
// set {
|
||||
// this.stale = 0;
|
||||
// // this._isSleeping = false;
|
||||
// _outputValue = value;
|
||||
// }
|
||||
// }
|
||||
|
||||
[NonSerialized]
|
||||
private int stale = 1000;
|
||||
// [NonSerialized]
|
||||
// private int stale = 1000;
|
||||
|
||||
// private bool _isSleeping = false;
|
||||
// public bool isSleeping => _isSleeping;
|
||||
public bool isSleeping => lengthsq(this.outputValue) == 0;
|
||||
// public bool isSleeping => lengthsq(this.outputValue) == 0;
|
||||
|
||||
public void UpdateNuclei() {
|
||||
this.stale++;
|
||||
// this._isSleeping = this.stale > 2;
|
||||
// if (isSleeping)
|
||||
if (this.stale > 2)
|
||||
_outputValue = Vector3.zero;
|
||||
}
|
||||
// public void UpdateNuclei() {
|
||||
// this.stale++;
|
||||
// // this._isSleeping = this.stale > 2;
|
||||
// // if (isSleeping)
|
||||
// if (this.stale > 2)
|
||||
// _outputValue = Vector3.zero;
|
||||
// }
|
||||
|
||||
#endregion Runtime state
|
||||
|
||||
// this clone the nucleus without the synapses and receivers
|
||||
public virtual IReceptor ShallowCloneTo(Cluster newParent) {
|
||||
public override IReceptor ShallowCloneTo(Cluster newParent) {
|
||||
Neuron clone = new(newParent, this.name) {
|
||||
array = null,
|
||||
curve = this.curve,
|
||||
@ -192,7 +192,7 @@ public class Neuron : INucleus {
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual IReceptor Clone() {
|
||||
public override IReceptor Clone() {
|
||||
Neuron clone = new(this.cluster, this.name) {
|
||||
array = this.array,
|
||||
curve = this.curve,
|
||||
@ -213,22 +213,22 @@ public class Neuron : INucleus {
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual void AddReceiver(INucleus receivingNucleus, float weight = 1) {
|
||||
this._receivers.Add(receivingNucleus);
|
||||
receivingNucleus.AddSynapse(this, weight);
|
||||
}
|
||||
// public virtual void AddReceiver(INucleus receivingNucleus, float weight = 1) {
|
||||
// this._receivers.Add(receivingNucleus);
|
||||
// receivingNucleus.AddSynapse(this, weight);
|
||||
// }
|
||||
|
||||
public void RemoveReceiver(INucleus receiverNucleus) {
|
||||
this._receivers.RemoveAll(receiver => receiver == receiverNucleus);
|
||||
receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this);
|
||||
}
|
||||
// public void RemoveReceiver(INucleus receiverNucleus) {
|
||||
// this._receivers.RemoveAll(receiver => receiver == receiverNucleus);
|
||||
// receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this);
|
||||
// }
|
||||
|
||||
public static void Delete(INucleus nucleus) {
|
||||
foreach (Synapse synapse in nucleus.synapses) {
|
||||
if (synapse.nucleus is Neuron synapse_nucleus) {
|
||||
if (synapse_nucleus._receivers.Count > 1) {
|
||||
if (synapse_nucleus.receivers.Count > 1) {
|
||||
// there is another nucleus feeding into this input nucleus
|
||||
synapse_nucleus._receivers.RemoveAll(r => r == nucleus);
|
||||
synapse_nucleus.receivers.RemoveAll(r => r == nucleus);
|
||||
}
|
||||
else {
|
||||
// No other links, delete it.
|
||||
@ -247,11 +247,11 @@ public class Neuron : INucleus {
|
||||
}
|
||||
}
|
||||
|
||||
public Synapse AddSynapse(IReceptor sendingNucleus, float weight = 1.0f) {
|
||||
Synapse synapse = new(sendingNucleus, weight);
|
||||
this.synapses.Add(synapse);
|
||||
return synapse;
|
||||
}
|
||||
// public Synapse AddSynapse(IReceptor sendingNucleus, float weight = 1.0f) {
|
||||
// Synapse synapse = new(sendingNucleus, weight);
|
||||
// this.synapses.Add(synapse);
|
||||
// return synapse;
|
||||
// }
|
||||
|
||||
// public virtual void UpdateState() {
|
||||
// //UpdateState(new float3(0, 0, 0));
|
||||
@ -296,10 +296,10 @@ public class Neuron : INucleus {
|
||||
// UpdateResult(result);
|
||||
// }
|
||||
|
||||
public virtual void UpdateStateIsolated() {
|
||||
UpdateStateIsolated(new float3(0, 0, 0));
|
||||
}
|
||||
public virtual void UpdateStateIsolated(float3 bias) {
|
||||
// public virtual void UpdateStateIsolated() {
|
||||
// UpdateStateIsolated(new float3(0, 0, 0));
|
||||
// }
|
||||
public override void UpdateStateIsolated(float3 bias) {
|
||||
float3 sum = bias;
|
||||
int n = 0;
|
||||
|
||||
|
||||
105
Nucleus.cs
Normal file
105
Nucleus.cs
Normal file
@ -0,0 +1,105 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
|
||||
public abstract class Nucleus : IReceptor {
|
||||
[SerializeField]
|
||||
protected string _name;
|
||||
public virtual string name {
|
||||
get => _name;
|
||||
set => _name = value;
|
||||
}
|
||||
|
||||
//[Obsolete]
|
||||
public ClusterPrefab cluster { get; set; }
|
||||
public Cluster parent { get; set; }
|
||||
|
||||
protected float3 _outputValue;
|
||||
public virtual float3 outputValue {
|
||||
get { return _outputValue; }
|
||||
set {
|
||||
this.stale = 0;
|
||||
// this._isSleeping = false;
|
||||
_outputValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool isSleeping => lengthsq(this.outputValue) == 0;
|
||||
[NonSerialized]
|
||||
private int stale = 1000;
|
||||
|
||||
// Cannot clone an abstract nucleus...
|
||||
public virtual IReceptor ShallowCloneTo(Cluster parent) { return null; }
|
||||
// Cannot clone an abstract nucleus...
|
||||
public virtual IReceptor Clone() { return null; }
|
||||
|
||||
#region Synapses
|
||||
|
||||
[SerializeField]
|
||||
private List<Synapse> _synapses = new();
|
||||
public List<Synapse> synapses => _synapses;
|
||||
|
||||
public Synapse AddSynapse(IReceptor sendingNucleus, float weight = 1.0f) {
|
||||
Synapse synapse = new(sendingNucleus, weight);
|
||||
this.synapses.Add(synapse);
|
||||
return synapse;
|
||||
}
|
||||
|
||||
public Synapse GetSynapse(INucleus sender) {
|
||||
foreach (Synapse synapse in this.synapses)
|
||||
if (synapse.nucleus == sender)
|
||||
return synapse;
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion Synapses
|
||||
|
||||
#region Receivers
|
||||
|
||||
[SerializeReference]
|
||||
private List<INucleus> _receivers = new();
|
||||
public List<INucleus> receivers {
|
||||
get { return _receivers; }
|
||||
set { _receivers = value; }
|
||||
}
|
||||
|
||||
public virtual void AddReceiver(INucleus receivingNucleus, float weight = 1) {
|
||||
this._receivers.Add(receivingNucleus);
|
||||
receivingNucleus.AddSynapse(this, weight);
|
||||
}
|
||||
|
||||
public void RemoveReceiver(INucleus receiverNucleus) {
|
||||
this._receivers.RemoveAll(receiver => receiver == receiverNucleus);
|
||||
receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this);
|
||||
}
|
||||
|
||||
|
||||
#endregion Receivers
|
||||
|
||||
[SerializeReference]
|
||||
private NucleusArray _array;
|
||||
public NucleusArray array {
|
||||
get { return _array; }
|
||||
set { _array = value; }
|
||||
}
|
||||
|
||||
#region Update
|
||||
|
||||
public virtual void UpdateStateIsolated() {
|
||||
UpdateStateIsolated(new float3(0, 0, 0));
|
||||
}
|
||||
|
||||
public virtual void UpdateStateIsolated(float3 bias) {
|
||||
}
|
||||
|
||||
public void UpdateNuclei() {
|
||||
this.stale++;
|
||||
if (this.stale > 2)
|
||||
_outputValue = Vector3.zero;
|
||||
}
|
||||
|
||||
#endregion Update
|
||||
|
||||
}
|
||||
2
Nucleus.cs.meta
Normal file
2
Nucleus.cs.meta
Normal file
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4310eea6ab77628b085387a226c1c386
|
||||
@ -9,8 +9,8 @@ public class SelectorBrain : NanoBrain {
|
||||
public Receptor receptor2;
|
||||
|
||||
protected void Awake() {
|
||||
receptor1 = Receptor.CreateReceptor(this.brain, "Selector");
|
||||
receptor2 = Receptor.CreateReceptor(this.brain, "Selector");
|
||||
receptor1 = new Receptor(this.brain, "Receptor", "Selector");
|
||||
receptor2 = new Receptor(this.brain, "Receptor", "Selector");
|
||||
}
|
||||
|
||||
protected void Update() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user