def propagate(self, **args):
        """
        Propagates activation through the network. Optionally, takes input layer names
        as keywords, and their associated activations. If input layer(s) are given, then
        propagate() will return the output layer's activation. If there is more than
        one output layer, then a dictionary is returned.

        Examples:

        >>> net = Network() # doctest: +ELLIPSIS
        Conx using seed: ...
        >>> net.addLayers(2, 5, 1)
        >>> len(net.propagate(input = [0, .5]))
        1
        """
        self.prePropagate(**args)
        for key in args:
            layer = self.getLayer(key)
            if layer.kind == 'Input':
                if self[key].verify and not self[key].activationSet == 0: 
                    raise AttributeError("attempt to set activations on input layer '%s' without reset" % key)
                self.copyActivations(layer, args[key])
            elif layer.kind == 'Context':
                self.copyActivations(layer, args[key])
            elif layer.kind == 'Output' and len(args[key]) == layer.size: # in case you expect propagate to handle the outputs
                self.copyTargets(layer, args[key])
        self.verifyInputs() # better have inputs set
        if self.verbosity > 2: print("Propagate Network '" + self.name + "':")
        # initialize netinput:
        for layer in self.layers:
            if layer.type != 'Input' and layer.active:
                layer.netinput = (layer.weight).copy() 
        # for each connection, in order:
        for layer in self.layers:
            if layer.active:
                for connection in self.connections:
                    if (connection.toLayer.name == layer.name
                        and connection.fromLayer.active
                        and connection.active):

                        a = connection.fromLayer.activation
                        w = connection.weight
                        m = Numeric.matrixmultiply(a, w)
                        ni = m + connection.toLayer.netinput

                        connection.toLayer.netinput = ni

                        #connection.toLayer.netinput = \
                        #    (connection.toLayer.netinput + 
                        #     Numeric.matrixmultiply(connection.fromLayer.activation,
                        #                            connection.weight)) # propagate!

                if layer.type != 'Input':
                    layer.activation = self.activationFunction(layer.netinput)
        for layer in self.layers:
            if layer.log and layer.active:
                layer.writeLog(self)
        self.count += 1 # counts number of times propagate() is called
        if len(args) != 0:
            dict = {}
            for layer in self.layers:
                if layer.type == "Output":
                    dict[layer.name] = layer.activation.copy()
            if len(dict) == 1:
                return dict[list(dict.keys())[0]]
            else:
                return dict
Propagates activation through the network. Optionally, takes input layer names
        as keywords, and their associated activations. If input layer(s) are given, then
        propagate() will return the output layer's activation. If there is more than
        one output layer, then a dictionary is returned.

        Examples:

        >>> net = Network() # doctest: +ELLIPSIS
        Conx using seed: ...
        >>> net.addLayers(2, 5, 1)
        >>> len(net.propagate(input = [0, .5]))
        1