Jason Cawley
Wolfram Science Group
Phoenix, AZ USA
Registered: Aug 2003
Posts: 712 
The idea of a continuous valued CA is that you store a machine precision number (or an arbitrarily higher precision if you like) at each cell location. Then your updating rule must provide some method of generating the next real number value for the cell from the values of its neighboring cells.
That is, it must be a mapping that takes a vector of real numbers to a single real number. The simplest case is a function like Mean that just averages the values of the cells in its neighborhood before  this would yield diffusion behavior, for example. But the mapping can be any function of N reals, with N given by the neighborhood size, and it can depend on the position of each prior number.
In the discrete valued case we are doing the same thing, we are just allowing the mapping to be an arbitrary one, and we can enumerate all the possible combinations of neighborhoods, and assign each one a specific subsequent value. We are still just taking a vector of previous numbers, position perhaps mattering, and mapping that vector to a next value number. We've restricted the set of input and output numbers to integers less than some number of colors, that's all.
Arbitrary maps from N reals to 1 real are uncountable. We don't need all that. We can restrict to continuous functions, for one, for all the cases we'd actually care about. If there is a modeling idea of empirical domain, it typical imposes additional restrictions on the sorts of function that make sense (symmetric ones, for example, or maps that preserve some invariant quantity, or both).
To implement continuous valued functions in Mathematica, you use the functional form of the CellularAutomaton builtin function. The rule specification in that form, instead of being a number, looks like this 
{function, {}, rangespec}
rangespec determines the dimensions of the CA as well as the size of the neighborbood. For example, a 1 would give a range 1, 1D CA, while {1,1} would give a range 1, 2D CA.
function needs to be a Mathematica function that accepts a neighborhood of the proper shape and returns a new centercell value. Thus for a 2D CA, it would take as input a 3 by 3 matrix of site values, and needs to return a single value. Here is a really simple example, that just smashes out the neighborhood shape and returns the average value within it, as the new value of the center cell on the next step 
MyFunction[neighborhood_]:= Mean[Flatten[neighborhood]]
The initial condition has to be the right shape for a CA of that dimensions. Here, a 2D array of real numbers. We'll start with just a random array of values between 0 and 1 
MyInitial = RandomReal[{0,1}, {10,10}]
Then the evolution function call itself would look like this (storing the results in a variable, MyData 
MyData = CellularAutomaton[{MyFunction[#]&, {}, {1,1}, MyInitial, 1][/m]
Notice that you get 2 steps, the initial and the new one, and that each is a 10 by 10 array. You can display them with ArrayPlot. Let's do a longer evolution and display the results, with a few options to make it prettier. We don't want to see the raw data though, so we put a semicolon behind the data generating call to just store the output in the variable without showing it 
MyData = CellularAutomaton[{MyFunction[#]&, {}, {1,1}, MyInitial, 7]; ArrayPlot[#, Mesh > True, ColorFunction > "BlueGreenYellow", ColorFunctionScaling > False] & /@ MyData
You can see the initial differences all rapidly "wash out", leaving a minor persistent difference in site values across the array, but one declining in total amplitude. If you look at 
Total[Flatten[#]]&/@MyData
 you see the total value has been preserved, a necessary consequence of the function chosen.
Obviously, a different function would produce a different behavior. When working with the functional form of CellularAutomaton, the rest of the code is entirely modular, so you just swap out or redefine MyFunction, and see the new behavior of your new updating rule.
For example, you might try 
MyFunction[neighborhood_] := 2*Mean[Delete[Flatten[neighborhood], 5]]  neighborhood[[2, 2]]
In that one, the center cell contributes negatively, all the other cells contribute positively. Again the total value is preserved, but now each cell's "contents" effectively try to "empty" at each step, into the surrounding cells. This yields "scroll" patterns of positive and negative site values across space at each point in time and high amplitude, singletimestep oscillating changes at each site through time (so it looks unchanged on alternate time steps), but rapidly stabilizes on such an oscillating pattern.
I hope this helps.
Report this post to a moderator  IP: Logged
