def __call__(self, pre_size, post_size): self.num_pre = num_pre = _size2len(pre_size) self.num_post = num_post = _size2len(post_size) assert len(pre_size) == 2 assert len(post_size) == 2 pre_height, pre_width = pre_size post_height, post_width = post_size # get the connections i, j, p = [], [], [] # conn_i, conn_j, probabilities for pre_i in range(num_pre): a = _gaussian_prob(pre_i=pre_i, pre_width=pre_width, pre_height=pre_height, num_post=num_post, post_width=post_width, post_height=post_height, p_min=self.p_min, sigma=self.sigma, normalize=self.normalize, include_self=self.include_self) i.extend(a[0]) j.extend(a[1]) p.extend(a[2]) p = np.asarray(p, dtype=np.float_) selected_idxs = np.where(np.random.random(len(p)) < p)[0] i = np.asarray(i, dtype=np.int_)[selected_idxs] j = np.asarray(j, dtype=np.int_)[selected_idxs] self.pre_ids = backend.as_tensor(i) self.post_ids = backend.as_tensor(j) return self
def __call__(self, pre_size, post_size): num_pre = _size2len(pre_size) num_post = _size2len(post_size) self.num_pre = num_pre self.num_post = num_post assert len(pre_size) == 2 assert len(post_size) == 2 pre_height, pre_width = pre_size post_height, post_width = post_size # get the connections and weights i, j, w = [], [], [] for pre_i in range(num_pre): a = _gaussian_weight(pre_i=pre_i, pre_width=pre_width, pre_height=pre_height, num_post=num_post, post_width=post_width, post_height=post_height, w_max=self.w_max, w_min=self.w_min, sigma=self.sigma, normalize=self.normalize, include_self=self.include_self) i.extend(a[0]) j.extend(a[1]) w.extend(a[2]) pre_ids = np.asarray(i, dtype=np.int_) post_ids = np.asarray(j, dtype=np.int_) w = np.asarray(w, dtype=np.float_) self.pre_ids = backend.as_tensor(pre_ids) self.post_ids = backend.as_tensor(post_ids) self.weights = backend.as_tensor(w) return self
def __call__(self, pre_size, post_size=None): self.num_pre = _size2len(pre_size) if post_size is not None: try: assert pre_size == post_size except AssertionError: raise errors.ModelUseError( f'The shape of pre-synaptic group should be the same with the post group. ' f'But we got {pre_size} != {post_size}.') self.num_post = _size2len(post_size) else: self.num_post = self.num_pre if len(pre_size) == 1: height, width = pre_size[0], 1 elif len(pre_size) == 2: height, width = pre_size else: raise errors.ModelUseError( 'Currently only support two-dimensional geometry.') conn_i = [] conn_j = [] for row in range(height): res = _grid_n(height=height, width=width, row=row, n=self.n, include_self=self.include_self) conn_i.extend(res[0]) conn_j.extend(res[1]) self.pre_ids = backend.as_tensor(conn_i) self.post_ids = backend.as_tensor(conn_j) return self
def __call__(self, pre_size, post_size): num_pre, num_post = _size2len(pre_size), _size2len(post_size) self.num_pre, self.num_post = num_pre, num_post prob_mat = np.random.random(size=(num_pre, num_post)) if not self.include_self: diag_index = np.arange(min([num_pre, num_post])) prob_mat[diag_index, diag_index] = 1. conn_mat = np.array(prob_mat < self.prob, dtype=np.int_) pre_ids, post_ids = np.where(conn_mat) self.conn_mat = backend.as_tensor(conn_mat) self.pre_ids = backend.as_tensor(np.ascontiguousarray(pre_ids)) self.post_ids = backend.as_tensor(np.ascontiguousarray(post_ids)) return self
def __call__(self, pre_size, post_size): pre_len = _size2len(pre_size) post_len = _size2len(post_size) self.num_pre = pre_len self.num_post = post_len mat = np.ones((pre_len, post_len)) if not self.include_self: eye = np.arange(min([pre_len, post_len])) self.conn_mat[eye, eye] = 0 pre_ids, post_ids = np.where(mat > 0) self.pre_ids = backend.as_tensor(np.ascontiguousarray(pre_ids)) self.post_ids = backend.as_tensor(np.ascontiguousarray(post_ids)) self.conn_mat = backend.as_tensor(mat) return self
def pre_slice_syn(i, j, num_pre=None): """Get post slicing connections by pre-synaptic ids. Parameters ---------- i : list, np.ndarray The pre-synaptic neuron indexes. j : list, np.ndarray The post-synaptic neuron indexes. num_pre : int The number of the pre-synaptic neurons. Returns ------- conn : list The conn list of post2syn. """ # check if len(i) != len(j): raise errors.ModelUseError( 'The length of "i" and "j" must be the same.') if num_pre is None: print( 'WARNING: "num_pre" is not provided, the result may not be accurate.' ) num_pre = i.max() # pre2post connection pre2post_list = [[] for _ in range(num_pre)] for pre_id, post_id in zip(i, j): pre2post_list[pre_id].append(post_id) pre_ids, post_ids = [], [] for pre_i, posts in enumerate(pre2post_list): post_ids.extend(posts) pre_ids.extend([pre_i] * len(posts)) post_ids = backend.as_tensor(post_ids) pre_ids = backend.as_tensor(pre_ids) # pre2post slicing slicing = [] start = 0 for posts in pre2post_list: end = start + len(posts) slicing.append([start, end]) start = end slicing = backend.as_tensor(slicing) return pre_ids, post_ids, slicing
def post2syn(j, num_post=None): """Get post2syn connections from `i` and `j` indexes. Parameters ---------- j : list, np.ndarray The post-synaptic neuron indexes. num_post : int The number of the post-synaptic neurons. Returns ------- conn : list The conn list of post2syn. """ if num_post is None: print( 'WARNING: "num_post" is not provided, the result may not be accurate.' ) num_post = j.max() post2syn_list = [[] for _ in range(num_post)] for syn_id, post_id in enumerate(j): post2syn_list[post_id].append(syn_id) post2syn_list = [backend.as_tensor(l) for l in post2syn_list] if _numba_backend(): post2syn_list_nb = nb.typed.List() for pre_ids in post2syn_list: post2syn_list_nb.append(pre_ids) post2syn_list = post2syn_list_nb return post2syn_list
def __call__(self, pre_size, post_size): num_pre, num_post = _size2len(pre_size), _size2len(post_size) self.num_pre, self.num_post = num_pre, num_post num = self.num if isinstance(self.num, int) else int(self.num * num_pre) assert num <= num_pre, f'"num" must be less than "num_pre", but got {num} > {num_pre}' prob_mat = np.random.random(size=(num_pre, num_post)) if not self.include_self: diag_index = np.arange(min([num_pre, num_post])) prob_mat[diag_index, diag_index] = 1.1 arg_sort = np.argsort(prob_mat, axis=0)[:num] pre_ids = np.asarray(np.concatenate(arg_sort), dtype=np.int_) post_ids = np.asarray(np.repeat(np.arange(num_post), num_pre), dtype=np.int_) self.pre_ids = backend.as_tensor(pre_ids) self.post_ids = backend.as_tensor(post_ids) return self
def mat2ij(conn_mat): """Get the i-j connections from connectivity matrix. Parameters ---------- conn_mat : np.ndarray Connectivity matrix with `(num_pre, num_post)` shape. Returns ------- conn_tuple : tuple (Pre-synaptic neuron indexes, post-synaptic neuron indexes). """ if len(backend.shape(conn_mat)) != 2: raise errors.ModelUseError('Connectivity matrix must be in the ' 'shape of (num_pre, num_post).') pre_ids, post_ids = backend.where(conn_mat > 0) return backend.as_tensor(pre_ids), backend.as_tensor(post_ids)
def __call__(self, pre_size, post_size): self.num_pre = num_pre = _size2len(pre_size) self.num_post = num_post = _size2len(post_size) assert len(pre_size) == 2 assert len(post_size) == 2 pre_height, pre_width = pre_size post_height, post_width = post_size # get the connections and weights i, j, w = [], [], [] # conn_i, conn_j, weights for pre_i in range(num_pre): a = _dog(pre_i=pre_i, pre_width=pre_width, pre_height=pre_height, num_post=num_post, post_width=post_width, post_height=post_height, w_max_p=self.w_max_p, w_max_n=self.w_max_n, w_min=self.w_min, sigma_p=self.sigma_p, sigma_n=self.sigma_n, normalize=self.normalize, include_self=self.include_self) i.extend(a[0]) j.extend(a[1]) w.extend(a[2]) # format connections and weights i = np.asarray(i, dtype=np.int_) j = np.asarray(j, dtype=np.int_) w = np.asarray(w, dtype=np.float_) self.pre_ids = backend.as_tensor(i) self.post_ids = backend.as_tensor(j) self.weights = backend.as_tensor(w) return self
def post2pre(i, j, num_post=None): """Get post2pre connections from `i` and `j` indexes. Parameters ---------- i : list, np.ndarray The pre-synaptic neuron indexes. j : list, np.ndarray The post-synaptic neuron indexes. num_post : int, None The number of the post-synaptic neurons. Returns ------- conn : list The conn list of post2pre. """ if len(i) != len(j): raise errors.ModelUseError( 'The length of "i" and "j" must be the same.') if num_post is None: print( 'WARNING: "num_post" is not provided, the result may not be accurate.' ) num_post = j.max() post2pre_list = [[] for _ in range(num_post)] for pre_id, post_id in zip(i, j): post2pre_list[post_id].append(pre_id) post2pre_list = [backend.as_tensor(l) for l in post2pre_list] if _numba_backend(): post2pre_list_nb = nb.typed.List() for post_id in range(num_post): post2pre_list_nb.append(post2pre_list[post_id]) post2pre_list = post2pre_list_nb return post2pre_list