Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Float array resampling

I want to "stretch" a one-dimensional float array into a bigger array.

//expected behaviour

float[] initialArray = {2.0, 6.5, 2.0}
float[] biggerArray = resample(initialArray, 7 /*new size*/)

//output: {2.0, 3.5, 5.0, 6.5, 5.0, 3.5, 2.0}

The new values should propobaly be calculated from linear interpolation of the previous array values but i can't figure out how to achieve that.

Any hint ?

like image 889
Chapapa Avatar asked Dec 28 '25 17:12

Chapapa


2 Answers

This one works for both if source size is larger than destination and vice versa.

    private double[] Resample(double[] source, int n)
    {
        //n destination length
        int m = source.Length; //source length
        double[] destination = new double[n];
        destination[0] = source[0];
        destination[n-1] = source[m-1];

        for (int i = 1; i < n-1; i++)
        {
            double jd = ((double)i * (double)(m - 1) / (double)(n - 1));
            int j = (int)jd;
            destination[i] = source[j] + (source[j + 1] - source[j]) * (jd - (double)j);
        }
        return destination;        
    }
like image 194
user10736013 Avatar answered Dec 31 '25 08:12

user10736013


Lets the length of a source array is N, and the length of a destination array is M where N < M and N > 1.

You can calculate the new index of the source i-th element by the formula:

j = i * (M - 1)/(N - 1);

When i == 0 then j == 0; and when i == N - 1 then j == M - 1. The external loop can looks like this:

float[] source = ...;
float[] destination = ...;

destination[0] = source[0];
for (int i = 1; i < source.Length; i++)
{
    int j = i * (destination.Length - 1)/(source.Length - 1);
    destination[j] = source[i];
    // interpolation
}

To interpolation you should calculate intermediate values for each pair (source[i - 1], source[i]). You'll need to store previous value of j:

destination[0] = source[0];
int jPrevious = 0;
for (int i = 1; i < source.Length; i++)
{
    int j = i * (destination.Length - 1)/(source.Length - 1);
    Interpolate(destination, jPrevious, j, source[i - 1], source[i]);

    jPrevious = j;
}

private static void Interpolate(float[] destination, int destFrom, int destTo, float valueFrom, float valueTo)
{
    int destLength = destTo - destFrom;
    float valueLength = valueTo - valueFrom;
    for (int i = 0; i <= destLength; i++)
        destination[destFrom + i] = valueFrom + (valueLength * i)/destLength;
}
like image 22
Mark Shevchenko Avatar answered Dec 31 '25 07:12

Mark Shevchenko