From 8c484e872e61058062c4213b4837d8b043c7fb65 Mon Sep 17 00:00:00 2001 From: Miha Kralj Date: Sun, 18 Jan 2026 22:39:58 -0800 Subject: [PATCH] reviews --- lib/filters/elliptic/Elliptic.cs | 4 +-- lib/filters/notch/Notch.cs | 10 ++++---- lib/numerics/accel/Accel.cs | 25 ++++++------------- .../stddev/StdDev.Validation.Tests.cs | 7 +++--- lib/trends_IIR/mama/Mama.cs | 4 +-- lib/trends_IIR/vama/Vama.Tests.cs | 2 +- lib/trends_IIR/vama/Vama.cs | 2 +- lib/trends_IIR/yzvama/Yzvama.cs | 4 +-- lib/volume/adosc/Adosc.cs | 2 +- 9 files changed, 26 insertions(+), 34 deletions(-) diff --git a/lib/filters/elliptic/Elliptic.cs b/lib/filters/elliptic/Elliptic.cs index 9814e36e..cfc625c5 100644 --- a/lib/filters/elliptic/Elliptic.cs +++ b/lib/filters/elliptic/Elliptic.cs @@ -128,7 +128,7 @@ public sealed class Elliptic : AbstractBase // Set internal state from calculated end state (no double-processing) _state = endState; _p_state = endState; - Last = new TValue(source[source.Count - 1].Time, results[results.Length - 1]); + Last = new TValue(source[^1].Time, results[^1]); return output; } @@ -309,4 +309,4 @@ public sealed class Elliptic : AbstractBase } base.Dispose(disposing); } -} \ No newline at end of file +} diff --git a/lib/filters/notch/Notch.cs b/lib/filters/notch/Notch.cs index 0b6e96d3..8cd61075 100644 --- a/lib/filters/notch/Notch.cs +++ b/lib/filters/notch/Notch.cs @@ -152,15 +152,15 @@ public sealed class Notch : AbstractBase _index += srcSpan.Length; // Best effort state restoration from the end of the block // We assume the strict history for X is valid. - double lastVal = srcSpan[srcSpan.Length - 1]; + double lastVal = srcSpan[^1]; _state.LastValue = lastVal; if (srcSpan.Length >= 2) { - _state.X1 = srcSpan[srcSpan.Length - 1]; - _state.X2 = srcSpan[srcSpan.Length - 2]; - _state.Y1 = outArray[outArray.Length - 1]; - _state.Y2 = outArray[outArray.Length - 2]; + _state.X1 = srcSpan[^1]; + _state.X2 = srcSpan[^2]; + _state.Y1 = outArray[^1]; + _state.Y2 = outArray[^2]; } else { diff --git a/lib/numerics/accel/Accel.cs b/lib/numerics/accel/Accel.cs index ac3811a2..80d83bc2 100644 --- a/lib/numerics/accel/Accel.cs +++ b/lib/numerics/accel/Accel.cs @@ -76,15 +76,10 @@ public sealed class Accel : AbstractBase _p_state = _state; double val = GetValidValue(input.Value); - if (_state.Count >= 2) - { - // accel = val - 2*prev1 + prev2 - result = Math.FusedMultiplyAdd(-2.0, _state.Prev1, val + _state.Prev2); - } - else - { - result = 0.0; - } + // accel = val - 2*prev1 + prev2 + result = _state.Count >= 2 + ? Math.FusedMultiplyAdd(-2.0, _state.Prev1, val + _state.Prev2) + : 0.0; // Shift history _state.Prev2 = _state.Prev1; @@ -97,14 +92,10 @@ public sealed class Accel : AbstractBase _state.LastValidValue = _p_state.LastValidValue; double val = GetValidValue(input.Value); - if (_p_state.Count >= 2) - { - result = Math.FusedMultiplyAdd(-2.0, _p_state.Prev1, val + _p_state.Prev2); - } - else - { - result = 0.0; - } + // accel = val - 2*prev1 + prev2 + result = _p_state.Count >= 2 + ? Math.FusedMultiplyAdd(-2.0, _p_state.Prev1, val + _p_state.Prev2) + : 0.0; // Update current state from previous (don't shift) _state.Prev2 = _p_state.Prev2; diff --git a/lib/statistics/stddev/StdDev.Validation.Tests.cs b/lib/statistics/stddev/StdDev.Validation.Tests.cs index 0672beff..7205e159 100644 --- a/lib/statistics/stddev/StdDev.Validation.Tests.cs +++ b/lib/statistics/stddev/StdDev.Validation.Tests.cs @@ -315,11 +315,12 @@ public sealed class StdDevValidationTests : IDisposable streamingResults.Add(streamingStdDev.Update(item).Value); } - // Compare all modes (allow 1e-8 tolerance for accumulated floating-point errors) + // Compare all modes (allow 1e-7 tolerance for accumulated floating-point errors + // between SIMD batch paths and scalar streaming paths with different FMA/sum ordering) for (int i = 0; i < _testData.Data.Count; i++) { - Assert.Equal(batchResult[i].Value, spanOutput[i], 1e-8); - Assert.Equal(batchResult[i].Value, streamingResults[i], 1e-8); + Assert.Equal(batchResult[i].Value, spanOutput[i], 1e-7); + Assert.Equal(batchResult[i].Value, streamingResults[i], 1e-7); } } } diff --git a/lib/trends_IIR/mama/Mama.cs b/lib/trends_IIR/mama/Mama.cs index ced321de..b2a7cab6 100644 --- a/lib/trends_IIR/mama/Mama.cs +++ b/lib/trends_IIR/mama/Mama.cs @@ -327,7 +327,7 @@ public sealed class Mama : AbstractBase // State variables (initialized: used before assignment; uninitialized: always assigned before read) double period = MinPeriod, sumPr = 0, lastValidPrice = 0; - double mama, fama, i2, q2, re, im; + double mama = 0, fama = 0, i2 = 0, q2 = 0, re = 0, im = 0; double p_period = MinPeriod, p_phase = 0, p_mama = 0, p_fama = 0; double p_i2 = 0, p_q2 = 0, p_re = 0, p_im = 0; @@ -484,4 +484,4 @@ public sealed class Mama : AbstractBase } } } -} \ No newline at end of file +} diff --git a/lib/trends_IIR/vama/Vama.Tests.cs b/lib/trends_IIR/vama/Vama.Tests.cs index e61fc52a..3037dde2 100644 --- a/lib/trends_IIR/vama/Vama.Tests.cs +++ b/lib/trends_IIR/vama/Vama.Tests.cs @@ -399,7 +399,7 @@ public class VamaTests Assert.True(double.IsFinite(vama.Last.Value)); // IsHot requires ValidCount >= minLength (5) and IsInitialized - Assert.True(vama.IsHot, $"Expected IsHot=true after 100 bars"); + Assert.True(vama.IsHot, "Expected IsHot=true after 100 bars"); } [Fact] diff --git a/lib/trends_IIR/vama/Vama.cs b/lib/trends_IIR/vama/Vama.cs index ead97b5b..8799cfa1 100644 --- a/lib/trends_IIR/vama/Vama.cs +++ b/lib/trends_IIR/vama/Vama.cs @@ -213,7 +213,7 @@ public sealed class Vama : AbstractBase int newHead = (_state.BufferHead + 1) % _maxLength; // Calculate SMA over adjusted_length most recent values - double result; + double result = 0; int actualCount = Math.Min(validCount, adjustedLength); if (actualCount > 0) { diff --git a/lib/trends_IIR/yzvama/Yzvama.cs b/lib/trends_IIR/yzvama/Yzvama.cs index 37bc54fd..af5aebfa 100644 --- a/lib/trends_IIR/yzvama/Yzvama.cs +++ b/lib/trends_IIR/yzvama/Yzvama.cs @@ -357,7 +357,7 @@ public sealed class Yzvama : AbstractBase int newHead = (_state.SourceHead + 1) % _maxLength; // Calculate SMA over adjustedLength most recent values - double result; + double result = 0; int actualCount = Math.Min(validCount, adjustedLength); if (actualCount > 0) { @@ -523,4 +523,4 @@ public sealed class Yzvama : AbstractBase _p_lastValidSource = double.NaN; Last = default; } -} \ No newline at end of file +} diff --git a/lib/volume/adosc/Adosc.cs b/lib/volume/adosc/Adosc.cs index c9ec3dc5..79f327f3 100644 --- a/lib/volume/adosc/Adosc.cs +++ b/lib/volume/adosc/Adosc.cs @@ -227,7 +227,7 @@ public sealed class Adosc : ITValuePublisher // 5. Compute compensated EMA values (same logic as Ema.cs Compute method) // Compensator decays: e *= decay, then result = ema / (1 - e) until e <= threshold - double fastValue, slowValue; + double fastValue = 0, slowValue = 0; if (!fastCompensated) {