Performance tweaking
This commit is contained in:
parent
6341d827e9
commit
5dbb5654a1
@ -68,32 +68,11 @@ namespace LinearAlgebra {
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
public static Spherical FromVector3(Vector3 v) {
|
||||
float distance = v.magnitude;
|
||||
// if (distance == 0.0f)
|
||||
// return Spherical.zero;
|
||||
// else {
|
||||
// float verticalAngle = (float)(Math.PI / 2 - Math.Acos(v.y / distance)) * AngleFloat.Rad2Deg;
|
||||
// float horizontalAngle = (float)Math.Atan2(v.x, v.z) * AngleFloat.Rad2Deg;
|
||||
// return Degrees(distance, horizontalAngle, verticalAngle);
|
||||
// }
|
||||
Direction direction = Direction.FromVector3(v.normalized);
|
||||
Direction direction = Direction.FromVector3(v / distance);
|
||||
return new Spherical(distance, direction);
|
||||
}
|
||||
|
||||
public readonly Vector3 ToVector3() {
|
||||
// float verticalRad = (AngleFloat.deg90 - this.direction.vertical).inRadians;
|
||||
// float horizontalRad = this.direction.horizontal.inRadians;
|
||||
// float cosVertical = (float)Math.Cos(verticalRad);
|
||||
// float sinVertical = (float)Math.Sin(verticalRad);
|
||||
// float cosHorizontal = (float)Math.Cos(horizontalRad);
|
||||
// float sinHorizontal = (float)Math.Sin(horizontalRad);
|
||||
|
||||
// float x = this.distance * sinVertical * sinHorizontal;
|
||||
// float y = this.distance * cosVertical;
|
||||
// float z = this.distance * sinVertical * cosHorizontal;
|
||||
|
||||
// Vector3 v = new(x, y, z);
|
||||
// return v;
|
||||
|
||||
Vector3 v = this.direction.ToVector3();
|
||||
v *= this.distance;
|
||||
return v;
|
||||
@ -247,150 +226,44 @@ namespace LinearAlgebra {
|
||||
|
||||
return Spherical.Radians(rAvg, azAvgRad, elAvgRad);
|
||||
}
|
||||
/*
|
||||
public static Spherical Average(List<Spherical> vectors) {
|
||||
// float sumSinPhiCosTheta = 0.0f;
|
||||
// float sumSinPhiSinTheta = 0.0f;
|
||||
// float sumCosPhi = 0.0f;
|
||||
|
||||
// int n = vectors.Count;
|
||||
public static Spherical Sum(List<Spherical> vectors) {
|
||||
if (vectors == null || vectors.Count == 0)
|
||||
throw new ArgumentException("vectors must contain at least one element", nameof(vectors));
|
||||
|
||||
// // 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);
|
||||
// }
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
Vector3 sum = Vector3.zero;
|
||||
#else
|
||||
Vector3Float sum = Vector3Float.zero;
|
||||
#endif
|
||||
foreach (Spherical v in vectors)
|
||||
sum += v.ToVector3();
|
||||
|
||||
// // 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));
|
||||
|
||||
if (vectors == null || vectors.Count == 0)
|
||||
throw new ArgumentException("vectors must contain at least one element", nameof(vectors));
|
||||
|
||||
float sumX = 0f, sumY = 0f, sumZ = 0f;
|
||||
int n = vectors.Count;
|
||||
|
||||
foreach (var v in vectors) {
|
||||
// AngleFloat -> radians; assume AngleFloat provides Radians property
|
||||
float theta = v.direction.horizontal.inRadians; // azimuth
|
||||
float phi = v.direction.vertical.inRadians; // elevation
|
||||
|
||||
float cosPhi = MathF.Cos(phi);
|
||||
float sinPhi = MathF.Sin(phi);
|
||||
float cosTheta = MathF.Cos(theta);
|
||||
float sinTheta = MathF.Sin(theta);
|
||||
|
||||
float x = v.distance * cosPhi * cosTheta;
|
||||
float y = v.distance * cosPhi * sinTheta;
|
||||
float z = v.distance * sinPhi;
|
||||
|
||||
sumX += x;
|
||||
sumY += y;
|
||||
sumZ += z;
|
||||
}
|
||||
|
||||
float avgX = sumX / n;
|
||||
float avgY = sumY / n;
|
||||
float avgZ = sumZ / n;
|
||||
|
||||
float rAvg = MathF.Sqrt(avgX * avgX + avgY * avgY + avgZ * avgZ);
|
||||
|
||||
if (rAvg == 0f) {
|
||||
return new Spherical(0f, new Direction(AngleFloat.Radians(0f), AngleFloat.Radians(0f)));
|
||||
}
|
||||
|
||||
// elevation = asin(z / r)
|
||||
AngleFloat verticalAvg = AngleFloat.Asin(avgZ / rAvg); // -90..90
|
||||
// azimuth = atan2(y, x) -> -pi..pi
|
||||
AngleFloat horizontalAvg = AngleFloat.Atan2(avgY, avgX); // -180..180
|
||||
|
||||
return new Spherical(rAvg, new Direction(horizontalAvg, verticalAvg));
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
public static Spherical Average(IEnumerable<Spherical> vectors) {
|
||||
const float EPS = 1e-6f;
|
||||
if (vectors == null) throw new ArgumentNullException(nameof(vectors));
|
||||
|
||||
float sumRx = 0f, sumRy = 0f, sumRz = 0f;
|
||||
float sumDistances = 0f;
|
||||
int count = 0;
|
||||
|
||||
bool firstSet = false;
|
||||
float firstAz = 0f, firstEl = 0f;
|
||||
bool allSameDirection = true;
|
||||
|
||||
foreach (var v in vectors) {
|
||||
float az = v.direction.horizontal.inRadians; // horizontal (azimuth)
|
||||
float el = v.direction.vertical.inRadians; // vertical (elevation)
|
||||
|
||||
if (!firstSet) {
|
||||
firstSet = true;
|
||||
firstAz = az;
|
||||
firstEl = el;
|
||||
}
|
||||
else {
|
||||
if (MathF.Abs(MathF.IEEERemainder(az - firstAz, MathF.PI * 2f)) >= EPS ||
|
||||
MathF.Abs(el - firstEl) >= EPS) {
|
||||
allSameDirection = false;
|
||||
}
|
||||
}
|
||||
|
||||
float cosEl = MathF.Cos(el);
|
||||
float ux = cosEl * MathF.Cos(az); // x
|
||||
float uy = cosEl * MathF.Sin(az); // y
|
||||
float uz = MathF.Sin(el); // z
|
||||
|
||||
sumRx += v.distance * ux;
|
||||
sumRy += v.distance * uy;
|
||||
sumRz += v.distance * uz;
|
||||
|
||||
sumDistances += v.distance;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0) throw new ArgumentException("Sequence contains no elements", nameof(vectors));
|
||||
|
||||
// All directions equal -> preserve exact angles, average distance
|
||||
if (allSameDirection) {
|
||||
float rAvg = sumDistances / count;
|
||||
return new Spherical(rAvg, Direction.Radians(firstAz, firstEl));
|
||||
}
|
||||
|
||||
// Total vector sum V
|
||||
float Vx = sumRx;
|
||||
float Vy = sumRy;
|
||||
float Vz = sumRz;
|
||||
float Vmag = MathF.Sqrt(Vx * Vx + Vy * Vy + Vz * Vz);
|
||||
|
||||
if (Vmag < EPS) {
|
||||
// Directions cancel out -> zero distance, angles arbitrary
|
||||
return Spherical.Radians(0f, 0f, 0f);
|
||||
}
|
||||
|
||||
float azAvg = MathF.Atan2(Vy, Vx);
|
||||
float elAvg = MathF.Asin(Float.Clamp(Vz / Vmag, -1f, 1f));
|
||||
float rAvgFinal = Vmag / count;
|
||||
|
||||
return Spherical.Radians(rAvgFinal, azAvg, elAvg);
|
||||
return FromVector3(sum);
|
||||
}
|
||||
|
||||
|
||||
public static Spherical Average(List<Spherical> vectors) {
|
||||
if (vectors == null || vectors.Count == 0)
|
||||
throw new ArgumentException("vectors must contain at least one element", nameof(vectors));
|
||||
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
Vector3 sum = Vector3.zero;
|
||||
#else
|
||||
Vector3Float sum = Vector3Float.zero;
|
||||
#endif
|
||||
int n = 0;
|
||||
foreach (Spherical v in vectors) {
|
||||
sum += v.ToVector3();
|
||||
n++;
|
||||
}
|
||||
var avg = sum / n;
|
||||
|
||||
// if (avg.sqrMagnitude == 0f)
|
||||
// return new Spherical(0f, new Direction(AngleFloat.Radians(0f), AngleFloat.Radians(0f)));
|
||||
// else
|
||||
return FromVector3(avg);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
#if !UNITY_5_6_OR_NEWER
|
||||
//#if !UNITY_5_6_OR_NEWER
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
@ -11,7 +11,11 @@ namespace LinearAlgebra.Test {
|
||||
|
||||
[Test]
|
||||
public void FromVector3() {
|
||||
#if UNITY_5_6_OR_NEWER
|
||||
UnityEngine.Vector3 v = new(0, 0, 1);
|
||||
#else
|
||||
Vector3Float v = new(0, 0, 1);
|
||||
#endif
|
||||
Spherical s = Spherical.FromVector3(v);
|
||||
Assert.AreEqual(1.0f, s.distance, "s.distance 0 0 1");
|
||||
Assert.AreEqual(0.0f, s.direction.horizontal.inDegrees, "s.hor 0 0 1");
|
||||
@ -46,7 +50,7 @@ namespace LinearAlgebra.Test {
|
||||
v2 = Spherical.Degrees(1, 0, 90);
|
||||
r = v1 + v2;
|
||||
Assert.AreEqual(Math.Sqrt(2), r.distance, 1.0E-05F, "Addition(1 0 90)");
|
||||
Assert.AreEqual(45.0f, r.direction.horizontal.inDegrees, "Addition(1 0 90)");
|
||||
Assert.AreEqual(45.0f, r.direction.horizontal.inDegrees, 1e-5f, "Addition(1 0 90)");
|
||||
Assert.AreEqual(45.0f, r.direction.vertical.inDegrees, 1.0E-05F, "Addition(1 0 90)");
|
||||
}
|
||||
|
||||
@ -166,7 +170,7 @@ namespace LinearAlgebra.Test {
|
||||
[Test]
|
||||
public void Average_SingleElement() {
|
||||
Spherical s = Spherical.Radians(1.234f, 0.3f, -0.7f);
|
||||
Spherical avg = Spherical.Average([s]);
|
||||
Spherical avg = Spherical.Average(new List<Spherical> { s });
|
||||
|
||||
Assert.AreEqual(s.distance, avg.distance, 1e-5f);
|
||||
Assert.AreEqual(s.direction.horizontal.inRadians, avg.direction.horizontal.inRadians, 1e-5f);
|
||||
@ -178,7 +182,7 @@ namespace LinearAlgebra.Test {
|
||||
// Two opposite vectors: same distance, horizontal opposite (pi apart), same vertical
|
||||
Spherical v1 = Spherical.Radians(1f, 0f, 0f);
|
||||
Spherical v2 = Spherical.Radians(1f, MathF.PI, 0f);
|
||||
Spherical avg = Spherical.Average([v1, v2]);
|
||||
Spherical avg = Spherical.Average(new List<Spherical> { v1, v2 });
|
||||
|
||||
Assert.AreEqual(0f, avg.distance, 1e-4f);
|
||||
// When distance is zero, angles may be undefined; allow any angle but ensure near-zero magnitude
|
||||
@ -190,7 +194,7 @@ namespace LinearAlgebra.Test {
|
||||
Direction dir = Direction.Radians(MathF.PI / 3f, MathF.PI / 4f);
|
||||
Spherical a = new(1f, dir);
|
||||
Spherical b = new(3f, dir);
|
||||
Spherical avg = Spherical.Average([a, b]);
|
||||
Spherical avg = Spherical.Average(new List<Spherical> { a, b });
|
||||
|
||||
// average distance should be (1+3)/2 = 2
|
||||
Assert.AreEqual(2f, avg.distance, 1e-5f);
|
||||
@ -248,7 +252,11 @@ namespace LinearAlgebra.Test {
|
||||
|
||||
Spherical avg = Spherical.Average(dirs);
|
||||
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
UnityEngine.Vector3 r = UnityEngine.Vector3.zero;
|
||||
#else
|
||||
Vector3Float r = Vector3Float.zero;
|
||||
#endif
|
||||
foreach (Spherical dir in dirs) {
|
||||
r += dir.ToVector3();
|
||||
}
|
||||
@ -260,4 +268,4 @@ namespace LinearAlgebra.Test {
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//#endif
|
||||
@ -75,23 +75,29 @@ public class Neuroid : Nucleus {
|
||||
}
|
||||
|
||||
public override void UpdateState() {
|
||||
List<Spherical> sVectors = new();
|
||||
Vector3 sum = Vector3.zero;
|
||||
int n = 0;
|
||||
foreach (Synapse synapse in this.synapses) {
|
||||
if (synapse.nucleus.isSleeping)
|
||||
continue;
|
||||
|
||||
Spherical outputValue = synapse.nucleus.outputValue;
|
||||
float weight = synapse.weight;
|
||||
float activatedValue = curve.Evaluate(synapse.nucleus.outputValue.magnitude);
|
||||
float activatedValue = curve.Evaluate(outputValue.magnitude);
|
||||
float magnitude = weight * activatedValue;
|
||||
Spherical sVector = new(magnitude, synapse.nucleus.outputValue.direction);
|
||||
sVectors.Add(sVector);
|
||||
Spherical sVector = new(magnitude, outputValue.direction);
|
||||
|
||||
sum += sVector.ToVector3();
|
||||
n++;
|
||||
}
|
||||
|
||||
Spherical sResult = Spherical.Average(sVectors);
|
||||
if (average == false)
|
||||
sResult *= sVectors.Count;
|
||||
Spherical result;
|
||||
if (average)
|
||||
result = Spherical.FromVector3(sum / n);
|
||||
else
|
||||
result = Spherical.FromVector3(sum);
|
||||
|
||||
UpdateResult(sResult);
|
||||
UpdateResult(result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -154,11 +154,11 @@ public class Nucleus {
|
||||
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;
|
||||
}
|
||||
// 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)
|
||||
|
||||
@ -176,9 +176,10 @@ PlayerSettings:
|
||||
tvOS: 0
|
||||
overrideDefaultApplicationIdentifier: 1
|
||||
AndroidBundleVersionCode: 1
|
||||
AndroidMinSdkVersion: 23
|
||||
AndroidMinSdkVersion: 25
|
||||
AndroidTargetSdkVersion: 0
|
||||
AndroidPreferredInstallLocation: 1
|
||||
AndroidPreferredDataLocation: 1
|
||||
aotOptions:
|
||||
stripEngineCode: 1
|
||||
iPhoneStrippingLevel: 0
|
||||
@ -193,11 +194,11 @@ PlayerSettings:
|
||||
VertexChannelCompressionMask: 4054
|
||||
iPhoneSdkVersion: 988
|
||||
iOSSimulatorArchitecture: 0
|
||||
iOSTargetOSVersionString: 13.0
|
||||
iOSTargetOSVersionString: 15.0
|
||||
tvOSSdkVersion: 0
|
||||
tvOSSimulatorArchitecture: 0
|
||||
tvOSRequireExtendedGameController: 0
|
||||
tvOSTargetOSVersionString: 13.0
|
||||
tvOSTargetOSVersionString: 15.0
|
||||
VisionOSSdkVersion: 0
|
||||
VisionOSTargetOSVersionString: 1.0
|
||||
uIPrerenderedIcon: 0
|
||||
@ -267,6 +268,7 @@ PlayerSettings:
|
||||
useCustomGradleSettingsTemplate: 0
|
||||
useCustomProguardFile: 0
|
||||
AndroidTargetArchitectures: 2
|
||||
AndroidAllowedArchitectures: -1
|
||||
AndroidSplashScreenScale: 0
|
||||
androidSplashScreen: {fileID: 0}
|
||||
AndroidKeystoreName:
|
||||
@ -569,7 +571,7 @@ PlayerSettings:
|
||||
locationUsageDescription:
|
||||
microphoneUsageDescription:
|
||||
bluetoothUsageDescription:
|
||||
macOSTargetOSVersion: 11.0
|
||||
macOSTargetOSVersion: 12.0
|
||||
switchNMETAOverride:
|
||||
switchNetLibKey:
|
||||
switchSocketMemoryPoolSize: 6144
|
||||
@ -937,3 +939,4 @@ PlayerSettings:
|
||||
androidVulkanAllowFilterList: []
|
||||
androidVulkanDeviceFilterListAsset: {fileID: 0}
|
||||
d3d12DeviceFilterListAsset: {fileID: 0}
|
||||
allowedHttpConnections: 3
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user