pinwheel_map.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import matplotlib.pyplot as plt
  2. import numpy as np
  3. from numpy.linalg import norm
  4. class PinwheelMap:
  5. A = 2.0
  6. B = 1.0
  7. lambda_1 = 2.0
  8. lambda_2 = 1.0
  9. max_length = 5.0
  10. w_scale = 0.01
  11. # def w(self,r):
  12. # return self.A*np.exp(-self.lambda_1*r**2)-self.B*np.exp(-self.lambda_2*r**2)
  13. def w(self, r):
  14. scale = self.scale
  15. return self.w_scale * np.piecewise(r, [r < int(scale / 2), r >= int(scale / 2) and r < scale,
  16. r >= scale], [1.0, -1.0, 0.0])
  17. def bound(self, z_i):
  18. return 1.0 if norm(z_i) < 1.0 else 0.0
  19. def __init__(self,x_dim,y_dim, scale, sheet_x=0, sheet_y=0, seed = -1):
  20. self.x_dim = x_dim
  21. self.y_dim = y_dim
  22. self.scale = int((scale/sheet_x)*x_dim) # in number of neurons?!?
  23. self.sheet_x = sheet_x
  24. self.sheet_y = sheet_y
  25. if seed != -1:
  26. np.random.seed(seed)
  27. self.seed = seed
  28. self.angle_grid = np.random.rand(x_dim,y_dim)*2.0*np.pi-np.pi
  29. self.vec_grid = np.ndarray((x_dim,y_dim,2))
  30. for idx in range(x_dim):
  31. for idy in range(y_dim):
  32. phi = self.angle_grid[idx, idy]
  33. vec = [0.01 * np.cos(phi), 0.01 * np.sin(phi)]
  34. self.vec_grid[idx, idy] = vec
  35. def pinwheel_map_by_id(self, id_x, id_y):
  36. return self.angle_grid[id_x, id_y]
  37. def get_tuning_by_id(self, id_x, id_y):
  38. return self.angle_grid[id_x, id_y]
  39. def tuning(self, x, y):
  40. id_x = int(x * (self.x_dim - 1) / self.sheet_x)
  41. id_y = int(y * (self.y_dim - 1) / self.sheet_y)
  42. return self.angle_grid[id_x, id_y]
  43. def iterate(self):
  44. vec_grid = self.vec_grid
  45. vec_list = list([((i, j), vec_grid[i, j]) for i in range(vec_grid.shape[0]) for j in range(vec_grid.shape[1])])
  46. delta_z_list = []
  47. for vec_i in vec_list:
  48. (i_x, i_y), z_i = vec_i
  49. if self.bound(z_i) == 1.0:
  50. d_z_i = np.array([0., 0.])
  51. for vec_j in vec_list:
  52. (j_x, j_y), z_j = vec_j
  53. if np.abs(i_x - j_x) < self.scale and np.abs(i_y - j_y) < self.scale and vec_i != vec_j:
  54. r = np.sqrt((i_x - j_x) * (i_x - j_x) + (i_y - j_y) * (i_y - j_y))
  55. d_z = z_j * self.w(r)
  56. # print(d_z)
  57. d_z_i += d_z
  58. delta_z_list.append(d_z_i)
  59. else:
  60. delta_z_list.append(np.array([0., 0.]))
  61. for i, vec_i in enumerate(vec_list):
  62. (i_x, i_y), z_i = vec_i
  63. if self.bound(z_i) == 1.0:
  64. vec_grid[i_x, i_y] += delta_z_list[i]
  65. def improve(self, iterations):
  66. for i in range(iterations):
  67. self.iterate()
  68. # print("Iteration {} out of {}".format(i + 1, iterations))
  69. vec_list = list([((i, j), self.vec_grid[i, j]) for i in range(self.vec_grid.shape[0]) for j in
  70. range(self.vec_grid.shape[1])])
  71. for vec_i in vec_list:
  72. (i_x, i_y), z_i = vec_i
  73. self.angle_grid[i_x, i_y] = np.arctan2(z_i[1], z_i[0])
  74. def plot_map(self, ax=None):
  75. if ax is None:
  76. fig, ax = plt.subplots(1, 1)
  77. X, Y = self.get_meshgrid_of_neuron_positions()
  78. Z = np.zeros((self.x_dim, self.y_dim))
  79. # For correctly displaying ticks
  80. for y_idx in range(Z.shape[1]):
  81. for x_idx in range(Z.shape[0]):
  82. o_map_val = self.pinwheel_map_by_id(x_idx, y_idx)
  83. Z[x_idx, y_idx] = o_map_val
  84. if ax is None:
  85. fig = plt.figure()
  86. ax = fig.add_subplot(111)
  87. plt.set_cmap('twilight')
  88. pcm = ax.pcolormesh(X, Y, Z.T)
  89. plt.gcf().colorbar(pcm, ax=ax)
  90. def get_meshgrid_of_neuron_positions(self):
  91. x_max = self.sheet_x
  92. d_x = x_max / self.x_dim
  93. y_max = self.sheet_y
  94. d_y = y_max / self.y_dim
  95. X, Y = np.meshgrid(np.arange(0, x_max + d_x, d_x) - d_x / 2., np.arange(0, y_max + d_y, d_y) - d_y / 2.)
  96. return X, Y