2

我想创建一个函数来改变整数数组的大小,同时保持其“形状”。

目的是加快 FFT 的计算。

它返回一个新的大小数组,y每个元素是它在旧数组中“覆盖”的元素的平均值。例如,如果我有一个w包含 3 个元素的数组,并且想要创建另一个z包含 2 个元素的数组,则第一个元素是:z[0] = (1 * w[0] + 0.5 * w[1]) * 2 / 3,第二个元素是:z[1] = (0.5 * w[1] + 1 * w[2]) * 2 / 3。这有点像改变数组的“分辨率”。(当然,对于小数字,四舍五入可能会丢失信息,但我需要它来处理相当大的数字,而几个数字并不重要。)

感觉这是一个非常简单的问题,但我花了太多时间在静脉上。我确实有一些代码,虽然我让它几乎可以工作,但我认为我走错了路(行太多)。基本上,它遍历原始数组,并计算如何划分每个元素,并使用局部变量跟踪将其放置在何处。

此外,我的搜索都出现了诸如动态更改数组大小之类的东西,这不是我想要的。

所以,这是一个可能的骨架:

public int[] the_function (int[] w, int y) {
    int[] z = new int[y];

    // Some code looping through the array

    return z;
}
4

2 回答 2

1

所以你想对数组应用过滤器?这是一个幼稚的实现...我认为关键是要聪明地对过滤器进行编码...我将通过将其表示为一系列浮点数来表示我想应用于输出的原始值的百分比价值。当涉及到过滤器时,这是非常标准的。

public static int[] applyFilter( int[] from , float[] filter ) { 
    if (filter.length > from.lenth){
        throw new IllegalArgumentException("Filter to large to apply to array!");
    } 

    int [] to = new int[from.length + 1 - filter.length];

    for ( int i = 0; i < from.length + 1 - filter.length; i++) { 
        float newValue = 0.0f;

        for( int j = 0; j < filter.length; j++){
           newValue += filter[j] * from[i+j]; 
        }

        to[i] = Math.round(newValue);
    }
    return to;

}

并调用过滤器,就像您在问题中指定的那样......

public static void main (String ... args){
    float[] filter = new float[] { 0.66f, 0.66f }; 
    int[] from = new int[] { 1, 2, 3, 4, 5, 6};

    int[] to = applyFilter(from, filter);
    for (int i : to){
        System.out.println(i);
    }
}

处理 from[1] 被缩放 1/2 的情况,可以通过预处理数组然后再应用过滤器来处理。像这样:

 public static void main (String ... args){
    float[] filter = new float[] { 0.66f, 0.66f }; 
    int[] from = new int[] { 1, 2, 3, 4, 5, 6};

            // Preprocess to apply static scalars to the source array.
            int[] frompp = from.clone();
            frompp[1] = Math.round((float) from[i] / 0.5f);

    int[] to = applyFilter(from, filterpp);
    for (int i : to){
        System.out.println(i);
    }
}
于 2013-05-13T15:28:49.690 回答
0

您可以使用最小公倍数lcm来使用积分算术。您在最小公倍数的网格上映射/缩放源数组 (w) 和目标数组。

public static int gcd(int a, int b) {
    while (a != b) {
        if (a > b) a -= b; else b -= a;
    }
    return a;
}

public static int lcm(int a, int b) {
    return a * (b / gcd(a, b);
}

One then can achieve a high precision in averaging.
For image scaling ideal and fast.
For your purpose `double` math will do, I think, and saves a bit on index juggling.
于 2013-05-13T16:21:30.600 回答