Esempio n. 1
0
    def _get_weight_maximum(self, weights, n_connections, synapse_info):
        """ Get the maximum of the weights.

        :param weights:
        :type weights: ~numpy.ndarray or ~pyNN.random.NumpyRNG or int or float
            or list(int) or list(float)
        :param int n_connections:
        :rtype: float
        """
        if isinstance(weights, RandomDistribution):
            mean_weight = utility_calls.get_mean(weights)
            if mean_weight < 0:
                min_weight = utility_calls.get_minimum_probable_value(
                    weights, n_connections)
                low = utility_calls.low(weights)
                if low is None:
                    return abs(min_weight)
                return abs(max(min_weight, low))
            else:
                max_weight = utility_calls.get_maximum_probable_value(
                    weights, n_connections)
                high = utility_calls.high(weights)
                if high is None:
                    return abs(max_weight)
                return abs(min(max_weight, high))
        elif isinstance(weights, str):
            d = self._get_distances(weights, synapse_info)
            return numpy.max(_expr_context.eval(weights, d=d))
        elif numpy.isscalar(weights):
            return abs(weights)
        elif hasattr(weights, "__getitem__"):
            return numpy.amax(numpy.abs(weights))
        raise SpynnakerException("Unrecognised weight format")
    def update_weight(self, graph_mapper):
        pre_vertex = graph_mapper.get_application_vertex(self.pre_vertex)
        pre_slice_index = graph_mapper.get_machine_vertex_index(
            self.pre_vertex)
        pre_vertex_slice = graph_mapper.get_slice(self.pre_vertex)
        pre_slices = graph_mapper.get_slices(pre_vertex)
        post_vertex = graph_mapper.get_application_vertex(self.post_vertex)
        post_slice_index = graph_mapper.get_machine_vertex_index(
            self.post_vertex)
        post_vertex_slice = graph_mapper.get_slice(self.post_vertex)
        post_slices = graph_mapper.get_slices(post_vertex)

        weight = 0
        for synapse_info in self._synapse_information:
            new_weight = synapse_info.connector.\
                get_n_connections_to_post_vertex_maximum(
                    pre_slices, pre_slice_index, post_slices,
                    post_slice_index, pre_vertex_slice, post_vertex_slice)
            new_weight *= pre_vertex_slice.n_atoms
            if hasattr(pre_vertex, "rate"):
                rate = pre_vertex.rate
                if hasattr(rate, "__getitem__"):
                    rate = max(rate)
                elif globals_variables.get_simulator().is_a_pynn_random(rate):
                    rate = utility_calls.get_maximum_probable_value(
                        rate, pre_vertex_slice.n_atoms)
                new_weight *= rate
            elif hasattr(pre_vertex, "spikes_per_second"):
                new_weight *= pre_vertex.spikes_per_second
            weight += new_weight

        self._traffic_weight = weight
    def _get_weight_maximum(weights, n_connections, connection_slices):
        """ Get the maximum of the weights
        """
        if isinstance(weights, RandomDistribution):
            mean_weight = utility_calls.get_mean(weights)
            if mean_weight < 0:
                min_weight = utility_calls.get_minimum_probable_value(
                    weights, n_connections)
                if weights.boundaries is not None:
                    return abs(max(min_weight, min(weights.boundaries)))
                return abs(min_weight)
            else:
                max_weight = utility_calls.get_maximum_probable_value(
                    weights, n_connections)
                if weights.boundaries is not None:
                    return abs(min(max_weight, max(weights.boundaries)))
                return abs(max_weight)

        elif numpy.isscalar(weights):
            return weights
        elif hasattr(weights, "__getitem__"):
            return numpy.amax([
                weights[connection_slice]
                for connection_slice in connection_slices
            ])
        raise Exception("Unrecognised weight format")
    def _get_weight_maximum(self, weights, n_connections):
        """ Get the maximum of the weights.
        """
        if get_simulator().is_a_pynn_random(weights):
            mean_weight = utility_calls.get_mean(weights)
            if mean_weight < 0:
                min_weight = utility_calls.get_minimum_probable_value(
                    weights, n_connections)
                low = utility_calls.low(weights)
                if low is None:
                    return abs(min_weight)
                return abs(max(min_weight, low))
            else:
                max_weight = utility_calls.get_maximum_probable_value(
                    weights, n_connections)
                high = utility_calls.high(weights)
                if high is None:
                    return abs(max_weight)
                return abs(min(max_weight, high))

        elif numpy.isscalar(weights):
            return abs(weights)
        elif hasattr(weights, "__getitem__"):
            return numpy.amax(numpy.abs(weights))
        raise Exception("Unrecognised weight format")
    def update_weight(self, graph_mapper):
        pre_vertex = graph_mapper.get_vertex_from_subvertex(
            self._pre_subvertex)
        pre_slice_index = graph_mapper.get_subvertex_index(self._pre_subvertex)
        pre_vertex_slice = graph_mapper.get_subvertex_slice(
            self._pre_subvertex)
        pre_slices = graph_mapper.get_subvertex_slices(pre_vertex)
        post_vertex = graph_mapper.get_vertex_from_subvertex(
            self._post_subvertex)
        post_slice_index = graph_mapper.get_subvertex_index(
            self._post_subvertex)
        post_vertex_slice = graph_mapper.get_subvertex_slice(
            self._post_subvertex)
        post_slices = graph_mapper.get_subvertex_slices(post_vertex)

        weight = 0
        for synapse_info in self._synapse_information:
            new_weight = synapse_info.connector.\
                get_n_connections_to_post_vertex_maximum(
                    pre_slices, pre_slice_index, post_slices,
                    post_slice_index, pre_vertex_slice, post_vertex_slice)
            new_weight *= pre_vertex_slice.n_atoms
            if hasattr(pre_vertex, "rate"):
                rate = pre_vertex.rate
                if hasattr(rate, "__getitem__"):
                    rate = max(rate)
                elif isinstance(rate, RandomDistribution):
                    rate = utility_calls.get_maximum_probable_value(
                        rate, pre_vertex_slice.n_atoms)
                new_weight *= rate
            elif hasattr(pre_vertex, "spikes_per_second"):
                new_weight *= pre_vertex.spikes_per_second
            weight += new_weight

        self._weight = weight
Esempio n. 6
0
    def _get_weight_maximum(weights, n_connections, connection_slices):
        """ Get the maximum of the weights
        """
        if globals_variables.get_simulator().is_a_pynn_random(weights):
            mean_weight = utility_calls.get_mean(weights)
            if mean_weight < 0:
                min_weight = utility_calls.get_minimum_probable_value(
                    weights, n_connections)
                if weights.boundaries is not None:
                    return abs(max(min_weight, min(weights.boundaries)))
                return abs(min_weight)
            else:
                max_weight = utility_calls.get_maximum_probable_value(
                    weights, n_connections)
                if weights.boundaries is not None:
                    return abs(min(max_weight, max(weights.boundaries)))
                return abs(max_weight)

        elif numpy.isscalar(weights):
            return abs(weights)
        elif hasattr(weights, "__getitem__"):
            return numpy.amax([
                numpy.abs(weights[connection_slice])
                for connection_slice in connection_slices
            ])
        raise Exception("Unrecognised weight format")
    def update_weight(self, graph_mapper):
        pre_vertex = graph_mapper.get_vertex_from_subvertex(
            self._pre_subvertex)
        pre_slice_index = graph_mapper.get_subvertex_index(self._pre_subvertex)
        pre_vertex_slice = graph_mapper.get_subvertex_slice(
            self._pre_subvertex)
        pre_slices = graph_mapper.get_subvertex_slices(pre_vertex)
        post_vertex = graph_mapper.get_vertex_from_subvertex(
            self._post_subvertex)
        post_slice_index = graph_mapper.get_subvertex_index(
            self._post_subvertex)
        post_vertex_slice = graph_mapper.get_subvertex_slice(
            self._post_subvertex)
        post_slices = graph_mapper.get_subvertex_slices(post_vertex)

        weight = 0
        for synapse_info in self._synapse_information:
            new_weight = synapse_info.connector.\
                get_n_connections_to_post_vertex_maximum(
                    pre_slices, pre_slice_index, post_slices,
                    post_slice_index, pre_vertex_slice, post_vertex_slice)
            new_weight *= pre_vertex_slice.n_atoms
            if hasattr(pre_vertex, "rate"):
                rate = pre_vertex.rate
                if hasattr(rate, "__getitem__"):
                    rate = max(rate)
                elif isinstance(rate, RandomDistribution):
                    rate = utility_calls.get_maximum_probable_value(
                        rate, pre_vertex_slice.n_atoms)
                new_weight *= rate
            elif hasattr(pre_vertex, "spikes_per_second"):
                new_weight *= pre_vertex.spikes_per_second
            weight += new_weight

        self._weight = weight
Esempio n. 8
0
    def _get_delay_maximum(self, delays, n_connections, synapse_info):
        """ Get the maximum delay given a float, RandomDistribution or list of\
            delays.

        :param delays:
        :type delays: ~numpy.ndarray or ~pyNN.random.NumpyRNG or int or float
            or list(int) or list(float)
        :param int n_connections:
        """
        if isinstance(delays, RandomDistribution):
            max_estimated_delay = utility_calls.get_maximum_probable_value(
                delays, n_connections)
            high = utility_calls.high(delays)
            if high is None:
                return max_estimated_delay

            # The maximum is the minimum of the possible maximums
            return min(max_estimated_delay, high)
        elif isinstance(delays, str):
            d = self._get_distances(delays, synapse_info)
            return numpy.max(_expr_context.eval(delays, d=d))
        elif numpy.isscalar(delays):
            return delays
        elif hasattr(delays, "__getitem__"):
            return numpy.max(delays)
        raise SpynnakerException("Unrecognised delay format: {:s}".format(
            type(delays)))
Esempio n. 9
0
    def _get_weight_maximum(weights, n_connections, connection_slices):
        """ Get the maximum of the weights
        """
        if isinstance(weights, RandomDistribution):
            mean_weight = utility_calls.get_mean(weights)
            if mean_weight < 0:
                min_weight = utility_calls.get_minimum_probable_value(
                    weights, n_connections)
                if weights.boundaries is not None:
                    return abs(max(min_weight, min(weights.boundaries)))
                return abs(min_weight)
            else:
                max_weight = utility_calls.get_maximum_probable_value(
                    weights, n_connections)
                if weights.boundaries is not None:
                    return abs(min(max_weight, max(weights.boundaries)))
                return abs(max_weight)

        elif numpy.isscalar(weights):
            return abs(weights)
        elif hasattr(weights, "__getitem__"):
            return numpy.amax([
                numpy.abs(weights[connection_slice])
                for connection_slice in connection_slices])
        raise Exception("Unrecognised weight format")
Esempio n. 10
0
    def _get_weight_maximum(self, weights, n_connections):
        """ Get the maximum of the weights.
        """
        if get_simulator().is_a_pynn_random(weights):
            mean_weight = utility_calls.get_mean(weights)
            if mean_weight < 0:
                min_weight = utility_calls.get_minimum_probable_value(
                    weights, n_connections)
                low = utility_calls.low(weights)
                if low is None:
                    return abs(min_weight)
                return abs(max(min_weight, low))
            else:
                max_weight = utility_calls.get_maximum_probable_value(
                    weights, n_connections)
                high = utility_calls.high(weights)
                if high is None:
                    return abs(max_weight)
                return abs(min(max_weight, high))

        elif numpy.isscalar(weights):
            return abs(weights)
        elif hasattr(weights, "__getitem__"):
            return numpy.amax(numpy.abs(weights))
        raise Exception("Unrecognised weight format")
 def _get_delay_maximum(delays, n_connections):
     """ Get the maximum delay given a float, RandomDistribution or list of\
         delays
     """
     if isinstance(delays, RandomDistribution):
         max_estimated_delay = utility_calls.get_maximum_probable_value(
             delays, n_connections)
         if delays.boundaries is not None:
             return min(max(delays.boundaries), max_estimated_delay)
         return max_estimated_delay
     elif numpy.isscalar(delays):
         return delays
     elif hasattr(delays, "__getitem__"):
         return max(delays)
     raise Exception("Unrecognised delay format")
Esempio n. 12
0
 def _get_delay_maximum(delays, n_connections):
     """ Get the maximum delay given a float, RandomDistribution or list of\
         delays
     """
     if isinstance(delays, RandomDistribution):
         max_estimated_delay = utility_calls.get_maximum_probable_value(
             delays, n_connections)
         if delays.boundaries is not None:
             return min(max(delays.boundaries), max_estimated_delay)
         return max_estimated_delay
     elif numpy.isscalar(delays):
         return delays
     elif hasattr(delays, "__getitem__"):
         return max(delays)
     raise Exception("Unrecognised delay format")
Esempio n. 13
0
    def _get_delay_maximum(self, delays, n_connections):
        """ Get the maximum delay given a float, RandomDistribution or list of\
            delays.
        """
        if get_simulator().is_a_pynn_random(delays):
            max_estimated_delay = utility_calls.get_maximum_probable_value(
                delays, n_connections)
            high = utility_calls.high(delays)
            if high is None:
                return max_estimated_delay

            # The maximum is the minimum of the possible maximums
            return min(max_estimated_delay, high)
        elif numpy.isscalar(delays):
            return delays
        elif hasattr(delays, "__getitem__"):
            return numpy.max(delays)
        raise Exception("Unrecognised delay format: {:s}".format(type(delays)))
    def _get_delay_maximum(self, delays, n_connections):
        """ Get the maximum delay given a float, RandomDistribution or list of\
            delays.
        """
        if get_simulator().is_a_pynn_random(delays):
            max_estimated_delay = utility_calls.get_maximum_probable_value(
                delays, n_connections)
            high = utility_calls.high(delays)
            if high is None:
                return max_estimated_delay

            # The maximum is the minimum of the possible maximums
            return min(max_estimated_delay, high)
        elif numpy.isscalar(delays):
            return delays
        elif hasattr(delays, "__getitem__"):
            return numpy.max(delays)
        raise Exception("Unrecognised delay format: {:s}".format(
            type(delays)))
Esempio n. 15
0
    def _get_delay_maximum(delays, n_connections):
        """ Get the maximum delay given a float, RandomDistribution or list of\
            delays
        """
        if globals_variables.get_simulator().is_a_pynn_random(delays):
            max_estimated_delay = utility_calls.get_maximum_probable_value(
                delays, n_connections)
            if hasattr(delays, "boundaries"):
                if delays.boundaries is not None:
                    return min(max(delays.boundaries), max_estimated_delay)
            elif isinstance(delays.parameters, dict):
                if "max" in delays.parameters:
                    return delays.parameters['max']

            return max_estimated_delay
        elif numpy.isscalar(delays):
            return delays
        elif hasattr(delays, "__getitem__"):
            return max(delays)
        raise Exception("Unrecognised delay format")
    def update_weight(self):
        pre_vertex = self.pre_vertex.app_vertex
        pre_vertex_slice = self.pre_vertex.vertex_slice

        weight = 0
        for synapse_info in self.__synapse_information:
            new_weight = synapse_info.connector.\
                get_n_connections_to_post_vertex_maximum(synapse_info)
            new_weight *= pre_vertex_slice.n_atoms
            if hasattr(pre_vertex, "rate"):
                rate = pre_vertex.rate
                if hasattr(rate, "__getitem__"):
                    rate = max(rate)
                elif isinstance(rate, RandomDistribution):
                    rate = utility_calls.get_maximum_probable_value(
                        rate, pre_vertex_slice.n_atoms)
                new_weight *= rate
            elif hasattr(pre_vertex, "spikes_per_second"):
                new_weight *= pre_vertex.spikes_per_second
            weight += new_weight

        self._traffic_weight = weight
    def update_weight(self, graph_mapper):
        pre_vertex = graph_mapper.get_application_vertex(
            self.pre_vertex)
        pre_vertex_slice = graph_mapper.get_slice(
            self.pre_vertex)

        weight = 0
        for synapse_info in self._synapse_information:
            new_weight = synapse_info.connector.\
                get_n_connections_to_post_vertex_maximum()
            new_weight *= pre_vertex_slice.n_atoms
            if hasattr(pre_vertex, "rate"):
                rate = pre_vertex.rate
                if hasattr(rate, "__getitem__"):
                    rate = max(rate)
                elif globals_variables.get_simulator().is_a_pynn_random(rate):
                    rate = utility_calls.get_maximum_probable_value(
                        rate, pre_vertex_slice.n_atoms)
                new_weight *= rate
            elif hasattr(pre_vertex, "spikes_per_second"):
                new_weight *= pre_vertex.spikes_per_second
            weight += new_weight

        self._traffic_weight = weight
Esempio n. 18
0
    def _get_ring_buffer_to_input_left_shifts(self, machine_vertex,
                                              machine_graph, graph_mapper,
                                              post_slices, post_slice_index,
                                              post_vertex_slice,
                                              machine_timestep, weight_scale):
        """ Get the scaling of the ring buffer to provide as much accuracy as\
            possible without too much overflow
        """
        weight_scale_squared = weight_scale * weight_scale
        n_synapse_types = self._synapse_type.get_n_synapse_types()
        running_totals = [RunningStats() for _ in range(n_synapse_types)]
        delay_running_totals = [RunningStats() for _ in range(n_synapse_types)]
        total_weights = numpy.zeros(n_synapse_types)
        biggest_weight = numpy.zeros(n_synapse_types)
        weights_signed = False
        rate_stats = [RunningStats() for _ in range(n_synapse_types)]
        steps_per_second = 1000000.0 / machine_timestep

        for m_edge in machine_graph.get_edges_ending_at_vertex(machine_vertex):

            pre_vertex_slice = graph_mapper.get_slice(m_edge.pre_vertex)
            app_edge = graph_mapper.get_application_edge(m_edge)
            pre_slices = [
                graph_mapper.get_slice(internal_machine_vertex)
                for internal_machine_vertex in
                graph_mapper.get_machine_vertices(app_edge.pre_vertex)
            ]
            pre_slice_index = pre_slices.index(pre_vertex_slice)
            if isinstance(app_edge, ProjectionApplicationEdge):
                for synapse_info in app_edge.synapse_information:
                    synapse_type = synapse_info.synapse_type
                    synapse_dynamics = synapse_info.synapse_dynamics
                    connector = synapse_info.connector
                    weight_mean = abs(
                        synapse_dynamics.get_weight_mean(
                            connector, pre_slices, pre_slice_index,
                            post_slices, post_slice_index, pre_vertex_slice,
                            post_vertex_slice) * weight_scale)
                    n_connections = \
                        connector.get_n_connections_to_post_vertex_maximum(
                            pre_slices, pre_slice_index, post_slices,
                            post_slice_index, pre_vertex_slice,
                            post_vertex_slice)
                    weight_variance = abs(
                        synapse_dynamics.get_weight_variance(
                            connector, pre_slices, pre_slice_index,
                            post_slices, post_slice_index, pre_vertex_slice,
                            post_vertex_slice) * weight_scale_squared)
                    running_totals[synapse_type].add_items(
                        weight_mean, weight_variance, n_connections)

                    delay_variance = synapse_dynamics.get_delay_variance(
                        connector, pre_slices, pre_slice_index, post_slices,
                        post_slice_index, pre_vertex_slice, post_vertex_slice)
                    delay_running_totals[synapse_type].add_items(
                        0.0, delay_variance, n_connections)

                    weight_max = (synapse_dynamics.get_weight_maximum(
                        connector, pre_slices, pre_slice_index, post_slices,
                        post_slice_index, pre_vertex_slice, post_vertex_slice)
                                  * weight_scale)
                    biggest_weight[synapse_type] = max(
                        biggest_weight[synapse_type], weight_max)

                    spikes_per_tick = max(
                        1.0, self._spikes_per_second / steps_per_second)
                    spikes_per_second = self._spikes_per_second
                    if isinstance(app_edge.pre_vertex, SpikeSourcePoisson):
                        spikes_per_second = app_edge.pre_vertex.rate
                        if hasattr(spikes_per_second, "__getitem__"):
                            spikes_per_second = max(spikes_per_second)
                        elif get_simulator().is_a_pynn_random(
                                spikes_per_second):
                            spikes_per_second = get_maximum_probable_value(
                                spikes_per_second, pre_vertex_slice.n_atoms)
                        prob = 1.0 - ((1.0 / 100.0) / pre_vertex_slice.n_atoms)
                        spikes_per_tick = spikes_per_second / steps_per_second
                        spikes_per_tick = scipy.stats.poisson.ppf(
                            prob, spikes_per_tick)
                    rate_stats[synapse_type].add_items(spikes_per_second, 0,
                                                       n_connections)
                    total_weights[synapse_type] += spikes_per_tick * (
                        weight_max * n_connections)

                    if synapse_dynamics.are_weights_signed():
                        weights_signed = True

        max_weights = numpy.zeros(n_synapse_types)
        for synapse_type in range(n_synapse_types):
            stats = running_totals[synapse_type]
            rates = rate_stats[synapse_type]
            if delay_running_totals[synapse_type].variance == 0.0:
                max_weights[synapse_type] = max(total_weights[synapse_type],
                                                biggest_weight[synapse_type])
            else:
                max_weights[synapse_type] = min(
                    self._ring_buffer_expected_upper_bound(
                        stats.mean, stats.standard_deviation, rates.mean,
                        machine_timestep, stats.n_items,
                        self._ring_buffer_sigma), total_weights[synapse_type])
                max_weights[synapse_type] = max(max_weights[synapse_type],
                                                biggest_weight[synapse_type])

        # Convert these to powers
        max_weight_powers = (0 if w <= 0 else int(
            math.ceil(max(0, math.log(w, 2)))) for w in max_weights)

        # If 2^max_weight_power equals the max weight, we have to add another
        # power, as range is 0 - (just under 2^max_weight_power)!
        max_weight_powers = (w + 1 if (2**w) <= a else w
                             for w, a in zip(max_weight_powers, max_weights))

        # If we have synapse dynamics that uses signed weights,
        # Add another bit of shift to prevent overflows
        if weights_signed:
            max_weight_powers = (m + 1 for m in max_weight_powers)

        return list(max_weight_powers)
Esempio n. 19
0
    def _get_ring_buffer_to_input_left_shifts(
            self, subvertex, sub_graph, graph_mapper, post_slices,
            post_slice_index, post_vertex_slice, machine_timestep,
            weight_scale):
        """ Get the scaling of the ring buffer to provide as much accuracy as\
            possible without too much overflow
        """
        weight_scale_squared = weight_scale * weight_scale
        n_synapse_types = self._synapse_type.get_n_synapse_types()
        running_totals = [RunningStats() for _ in range(n_synapse_types)]
        delay_running_totals = [RunningStats() for _ in range(n_synapse_types)]
        total_weights = numpy.zeros(n_synapse_types)
        biggest_weight = numpy.zeros(n_synapse_types)
        weights_signed = False
        rate_stats = [RunningStats() for _ in range(n_synapse_types)]

        for subedge in sub_graph.incoming_subedges_from_subvertex(subvertex):
            pre_vertex_slice = graph_mapper.get_subvertex_slice(
                subedge.pre_subvertex)
            edge = graph_mapper.get_partitionable_edge_from_partitioned_edge(
                subedge)
            pre_slices = [
                graph_mapper.get_subvertex_slice(subv)
                for subv in graph_mapper.get_subvertices_from_vertex(
                    edge.pre_vertex)]
            pre_slice_index = pre_slices.index(pre_vertex_slice)
            if isinstance(edge, ProjectionPartitionableEdge):
                for synapse_info in edge.synapse_information:
                    synapse_type = synapse_info.synapse_type
                    synapse_dynamics = synapse_info.synapse_dynamics
                    connector = synapse_info.connector
                    weight_mean = abs(synapse_dynamics.get_weight_mean(
                        connector, pre_slices, pre_slice_index,
                        post_slices, post_slice_index, pre_vertex_slice,
                        post_vertex_slice) * weight_scale)
                    n_connections = \
                        connector.get_n_connections_to_post_vertex_maximum(
                            pre_slices, pre_slice_index, post_slices,
                            post_slice_index, pre_vertex_slice,
                            post_vertex_slice)
                    weight_variance = abs(synapse_dynamics.get_weight_variance(
                        connector, pre_slices, pre_slice_index,
                        post_slices, post_slice_index, pre_vertex_slice,
                        post_vertex_slice) * weight_scale_squared)
                    running_totals[synapse_type].add_items(
                        weight_mean, weight_variance, n_connections)

                    delay_variance = synapse_dynamics.get_delay_variance(
                        connector, pre_slices, pre_slice_index,
                        post_slices, post_slice_index, pre_vertex_slice,
                        post_vertex_slice)
                    delay_running_totals[synapse_type].add_items(
                        0.0, delay_variance, n_connections)

                    weight_max = (synapse_dynamics.get_weight_maximum(
                        connector, pre_slices, pre_slice_index,
                        post_slices, post_slice_index, pre_vertex_slice,
                        post_vertex_slice) * weight_scale)
                    biggest_weight[synapse_type] = max(
                        biggest_weight[synapse_type], weight_max)

                    spikes_per_tick = self._spikes_per_tick
                    spikes_per_second = self._spikes_per_second
                    if isinstance(edge.pre_vertex, SpikeSourcePoisson):
                        spikes_per_second = edge.pre_vertex.rate
                        if hasattr(spikes_per_second, "__getitem__"):
                            spikes_per_second = max(spikes_per_second)
                        elif isinstance(spikes_per_second, RandomDistribution):
                            spikes_per_second = \
                                utility_calls.get_maximum_probable_value(
                                    spikes_per_second,
                                    pre_vertex_slice.n_atoms)
                        prob = 1.0 - ((1.0 / 100.0) / pre_vertex_slice.n_atoms)
                        spikes_per_tick = (
                            spikes_per_second /
                            (1000000.0 / float(self._machine_time_step)))
                        spikes_per_tick = scipy.stats.poisson.ppf(
                            prob, spikes_per_tick)
                    rate_stats[synapse_type].add_items(
                        spikes_per_second, 0, n_connections)
                    total_weights[synapse_type] += spikes_per_tick * (
                        weight_max * n_connections)

                    if synapse_dynamics.are_weights_signed():
                        weights_signed = True

        max_weights = numpy.zeros(n_synapse_types)
        for synapse_type in range(n_synapse_types):
            stats = running_totals[synapse_type]
            rates = rate_stats[synapse_type]
            if delay_running_totals[synapse_type].variance == 0.0:
                max_weights[synapse_type] = total_weights[synapse_type]
            else:
                max_weights[synapse_type] = min(
                    self._ring_buffer_expected_upper_bound(
                        stats.mean, stats.standard_deviation,
                        rates.mean, machine_timestep, stats.n_items,
                        self._ring_buffer_sigma),
                    total_weights[synapse_type])
                max_weights[synapse_type] = max(
                    max_weights[synapse_type], biggest_weight[synapse_type])

        # Convert these to powers
        max_weight_powers = [0 if w <= 0
                             else int(math.ceil(max(0, math.log(w, 2))))
                             for w in max_weights]

        # If 2^max_weight_power equals the max weight, we have to add another
        # power, as range is 0 - (just under 2^max_weight_power)!
        max_weight_powers = [w + 1 if (2 ** w) <= a else w
                             for w, a in zip(max_weight_powers, max_weights)]

        # If we have synapse dynamics that uses signed weights,
        # Add another bit of shift to prevent overflows
        if weights_signed:
            max_weight_powers = [m + 1 for m in max_weight_powers]

        return max_weight_powers