浮点数数组重采样

3
我想要将一维浮点数数组“拉伸”成更大的数组。
//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}

新的数值应该从前一个数组值的线性插值计算而来,但我不知道如何实现。
有什么提示吗?

1
你的意思是多项式插值。它很容易编程。我发现牛顿插值法最容易编写(我曾在一次比赛中编写过它,不到15分钟就完成了)。 - amit
3
@amit: 这个例子中的插值对我来说看起来几乎是线性的。 - M Oehm
@MOehm 看起来对我来说是二次的,因为在 x=2,y=6.5 有一个局部最大值。 - amit
@amit:我提到的是采样点之间的插值,这是线性的。(我认为插值是分段的。在我看来,没有迹象表明OP想要数据点的多项式逼近。) - M Oehm
1
@DavidWatts 如果Mark Shevchenko的解决方案不起作用,我本来会尝试那个的。这个库看起来很不错,而且它是mono兼容的(我正在使用)。 - Chapapa
显示剩余2条评论
3个回答

2
如果源大小大于目标大小或者反之,则此方法适用。
    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;        
    }

1

假设源数组的长度为N,目标数组的长度为M,其中N < MN > 1

您可以通过以下公式计算源数组中第i个元素的新索引:

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

i==0时,j==0; 当i==N-1时,j==M-1。外部循环可以如下所示:
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
}

为了进行插值,您需要计算每对 (source[i - 1], source[i]) 的中间值。您需要存储先前的 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;
}

0
你可以使用 List<float>:
float[] initialArray = { 2.0f, 6.5f, 2.0f };
List<float> initialArrayTemp = ToListFloat(initialArray);

private List<float> ToListFloat(float[] array)
        {
            List<float> list = new List<float>();
            for (int i = 0; i < array.Length; i++)
            {
                list.Add(array[i]);
            }
            return list;
        }

现在你的数组是一个动态数组,你可以使用Insert()方法在任何位置添加新节点到你的Array中。

如果你需要一个新的静态数组,请使用以下代码:

float[] newInitialArray = initialArrayTemp.ToArray();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接