Looking for an efficient way to update multi-dimensional arrays

Viewed 88

I update the values of a multi-dimensional array (Y[i][t][k]). Since the update needs to be done over many iterations, the runtime of this part of the code is really important. I was wondering if anyone knows how to do this in a more efficient way.

Below is the part that needs to be updated.

double [][][] Y=new double [a.length][b.length][c.length];
for(int i=0;i<a.length;i++){
 for(int j=0;j<b;j++){
  for (int k=0; k<c.length; k++){
    if(i==w && j==r && k==u){// w, r and u can have any value.
      Y[i][j][k]=g;
     }else{
      Y[i][j][k]=f; 
     }
    }
  }
}

Note that:

    a is int [][].
    b is int.
    c is int [][].
    q is double.
    YIN is double [][][].
    F is double.
    g=q*YIN[i][j][k]+(1-q)*(Y[i][j][k]-F)
    f=q*YIN[i][j][k]+(1-q)*(Y[j][j][k])
2 Answers

You are setting every element of a region of your multidimensional array, at a cost proportional to the number of elements set, so there's no reason to think that you can do it asymptotically better. However, it is likely that you can get some speed increase by using bulk-operation methods, and by handling the special case outside the loop instead of testing for it on every iteration. For example,

for (int i = 0; i < a.length; i++) {
    for (int j = 0; j < b.length; j++) {
        Arrays.fill(Y[i][j], 0, c.length, f);
    }
}

if (c.length > 10) {
    Y[0][0][10] = g;
}

Of course, this assumes that f is a constant expression, or at least that every evaluation of it is equal to every other (in the sense of the == operator) and produces no side effects. In that case, it is probably a bit better yet to engage bulk copying in place of bulk setting where you can do so:

for (int i = 0; i < a.length; i++) {
    Arrays.fill(Y[i][0], 0, c.length, f);
    for (int j = 1; j < b.length; j++) {
        System.arraycopy(Y[i][0], 0, Y[i][j], 0, c.length);
    }
}

if (c.length > 10) {
    Y[0][0][10] = g;
}

If expression f does not satisfy the requirements above, then the best you can do might be just to lift the special case out of the loop, without changing anything else. For some expressions f and / or g, even that might not be possible, in the sense that it could produce an inequivalent result. For example, this would be the case where one or both are stateful in some relevant way, such as by closing over a counter.

As I understand from your code, your goal is to set Y[0][0][10] to g and other elements to f.

So how about forgetting about crazy loops and doing like the following code ?

Arrays.fill(Y, f);

Y[0][0][10] = g;
Related