Message Boards Message Boards

Waiting times between cyclical changes in matrix for CellularAutomaton

Hi all,

I have recently been learning my way around the CellularAutomaton function and I'm seeking assistance in calculating the waiting times between changing events at each time step.

The CA is setup such that the result is a list, of length t, of n by n (I'm using n=100) matrices, ie. one for each time step. Each matrix is filled with 0,1,2's and is updated at each time step according to certain rules, which change the 0,1,2 to a different 0,1,2 depending on the rule.

What I am trying to do, is note the time taken (delta t) for a value 2, to cycle back to a value 2. i.e. to calculate the waiting time between the 2's occurring.

I have had a few attempts at doing so but seem to keep hitting the same dead end, or having very poor efficiency in the code.

My idea was the find the {i,j} position of all the 2's in all of the matrices, put them into a dataset with columns "t ->{ t1 , t2,...,} , "i,j" -> { i, j } and to combine only the values for t.

The counts of 2's are on the order 10^6, as I'm taking 3000 time steps for one sample of the CA result.

Rather than iterate over each position value given, is there an easier way to do this? This was my initial code:

For[ii = 1, ii < t + 1, ii++,

  pos = Position[result3[[ii]], 2];

  For[i = 1, i < Length[pos] + 1, i++,

   If[MemberQ[wait[[All, 1]], pos[[i]]],

    (*If the site for run y is in the dataset, 
    append the "t" to add in the time step that the 2 occurs*)
    pos1 = Position[wait[All, 1], pos[[i]]][[1]][[1]];
    wait = 
     ReplacePart[
      wait, {pos1, "t"} -> 
       Flatten[Join[{Normal[wait[pos1, "t"]]}, {ii}]]];,

    (*add a new row to the dataset*)
    wait = Append[wait, <|"i,j" -> pos[[i]], "t" -> ii|>]
    ]
   ](*end for i*)

  ];

And that was far too inefficient. Then I tried datasets (I'm fairly new to them)

wait = Dataset[
   Flatten[Table[<|"i,j" -> {i, j}, "t" -> {0}|>, {i, 100}, {j, 
      100}]]];
waittimes = Dataset[{<|"run" -> {}, "wt" -> {}|>}];

two = Table[Position[result3[[ii]], 2], {ii, t}];
For[ii = 2, ii < 3, ii++,

  pos = Position[wait, #] & /@ two[[ii]];

  (*Append the "t" column to add in the time step that the 2 occurs*)


  wait = ReplacePart[
    wait, {{pos[[All, 1, 1]], "t"} -> 
      Flatten[Join[{Normal[wait[pos[[All, 1, 1]], "t"]]}, {ii}]]}];

  ];

This also didn't go very well..

Any assistance is greatly appreciated! <3

POSTED BY: Jon Rickett
2 Replies

Thanks Michael! That's worked a treat.

POSTED BY: Jon Rickett
Posted 4 years ago

Hello Jon, I would try to do it the following way:

ndim = 100;
tdim = 50;
data = RandomChoice[{0, 1, 2}, {tdim, ndim, ndim}];
Dimensions[data]

First I created test data which should resemble your data. Next I transform the data into a matrix with dimensions 10000 x tdim:

data2 = Flatten[Transpose[data, TwoWayRule[1, 3]], 1];
Dimensions[data2]

Now each matrix element of the former ndim + ndim matrix corrsponds to a row index (for 100*100 this will be 10000 row indices) , the columns represent the t-axis. For each row element the position of "2" along the t axis is determined, which results for each matrix element in a list. If in a t vector there are less than two occurences of "2", this vector is ignored:

data3 = DeleteCases[
   Flatten[Map[Position[#, 2] &, data2], {1, 
     3}], _?(Length[#] < 2 &)];

Finally the differences of index positions is determined for each remaining list:

Map[Differences[#] &, data3] // Flatten // Histogram

For the test data I casted the result in a histogram which shows the distribution of distances between "2"s.

Not sure whether what I described is what you intended to do, so please check yourself. Regards, Michael

POSTED BY: Michael Helmle
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract