[exporting coordinates of 2d and 2d CA] - A New Kind of Science: The NKS Forum

A New Kind of Science: The NKS Forum

Pages:1



exporting coordinates of 2d and 2d CA

(Click here to view the original thread with full colors/images)



Posted by: pietro

Hi, I study Architecture, I am looking for a way to export 2d or 3d steps in .txt format i.e ([0,0,0], …) and not [{0,0,0}, ….], I need the change of parenthesis because the program I will import the coordinates is not recognizing {0,0,0} as a point3D.
I need even to have every generation coordinates separated one from each other.
Do you know how I can do it?
would be cool even the list of coordinates of :
http://www.wolframscience.com/nksonline/page-892c-text
bottom page

Basically I am looking for something interesting that evolves in 3d like the FlatStickDemo.nb (protein) .
Do you know also where I can find the 2d CA application on a hexagonal lattice?

Best Pietro G.



Posted by: Jesse Nochella

you can convert a list {{0,0,0},{0,0,0}...} to ([0,0,0],[0,0,0]...) with something like:

StringReplace[ToString@#, {"{{" -> "([", "}}" -> "])", "{" -> "[", "}" -> "]"}] &

if the inital format is in [{0,0,0},{0,0,0}], then use:

StringReplace[#, {"[{" -> "([", "}]" -> "])", "{" -> "[", "}" -> "]"}] &

If you want to map that function to all parts of a list that contains your data, just put a /@ in between the two

StringReplace[#, {"[{" -> "([", "}]" -> "])", "{" -> "[", "}" -> "]"}] & /@
{"[{1,1,1},{1,1,2}]", "[{1,2,1},{1,2,2}]", "[{2,1,1},{2,1,2}]", "[{2,2,1},{2,2,2}]"}


and you get

{([1,1,1],[1,1,2]), ([1,2,1],[1,2,2]), ([2,1,1],[2,1,2]), ([2,2,1],[2,2,2])}

When exporting you can use the format "Table" like:

Export["/Users/Riggz/Desktop/test.txt", {"([1,1,1],[1,1,2])", "([1,2,1],[1,2,2])", "([2,1,1],[2,1,2])", "([2,2,1],[2,2,2])"}, "Table"]

and get a text file you get looks like:

([1,1,1],[1,1,2])
([1,2,1],[1,2,2])
([2,1,1],[2,1,2])
([2,2,1],[2,2,2])


Hope that helps.



Posted by: pietro

thank you for the precious help Jesse

in this forum sector at
http://forum.wolframscience.com/sho...s=&threadid=627
is an implementation on ca like on page 371 of NKS. I wonder if is possible to change the code so that
- is possible to print coordinates instead of the graph,
-and so that you can see more steps in the same graph of the same rule and not different rules at the same step (default 20) i.e. a range from step 1 to 15.
- print the coordinates for a step range.
-it seems the total possible rules are 16383 why this number and how to uncode a rule so that is clear how it works (i.e can be re-done by hand)?

Do you think the code is copyrighted?

That could be cool.
Thanks Pietro



Posted by: Jason Cawley

To get the display of successive steps from the same rule, use -


GraphicsArray[Partition[Map[GridHexCAGraphics,  
Map[Reverse, Table[CellularAutomaton[
{11022, {2, {{0, 2, 2}, {2, 1, 2}, {2, 2, 0}}}, {1, 1}}, 
CenterList[(41) {1, 1}, {{1}}], 20][[i]]
{i, 1, 20}]]], 4]] // Show


(Note that this needs functions in Ed's notebook, on the thread you linked to).

For the other patterns, substitute the other rule numbers in place of 11022.

As for the number of rules of this type, this is a hexagonal outer totalistic rule. That means it counts the number of black cells adjacent to the center cell, with six positions considered "adjacent". In the line above, that is specified in the bit that reads -
{{0,2,2},{2,1,2},{2,2,0}}

- which we call the "kernel" of the CA. The way to read it is, the 0s are cells that could be neighbors at range 1, but that aren't considered to be. Notice, a hex grid is specified by dropping 2 of the corners from the "diagonals count" case. The underlying data is held as a standard 2D matrix. Adjacency in the hex grid sense rrather than the square array sense follows from dropping opposite corners.

The 1 in the middle means the center cell acts as the least significant "digit" in the rule. All the 2s mean that the 2nd "digit" is a count of the number of 1s in those offsets from the center cell.

Ok, so how many possible rules of this type are there? There are 6 slots with 2s. Count the 1s in them. That can range from 0 to 6, 7 possible values. The middle cell doubles that to 14 - outer count 6 with center 1, outer count 6 with center 0, outer count 5 with center 1, etc, ending at outer count 0 and center 0. That is effectively the number of cases in the rule table. Each cell can take 2 values, so each of those cases, when it applies, could give a 0 or could give a 1 for the value of the center cell on the next step.

So there are 2^14 possible rules of this type. 2^14 is 16384. The rules range from 0 to 16383. You can find the form of the rule table for a given rule number, with -

IntegerDigits[11022, 2, 14]

{1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0}


You can split those up into what happens for different outer counts with -

Partition[%,2]

{{1, 0}, {1, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 0}}


Which you can read as "If the outer count is 6 and the center cell is 1, the next cell is 1. If the outer count is 6 and the center cell is 0, the next cell is 0. If the outer count is 5..."

As for "coordinates", you can get the underlying array of 0-1 data by just removing the graphics functions from the first line above, as follows -


Map[Reverse, Table[CellularAutomaton[{
11022, {2, {{0, 2, 2}, {2, 1, 2}, {2, 2, 0}}}, {1, 1}}, 
CenterList[(41) {1, 1}, {{1}}], 20][[i]], {i, 1, 20}]]


But that may not be what you mean by "coordinates"...



Posted by: pietro

Dear Jason,

Tell me if I am doing right:

- 1 in the "kernel" = range of the outer counted cells?
- {{1, 0}, {1, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 0}}
means:
outer count 6, 5, 0, alive>alive, dead>dead
outer count 4,1 alive>alive, dead>birth
outer count 3, 2 alive>dead, dead>dead

-And if I have an unbalanced kernel i.e. {0,0,0}, {2,1,2}, {0,2,0} I have 4 possible states *2 = 8
2^8 = 256 rule range is from 0 to 255
the position in the kernel is like the position in the matrix I assume?
000
212
022


If is like that I guess is clear,
And to get the rule from the reverse?
Let us say
{0,0,0,0,0,0,1,1,1,0,1,0,1,0}
2^^00000011101010
is rule 234?

-is it there a way to get another initial condition than the center cell active?

For the coordinates I mean instead of having a sequence of rows of 0 and 1s (that is in a way the graphic itself), a list of alive hexagons starting from the centre and telling in x and y what other are active (i.e. LifeStep[list_]).
Do you think that is possible?

thanks a lot for your clear reply. I really appreciate that.



Posted by: Jason Cawley

You can look in the help browser under CellularAutomaton to get a description of all its various arguments and their options. But focusing on the first argument, it specifies the rule to be used. In the case we are looking at, we have for example -

CellularAutomaton[
{11022, {2, {{0, 2, 2}, {2, 1, 2}, {2, 2, 0}}}, {1, 1}}, 


That all counts as the "first argument", despite how complicated it looks. To see why, notice it is all contained within curly brackets, and followed by a comma. Now I will explain each bit inside.

The first 11022 is the rule number. It's digit sequence in the appropriate base specifies which exact pattern of 0s and 1s etc go in which positions on the right hand sides of all its rule cases. Alone, it does not tell the function anything about what rule cases there might be. It just tells it how to fill them out, once it knows their form and number.

The next bit starts - {2, - that is the number of colors. Meaning, each position in the CA can take that number of distinct values. This naturally also determines the base for the enumeration, since each possible output color needs its own slot as it were. Notice that we are also now inside one curly brace.

Next comes the kernel, that little matrix, in double curlies. I've already sketched what it does, but will cover it in more detail below. Briefly, it is specifying the neighborhood and weights of cells in that neighborhood, as little offsets from the position of a notional center cell. With weight = 0 effectively meaning, not really in the neighborhood - since it means the cell value there will have no effect on anything. Understand that the notional center cell then scans across the entire array - every cell has its neighborhood on the same pattern. The kernel is that pattern, basically.

Then notice, we close that extra curly brace we were in. Thus the thing we just examined had the overall form "colors, kernel".

Then we have a comma and another item, a {1,1}. That specifies the range of the rule. The range is 1, in each of two dimensions. Notice that the kernel needs to match the dimensionality specified here, as the length of this little list of ranges - and the kernel's lengths in its various directions need to agree with the ranges. Range 1 in each of two dimensions means the kernel needs to be a two dimensional matrix with 9 entries, one for each potential neighbor at offsets up to 1, in the two directions, plus the center cell itself. A range 2 rule in 2D would need a {2,2} in this position. And a 5 by 5 kernel.

Now, within the kernel, what do the positions and values mean? The positions are offsets from a notional center cell as one scans across the whole array. The first entry is a -1, +1 position or upper left and corresponds to an x-1, y+1 position, added to the center cell's position. Then comes 0,+1. Then +1, +1. All as the first "line" of the matrix. The next line gives the cell immediately to the left, the center cell at offset 0,0 - or position 2,2 within the kernel itself - then the cell immediately to the right. The last line is the line of cells below the notional center, aka the ones with -1,-1, then 0,-1, and last +1,-1 offsets from the center cell.

What do the numbers in these positions mean? They say what bit (or "digit") in the rule that cell contributes to, effectively. The value there will be multipled by the cell value in that position - that is the mechanics of it. A 0 thus contributes 0 whatever the cell at that offset was. A 1, as you see for the center cell in an outer totalistic rule, means you add the value of the center cell. It therefore matters. If there is no other 1 anywhere in the kernel of weights, it matters as - the least significant digit in the case to be used. All the case numbers to be used will have the form, (lotsofotherstuff) + thiscell. And the last digit of the digit expansion of that number, will always just be thiscell. Which means, the case looked up in the rule to decide what to do, will depend on the value here - if this cell is 0, use this class of cases, if this cell is 1 use this other class, if this cell is 2 use a third class, etc.

What is the effect of having lots of 2s at various positions? Answer, a totalistic rule. Because now the values at all of these offsets will be lumped together into one sum, the whole thing then multiplied by 2. The "2th place" and above in the resulting case number, will be determined by the sum of the numbers in all the 2 positions. But the case used will not care, whether there is a 2 at position -1,-1 and a 1 at position 0,+1 or the reverse. It just sees "2+1 at positions of weight 2, so use case (2+1) x 2 = 6".

How do you specify a general rule using a kernel? What would it look like? Suppose you have a 9 neighbor rule, diagonals included. Every position would have to be a separate, independent digit. You'd have a kernel with cell weights -

{{k^8, k^7, k^6},{k^5, k^4, k^3},{k^2, k^1, 1}}

The k^8 weight would e.g. give the "256 ths place" in a two color rule, to determine which case to use. All told there would be k^9 cases, from 0 to k^9-1. (There is a special case short form for this, though, because it is often wanted - see the help documentation).

What does

{{1, 0}, {1, 0}, {1, 1}, {0, 0}, {0, 0}, {1, 1}, {1, 0}}

- mean as a (partition of a) rule number for an outer totalistic hex neighbor CA? The largest digit is what happens with outer total ("2ths place") of 6. The answer is {1,0}, depending on the other bit of the rule (the "1ths place"). So 6 1s around the center cell, and a 1 at the center cell, means the next cell is 1. 6 1s around the center cell, and a 0 at the center cell, means the next cell is a 0.

Then next {1,0} says the same thing happens if the outer total = number of neighboring cells that are 1, is 5 rather than 6.

Notice, if every pair read {1,0}, the CA state would never change. That is the identity rule. 1s at the center cell stay 1 regardless of the outer total. 0s stay 0.

Where in the rule above do we see things different from {1,0}? Well, outer total 4 and a 0 at the center cell, gives 1. So if a white cell has 4 black neighbors, it will become black. Same thing {1,1} if it has exactly 1 black neighbor.

That is the {1,1}'s. There are also two {0,0}'s. Those say, if a black cell has 3, or 2 black neighbors, it will become white.

Outer total 1 or 4 implies white becomes black. 2 or 3 implies black becomes white. Otherwise, the cell is unchanged.

"if I have an unbalanced kernel i.e. {0,0,0}, {2,1,2}, {0,2,0} I have 4 possible states *2 = 8 2^8 = 256 rule range is from 0 to 255"

Yes, that is the right number of rules - assuming the number of colors is 2. There are 3 2s, thus the outer total or 2th place can read any of {0,1,2,3}. The 1th place can read {0,1}. You have a mixed base number, with 4 possible values in the left position and 2 possible values in the right position. If you have 0-9 in 2 positions, you'd have 10x10 thus 0 to 99 or 100 possibilties. Since instead you have 0-3 and 0-1, you have 4x2 thus 0 to 7 or 8 possibilities. They are -

outer total 3 and center cell 1
outer total 3 and center cell 0
outer total 2 and center cell 1
outer total 2 and center cell 0
outer total 1 and center cell 1
outer total 1 and center cell 0
outer total 0 and center cell 1
outer total 0 and center cell 0

That is all of them. Each such case then needs an outcome. Since the outcome could be 0 or 1 for each of those cases, independently, you have 2^8 possible rules. The first has 0 for all 8 of those cases. The next has a 0 for seven of them, and a 1 in the very last case. The next has a 0 for the first 6, a 1 for the seventh case, and a 0 again for the last case. Etc. You count in binary up through that list of cases. When all of them yield a 1, you have 1,1,1,1,1,1,1,1 as the outcomes.

FromDigits[{1,1,1,1,1,1,1,1},2] 

Out[1] = 255


the position in the kernel is like the position in the matrix I assume?

000
212
022

Yes that's right. That kernel would "care" only about the cells right, left, below, and below and to the right - outer totalistically - and the center cell itself.

Can you see how to make a totalistic rule as opposed to an outer totalistic one? Hint - you want to treat the center cell the same as the others in its neighborhood.

And to get the rule from the reverse?
Let us say {0,0,0,0,0,0,1,1,1,0,1,0,1,0}
2^^00000011101010
is rule 234?

Yes, which you can get just with "FromDigits[xxx,2]"

"is it there a way to get another initial condition"

Sure, that is the second argument of CellularAutomaton. For a 2D, 2 color rule, that can be any array of 1s and 0s. You can make one of those with, for example -

Table[Random[Integer],{100},{100}]

- where Ed has -

CenterList[(41) {1, 1}, {{1}}]

- inside the CellularAutomaton function call.

"a list of alive hexagons starting from the centre and telling in x and y what other are active"

You want the positions of the 1s in the array at a given step. The function to use for that is Position. It returns the locations in some data structure were something matching any pattern you give, is found. The format is Position[expr, pattern]. You then want to apply this function to the array created at every step, with expr varying and the pattern fixed, as "1". I'll store the results in a variable, pos, and not display them immediately. To do that you write -

pos = Map[Position[#, 1] &,
   Map[Reverse, Table[CellularAutomaton[{
11022, {2, {{0, 2, 2}, {2, 1, 2}, {2, 2, 0}}}, {1, 1}}, 
CenterList[(41) {1, 1}, {{1}}], 15][[i]], {i, 1, 15}]]];


pos = tells Mathematica to store the result in that variable. The semicolon at the end of the line tell it not to display the result immediately (it would be too big to handle). The Map function tells it to apply some function to every element of some data structure - we say, "map function so-n-so over expr". The function we want to use in the first case is Position, looking for the pattern "1" - which will match literal 1s and nothing else. The # sign says, put here the argument of this function - it is like a generalized x and is called a "slot". The & says, treat the previous expression as a pure function, ready to be applied to anything but only "executing" when it is so applied.

The rest is just the data we had before, that previously we asked our graphics functions to display.

Now, suppose I want the positions for the first step. I just ask for the first element of the variable pos -

pos[[1]]

{{21, 21}}


Suppose you want everything in x-y coordinates that take that initial position as 0,0. Then you'd just want to shift every number in the whole list of values, downward by 21. You don't need to know anything about the data structure or tell Mathematica which elements to operate on. If you tell it to subtract an integer from a whole list of arrays, it does the obvious thing -

shifted = pos - 21;
shifted[[3]]

{{-2, -2}, {-2, 0}, {0, -2}, {0, 0}, {0, 2}, {2, 0}, {2, 2}}



All the values are there, but shifted[[11]] would look rather busy in a forum post...

As for Ed's snowflakes, certainly that notebook is his creation. If you have commercial uses in mind that would be derivative from it, contact us. We are reasonable people.

Fine questions. I hope this is useful.



Posted by: pietro

Dear Jason,
thank you very much for your fast and extremely clear reply.
I guess it tells everything is needed to be known on the subject!

Is a bit unclear the role of the 1 in the kernel, i.e. if I have a kernel such as
{0,0,1}, {1, 1, 0}, {0,2, 2} it tells me I have 255 rules?

You know the .nb for a random walk on an hexagonal grid?[0,1,0], [0,-1,0], [0.5,-0.866,0], [0.5, 0.866,0],[-0.5,-0.866,0],
[-0.5,0.866,0] are the possible steps?


It happens that if I export the coordinates in a 3d program and in the array I assign the position to an array of boxes, the ensemble of the cells appears squeezed on the x axis or if you prefer stretched on the y axis, I do not know why.

When I was talking about the copyright I was just asking because of all nks specification on book, that sounds complicate.
(i.e. if in my thesis I am talking about random walks, that does not mean I have to quote nks, sometimes the problem sounds like :who was born fist the egg or of the chicken?).
Basically I am thinking about including the snowflakes.nb in my diploma in architecture at the university that as said above (above) is a base in Antarctica, (I will even submit my diploma as a student competition entry). The program will be used to explain a possible method (rule based) to determine the evolution of a modular building (i.e. the base), the cool thing is that is neighbour dependent (as GOL), the concept is to offer a model that can be repeated, and is not the simple product of a one night architect’s dream.
It is not going to be the only one thing that will produce the building, but other scripts will in-form it in other steps. So I just wanted to know if for this purpose is ok if I use the .nb file (shall I quote the author, …?).

I am really amazed by nks, since I started to be obsessed with the necessity of justifying the design process.
I wonder if you know about courses in Itay as the one you are organizing in USA.
Best,
P.



Posted by: Jason Cawley

The 1s and 2s in the kernel are different digits of the rule cases, effectively. If you have several 1s, they will add up in the same totalistic fashion as 2s do in an outer totalistic rule. If you have all 1s, you will get a totalistic rule simply - the rule case used will just be a count of the black cells at the offsets with 1s in the kernel.

Note that 1s and 2s have this effect in 2 color rules. For higher color rules with colors = k, they'd need to be 1 and k. You can have a third "digit" in the rule cases as k^2, a fourth as k^3. In the limit you let each position in the kernel act as an independent digit, with no adding involved. Then for 5 neighbors, you have a kernel that has entries - k^4, k^3, k^2, k, 1. All of these are effecting which case to look up, how many cases there will be, whether one pattern does something different from another.

In the case you ask about, a kernel of {0, 0, 1}, {1, 1, 0}, {0, 2, 2}, you have 2 digits in the case table, as it were. The 1 digit is a sum of 3 positions each 0 or 1. It can therefore have values 0,1,2,3. The 2s digit is a sum of 2 positions each 0 or 1. It can have values 0,1,2. A mixed base number with 3 and 4 possible values means 12 total cases. Each of them can go to a 0 or to a 1. The total number of rules of this type is therefore 2^12 = 4096.

You call them a "lower total" and a "rest total" or something. By "lower total" I mean the 2 in your kernel, which is counting the number of black cells below or below and to the right of the center cell. The cases would be -

lower total 2, rest total 3 - goes to 0 or goes to 1?
lower total 2, rest total 2 - goes to 0 or goes to 1?
lower total 2, rest total 1 - goes to 0 or goes to 1?
lower total 2, rest total 0 - goes to 0 or goes to 1?
lower total 1, rest total 3 - goes to 0 or goes to 1?
...
lower total 0, rest total 0 - goes to 0 or goes to 1?

Those 12 cases are like digits, that each get a 0 or a 1. Take FromDigits of that list of 12 0s and 1s. That is your rule number. Notice, the bit of the kernel you label as "1s" rather than "2s", "counts fastest" or is innermost in the above enumeration.

Why do your exported array graphics look stretched? Because the simple way to impliment a hex grid in a matrix is to use a neighborness relation like -

1,1,0
1,1,1
0,1,1

That gets right whether a location is adjacent to another location, for a hex grid. But notice, the angles around that little matrix, between successive positions that have 1s, starting with straight up, are: 90 degrees to the right, 45 degrees, 45 degrees, 90 degrees, 45 degrees, 45 degrees. Not 60,60,60,60,60,60 as in a true hexagonal array. The "sides" with 90 degree angles look flatter, and the ones with 45 pointier and longer, while all the adjacency relations are correct.

A quick and dirty way to correct this is to imagine shoving alternate lines in the array one half a cell to the right, and where necessary wrap the array. I'll illustrate that idea with periods for "half cell spacers"-

.1,1,0
1,1,1
.1,1,0

Coding hexagonal graphics and the way they talk to matrix data can be fiddly...

On using a notebook from off the forum, for a typical academic use like citation in a thesis, you clearly want to cite, quote, and credit the author, in this case Ed Pegg, and cite the forum as the place you got it, e.g. with a link. There is an FAQ about how to cite things from the forum. With academic rather than commerical uses, just giving proper credit is the essential thing.

Incidentally, Ed is probably most well known for his site mathpuzzle.com which you can find here -

http://www.mathpuzzle.com/

I hope this helps.





Forum Sponsored by Wolfram Research

© 2004-2008 Wolfram Research, Inc. | Powered by vBulletin 2.3.0 © 2000-2002 Jelsoft Enterprises, Ltd. | Disclaimer
vB Easy Archive Final - Created by Xenon and modified/released by SkuZZy from the Job Openings