Evaluate neighboring nodes in a 2D lattice and change node value, as required

3 views (last 30 days)
Hello All,
Thanks to some excellent help from you, I have the code I need to create a 2-D lattice with nodes assigned random values of 1 or 2, plotted by color:
if true
% Generate the random values on the nxn, 2-dimensional lattice
% using X = randi(imax,sz1,...,szN) syntax.
n = 100;
P = randi(2, n+1, n+1); % 0:n -> n+1 elements
% Use linear indexing to find the values to plot.
isOne = P==1;
[i1,j1] = ind2sub(size(P),find( isOne)); % ones
[i2,j2] = ind2sub(size(P),find(~isOne)); % twos
% Create figure with axes on hold, so successive plot commands will add and
% not replace. Also add zero-based axis limits and make the axes square.
figure
axes('NextPlot','add','XLim',[0 size(P,1)-1],'YLim',[0 size(P,2)-1]);
axis square;
% Plot the figure. Subtract 1 to get zero-based ids.
plot(i1-1, j1-1, 'bo', 'MarkerFaceColor', 'b');
plot(i2-1, j2-1, 'ro', 'MarkerFaceColor', 'r');
end
The next step is to evaluate the 4 neighboring nodes: above, below, left, right (not diagonal). For the nodes at the corners and edges, they would only evaluate the 2 or 3 neighbors that they do have. If two or more of the neighboring nodes have a different value (eg, if the middle node = 1 and at least two of the neighboring nodes = 2, then the middle node will change its value to equal the prevailing "opinion." I need to iterate this process for a number of time steps (say 100) to observe the clustering effect.
The code I have so far doesn't work for the edge and corner nodes and I'm not sure it handles the nodes above and below, either.
if true
% Run the time steps to evaluate neighboring nodes and increment the
% counter if values are not equal. Change or retain value based on
% prevailing "opinion."
timeStep = 100;
count = 0;
for iteration = 1:timeStep
for node = 1:n+1
if [i1(node), j1(node)] ~= [i1(node-1), j1(node-1)];
count = count+1;
else count = count;
end
if [i1(node), j1(node)] ~= [i1(node+1), j1(node+1)];
count = count+1;
else count = count;
end
if [i2(node), j2(node)] ~= [i2(node-1), j2(node-1)];
count = count+1;
else count = count;
end
if [i2(node), j2(node)] ~= [i2(node+1), j2(node+1)];
count = count+1;
else count = count;
end
if count >= 2 && [i1(node),j1(node)] == 1;
[i1(node),j1(node)] == 2;
elseif count >= 2 && [i1(node),j1(node)] == 2;
[i1(node),j1(node)] == 1;
end
if count >= 2 && [i2(node),j2(node)] == 1;
[i2(node),j2(node)] == 2;
elseif count >= 2 && [i2(node),j2(node)] == 2;
[i2(node),j2(node)] == 1;
end
end
end
% Repeat the steps above to find and plot correct values
% Use linear indexing to find the values to plot.
isOne = P==1;
[i1,j1] = ind2sub(size(P),find( isOne)); % ones
[i2,j2] = ind2sub(size(P),find(~isOne)); % twos
% Create figure with axes on hold, so successive plot commands will add and
% not replace. Also add zero-based axis limits and make the axes square.
figure
axes('NextPlot','add','XLim',[0 size(P,1)-1],'YLim',[0 size(P,2)-1]);
axis square;
% Plot the figure. Subtract 1 to get zero-based ids.
plot(i1-1, j1-1, 'bo', 'MarkerFaceColor', 'b');
plot(i2-1, j2-1, 'ro', 'MarkerFaceColor', 'r');
end
If you have any ideas, I would greatly appreciate your help!

Accepted Answer

Sonam Gupta
Sonam Gupta on 9 Mar 2017
One of the ways in which you can achieve the desired result is by using the code below.
[row, col] = size(P);
result = zeros(row, col); % result matrix is created so that we can use previous values in one iteration
for iteration = 1:timeStep
% writing the new values in result matrix
for i = 1:row
for j = 1:col
count = 0;
if(validLeft(i, j,row, col))
if(P(i, j) ~= P(i, j-1))
count = count + 1;
end
end
if(validRight(i, j, row, col))
if(P(i, j) ~= P(i, j+1))
count = count + 1;
end
end
if(validTop(i, j, row, col))
if(P(i, j) ~= P(i-1, j))
count = count + 1;
end
end
if(validBottom(i, j, row, col))
if(P(i, j) ~= P(i+1, j))
count = count + 1;
end
end
if(count >= 2)
currentVal = P(i,j);
if(currentVal == 1)
result(i,j) = 2;
else
result(i,j) = 1;
end
else
result(i,j) = P(i,j);
end
end
end
%copying the result back to original matrix for next iteration
P = result;
end
Here, I have defined four functions validLeft, validRight, validTop, validBottom to check from coordinates values whether corresponding neighbor will exist or not. After that count is incremented if the value of current element differs from its neighbor. For elements having two or more than two different neighbors, updated value is stored in result otherwise previous value is retained. After one iteration you get the current updated values in result matrix which is then copied back to P, so that we can run the same logic for next iteration.
validLeft, validRight, validTop, validBottom are defined in separate function files with function definition as below.
function val = validLeft(x, y, row, col)
if( y == 1)
val = false;
else
val = true;
end
end
function val = validRight(x, y, row, col)
if( y == col)
val = false;
else
val = true;
end
end
function val = validTop(x, y, row, col)
if( x == 1)
val = false;
else
val = true;
end
end
function val = validBottom(x, y, row, col)
if( x == row)
val = false;
else
val = true;
end
end
Hope this helps.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!