1

This code is supposed to generate a vector field from data (data) which describes how often a cell is visited.

def vectorfield(maze, walk, data):
    # associate a zero vector with each location in walkable space
    tempdata = {pair:np.zeros(2) for pair in walk}

    for x, y in tempdata.keys():
        value = data[x][y] # how many times an agent visited this cell
        for dx, dy in itertools.product([-1, 0, 1], [-1, 0, 1]):
            # if (x+dx, y+dy) is a neigbhor of (x, y) use its value for computation
            if dx or dy and (x+dx, y+dy) in walk:
                tempdata[(x, y)] += np.array([dx*value,dy*value])

    # largest length of corresponding vectors
    m = np.amax(np.sqrt(vx**2 + vy**2) for vx, vy in tempdata.values())
    t = {key : value/m for key, value in tempdata.items()}
    tempdata = t

    x, y = tempdata.keys()
    u, v = tempdata.values()

    return x, y, u, v

The bit of code with {key : value/m for key, value in tempdata.items()} yields an error: TypeError: unsupported operand type(s) for /: 'float' and 'generator'. The division comes from the fact that I need to normalize each vector. Why is that error displayed?

gournge
  • 25
  • 5

2 Answers2

1

Native Python max, and many other functions, take an iterable as their parameter, meaning an object that has either a __getitem__ method or an __iter__ method which returns an iterator (source). This includes lists, tuples and generators.

numpy functions such as np.amax take a different approach, usually accepting an "array-like" argument. Generally, these have __getitem__ and also have a defined length. Generators do not have a defined length. If it gets something else, such as a generator, it treats it as a 0-dimensional array containing only that object. The maximum of such an array is simply the generator object it contains.

This is why m in your code is a generator rather than a number, and why value/m raises an error.

As already answered, you can get around this using a list comprehension. You could also use np.fromiter.

Stuart
  • 9,597
  • 1
  • 21
  • 30
0
(np.sqrt(vx**2 + vy**2) for vx, vy in tempdata.values())

creates a generator expression. np.amax doesn't change the type, it just returns the max value. Try to make it a list instead

m = np.amax([np.sqrt(vx**2 + vy**2) for vx, vy in tempdata.values()])
Guy
  • 46,488
  • 10
  • 44
  • 88