public double GetQuantile() { if (totalElementCount == 0) { throw new EmptySequenceException(); } if (HyndmanFanType != null && !double.IsNaN(probability)) { if (totalElementCount < windowSize) { throw new InvalidOperationException($"Sequence should contain at least {windowSize} elements"); } double GetValue(int index) { index = (index - 1).Clamp(0, windowSize - 1); // Adapt one-based formula to the zero-based list if (k - 1 <= index && index <= k + 1) { return(h[rootHeapIndex + index - k]); } throw new InvalidOperationException(); } return(HyndmanFanEquations.Evaluate(HyndmanFanType.Value, windowSize, probability, GetValue)); } if (initStrategy == MovingQuantileEstimatorInitStrategy.OrderStatistics && k >= totalElementCount) { throw new IndexOutOfRangeException($"Not enough values (n = {totalElementCount}, k = {k})"); } return(h[rootHeapIndex]); }
public PartitioningHeapsMovingQuantileEstimator(int windowSize, Probability p, HyndmanFanType HyndmanFanType) : this(windowSize, ((int)HyndmanFanEquations.GetH(HyndmanFanType, windowSize, p) - 1).Clamp(0, windowSize - 1)) { this.HyndmanFanType = HyndmanFanType; probability = p; }