mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-08-17 10:08:05 +00:00
Merge dev into main: v0.8.7 Kahan compensated summation
This commit is contained in:
@@ -34,14 +34,13 @@ public sealed class Inertia : AbstractBase
|
||||
private record struct State(
|
||||
double SumY,
|
||||
double SumXY,
|
||||
double SumYComp,
|
||||
double SumXYComp,
|
||||
int Count,
|
||||
double LastValid);
|
||||
private State _state;
|
||||
private State _p_state;
|
||||
|
||||
private const int ResyncInterval = 1000;
|
||||
private int _tickCount;
|
||||
|
||||
/// <summary>
|
||||
/// Creates Inertia with specified period.
|
||||
/// </summary>
|
||||
@@ -102,29 +101,48 @@ public sealed class Inertia : AbstractBase
|
||||
{
|
||||
_p_state = _state;
|
||||
|
||||
// O(1) incremental sumXY maintenance (PineScript algorithm)
|
||||
// Kahan compensated O(1) incremental maintenance
|
||||
if (_buffer.Count == _buffer.Capacity)
|
||||
{
|
||||
double oldest = _buffer.Oldest;
|
||||
_state.SumY -= oldest;
|
||||
_state.SumXY -= _state.SumY;
|
||||
_state.SumXY += (_period - 1) * value;
|
||||
// Kahan delta for SumY
|
||||
{
|
||||
double delta = value - oldest;
|
||||
double y = delta - _state.SumYComp;
|
||||
double t = _state.SumY + y;
|
||||
_state.SumYComp = (t - _state.SumY) - y;
|
||||
_state.SumY = t;
|
||||
}
|
||||
// SumXY net delta = -SumY_new + period*value
|
||||
{
|
||||
double netDelta = -_state.SumY + (_period * value);
|
||||
double y = netDelta - _state.SumXYComp;
|
||||
double t = _state.SumXY + y;
|
||||
_state.SumXYComp = (t - _state.SumXY) - y;
|
||||
_state.SumXY = t;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_state.SumXY += _state.Count * value;
|
||||
// Warmup: Kahan addition for SumY
|
||||
{
|
||||
double y = value - _state.SumYComp;
|
||||
double t = _state.SumY + y;
|
||||
_state.SumYComp = (t - _state.SumY) - y;
|
||||
_state.SumY = t;
|
||||
}
|
||||
// Kahan addition for SumXY
|
||||
{
|
||||
double addXY = _state.Count * value;
|
||||
double y = addXY - _state.SumXYComp;
|
||||
double t = _state.SumXY + y;
|
||||
_state.SumXYComp = (t - _state.SumXY) - y;
|
||||
_state.SumXY = t;
|
||||
}
|
||||
_state.Count++;
|
||||
}
|
||||
|
||||
_state.SumY += value;
|
||||
_buffer.Add(value);
|
||||
|
||||
_tickCount++;
|
||||
if (_buffer.IsFull && _tickCount >= ResyncInterval)
|
||||
{
|
||||
_tickCount = 0;
|
||||
RecalculateSums();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -201,7 +219,6 @@ public sealed class Inertia : AbstractBase
|
||||
_buffer.Clear();
|
||||
_state = default;
|
||||
_p_state = default;
|
||||
_tickCount = 0;
|
||||
Last = default;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user