walking our grid

Last time we defined a grid structure. This time we are going to walk it (perhaps emulating what happens if we have a single ant leaving a scent trail as it walks).
Let's jump right into the code:

First, we add this line in to the learn a grid for loop from yesterday:
c.learn("cell-value",elt,"0")
ie, define the value 0 for every location in our grid.

Then some code to output our grid:
def string_grid(c,grid):
  I = int(grid.apply_op(c,"dim-1").label)
  J = int(grid.apply_op(c,"dim-2").label)

  s = ""
  s += "I: " + str(I) + "\n"
  s += "J: " + str(J) + "\n"

  for j in range(1,J+1):
    s += str(j).ljust(4)
    for i in range(1,I+1):
      x = ket_elt(j,i)
      value = x.apply_op(c,"cell-value").the_label()
      if value == "0":
        value = "."
      s += value.rjust(3)
    s += "\n"
  return s
Then we want to implement something like this to walk the grid, though that would require the non-existent swc language (because of the repeat n: loop) that we intend as a wrapper around the current BKO:
next |*> #=> pick-elt (SW |_self> + S |_self> + SE |_self>)
|cell> => |grid: 1 22>
repeat n:
  cell-value "" |cell> => arithmetic(cell-value |_self>,|+>,|1>)
  |cell> => next "" |cell> 
Instead we have this python:
# set context: 
C = context_list("walking a grid")

# create a 20*20 grid:
create_grid(C,20,20)

# define the grid ket:
grid = ket("grid")

# number of steps:
n = 20

# the seed/starting cell:
seed_cell = ket("grid: 10 10")

# define some cell propagation rules:
C.learn("SW-S-SE","*",stored_rule("pick-elt (SW |_self> + S |_self> + SE |_self>)"))
C.learn("W-SW-S-SE-E","*",stored_rule("pick-elt (W |_self> + SW |_self> + S |_self> + SE |_self> + E |_self>)"))
C.learn("W-SW-S-SE-E-NE","*",stored_rule("pick-elt (W |_self> + SW |_self> + S |_self> + SE |_self> + E |_self> + NE |_self>)"))
C.learn("NW-W-SW-S-SE-E","*",stored_rule("pick-elt (NW |_self> + W |_self> + SW |_self> + S |_self> + SE |_self> + E |_self>)"))
C.learn("NW-W-SW-S-SE-E-NE","*",stored_rule("pick-elt (NW |_self> + W |_self> + SW |_self> + S |_self> + SE |_self> + E |_self> + NE |_self>)"))

# define our walk_grid() function:
def walk_grid(C,seed_cell,next,steps):
  C.learn("next-value","*",stored_rule("arithmetic(cell-value |_self>,|+>,|1>)"))

  cell = seed_cell
  for k in range(steps):
    next_value = cell.apply_op(C,"next-value")
    C.learn("cell-value",cell,next_value)
    cell = cell.apply_op(C,next).ket() 


# walk the grid, noting the data is all stored in our context variable C:
# and note in this case we use the "SW-S-SE" propagation rule.
# ie, randomly pick from SW, S and SE.
walk_grid(C,seed_cell,"SW-S-SE",30)

# print it out:
print(string_grid(C,grid))
And we get something like this:
1     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
2     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
3     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
4     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
5     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
6     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
7     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
8     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
9     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
10    .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .  .
11    .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .  .
12    .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .  .
13    .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .  .
14    .  .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .
15    .  .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .
16    .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .  .
17    .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .  .  .
18    .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .  .  .
19    .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .  .
20    .  .  .  .  .  .  .  .  . 20  .  .  .  .  .  .  .  .  .  .
Note we ran into the wall because we are using a finite universe model. With torus model it would wrap around to the top of the grid. To see how these alternatives are implemented see the ket_elt_bd(j,i,I,J) code from yesterday.

Next, try another example:
-- a new seed_cell:
seed_cell = ket("grid: 2 10")
-- the "W-SW-S-SE-E" propagation rule.
-- and 200 steps:
walk_grid(C,seed_cell,"W-SW-S-SE-E",200)
print(string_grid(C,grid))
1     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
2     .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .  .
3     .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .  .  .  .  .
4     .  .  .  .  .  .  .  .  .  1  1  .  .  .  .  .  .  .  .  .
5     .  .  .  .  .  .  .  .  .  1  1  1  1  .  .  .  .  .  .  .
6     .  .  .  .  .  .  .  .  .  .  .  .  1  1  .  .  .  .  .  .
7     .  .  .  .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .  .
8     .  .  .  .  .  .  .  .  .  .  .  1  1  2  2  1  .  .  .  .
9     .  .  .  .  .  .  .  .  .  .  .  .  1  1  .  .  .  .  .  .
10    .  .  .  .  .  .  .  .  .  .  .  .  2  1  .  .  .  .  .  .
11    .  .  .  .  .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .
12    .  .  .  .  .  .  .  .  .  .  .  .  .  .  1  1  .  .  .  .
13    .  .  .  .  .  .  .  .  .  .  .  .  1  2  1  .  .  .  .  .
14    .  .  .  .  .  .  .  .  .  .  .  .  1  1  .  .  .  .  .  .
15    .  .  .  .  .  .  .  .  .  .  .  .  1  1  .  .  .  .  .  .
16    .  .  .  .  .  .  .  .  .  .  .  .  1  1  .  .  .  .  .  .
17    .  .  .  .  .  .  .  .  .  .  .  .  .  1  .  .  .  .  .  .
18    .  .  .  .  .  .  .  .  .  .  .  1  1  .  .  .  .  .  .  .
19    .  .  .  .  .  .  .  .  .  .  .  1  1  .  .  .  .  .  .  .
20    .  .  .  .  2  8 11  8  7 14 15 12 14 14 11  6  6 12 13  6
I guess that is enough of an example. A couple of notes:
1) the above propagation rules are quite stupid. They just pick randomly from available directions for a given grid cell. In practice you would have rules with more intelligence. Exactly how you would implement these more intelligent propagation rules I'm not 100% sure yet.
2) It is easy enough to associate values with grid locations.
eg, something like this:
C.learn("cell-value","grid: 3 5","13")
C.learn("cell-value","grid: 7 2","8")
C.learn("cell-value","grid: 1 5","H")
C.learn("cell-value","grid: 10 8","G")
C.learn("cell-value","grid: 10 9","R")
C.learn("cell-value","grid: 10 10","I")
C.learn("cell-value","grid: 10 11","D")
print(string_grid(C,grid))

-- giving this output:
I: 20
J: 20
1     .  .  .  .  H  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
2     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
3     .  .  .  . 13  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
4     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
5     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
6     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
7     .  8  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
8     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
9     .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
10    .  .  .  .  .  .  .  G  R  I  D  .  .  .  .  .  .  .  .  .
11    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
12    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
13    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
14    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
15    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
16    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
17    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
18    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
19    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
20    .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
And of course, you can associate arbitrary superpositions with grid locations (something we will do later!), they are just harder to display. Indeed, the above cell values are actually kets, since context.learn(a,b,c) auto-casts c to a ket if it is a string.

OK. I dug up an example of mapping locations to superpositions. Here we have pixel locations mapped to rgb values, using the Lenna image.
eg a few sample pixels to superpositions:
pixel-value |pixel: 0: 29> => 236.000|r> + 147.000|g> + 116.000|b> + 255.000|a>
pixel-value |pixel: 0: 30> => 238.000|r> + 149.000|g> + 122.000|b> + 255.000|a>
pixel-value |pixel: 0: 31> => 238.000|r> + 150.000|g> + 123.000|b> + 255.000|a>
pixel-value |pixel: 0: 32> => 239.000|r> + 147.000|g> + 119.000|b> + 255.000|a>
pixel-value |pixel: 0: 33> => 236.000|r> + 141.000|g> + 116.000|b> + 255.000|a>
And that should be it for now. More in my next post!

Update: uploaded the make grid code to here.


Home
previous: learning a grid
next: temperature conversion

updated: 19/12/2016
by Garry Morrison
email: garry -at- semantic-db.org