1
votes

I have a matrix of zeros and ones. Each cell with a one value represents a non empty cell. The cells with the ones is kept in a vector with the coordinates. I'm iterating through the list and move each element randomly to one of its free neighboring cells.

Is there a way to do this with vector operations?

Thanks

2
Can dots move on top one another, or is there repulsion? Vector operations means that you need to be able to move in parallel. - Jonas
They can't be on top one another. Only one dot per cell :| - Guy Wald
since this can be implemented in a 1-D loop, I would assume that a for loop would be faster than a "vectorized" arrayfun. - bla
Have you profiled your code to identify where the bottleneck is? Such a small problem should be pretty fast, as long as you only represent the points by their coordinates, instead of attempting to create the zero and one matrix at each iteration (which is completely unnecessary, and which can be a vectorized operation at the end of the simulation) - Jonas

2 Answers

1
votes

Here's an attempt, not the most elegant or efficient one, but still it should work.

first I assume you have the x,y coordinates of your non empty cells, something like

c=[x y];

The relative positions of the 8 nearest neighbors (n.n.) in a 2D array are given by:

nn=[1 1;1 -1;-1 1;0 -1;-1 0;0 1;1 0;-1 -1];

Let's take all possible permutation of each x,y coordinate in c around its n.n.

permc=bsxfun(@plus,repmat(c,[1 8]),nn(:)');

Now set a vector of random n.n. out of the 8 options for each x,y coordinates:

ri=randi(8,numel(x), 1);

and use it to select random new coordinates

new_c= [ permc(sub2ind(size(permc), (1:numel(x))', 2*ri-1 )) , ...
         permc(sub2ind(size(permc), (1:numel(x))', 2*ri))];  

Issues:

  • The code doesn't check if there is a n.n. that is not free, not hard to solve having info of c and permc at hand.

  • The code doesn't care that a point is on the edge of the array, so it can select a coordinate that is either 0 or one larger than the size of the array. Again, permc has the info to tackle this case and it can be treated separately in several ways.

That's the jist.

0
votes

Probably, but I think it would be quite tricky to write. You'd have to be careful to prevent two "dots" from moving into the same empty location at the same time.

Looping over the vector and dealing with one dot at a time seems far easier. What's your reason for wanting to do this with vector operations? If you're looking to make your code faster, post your code and ask for suggestions.