MathGroup Archive 2001

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: weighting CA neighbors by distance

  • To: mathgroup at smc.vnet.net
  • Subject: [mg29886] Re: [mg29866] weighting CA neighbors by distance
  • From: Daniel Lichtblau <danl at wolfram.com>
  • Date: Tue, 17 Jul 2001 01:00:32 -0400 (EDT)
  • References: <200107140536.BAA18400@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

Brent Pedersen wrote:
> 
> I am doing some variations of cellular automata.
> Using only the actual value of the neighbors in determining the value of
> the current cell, I can use:
> 
> Apply[Plus, Map[RotateRight[mat1, ##] &, nbrs]];
> 
> where mat1 is the matrix of values for whatever the CA is modelling.
> and nbrs is a list of pairs (eg.
> {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},
> {1,1}} for the 8 cell moore neighborhood.)  defining the neighborhood I
> am interested in.
> 
> The line above sums all neighbors as they are but, I wish to weight the
> neighbors
> according to their distance (eg. {-1,-1} is farther away than {-1,0}
> when using the
> RotateRight function.
> I think I may be able to do this with ListConvolve, or Inner but I can't
> figure it out.
> Anyone have any ideas?

You can do this with ListCorrelate. We construct an example as below.

npoints = 7;
SeedRandom[1111];

In[19]:= InputForm[mat = Table[Random[Integer, 10], {npoints},
{npoints}]]
Out[19]//InputForm= 
{{8, 3, 9, 8, 7, 2, 9}, {7, 3, 3, 10, 9, 8, 0}, {3, 2, 1, 0, 4, 1, 7}, 
 {3, 0, 7, 0, 0, 5, 6}, {1, 0, 1, 6, 2, 1, 9}, {10, 3, 4, 7, 4, 3, 6}, 
 {2, 3, 7, 2, 8, 8, 10}}

Suppose you wish to weight adjacent elements with 1, and diagonal
neighbors with 1/2. We can use the kernel below for this.

kernel = {{1/2, 1, 1/2}, {1, 0, 1}, {1/2, 1, 1/2}};

as implicitly continued cyclicly.

In[25]:= InputForm[newmat = ListCorrelate[kernel, mat, {2, -2}]]
Out[25]//InputForm= 
{{29, 65/2, 30, 83/2, 41, 91/2, 65/2}, {49/2, 51/2, 59/2, 61/2, 69/2,
51/2, 
  38}, {47/2, 17, 37/2, 49/2, 43/2, 63/2, 43/2}, {19, 15, 6, 17, 15, 19,
27}, 
 {59/2, 17, 22, 35/2, 37/2, 27, 49/2}, {23, 45/2, 47/2, 25, 57/2, 67/2,
38}, 
 {83/2, 61/2, 57/2, 42, 31, 36, 73/2}}

If instead you want to regard the matrix as implicitly bordered by
zeros, you can do that as follows.

In[27]:= InputForm[newmat2 = ListCorrelate[kernel, mat, {2, -2}, 0]]
Out[27]//InputForm= 
{{23/2, 25, 41/2, 32, 28, 57/2, 6}, {33/2, 51/2, 59/2, 61/2, 69/2, 51/2, 
  51/2}, {27/2, 17, 37/2, 49/2, 43/2, 63/2, 27/2}, 
 {5, 15, 6, 17, 15, 19, 22}, {29/2, 17, 22, 35/2, 37/2, 27, 17}, 
 {15/2, 45/2, 47/2, 25, 57/2, 67/2, 53/2}, {29/2, 19, 14, 26, 19, 26,
31/2}}

Getting the various parameters exactly right for your intended use may
take some fiddling, so don't assume either of the above is quite what
you need. But I think they should put you within shouting distance, and
I tested that the cyclic case, with ones for all weights except at the
center, agrees with your code on this example.

I illustrated with exact matrices and weights, and that may be
appropriate for cellular automata in 2D. Note that for many purposes,
e.g. image processing with values in a continuum, it will be faster to
use approximate arithmetic.


Daniel Lichtblau
Wolfram Research


  • Prev by Date: Re: inability to pass argument(s) to functions..
  • Next by Date: Re: Re: about ConstrainedMin
  • Previous by thread: weighting CA neighbors by distance
  • Next by thread: Re: weighting CA neighbors by distance