Skip to content

Instantly share code, notes, and snippets.

@mikeminutillo
Created May 23, 2018 03:48
Show Gist options
  • Save mikeminutillo/f52a5f87a6672ff824142848b97566ea to your computer and use it in GitHub Desktop.
Save mikeminutillo/f52a5f87a6672ff824142848b97566ea to your computer and use it in GitHub Desktop.
Linearly Interpolate values in an enumerable stream of decimals
public static class Ext
{
private static IEnumerable<decimal> LinearInterpolate(decimal lowerBound, decimal upperBound, int pointCount)
{
var gradient = (upperBound - lowerBound) / (pointCount + 1);
for(var i = 1; i <= pointCount; i++)
{
yield return lowerBound + gradient * i;
}
}
public static IEnumerable<decimal> Interpolate(this IEnumerable<decimal> original)
{
var zeroCount = 0;
var previousValue = 0m;
var enumerator = original.GetEnumerator();
// Strip leading 0s
while(enumerator.MoveNext())
{
if(enumerator.Current == 0)
{
yield return 0;
}
else
{
previousValue = enumerator.Current;
yield return enumerator.Current;
break;
}
}
// Interpolate 0s
while(enumerator.MoveNext())
{
if(enumerator.Current == 0)
{
zeroCount++;
}
else
{
if(zeroCount > 0)
{
foreach(var item in LinearInterpolate(previousValue, enumerator.Current, zeroCount))
{
yield return item;
}
zeroCount = 0;
}
yield return enumerator.Current;
previousValue = enumerator.Current;
}
}
// Strip trailing 0s
for (var i = 0; i < zeroCount; i++)
{
yield return 0;
}
}
}
var points = new decimal[] { 0m, 0m, 10m, 0m, 7m, 5m, 3m, 0m, 0m, 7m, 1m, 2m, 3m, 0m, 0m };
points.Interpolate();
// 0
// 0
// 10
// 8.5
// 7
// 5
// 3
// 4.333333
// 5.666666
// 7
// 1
// 2
// 3
// 0
// 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment