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
|
// Now clone the connections
|
||||||
for (int nucleusIx = 0; nucleusIx < nuclei.Length; nucleusIx++) {
|
for (int nucleusIx = 0; nucleusIx < nuclei.Length; nucleusIx++) {
|
||||||
IReceptor receptor = nuclei[nucleusIx];
|
IReceptor receptor = nuclei[nucleusIx];
|
||||||
IReceptor clonedSender = clonedNuclei[nucleusIx];
|
IReceptor clonedReceptor = clonedNuclei[nucleusIx];
|
||||||
if (clonedSender == null)
|
if (clonedReceptor == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Copy the receivers, which will also create the synapses
|
// Copy the receivers, which will also create the synapses
|
||||||
@ -76,27 +76,49 @@ public class Cluster : INucleus {
|
|||||||
|
|
||||||
// Find the synapse for the weight
|
// Find the synapse for the weight
|
||||||
float weight = 1;
|
float weight = 1;
|
||||||
NucleusArray nucleusArray = null;
|
//NucleusArray clonedNucleusArray = null;
|
||||||
foreach (Synapse synapse in receiver.synapses) {
|
foreach (Synapse synapse in receiver.synapses) {
|
||||||
|
// Find the weight for this synapse
|
||||||
if (synapse.nucleus == receptor)
|
if (synapse.nucleus == receptor)
|
||||||
weight = synapse.weight;
|
weight = synapse.weight;
|
||||||
if (synapse.nucleus is INucleus synapseNucleus) {
|
|
||||||
if (synapseNucleus.array != null && synapseNucleus.array.nuclei.Length > 0) {
|
// if (synapse.nucleus is INucleus synapseNucleus) {
|
||||||
if (nucleusArray == null) {
|
// if (synapseNucleus.array != null && synapseNucleus.array.nuclei.Length > 0) {
|
||||||
// copy the array
|
// Debug.Log("Clone: Nucleus array");
|
||||||
nucleusArray = new NucleusArray(synapseNucleus.array.nuclei.Length, "array");
|
// if (clonedNucleusArray == null) {
|
||||||
for (int arrayIx = 0; arrayIx < synapseNucleus.array.nuclei.Length; arrayIx++) {
|
// // copy the array
|
||||||
IReceptor arrayNucleus = synapseNucleus.array.nuclei[arrayIx];
|
// clonedNucleusArray = new NucleusArray(synapseNucleus.array.nuclei.Length, "array");
|
||||||
int ix2 = GetNucleusIndex(nuclei, arrayNucleus);
|
// for (int arrayIx = 0; arrayIx < synapseNucleus.array.nuclei.Length; arrayIx++) {
|
||||||
nucleusArray.nuclei[arrayIx] = clonedNuclei[ix2];
|
// IReceptor arrayNucleus = synapseNucleus.array.nuclei[arrayIx];
|
||||||
}
|
// int ix2 = GetNucleusIndex(nuclei, arrayNucleus);
|
||||||
}
|
// clonedNucleusArray.nuclei[arrayIx] = clonedNuclei[ix2];
|
||||||
synapseNucleus.array = nucleusArray;
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// 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) {
|
// 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
|
// 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;
|
using static Unity.Mathematics.math;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class Neuron : INucleus {
|
public class Neuron : Nucleus, INucleus {
|
||||||
|
|
||||||
public Neuron(Cluster parent, string name) {
|
public Neuron(Cluster parent, string name) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
@ -24,30 +24,30 @@ public class Neuron : INucleus {
|
|||||||
// Debug.LogError("No neuroid network");
|
// Debug.LogError("No neuroid network");
|
||||||
}
|
}
|
||||||
|
|
||||||
[SerializeField]
|
// [SerializeField]
|
||||||
protected string _name;
|
// protected string _name;
|
||||||
public virtual string name {
|
// public virtual string name {
|
||||||
get => _name;
|
// get => _name;
|
||||||
set => _name = value;
|
// set => _name = value;
|
||||||
}
|
// }
|
||||||
|
|
||||||
[SerializeField]
|
// [SerializeField]
|
||||||
private List<Synapse> _synapses = new();
|
// private List<Synapse> _synapses = new();
|
||||||
public List<Synapse> synapses => _synapses;
|
// public List<Synapse> synapses => _synapses;
|
||||||
|
|
||||||
[SerializeReference]
|
// [SerializeReference]
|
||||||
private List<INucleus> _receivers = new();
|
// private List<INucleus> _receivers = new();
|
||||||
public List<INucleus> receivers {
|
// public List<INucleus> receivers {
|
||||||
get { return _receivers; }
|
// get { return _receivers; }
|
||||||
set { _receivers = value; }
|
// set { _receivers = value; }
|
||||||
}
|
// }
|
||||||
|
|
||||||
[SerializeReference]
|
// [SerializeReference]
|
||||||
private NucleusArray _array;
|
// private NucleusArray _array;
|
||||||
public NucleusArray array {
|
// public NucleusArray array {
|
||||||
get { return _array; }
|
// get { return _array; }
|
||||||
set { _array = value; }
|
// set { _array = value; }
|
||||||
}
|
// }
|
||||||
|
|
||||||
#region Serialization
|
#region Serialization
|
||||||
|
|
||||||
@ -102,8 +102,8 @@ public class Neuron : INucleus {
|
|||||||
|
|
||||||
#region Runtime state (not serialized)
|
#region Runtime state (not serialized)
|
||||||
|
|
||||||
public ClusterPrefab cluster { get; set; }
|
// public ClusterPrefab cluster { get; set; }
|
||||||
public Cluster parent { get; set; }
|
// public Cluster parent { get; set; }
|
||||||
|
|
||||||
#region Activation
|
#region Activation
|
||||||
|
|
||||||
@ -153,35 +153,35 @@ public class Neuron : INucleus {
|
|||||||
|
|
||||||
#endregion Activation
|
#endregion Activation
|
||||||
|
|
||||||
protected float3 _outputValue;
|
// protected float3 _outputValue;
|
||||||
public virtual float3 outputValue {
|
// public virtual float3 outputValue {
|
||||||
get { return _outputValue; }
|
// get { return _outputValue; }
|
||||||
set {
|
// set {
|
||||||
this.stale = 0;
|
// this.stale = 0;
|
||||||
// this._isSleeping = false;
|
// // this._isSleeping = false;
|
||||||
_outputValue = value;
|
// _outputValue = value;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
[NonSerialized]
|
// [NonSerialized]
|
||||||
private int stale = 1000;
|
// private int stale = 1000;
|
||||||
|
|
||||||
// private bool _isSleeping = false;
|
// private bool _isSleeping = false;
|
||||||
// public bool isSleeping => _isSleeping;
|
// public bool isSleeping => _isSleeping;
|
||||||
public bool isSleeping => lengthsq(this.outputValue) == 0;
|
// public bool isSleeping => lengthsq(this.outputValue) == 0;
|
||||||
|
|
||||||
public void UpdateNuclei() {
|
// public void UpdateNuclei() {
|
||||||
this.stale++;
|
// this.stale++;
|
||||||
// this._isSleeping = this.stale > 2;
|
// // this._isSleeping = this.stale > 2;
|
||||||
// if (isSleeping)
|
// // if (isSleeping)
|
||||||
if (this.stale > 2)
|
// if (this.stale > 2)
|
||||||
_outputValue = Vector3.zero;
|
// _outputValue = Vector3.zero;
|
||||||
}
|
// }
|
||||||
|
|
||||||
#endregion Runtime state
|
#endregion Runtime state
|
||||||
|
|
||||||
// this clone the nucleus without the synapses and receivers
|
// 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) {
|
Neuron clone = new(newParent, this.name) {
|
||||||
array = null,
|
array = null,
|
||||||
curve = this.curve,
|
curve = this.curve,
|
||||||
@ -192,7 +192,7 @@ public class Neuron : INucleus {
|
|||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IReceptor Clone() {
|
public override IReceptor Clone() {
|
||||||
Neuron clone = new(this.cluster, this.name) {
|
Neuron clone = new(this.cluster, this.name) {
|
||||||
array = this.array,
|
array = this.array,
|
||||||
curve = this.curve,
|
curve = this.curve,
|
||||||
@ -213,22 +213,22 @@ public class Neuron : INucleus {
|
|||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void AddReceiver(INucleus receivingNucleus, float weight = 1) {
|
// public virtual void AddReceiver(INucleus receivingNucleus, float weight = 1) {
|
||||||
this._receivers.Add(receivingNucleus);
|
// this._receivers.Add(receivingNucleus);
|
||||||
receivingNucleus.AddSynapse(this, weight);
|
// receivingNucleus.AddSynapse(this, weight);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void RemoveReceiver(INucleus receiverNucleus) {
|
// public void RemoveReceiver(INucleus receiverNucleus) {
|
||||||
this._receivers.RemoveAll(receiver => receiver == receiverNucleus);
|
// this._receivers.RemoveAll(receiver => receiver == receiverNucleus);
|
||||||
receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this);
|
// receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public static void Delete(INucleus nucleus) {
|
public static void Delete(INucleus nucleus) {
|
||||||
foreach (Synapse synapse in nucleus.synapses) {
|
foreach (Synapse synapse in nucleus.synapses) {
|
||||||
if (synapse.nucleus is Neuron synapse_nucleus) {
|
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
|
// there is another nucleus feeding into this input nucleus
|
||||||
synapse_nucleus._receivers.RemoveAll(r => r == nucleus);
|
synapse_nucleus.receivers.RemoveAll(r => r == nucleus);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// No other links, delete it.
|
// No other links, delete it.
|
||||||
@ -247,11 +247,11 @@ public class Neuron : INucleus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Synapse AddSynapse(IReceptor sendingNucleus, float weight = 1.0f) {
|
// public Synapse AddSynapse(IReceptor sendingNucleus, float weight = 1.0f) {
|
||||||
Synapse synapse = new(sendingNucleus, weight);
|
// Synapse synapse = new(sendingNucleus, weight);
|
||||||
this.synapses.Add(synapse);
|
// this.synapses.Add(synapse);
|
||||||
return synapse;
|
// return synapse;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// public virtual void UpdateState() {
|
// public virtual void UpdateState() {
|
||||||
// //UpdateState(new float3(0, 0, 0));
|
// //UpdateState(new float3(0, 0, 0));
|
||||||
@ -296,10 +296,10 @@ public class Neuron : INucleus {
|
|||||||
// UpdateResult(result);
|
// UpdateResult(result);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public virtual void UpdateStateIsolated() {
|
// public virtual void UpdateStateIsolated() {
|
||||||
UpdateStateIsolated(new float3(0, 0, 0));
|
// UpdateStateIsolated(new float3(0, 0, 0));
|
||||||
}
|
// }
|
||||||
public virtual void UpdateStateIsolated(float3 bias) {
|
public override void UpdateStateIsolated(float3 bias) {
|
||||||
float3 sum = bias;
|
float3 sum = bias;
|
||||||
int n = 0;
|
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;
|
public Receptor receptor2;
|
||||||
|
|
||||||
protected void Awake() {
|
protected void Awake() {
|
||||||
receptor1 = Receptor.CreateReceptor(this.brain, "Selector");
|
receptor1 = new Receptor(this.brain, "Receptor", "Selector");
|
||||||
receptor2 = Receptor.CreateReceptor(this.brain, "Selector");
|
receptor2 = new Receptor(this.brain, "Receptor", "Selector");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Update() {
|
protected void Update() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user