mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-21 03:58:04 +00:00
Refactor error handling and calculations in TheilU, Wmape, and TukeyBiweight classes; update buffer handling for consistency
- Updated buffer handling in TheilU and Wmape classes to ensure consistency after adding new values. - Changed the resync interval constant in TukeyBiweight for better clarity. - Refactored state structures to record structs in Gauss, Hann, Hp, Hpf, Kalman, Loess, Notch, and other filter classes for improved performance and readability. - Enhanced numerical stability in Mama class calculations using Fused Multiply-Add (FMA) for precision. - Added comprehensive tests for Atan2 validation to compare .NET's Math.Atan2 with PineScript's implementation, ensuring accuracy across various edge cases. - Updated NDepend badges to reflect changes in classes, methods, and lines of code.
This commit is contained in:
@@ -104,18 +104,15 @@ public sealed class Mase : AbstractBase
|
||||
{
|
||||
_state = _p_state;
|
||||
|
||||
// Incremental update for error buffer: get current newest, compute delta
|
||||
double currentNewestError = _errorBuffer.Count > 0 ? _errorBuffer.Newest : 0.0;
|
||||
double deltaError = absError - currentNewestError;
|
||||
_state.ErrorSum += deltaError;
|
||||
// Bar correction: update buffer and recalculate sums
|
||||
// Note: _p_state was saved BEFORE the Add, but buffer still has the added value
|
||||
// So we update newest and recalculate to ensure consistency
|
||||
_errorBuffer.UpdateNewest(absError);
|
||||
|
||||
// Incremental update for scale buffer: get current newest, compute delta
|
||||
double currentNewestScale = _scaleBuffer.Count > 0 ? _scaleBuffer.Newest : 0.0;
|
||||
double deltaScale = naiveDiff - currentNewestScale;
|
||||
_state.ScaleSum += deltaScale;
|
||||
_scaleBuffer.UpdateNewest(naiveDiff);
|
||||
|
||||
_state.ErrorSum = _errorBuffer.RecalculateSum();
|
||||
_state.ScaleSum = _scaleBuffer.RecalculateSum();
|
||||
|
||||
_state.PrevActual = actualVal;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,9 +107,7 @@ public sealed class Rae : AbstractBase
|
||||
{
|
||||
_state = _p_state;
|
||||
|
||||
// Update actual buffer
|
||||
double removedActual = _actualBuffer.Count == _actualBuffer.Capacity ? _actualBuffer.Oldest : 0.0;
|
||||
_state.ActualSum = _state.ActualSum - removedActual + actualVal;
|
||||
// Update buffers and recalculate sums (buffer state is inconsistent with _p_state)
|
||||
_actualBuffer.UpdateNewest(actualVal);
|
||||
_state.ActualSum = _actualBuffer.RecalculateSum();
|
||||
|
||||
@@ -118,12 +116,9 @@ public sealed class Rae : AbstractBase
|
||||
double absError = Math.Abs(actualVal - predictedVal);
|
||||
double absBaseline = Math.Abs(actualVal - mean);
|
||||
|
||||
// Update error buffer
|
||||
_absErrorBuffer.UpdateNewest(absError);
|
||||
_state.AbsErrorSum = _absErrorBuffer.RecalculateSum();
|
||||
|
||||
// Update baseline buffer
|
||||
_absBaselineBuffer.UpdateNewest(absBaseline);
|
||||
_state.AbsErrorSum = _absErrorBuffer.RecalculateSum();
|
||||
_state.AbsBaselineSum = _absBaselineBuffer.RecalculateSum();
|
||||
}
|
||||
|
||||
@@ -292,4 +287,4 @@ public sealed class Rae : AbstractBase
|
||||
}
|
||||
}
|
||||
}
|
||||
}␍
|
||||
}
|
||||
|
||||
@@ -110,25 +110,22 @@ public sealed class Rsquared : AbstractBase
|
||||
{
|
||||
_state = _p_state;
|
||||
|
||||
// Update actual buffer
|
||||
double removedActual = _actualBuffer.Count == _actualBuffer.Capacity ? _actualBuffer.Oldest : 0.0;
|
||||
_state.ActualSum = _state.ActualSum - removedActual + actualVal;
|
||||
// Bar correction: update buffers and recalculate sums
|
||||
_actualBuffer.UpdateNewest(actualVal);
|
||||
_state.ActualSum = _actualBuffer.RecalculateSum();
|
||||
|
||||
// Calculate mean and errors
|
||||
double mean = _state.ActualSum / _actualBuffer.Count;
|
||||
double mean = _actualBuffer.RecalculateSum() / _actualBuffer.Count;
|
||||
_state.ActualSum = _actualBuffer.RecalculateSum();
|
||||
|
||||
double residual = actualVal - predictedVal;
|
||||
double totalDev = actualVal - mean;
|
||||
double sqResidual = residual * residual;
|
||||
double sqTotal = totalDev * totalDev;
|
||||
|
||||
// Update squared residual buffer
|
||||
_sqResidualBuffer.UpdateNewest(sqResidual);
|
||||
_state.SqResidualSum = _sqResidualBuffer.RecalculateSum();
|
||||
|
||||
// Update squared total buffer
|
||||
_sqTotalBuffer.UpdateNewest(sqTotal);
|
||||
|
||||
_state.SqResidualSum = _sqResidualBuffer.RecalculateSum();
|
||||
_state.SqTotalSum = _sqTotalBuffer.RecalculateSum();
|
||||
}
|
||||
|
||||
|
||||
@@ -124,14 +124,15 @@ public sealed class TheilU : AbstractBase
|
||||
{
|
||||
_state = _p_state;
|
||||
|
||||
// Simplified: just update buffers and recalculate sums (no redundant arithmetic)
|
||||
// Bar correction: update buffer and recalculate sums
|
||||
// Note: _p_state was saved BEFORE the Add, but buffer still has the added value
|
||||
// So we update newest and recalculate to ensure consistency
|
||||
_sqErrorBuffer.UpdateNewest(sqError);
|
||||
_state.SqErrorSum = _sqErrorBuffer.RecalculateSum();
|
||||
|
||||
_sqActualBuffer.UpdateNewest(sqActual);
|
||||
_state.SqActualSum = _sqActualBuffer.RecalculateSum();
|
||||
|
||||
_sqPredBuffer.UpdateNewest(sqPred);
|
||||
|
||||
_state.SqErrorSum = _sqErrorBuffer.RecalculateSum();
|
||||
_state.SqActualSum = _sqActualBuffer.RecalculateSum();
|
||||
_state.SqPredSum = _sqPredBuffer.RecalculateSum();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ public sealed class TukeyBiweight : BiInputIndicatorBase
|
||||
{
|
||||
private readonly double _cSquaredOver6;
|
||||
private const double DefaultC = 4.685; // 95% efficiency for normal distribution
|
||||
private const int BatchResyncInterval = 1000; // Local constant for static Batch method
|
||||
|
||||
public TukeyBiweight(int period, double c = DefaultC)
|
||||
: base(period, $"TukeyBiweight({period},{c:F3})")
|
||||
@@ -104,7 +105,7 @@ public sealed class TukeyBiweight : BiInputIndicatorBase
|
||||
ErrorHelpers.ComputeTukeyBiweightErrors(actual, predicted, errors, c);
|
||||
|
||||
// Step 2: Apply rolling mean
|
||||
ErrorHelpers.ApplyRollingMean(errors, output, period, ResyncInterval);
|
||||
ErrorHelpers.ApplyRollingMean(errors, output, period, BatchResyncInterval);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -97,11 +97,13 @@ public sealed class Wmape : AbstractBase
|
||||
}
|
||||
else
|
||||
{
|
||||
// Simplified: just update buffers and recalculate sums (no redundant arithmetic)
|
||||
// Bar correction: update buffer and recalculate sums
|
||||
// Note: _p_state was saved BEFORE the Add, but buffer still has the added value
|
||||
// So we update newest and recalculate to ensure consistency
|
||||
_absErrorBuffer.UpdateNewest(absError);
|
||||
_state.AbsErrorSum = _absErrorBuffer.RecalculateSum();
|
||||
|
||||
_absActualBuffer.UpdateNewest(absActual);
|
||||
|
||||
_state.AbsErrorSum = _absErrorBuffer.RecalculateSum();
|
||||
_state.AbsActualSum = _absActualBuffer.RecalculateSum();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user