3
$\begingroup$

Suppose we have a 2D grid, divided by cells, and that we assign people to each cell. Each person has 4 neighbors, one in the cell above, another in the cell below, and neighbors in the cells to the left and to the right, respectively. Then, let each person in its cell be assigned a random number. I then want each person in its cell to look at what their neighbors assigned number is, and out of the 4 neighbors that they choose the max of that group of people. I want to do this for all cells. Lets say we had a square divided into 9 cells.

I am trying to replicate the results of a paper (link provided below), but with an easier structure (because I dont know how to do this in Mathematica). The authors converted their 2D grid into a torus, so that those cells in the edges of the 2D space can also have four neighbors (a more detailed explanation is on the link provided below, page 5, title 2.2).

How could I ask Mathematica to compute the max for each cell's neighbors?

Article: http://www.feem.it/userfiles/attach/Publication/NDL2005/NDL2005-078.pdf

$\endgroup$
  • 1
    $\begingroup$ I will do that. I am kind of newbie to Mathematica but I will do my best to contribute. $\endgroup$ – Goose Mar 7 '15 at 8:28
  • $\begingroup$ Does the max include the member and its neighbors, or just the neighbors? $\endgroup$ – ciao Mar 7 '15 at 9:16
2
$\begingroup$
ClearAll[maxF];
maxF = Function[{mat}, Block[{cm = {{0, 1, 0}, {1, 0, 1}, {0, 1, 0}}},
    Developer`PartitionMap[Max[cm #] &, mat, {3, 3}, 1, 2, mat]]];

Example:

SeedRandom[0];
mat = RandomInteger[10, {5, 5}];
Row[Labeled[MatrixForm@#, #2, Top] & @@@ {{mat, "mat"}, {maxF@mat, "maxF@mat"}}]

enter image description here

Row[Labeled[MatrixPlot[#, ImageSize->300], #2, Top] & @@@ {{mat, "mat"}, {maxF@mat, "maxF@mat"}}] 

enter image description here

SeedRandom[0];
mat = RandomReal[1, {10, 10}];
ListAnimate[MatrixPlot[#, ImageSize -> 300, ColorFunction -> "TemperatureMap"] & /@ 
            NestList[maxF, mat, 20],  DefaultDuration -> 10]

enter image description here

$\endgroup$
  • $\begingroup$ Wow! Thanks! This is really good! $\endgroup$ – Goose Mar 7 '15 at 21:10
  • $\begingroup$ @Goose, my pleasure. Thank you for the Accept. $\endgroup$ – kglr Mar 7 '15 at 21:22
4
$\begingroup$

With kguler's example matrix

SeedRandom[0];
mat = RandomInteger[10, {5, 5}];

You could do this:

MapThread[Max, RotateRight[mat, #] & /@ {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}, 2]

(* {{ 8, 10,  8, 10, 10},
    {10, 10,  5,  8,  2},
    {10,  7, 10, 10, 10},
    {10, 10, 10, 10, 10},
    {10,  8, 10, 10, 10}} *)

Or if all entries are positive you could use ListConvolve like this:

ListConvolve[{{0, 1, 0}, {1, 0, 1}, {0, 1, 0}}, mat, {2, 2}, mat, Times, Max]

(* {{ 8, 10,  8, 10, 10},
    {10, 10,  5,  8,  2},
    {10,  7, 10, 10, 10},
    {10, 10, 10, 10, 10},
    {10,  8, 10, 10, 10}} *)
$\endgroup$
  • $\begingroup$ Now I see why ListConvolve did not work when i tried:) +1 $\endgroup$ – kglr Mar 7 '15 at 11:40
  • $\begingroup$ Super elegant. +1 $\endgroup$ – ciao Mar 7 '15 at 21:43
3
$\begingroup$

I think this is what you're after:

maxed = With[{z = ArrayPad[#, 1, #]}, 
    ArrayPad[ReplacePart[z, {i_, j_} /; i > 1 && i < Length@z && j > 1 && j < Length@z[[1]] :> 
       Max[z[[i, j]], z[[i - 1, j]], z[[i + 1, j]], z[[i, j - 1]], z[[i, j + 1]]]], -1]] &;

test = RandomInteger[{1, 5}, {5, 5}];
test // MatrixForm
maxed@test // MatrixForm

enter image description here

enter image description here

If the member itself is not to be included, remove the first item in Max.

$\endgroup$
  • $\begingroup$ Thank you so much! I tried for hours and could not come up with a code for this. Thanks again! $\endgroup$ – Goose Mar 7 '15 at 21:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.