1

I have a very big array with dimensions (nr,nc) row and cols. I iterate over this array to calculate the function "fun" from a constant entry of this array (px,py). The calculation for this function is only relevant in a constant area (distance d) around this point. So my goal is to speed up the code and only calculate in this circle around the point (px,py).

int i;
int j;
for(i=0; i<nr; i++){
    for(j=0; j<nc; j++){
        *(arr_stg+i*nc+j) = fun(i,j,px,py);
    }
}

I also have a function to calculate a boolean "mask" (I don't know if that's the right word for this). I calculate it with the euclidean distance around a sample point. So for a given distance, i.e. 4 I calculate this kind of mask-array:

0 0 0 0 1 0 0 0 0
0 0 0 1 1 1 0 0 0
0 0 1 1 1 1 1 0 0
0 1 1 1 1 1 1 1 0
1 1 1 1 1 1 1 1 1
0 1 1 1 1 1 1 1 0
0 0 1 1 1 1 1 0 0
0 0 0 1 1 1 0 0 0
0 0 0 0 1 0 0 0 0

The exact form (if it's a zero or a one) is not relevant here, should be working for any kind of this nxn-"masks".

My question is, how do I have to change the two for loops to iterate only over this mask around the given point in a way that I get a faster code then just calculate it for all i,j's of the big array and don't use the ones with a distance greater than the given one.

10
  • You can always use BFS or DFS algorithms from your (px, py) point. This way you will process only points inside the circle. And you won't even need to precalculate and save mask and iterate over the whole array. Commented Oct 17, 2019 at 10:14
  • 1
    With your mask, you can use a simple if statement. if(mask[i][j]) *(arr_stg+i*nc+j) = fun(i,j,px,py); Commented Oct 17, 2019 at 10:15
  • What is arr_stg definition ? nc ? px? py? iterate only over this mask - in what way or does it doesn't matter which point is the first? Commented Oct 17, 2019 at 10:15
  • 1
    If your mask is sparse (has only few 1's in relation to the number of 0's), it might be better to have a list of coordinate pairs over which to iterate or have a smaller mask with a bounding box. Commented Oct 17, 2019 at 10:17
  • 2
    instead of pre-calculating the mask array, you can pre-calculate the pairs of indexes (as a single-dimensional array) and then use them in a single loop to calculate the fun. Commented Oct 17, 2019 at 10:40

1 Answer 1

1

Generally, if you have a mask of size d centered around a point (xc, yc), you need to iterate through the ranges of:

(xc - d) <= x <= (xc + d)
(yc - d) <= y <= (yc + d)

Or, if you have a mask array MASK[2*d+1, 2*d+1], then you would simply end up with:

// iterate through MASK dimensions
for (var mi = 0; mi < 2 * d + 1; mi++)
   for (var mj = 0; mj < 2 * d + 1; mj++)
   {
        // move to the right location
        var x = xoffset + mi;
        var y = yoffset + mj;

        // do something with (x, y) and MASK[mi, mj]
   }

You need to make sure, however, that xoffset + mi and yoffset + mj does not exceed the bounds.

Sign up to request clarification or add additional context in comments.

2 Comments

I think that you gave me the right idea here, but your code isn't exactly doing what I want or what you stated before. You are iterating over the mask but starting with the offset-point at (0,0) of the max and not the mid-point of the mask. I think mi and mj should start at -d and go up to d. Maybe that's the best solution. But I still would have a bit of an overhead because of the iterations trough the zeros of the mask. Maybe that's good enough.
Well, the range is centered around (xc, yc), but there are no negative indices in C arrays. My assumption was that the mask array is smaller than the actual array and contains just the mask, in which case you would need to offset it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.