Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
 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
Esempio n. 9
0
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)
Esempio n. 10
0
    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
Esempio n. 11
0
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