Show
Ignore:
Timestamp:
03/05/10 15:33:46 (2 years ago)
Author:
pierre
Message:

Commit an home made version of the DistanceDependentProbabilityConnector? for NEST. Again, this is much faster than the generic implementation. Only this implementation scales and can be used for large scale networks. It is time and memory efficient, the only difference is that weights and delays are not saved in the connector. But anyway, I don't think that the way it is currently done in the generic implementation is efficient: those weights and delays should not be kept by the Connector, and I think that the Probabilistic object should be called for each sources, and not only once.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/nest/connectors.py

    r687 r724  
    44$Id$ 
    55""" 
    6 from pyNN import random, common 
    7  
     6from pyNN import random, common, core 
     7from numpy import arccos, arcsin, arctan, arctan2, ceil, cos, cosh, e, exp, \ 
     8                  fabs, floor, fmod, hypot, ldexp, log, log10, modf, pi, power, \ 
     9                  sin, sinh, sqrt, tan, tanh 
    810from pyNN.connectors import AllToAllConnector, \ 
    911                            OneToOneConnector, \ 
     
    1416                            FixedNumberPreConnector, \ 
    1517                            FixedNumberPostConnector 
    16  
     18import numpy 
    1719 
    1820class FixedNumberPreConnector(FixedNumberPreConnector): 
     
    4850             
    4951            projection.connection_manager.convergent_connect(sources, [target], weights, delays) 
     52 
     53 
     54class DistanceDependentProbabilityConnector(DistanceDependentProbabilityConnector): 
     55 
     56    __doc__ = DistanceDependentProbabilityConnector.__doc__ 
     57     
     58    def connect(self, projection): 
     59        """Connect-up a Projection.""" 
     60        local          = projection.post._mask_local.flatten() 
     61        positions      = self.space.scale_factor*(projection.post.positions[:, local] + self.space.offset) 
     62        N              = projection.post.size             
     63        is_conductance = common.is_conductance(projection.post.index(0))    
     64         
     65        if isinstance(projection.rng, random.NativeRNG): 
     66            raise Exception("Use of NativeRNG not implemented.") 
     67        else: 
     68            rng = projection.rng 
     69         
     70        for src in projection.pre.all():             
     71            d     = self.space.distances(src.position, positions).flatten() 
     72            proba = eval(self.d_expression) 
     73            if proba.dtype == 'bool': 
     74                proba = proba.astype(float) 
     75            rarr = rng.next(N, 'uniform', (0, 1), mask_local=local) 
     76            if not core.is_listlike(rarr) and numpy.isscalar(rarr): # if N=1, rarr will be a single number 
     77                rarr = numpy.array([rarr]) 
     78            create = rarr < proba 
     79            if create.shape != projection.post.local_cells.shape: 
     80                logger.warning("Too many random numbers. Discarding the excess. Did you specify MPI rank and number of processes when you created the random number generator?") 
     81                create = create[:projection.post.local_cells.size] 
     82            targets = projection.post.local_cells[create].tolist() 
     83             
     84            if hasattr(self, 'w_expr'): 
     85                weights = eval(self.w_expr)[create] 
     86            else: 
     87                weights = self.get_weights(N, local)[create]             
     88            weights = common.check_weight(weights, projection.synapse_type, is_conductance) 
     89             
     90            if hasattr(self, 'd_expr'): 
     91                delays = eval(self.d_expr)[create] 
     92            else: 
     93                delays = self.get_delays(N, local)[create]             
     94                 
     95            if not self.allow_self_connections and projection.pre == projection.post and src in targets: 
     96                assert len(targets) == len(weights) == len(delays) 
     97                i       = targets.index(src) 
     98                weights = numpy.delete(weights, i) 
     99                delays  = numpy.delete(delays, i) 
     100                targets.remove(src) 
     101 
     102            if len(targets) > 0: 
     103                projection.connection_manager.connect(src, targets, weights, delays)