Skip to content

RingBuffer.Resample repeats source elements unevenly because of banker's rounding, and its docs promise linear interpolation it doesn't do #88

Description

@matt-edmondson

What's wrong

The XML doc on RingBuffer<T>.Resample (Containers/RingBuffer.cs:237) says it "preserves the data pattern by applying simple linear interpolation". It also says that when upsampling, new values are created between existing ones.

The implementation (RingBuffer.cs:274-275) does not interpolate. It picks the nearest existing element:

double oldIndex = (double)i * (oldCount - 1) / Math.Max(length - 1, 1);
int index = (int)Math.Round(oldIndex);

Nearest-neighbour is unavoidable for a generic T. The problem is Math.Round, which defaults to MidpointRounding.ToEven. For common ratios the mapping often lands exactly on .5, and every such tie goes to the even index. Some source elements then appear three times while their neighbours appear once, which distorts the resampled shape.

Reproduction (verified)

new RingBuffer<float>([0, 10], 2).Resample(3);        // [0, 0, 10]
new RingBuffer<float>([0, 1, 2, 3, 4], 5).Resample(9); // [0,0,1,2,2,2,3,4,4]
new RingBuffer<float>([0, 1, 2], 3).Resample(5);       // [0,0,1,2,2]

In the 5→9 case, element 2 appears three times while elements 1 and 3 each appear once.

The existing test ResampleWithSpecificValues_CorrectlyInterpolates (Containers.Test/RingBufferTests.cs:221-235) has a comment saying it expects 10, 15, 20, 25, 30. The actual output is 10, 10, 20, 30, 30. The test passes only because it asserts indices 0, 2 and 4.

Why it matters

Resample is offered for resampling time series and changing sample rates. A caller who relies on the documented interpolation, or at least on even duplication of samples, gets a distorted signal with no error.

Suggested fix / acceptance criteria

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions