[Date Index]
[Thread Index]
[Author Index]
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**
| |