Java中的数组修改(更改数组“分辨率”)

时间:2013-05-13 14:55:20

标签: java arrays

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

目的是加速FFT的计算。

它返回一个大小为y的新数组,每个元素是旧数组中“覆盖”的元素的平均值。例如,如果我有一个包含3个元素的数组w,并且想要创建另一个包含2个元素的数组z,则第一个元素将是: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;
}

2 个答案:

答案 0 :(得分: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);
    }
}

处理从[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);
    }
}

答案 1 :(得分: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.