views:

247

answers:

2

Does anyone know how I can compare the elements in an array with the adjacent elements?

For example, if I have an array:

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

Is there a way to cycle through each element and perform a logical test of whether the elements around it are equal to 1?

+8  A: 

Oops, it looks like someone is doing a homework assignment. Game of life maybe?

There are many ways to do such a test. But learn to do it in a vectorized form. This involves understanding how matlab does indexing, and how the elements of a 2-d array are stored in memory. That will take some time to explain in detail, more than I want to do at this exact moment. I would definitely recommend you learn it though.

Until then, I'll just suggest that if you really are doing the game of life, then the best trick is to use conv2. Thus,

A =[0     0     0     1     1     1     1     0
    0     1     1     1     1     1     1     0
    0     1     0     1     1     1     1     0
    0     1     1     1     1     1     0     0
    0     0     0     0     1     1     1     1
    1     1     1     1     1     1     1     1];

B = conv2(A,[1 1 1;1 0 1;1 1 1],'same')
B =
    1     2     4     4     5     5     3     2
    2     2     5     6     8     8     5     3
    3     4     8     7     8     7     4     2
    2     2     4     5     7     7     6     3
    3     5     6     7     7     7     6     3
    1     2     2     3     4     5     5     3
woodchips
Wow, I wish I had known about conv2 back in the days when I was doing finite difference methods.
celion
+1 - I think any other solution would be too convoluted. `conv2` is definitely the most elegant solution to the problem.
Jacob
Was that pun intentional? :)
celion
@Jacob: I agree. But just to answer the OP's question, maybe you should add `B==8` to detect elements whose 8-neighbors are all equal to 1. You can of course change the mask to check only for the immediate 4-neighbors (no diagonals)
Amro
Also if you want to handle edges correctly, you might want to use the border replication options of the imfilter function, something like: `B = imfilter(A,[1 1 1;1 0 1; 1 1 1],'replicate','same','conv')==8`
Amro
@celion: Yes, pun intended :)@Amro: That's an improvement, no doubt
Jacob
+5  A: 

Loren has recently posted about this very issue: http://blogs.mathworks.com/loren/2010/01/19/mathematical-recreations-tweetable-game-of-life/ - lots of interesting things can be learned by studying the code in that post and its comments

Yair Altman