Reputation: 475
Sorry for the stupid question.
I'm programming in PHP but found some nice code in Python and want to "recreate" it in PHP.
But I'm quite frustrated about the line:
self.h = -0.1
self.activity = numpy.zeros((512, 512)) + self.h
self.activity[:, :] = self.h
I don't understand what [:, :]
means.
I couldn't find an answer by googling it.
Full code
import math
import numpy
import pygame
from scipy.misc import imsave
from scipy.ndimage.filters import gaussian_filter
class AmariModel(object):
def __init__(self, size):
self.h = -0.1
self.k = 0.05
self.K = 0.125
self.m = 0.025
self.M = 0.065
self.stimulus = -self.h * numpy.random.random(size)
self.activity = numpy.zeros(size) + self.h
self.excitement = numpy.zeros(size)
self.inhibition = numpy.zeros(size)
def stimulate(self):
self.activity[:, :] = self.activity > 0
sigma = 1 / math.sqrt(2 * self.k)
gaussian_filter(self.activity, sigma, 0, self.excitement, "wrap")
self.excitement *= self.K * math.pi / self.k
sigma = 1 / math.sqrt(2 * self.m)
gaussian_filter(self.activity, sigma, 0, self.inhibition, "wrap")
self.inhibition *= self.M * math.pi / self.m
self.activity[:, :] = self.h
self.activity[:, :] += self.excitement
self.activity[:, :] -= self.inhibition
self.activity[:, :] += self.stimulus
class AmariMazeGenerator(object):
def __init__(self, size):
self.model = AmariModel(size)
pygame.init()
self.display = pygame.display.set_mode(size, 0)
pygame.display.set_caption("Amari Maze Generator")
def run(self):
pixels = pygame.surfarray.pixels3d(self.display)
index = 0
running = True
while running:
self.model.stimulate()
pixels[:, :, :] = (255 * (self.model.activity > 0))[:, :, None]
pygame.display.flip()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
elif event.key == pygame.K_s:
imsave("{0:04d}.png".format(index), pixels[:, :, 0])
index = index + 1
elif event.type == pygame.MOUSEBUTTONDOWN:
position = pygame.mouse.get_pos()
self.model.activity[position] = 1
pygame.quit()
def main():
generator = AmariMazeGenerator((512, 512))
generator.run()
if __name__ == "__main__":
main()
Upvotes: 47
Views: 94642
Reputation: 39406
numpy uses tuples as indexes. In this case, this is a detailed slice assignment.
[0] #means line 0 of your matrix
[(0,0)] #means cell at 0,0 of your matrix
[0:1] #means lines 0 to 1 excluded of your matrix
[:1] #excluding the first value means all lines until line 1 excluded
[1:] #excluding the last param mean all lines starting form line 1
included
[:] #excluding both means all lines
[::2] #the addition of a second ':' is the sampling. (1 item every 2)
[::] #exluding it means a sampling of 1
[:,:] #simply uses a tuple (a single , represents an empty tuple) instead
of an index.
It is equivalent to the simpler
self.activity[:] = self.h
(which also works for regular lists as well)
Upvotes: 25
Reputation: 85462
The [:, :]
stands for everything from the beginning to the end just like for lists. The difference is that the first :
stands for first and the second :
for the second dimension.
a = numpy.zeros((3, 3))
In [132]: a
Out[132]:
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
Assigning to second row:
In [133]: a[1, :] = 3
In [134]: a
Out[134]:
array([[ 0., 0., 0.],
[ 3., 3., 3.],
[ 0., 0., 0.]])
Assigning to second column:
In [135]: a[:, 1] = 4
In [136]: a
Out[136]:
array([[ 0., 4., 0.],
[ 3., 4., 3.],
[ 0., 4., 0.]])
Assigning to all:
In [137]: a[:] = 10
In [138]: a
Out[138]:
array([[ 10., 10., 10.],
[ 10., 10., 10.],
[ 10., 10., 10.]])
Upvotes: 54
Reputation: 309929
This is slice assignment. Technically, it calls1
self.activity.__setitem__((slice(None,None,None),slice(None,None,None)),self.h)
which sets all of the elements in self.activity
to whatever value self.h
is storing. The code you have there really seems redundant. As far as I can tell, you could remove the addition on the previous line, or simply use slice assignment:
self.activity = numpy.zeros((512,512)) + self.h
or
self.activity = numpy.zeros((512,512))
self.activity[:,:] = self.h
Perhaps the fastest way to do this is to allocate an empty array and .fill
it with the expected value:
self.activity = numpy.empty((512,512))
self.activity.fill(self.h)
1Actually, __setslice__
is attempted before calling __setitem__
, but __setslice__
is deprecated, and shouldn't be used in modern code unless you have a really good reason for it.
Upvotes: 11