@@ -98,7 +98,12 @@ def bernoulli(
9898
9999
100100def poisson (
101- datum : torch .Tensor , time : int , dt : float = 1.0 , device = "cpu" , ** kwargs
101+ datum : torch .Tensor ,
102+ time : int ,
103+ dt : float = 1.0 ,
104+ device = "cpu" ,
105+ approx = False ,
106+ ** kwargs
102107) -> torch .Tensor :
103108 # language=rst
104109 """
@@ -110,6 +115,8 @@ def poisson(
110115 :param datum: Tensor of shape ``[n_1, ..., n_k]``.
111116 :param time: Length of Poisson spike train per input variable.
112117 :param dt: Simulation time step.
118+ :param device: target destination of poisson spikes.
119+ :param approx: Bool: use alternate faster, less accurate computation.
113120 :return: Tensor of shape ``[time, n_1, ..., n_k]`` of Poisson-distributed spikes.
114121 """
115122 assert (datum >= 0 ).all (), "Inputs must be non-negative"
@@ -119,28 +126,36 @@ def poisson(
119126 datum = datum .flatten ()
120127 time = int (time / dt )
121128
122- # Compute firing rates in seconds as function of data intensity,
123- # accounting for simulation time step.
124- rate = torch .zeros (size , device = device )
125- rate [datum != 0 ] = 1 / datum [datum != 0 ] * (1000 / dt )
126-
127- # Create Poisson distribution and sample inter-spike intervals
128- # (incrementing by 1 to avoid zero intervals).
129- dist = torch .distributions .Poisson (rate = rate )
130- intervals = dist .sample (sample_shape = torch .Size ([time + 1 ]))
131- intervals [:, datum != 0 ] += (intervals [:, datum != 0 ] == 0 ).float ()
132-
133- # Calculate spike times by cumulatively summing over time dimension.
134- times = torch .cumsum (intervals , dim = 0 ).long ()
135- times [times >= time + 1 ] = 0
136-
137- # Create tensor of spikes.
138- spikes = torch .zeros ([time + 1 , size ], device = device , dtype = torch .bool )
139- spikes [times , torch .arange (size )] = 1
140- spikes = spikes [1 :]
141-
142- return spikes .view (time , * shape )
129+ if approx :
130+ # random normal power awful approximation
131+ x = torch .randn ((time , size ), device = device ).abs ()
132+ x = torch .pow (x , (datum * 0.11 + 5 ) / 50 )
133+ y = torch .tensor (x < 0.6 , dtype = torch .bool , device = device )
143134
135+ return y .view (time , * shape ).byte ()
136+ else :
137+ # Compute firing rates in seconds as function of data intensity,
138+ # accounting for simulation time step.
139+ rate = torch .zeros (size , device = device )
140+ rate [datum != 0 ] = 1 / datum [datum != 0 ] * (1000 / dt )
141+
142+ # Create Poisson distribution and sample inter-spike intervals
143+ # (incrementing by 1 to avoid zero intervals).
144+ dist = torch .distributions .Poisson (rate = rate )
145+ intervals = dist .sample (sample_shape = torch .Size ([time + 1 ]))
146+ intervals [:, datum != 0 ] += (intervals [:, datum != 0 ] == 0 ).float ()
147+
148+ # Calculate spike times by cumulatively summing over time dimension.
149+ times = torch .cumsum (intervals , dim = 0 ).long ()
150+ times [times >= time + 1 ] = 0
151+
152+ # Create tensor of spikes.
153+ spikes = torch .zeros (time + 1 , size , device = device ).byte ()
154+ spikes [times , torch .arange (size )] = 1
155+ spikes = spikes [1 :]
156+
157+ return spikes .view (time , * shape )
158+
144159
145160def rank_order (
146161 datum : torch .Tensor , time : int , dt : float = 1.0 , ** kwargs
0 commit comments