neuroprob/filters.py
def forward(self, input, stimulus):
        """
        The two modes of stimulus coupling are `unfold` and `repeat`, the first evaluates the filter GP at 
        stimulus values at the instantaneous time, whereas the latter uses the stimulus value at the time 
        one wants to evaluate the conditional rate expanded across the history.
        
        :param torch.tensor input: input spiketrain or covariates with shape (trials, neurons, timesteps) 
                                   or (samples, neurons, timesteps)
        :param torch.tensor stimulus: input stimulus of shape (trials, timesteps, dims)
        :returns: filtered input of shape (trials, neurons, timesteps)
        """
        assert stimulus is not None
        assert input.shape[0] == 1
        #assert stimulus.shape[1] == input.shape[-1]-self.history_len+1
        
        input_unfold = input.unfold(-1, self.history_len, 1) # samples, neurons, timesteps, fold_dim
        if self.mode == 'unfold':
            stim_unfold = stimulus[:, :-1, :].unfold(1, self.history_len, 1) # samples, timesteps, dims, fold_dim
        else: # repeat
            stim_ = stimulus[:, self.history_len:, :]
            stim_unfold = stim_[..., None].expand(*stim_.shape, self.history_len) # samples, timesteps, dims, fold_dim
            
        K = stim_unfold.shape[0]
        T = input_unfold.shape[-2]
        
        inner_batches = np.ceil(T / self.inner_bs).astype(int)
        a_ = []
        a_var_ = []
        for b in range(inner_batches): # inner loop batching
            stim_in = stim_unfold[:, b*self.inner_bs:(b+1)*self.inner_bs, ...].reshape(-1, *stim_unfold.shape[-2:]) # KxT, D, D_fold
            input_in = input_unfold[..., b*self.inner_bs:(b+1)*self.inner_bs, :]
            
            h_, v_ = self.compute_filter(stim_in.permute(0, 2, 1)) # KxT, out, in, D_fold      
                
            if h_.shape[1] == 1: # output dims
                a = (input_in*h_[:, 0, ...].view(K, -1, *h_.shape[-2:]).permute(0, 2, 1, 3)) # K, N, T, D_fold
                a_.append(a.sum(-1)) # K, N, T
                if isinstance(v_, Number) is False:
                    a_var = (input_in*v_[:, 0, ...].view(K, -1, *v_.shape[-2:]).permute(0, 2, 1, 3))
                    a_var_.append(a_var.sum(-1)) # K, N, T
                
            else: # neurons
                a = (input_in[..., None, :]*h_.view(K, -1, *h_.shape[-3:]).permute(0, 2, 1, 3, 4)) # K, N, T, n_in, D_fold
                a_.append(a.sum(-1).sum(-1)) # K, N, T
                if isinstance(v_, Number) is False:
                    a_var = (input_in[..., None, :]*v_.view(K, -1, *v_.shape[-3:]).permute(0, 2, 1, 3, 4))
                    a_var_.append(a_var.sum(-1).sum(-1)) # K, N, T
                
        filt_var = 0 if len(a_var_) == 0 else torch.cat(a_var_, dim=-1)
        return torch.cat(a_, dim=-1), filt_var

        The two modes of stimulus coupling are `unfold` and `repeat`, the first evaluates the filter GP at 
        stimulus values at the instantaneous time, whereas the latter uses the stimulus value at the time 
        one wants to evaluate the conditional rate expanded across the history.
        
        :param torch.tensor input: input spiketrain or covariates with shape (trials, neurons, timesteps) 
                                   or (samples, neurons, timesteps)
        :param torch.tensor stimulus: input stimulus of shape (trials, timesteps, dims)
        :returns: filtered input of shape (trials, neurons, timesteps)
        
The two modes of stimulus coupling are `unfold` and `repeat`, the first evaluates the filter GP at
stimulus values at the instantaneous time, whereas the latter uses the stimulus value at the time
one wants to evaluate the conditional rate expanded across the history.
The two modes of stimulus coupling are ` unfold ` and ` repeat ` the first evaluates the filter GP at stimulus values at the instantaneous time whereas the latter uses the stimulus value at the time one wants to evaluate the conditional rate expanded across the history .
def forward(self, input, stimulus):
        assert stimulus is not None
        assert input.shape[0] == 1
        input_unfold = input.unfold(-1, self.history_len, 1) 
        if self.mode == 'unfold':
            stim_unfold = stimulus[:, :-1, :].unfold(1, self.history_len, 1) 
        else: 
            stim_ = stimulus[:, self.history_len:, :]
            stim_unfold = stim_[..., None].expand(*stim_.shape, self.history_len) 
        K = stim_unfold.shape[0]
        T = input_unfold.shape[-2]
        inner_batches = np.ceil(T / self.inner_bs).astype(int)
        a_ = []
        a_var_ = []
        for b in range(inner_batches): 
            stim_in = stim_unfold[:, b*self.inner_bs:(b+1)*self.inner_bs, ...].reshape(-1, *stim_unfold.shape[-2:]) 
            input_in = input_unfold[..., b*self.inner_bs:(b+1)*self.inner_bs, :]
            h_, v_ = self.compute_filter(stim_in.permute(0, 2, 1)) 
            if h_.shape[1] == 1: 
                a = (input_in*h_[:, 0, ...].view(K, -1, *h_.shape[-2:]).permute(0, 2, 1, 3)) 
                a_.append(a.sum(-1)) 
                if isinstance(v_, Number) is False:
                    a_var = (input_in*v_[:, 0, ...].view(K, -1, *v_.shape[-2:]).permute(0, 2, 1, 3))
                    a_var_.append(a_var.sum(-1)) 
            else: 
                a = (input_in[..., None, :]*h_.view(K, -1, *h_.shape[-3:]).permute(0, 2, 1, 3, 4)) , n_in, D_fold
                a_.append(a.sum(-1).sum(-1)) 
                if isinstance(v_, Number) is False:
                    a_var = (input_in[..., None, :]*v_.view(K, -1, *v_.shape[-3:]).permute(0, 2, 1, 3, 4))
                    a_var_.append(a_var.sum(-1).sum(-1)) 
        filt_var = 0 if len(a_var_) == 0 else torch.cat(a_var_, dim=-1)
        return torch.cat(a_, dim=-1), filt_var
def forward ( self , input , stimulus ) : assert stimulus is not None assert input . shape [ 0 ] == 1 input_unfold = input . unfold ( - 1 , self . history_len , 1 ) if self . mode == 'unfold' : stim_unfold = stimulus [ : , : - 1 , : ] . unfold ( 1 , self . history_len , 1 ) else : stim_ = stimulus [ : , self . history_len : , : ] stim_unfold = stim_ [ ... , None ] . expand ( * stim_ . shape , self . history_len ) K = stim_unfold . shape [ 0 ] T = input_unfold . shape [ - 2 ] inner_batches = np . ceil ( T / self . inner_bs ) . astype ( int ) a_ = [ ] a_var_ = [ ] for b in range ( inner_batches ) : stim_in = stim_unfold [ : , b * self . inner_bs : ( b + 1 ) * self . inner_bs , ... ] . reshape ( - 1 , * stim_unfold . shape [ - 2 : ] ) input_in = input_unfold [ ... , b * self . inner_bs : ( b + 1 ) * self . inner_bs , : ] h_ , v_ = self . compute_filter ( stim_in . permute ( 0 , 2 , 1 ) ) if h_ . shape [ 1 ] == 1 : a = ( input_in * h_ [ : , 0 , ... ] . view ( K , - 1 , * h_ . shape [ - 2 : ] ) . permute ( 0 , 2 , 1 , 3 ) ) a_ . append ( a . sum ( - 1 ) ) if isinstance ( v_ , Number ) is False : a_var = ( input_in * v_ [ : , 0 , ... ] . view ( K , - 1 , * v_ . shape [ - 2 : ] ) . permute ( 0 , 2 , 1 , 3 ) ) a_var_ . append ( a_var . sum ( - 1 ) ) else : a = ( input_in [ ... , None , : ] * h_ . view ( K , - 1 , * h_ . shape [ - 3 : ] ) . permute ( 0 , 2 , 1 , 3 , 4 ) ) a_ . append ( a . sum ( - 1 ) . sum ( - 1 ) ) if isinstance ( v_ , Number ) is False : a_var = ( input_in [ ... , None , : ] * v_ . view ( K , - 1 , * v_ . shape [ - 3 : ] ) . permute ( 0 , 2 , 1 , 3 , 4 ) ) a_var_ . append ( a_var . sum ( - 1 ) . sum ( - 1 ) ) filt_var = 0 if len ( a_var_ ) == 0 else torch . cat ( a_var_ , dim = - 1 ) return torch . cat ( a_ , dim = - 1 ) , filt_var
The two modes of stimulus coupling are `unfold` and `repeat`, the first evaluates the filter GP at
stimulus values at the instantaneous time, whereas the latter uses the stimulus value at the time
one wants to evaluate the conditional rate expanded across the history.
The two modes of stimulus coupling are ` unfold ` and ` repeat ` the first evaluates the filter GP at stimulus values at the instantaneous time whereas the latter uses the stimulus value at the time one wants to evaluate the conditional rate expanded across the history .
"""
        The two modes of stimulus coupling are `unfold` and `repeat`, the first evaluates the filter GP at 
        stimulus values at the instantaneous time, whereas the latter uses the stimulus value at the time 
        one wants to evaluate the conditional rate expanded across the history.
        
        :param torch.tensor input: input spiketrain or covariates with shape (trials, neurons, timesteps) 
                                   or (samples, neurons, timesteps)
        :param torch.tensor stimulus: input stimulus of shape (trials, timesteps, dims)
        :returns: filtered input of shape (trials, neurons, timesteps)
        """ #assert stimulus.shape[1] == input.shape[-1]-self.history_len+1 # samples, neurons, timesteps, fold_dim # samples, timesteps, dims, fold_dim # repeat # samples, timesteps, dims, fold_dim # inner loop batching # KxT, D, D_fold # KxT, out, in, D_fold       # output dims # K, N, T, D_fold # K, N, T # K, N, T # neurons # K, N, T, n_in, D_fold # K, N, T # K, N, T
filtered input of shape (trials, neurons, timesteps)
filtered input of shape ( trials neurons timesteps )
self
input
input spiketrain or covariates with shape (trials, neurons, timesteps)
or (samples, neurons, timesteps)
input spiketrain or covariates with shape ( trials neurons timesteps ) or ( samples neurons timesteps )
stimulus
input stimulus of shape (trials, timesteps, dims)
input stimulus of shape ( trials timesteps dims )