Prepare for spherical average
This commit is contained in:
parent
1e1e5b1344
commit
d026996ce2
@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
#if UNITY_5_3_OR_NEWER
|
#if UNITY_5_3_OR_NEWER
|
||||||
using Vector3 = UnityEngine.Vector3;
|
using Vector3 = UnityEngine.Vector3;
|
||||||
#endif
|
#endif
|
||||||
@ -137,6 +139,19 @@ namespace LinearAlgebra {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Spherical operator *(Spherical v, float d) {
|
||||||
|
Spherical r = new(v.distance * d, v.direction);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(Spherical v1, Spherical v2) {
|
||||||
|
return (v1.distance == v2.distance && v1.direction == v2.direction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator !=(Spherical v1, Spherical v2) {
|
||||||
|
return (v1.distance != v2.distance || v1.direction != v2.direction);
|
||||||
|
}
|
||||||
|
|
||||||
public static float Distance(Spherical v1, Spherical v2) {
|
public static float Distance(Spherical v1, Spherical v2) {
|
||||||
// Convert degrees to radians
|
// Convert degrees to radians
|
||||||
float thetaARadians = v1.direction.horizontal.inRadians;
|
float thetaARadians = v1.direction.horizontal.inRadians;
|
||||||
@ -162,5 +177,37 @@ namespace LinearAlgebra {
|
|||||||
|
|
||||||
return distance;
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Spherical Average(List<Spherical> vectors) {
|
||||||
|
float sumSinPhiCosTheta = 0.0f;
|
||||||
|
float sumSinPhiSinTheta = 0.0f;
|
||||||
|
float sumCosPhi = 0.0f;
|
||||||
|
|
||||||
|
int n = vectors.Count;
|
||||||
|
|
||||||
|
// Step 1: Accumulate sine and cosine components
|
||||||
|
foreach(Spherical v in vectors) {
|
||||||
|
float sinHorizontal = AngleFloat.Sin(v.direction.horizontal);
|
||||||
|
sumSinPhiCosTheta += v.distance * sinHorizontal * AngleFloat.Cos(v.direction.vertical);
|
||||||
|
sumSinPhiSinTheta += v.distance * sinHorizontal * AngleFloat.Sin(v.direction.vertical);
|
||||||
|
sumCosPhi += v.distance * AngleFloat.Cos(v.direction.horizontal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: Calculate average components
|
||||||
|
float avgSinPhiCosTheta = sumSinPhiCosTheta / n;
|
||||||
|
float avgSinPhiSinTheta = sumSinPhiSinTheta / n;
|
||||||
|
float avgCosPhi = sumCosPhi / n;
|
||||||
|
|
||||||
|
// Step 3: Calculate the magnitude of the average vector
|
||||||
|
float rAvg = MathF.Sqrt(avgSinPhiCosTheta * avgSinPhiCosTheta +
|
||||||
|
avgSinPhiSinTheta * avgSinPhiSinTheta +
|
||||||
|
avgCosPhi * avgCosPhi);
|
||||||
|
|
||||||
|
// Step 4: Calculate average angles
|
||||||
|
AngleFloat horizontalAvg = AngleFloat.Acos(avgCosPhi / rAvg); // Handle rAvg != 0 case
|
||||||
|
AngleFloat verticalAvg = AngleFloat.Atan2(avgSinPhiSinTheta, avgSinPhiCosTheta);
|
||||||
|
|
||||||
|
return new Spherical(rAvg, new Direction(horizontalAvg, verticalAvg));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using LinearAlgebra;
|
using LinearAlgebra;
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ public class Neuroid : Nucleus {
|
|||||||
UpdateState();
|
UpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void UpdateState() {
|
public override void UpdateState() {
|
||||||
Vector3 resultVector = Vector3.zero;
|
Vector3 resultVector = Vector3.zero;
|
||||||
foreach (Synapse synapse in this.synapses) {
|
foreach (Synapse synapse in this.synapses) {
|
||||||
Nucleus synapseNucleus = synapse.nucleus;
|
Nucleus synapseNucleus = synapse.nucleus;
|
||||||
@ -93,18 +94,23 @@ public class Neuroid : Nucleus {
|
|||||||
resultVector /= this.synapses.Count;
|
resultVector /= this.synapses.Count;
|
||||||
|
|
||||||
Spherical result = Spherical.FromVector3(resultVector);
|
Spherical result = Spherical.FromVector3(resultVector);
|
||||||
float d = Spherical.Distance(result, this.outputValue);
|
|
||||||
if (d < 0.1f) {
|
|
||||||
//Debug.Log($"insignificant update: {d}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.outputValue = result;
|
// List<Spherical> vectors = new();
|
||||||
|
// foreach (Synapse synapse in this.synapses) {
|
||||||
|
// if (synapse.nucleus.isSleeping)
|
||||||
|
// continue;
|
||||||
|
|
||||||
|
// vectors.Add(synapse.nucleus.outputValue);
|
||||||
|
// }
|
||||||
|
// Spherical result2 = Spherical.Average(vectors);
|
||||||
|
// if (average == false)
|
||||||
|
// result2 *= vectors.Count;
|
||||||
|
|
||||||
foreach (Receiver receiver in this.receivers) {
|
// if (result2 != result)
|
||||||
if (receiver.nucleus is Neuroid neuroid)
|
// Debug.Log($"update error {result2} != {result}");
|
||||||
neuroid.SetInput(this);
|
|
||||||
}
|
UpdateResult(result);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -151,6 +151,20 @@ public class Nucleus {
|
|||||||
synapses.Add(newSynapse);
|
synapses.Add(newSynapse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void UpdateState() { }
|
||||||
|
|
||||||
|
public void UpdateResult(Spherical result) {
|
||||||
|
float d = Spherical.Distance(result, this.outputValue);
|
||||||
|
if (d < 0.1f) {
|
||||||
|
//Debug.Log($"insignificant update: {d}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.outputValue = result;
|
||||||
|
foreach (Receiver receiver in this.receivers)
|
||||||
|
receiver.nucleus.UpdateState();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
|
|||||||
@ -74,19 +74,9 @@ public class Perceptoid : Neuroid {
|
|||||||
this.receivers = new();
|
this.receivers = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateState(int thingId, Spherical receptorValue) {
|
public override void UpdateState() {
|
||||||
this.thingId = thingId;
|
Spherical result = this.receptor.localPosition;
|
||||||
Spherical result = receptorValue;
|
UpdateResult(result);
|
||||||
|
|
||||||
float d = Spherical.Distance(result, this.outputValue);
|
|
||||||
if (d < 0.1f) {
|
|
||||||
//Debug.Log($"insignificant update: {d}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.outputValue = result;
|
|
||||||
foreach (Receiver receiver in this.receivers)
|
|
||||||
if (receiver.nucleus is Neuroid neuroid)
|
|
||||||
neuroid.SetInput(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -87,6 +87,7 @@ public class Receptor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Debug.Log($"Stimulus {thingType} {thingId} {selectedPerceptoid.name}");
|
// Debug.Log($"Stimulus {thingType} {thingId} {selectedPerceptoid.name}");
|
||||||
selectedPerceptoid.UpdateState(thingId, this.localPosition);
|
selectedPerceptoid.thingId = thingId;
|
||||||
|
selectedPerceptoid.UpdateState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user