private static void lower_upper_lemire(TimeSeries t, int r, out TimeSeries l, out TimeSeries u) { l = new TimeSeries(t.Values.Count); u = new TimeSeries(t.Values.Count); var du = new Deque(2*r + 2); var dl = new Deque(2*r + 2); du.push_back(0); dl.push_back(0); for (int i = 1; i < t.Values.Count; i++) { if (i > r) { u.Values[i - r - 1] = t.Values[du.front()]; l.Values[i - r - 1] = t.Values[dl.front()]; } if (t.Values[i] > t.Values[i - 1]) { du.pop_back(); while (!du.empty() && t.Values[i] > t.Values[du.back()]) du.pop_back(); } else { dl.pop_back(); while (!dl.empty() && t.Values[i] < t.Values[dl.back()]) dl.pop_back(); } du.push_back(i); dl.push_back(i); if (i == 2*r + 1 + du.front()) du.pop_front(); else if (i == 2*r + 1 + dl.front()) dl.pop_front(); } for (int i = t.Values.Count; i < t.Values.Count + r + 1; i++) { u.Values[i - r - 1] = t.Values[du.front()]; l.Values[i - r - 1] = t.Values[dl.front()]; if (i - du.front() >= 2*r + 1) du.pop_front(); if (i - dl.front() >= 2*r + 1) dl.pop_front(); } }