Source code for dipde.internals.connectiondistribution
"""Module containing ConnectionDistribution class, organizing connection details."""
# Copyright 2013 Allen Institute
# This file is part of dipde
# dipde is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# dipde is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with dipde. If not, see <http://www.gnu.org/licenses/>.
import numpy as np
from dipde.internals import utilities as util
[docs]class ConnectionDistribution(object):
'''Container for matrix that computes element flux, and associated methods.
A ConnectionDistribution object contains a matrix used to compute the time
propogation of the voltage probability distribution, and a vector used to
compute the flux over threshold at the end of the timestep. It is unique up
to the descretization of the target voltage distribution, and the specific
synaptic weight distribution of the connection. Therefore, whenever
possible, a ConnectionDistribution object is reused for multiple connections
with identical signatures, to reduce memory consumption.
Parameters
----------
edges: np.ndarray
Voltage bin discretization of target population.
weights: np.ndarray
Weights defining the discrete synaptic distribution.
probs : np.ndarray
Probabilities corresponding to weights.
Attributes
----------
self.threshold_flux_vector : np.ndarray
Vector used to compute over-threshold flux.
self.flux_matrix : np.ndarray
Matrix used to propagate voltage distribution.
'''
def __init__(self, edges, weights, probs, sparse=True):
# Assign inputs:
self.edges = edges
self.weights = weights
self.probs = probs
# Not implemented yet
self.reversal_potential = None
if self.reversal_potential != None:
assert NotImplementedError # pragma: no cover
# Must be probabilty distribution
assert np.sum(probs) == 1.
# Defined at runtime:
self.threshold_flux_vector = None
self.flux_matrix = None
[docs] def initialize(self):
"""Initialize connection distribution.
Initialization creates the flux_matrix and threshold_flux_vector.
Implemented lazily via a try catch when flux matrix is requested, that
does not exist.
"""
nv = len(self.edges)-1
self.flux_matrix = np.zeros((nv, nv))
self.threshold_flux_vector = np.zeros(nv)
for curr_weight, curr_prob in zip(self.weights, self.probs):
curr_threshold_flux_vector, curr_flux_matrix = util.flux_matrix(self.edges, curr_weight, curr_prob)
self.flux_matrix += curr_flux_matrix
self.threshold_flux_vector += curr_threshold_flux_vector
# Guarantee zero flux:
np.testing.assert_almost_equal(np.abs(np.sum(self.flux_matrix, axis=0)).sum(), 0, 12)
@property
def signature(self):
"""A unique key used to organize ConnectionDistributions."""
return (tuple(self.edges),
tuple(self.weights),
tuple(self.probs),
self.reversal_potential)