.. currentmodule:: brian2 .. efficient_gaussian_connectivity: Example: efficient_gaussian_connectivity ======================================== .. only:: html .. |launchbinder| image:: http://mybinder.org/badge.svg .. _launchbinder: https://mybinder.org/v2/gh/brian-team/brian2-binder/master?filepath=examples/synapses/efficient_gaussian_connectivity.ipynb .. note:: You can launch an interactive, editable version of this example without installing any local files using the Binder service (although note that at some times this may be slow or fail to open): |launchbinder|_ An example of turning an expensive `Synapses.connect` operation into three cheap ones using a mathematical trick. Consider the connection probability between neurons i and j given by the Gaussian function :math:`p=e^{-\alpha(i-j)^2}` (for some constant :math:`\alpha`). If we want to connect neurons with this probability, we can very simply do:: S.connect(p='exp(-alpha*(i-j)**2)') However, this has a problem. Although we know that this will create :math:`O(N)` synapses if N is the number of neurons, because we have specified ``p`` as a function of i and j, we have to evaluate ``p(i, j)`` for every pair ``(i, j)``, and therefore it takes :math:`O(N^2)` operations. Our first option is to take a cutoff, and say that if :math:`pw`. This time, we note that we want to create a synapse with probability :math:`p(i-j)` and we can rewrite this as :math:`p(i-j)/p(w)\cdot p(w)`. If :math:`|i-j|>w` then this is a product of two probabilities :math:`p(i-j)/p(w)` and :math:`p(w)`. So in the region :math:`|i-j|>w` a synapse will be created if two random events both occur, with these two probabilities. This might seem a little strange until you notice that one of the two probabilities :math:`p(w)` doesn't depend on i or j. This lets us use the much more efficient ``sample`` algorithm to generate a set of candidate ``j`` values, and then add the additional test ``rand()