|
|
|
@ -23,7 +23,10 @@ grating_f = sp.cos(k * (x - x0) * sp.cos(theta) + k * (y - y0) * sp.sin(theta) +
|
|
|
|
|
receptive_field = 1 / (2 * sp.pi * sigma * sigma) * sp.exp(-(x ** 2 + y ** 2) / (2 * sigma ** 2)) * sp.cos( |
|
|
|
|
k * x * sp.cos(theta) + k * y * sp.sin(theta) + phi) |
|
|
|
|
receptive_field = receptive_field.subs(theta, 0).subs(phi, 0) |
|
|
|
|
p = sp.cosh(k ** 2 * sigma ** 2 * sp.cos(theta)) * sp.exp(k ** 2 * (1 + sp.cos(theta) ** 2) / 2) * sp.cos( |
|
|
|
|
# p = sp.cosh(k ** 2 * sigma ** 2 * sp.cos(theta)) * sp.exp(k ** 2 * (1 + sp.cos(theta) ** 2) / 2) * sp.cos( |
|
|
|
|
# phi - k * (x0 * sp.cos(theta) + y0 * sp.sin(theta))) |
|
|
|
|
|
|
|
|
|
p = sp.cosh(k ** 2 * sigma ** 2 * sp.cos(theta) * 4) * sp.exp(-4 * k ** 2 * sigma ** 2) * sp.cos( |
|
|
|
|
phi - k * (x0 * sp.cos(theta) + y0 * sp.sin(theta))) |
|
|
|
|
|
|
|
|
|
sigma_split = np.arange(0.1, 1, 0.05) |
|
|
|
@ -31,6 +34,10 @@ k_split = np.arange(0.2, 6, 0.2)
|
|
|
|
|
xy_split = np.arange(-1, 1, 0.05) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def sigmoid(x): |
|
|
|
|
return 1 / (1 + np.exp(-x)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass |
|
|
|
|
class Cell: |
|
|
|
|
sigma_val: float = defaults[sigma] |
|
|
|
@ -93,11 +100,17 @@ class Population:
|
|
|
|
|
xy_dist: np.ndarray = np.ones(len(xy_split))): |
|
|
|
|
return cls(cells=[Cell.random(sigma_dist, k_val, xy_dist) for _ in range(n)]) |
|
|
|
|
|
|
|
|
|
def get_response(self, phi_deg: float, theta_deg: float) -> typing.List[float]: |
|
|
|
|
return [cell.get_value(theta_deg, phi_deg) for cell in self.cells] |
|
|
|
|
def get_response(self, phi_deg: float, theta_deg: float, coef: float = 4, use_sigmoid: bool = True) -> np.ndarray: |
|
|
|
|
return (sigmoid if use_sigmoid else (lambda x: x))(np.array([cell.get_value(theta_deg, phi_deg) for cell in self.cells]) * coef) |
|
|
|
|
|
|
|
|
|
def sample_responses(self, n: int) -> np.ndarray: |
|
|
|
|
def sample_responses( |
|
|
|
|
self, n: int, noise_sigma: float = 0, coef: float = 2, use_sigmoid: bool = True, |
|
|
|
|
custom_grid: typing.Optional[np.ndarray] = None |
|
|
|
|
) -> np.ndarray: |
|
|
|
|
return np.array([ |
|
|
|
|
self.get_response(phi_deg, theta_deg % 180) |
|
|
|
|
for phi_deg, theta_deg in np.random.uniform(0, 360, (n, 2)) |
|
|
|
|
]) |
|
|
|
|
np.array([self.get_response(phi_deg, theta_deg % 180, coef=coef, use_sigmoid=use_sigmoid), np.ones(len(self.cells)) * phi_deg, |
|
|
|
|
np.ones(len(self.cells)) * theta_deg]).swapaxes(0, 1) |
|
|
|
|
for phi_deg, theta_deg in (np.random.uniform(0, 360, (n, 2)) if custom_grid is None else custom_grid) |
|
|
|
|
]) + np.random.normal( |
|
|
|
|
0, [noise_sigma, 0, 0], |
|
|
|
|
(n if custom_grid is None else len(custom_grid), len(self.cells), 3)) |
|
|
|
|