Пример #1
0
    def test_flatten_first_level(self):
        # Signature: name(nested_list)
                # Flattens the first level of an iterable, ie
                #
                # >>> flatten_first_level( [ ['This','is'],['a','short'],['phrase'] ] ) #doctest: +NORMALIZE_WHITESPACE
                # ['This', 'is', 'a', 'short', 'phrase']

        self.assertEqual(
            flatten_first_level([[1, 2], [3, 4, 5], [6]]),
            [1, 2, 3, 4, 5, 6]
        )

        self.assertEqual(
            flatten_first_level(((1, 2), (3, 4, 5), (6,))),
            [1, 2, 3, 4, 5, 6]
        )

        # Check nesting is not flattened:
        self.assertEqual(
            flatten_first_level([[1, ['a', 'b'], 2], [3, 4, ['c', 'd'], 5], [6]]),
            [1, ['a', 'b'], 2, 3, 4, ['c', 'd'], 5, 6]
        )

        self.assertRaises(NineMLRuntimeError, flatten_first_level, [None])
        self.assertRaises(NineMLRuntimeError, flatten_first_level, ['abbn'])
        self.assertRaises(NineMLRuntimeError, flatten_first_level, [True])
        self.assertRaises(NineMLRuntimeError, flatten_first_level, [None, None])
Пример #2
0
    def __init__(self, componentclass, componentname=None):
        assert isinstance(componentclass, DynamicsClass)

        # Is our componentclass already flat??
        if componentclass.is_flat():
            self.reducedcomponent = DynamicsClonerVisitor().visit(componentclass)
            if componentclass.was_flattened():
                self.reducedcomponent.set_flattener(componentclass.flattener)
            return

        # New components name
        self.componentname = componentname if componentname else componentclass.name

        # Make a clone of the componentclass; in which all hierachical components
        # have their internal symbols prefixed:
        cloned_comp = DynamicsClonerVisitorPrefixNamespace().visit(componentclass)

        # Make a list of all components, and those components with regimes:
        self.all_components = list(cloned_comp.query.recurse_all_components)
        self.componentswithregimes = [
            m for m in self.all_components if list(m.regimes)]

        # This will get filled in build_new_regime_space(): (It maps {
        # (Regime,Regime,...,Regime) : Regime, (Regime,Regime,...,Regime) :
        # Regime,} Where the key tuple represents the regimes in the
        # hierachical componentclass, corresponding to self.componentswithregimes.
        # And the values are the regimes in the new componentclass.
        self.old_regime_tuple_to_new_regime_map = None

        # OK, Heavy-lifting Code:
        # ===================== #
        self.build_new_regime_space()

        # Build Our New Component
        self.reducedcomponent = DynamicsClass(
            name=self.componentname,
            aliases=flatten_first_level(
                [m.aliases for m in self.all_components]),
            state_variables=flatten_first_level(
                [m.state_variables for m in self.all_components]),
            regimes=self.old_regime_tuple_to_new_regime_map.values(),
            analog_ports=flatten_first_level(
                [comp.analog_ports for comp in self.all_components]),
            event_ports=flatten_first_level(
                [comp.event_ports for comp in self.all_components]),
            parameters=flatten_first_level([m.parameters
                                            for m in self.all_components]))

        self.remap_analog_ports()

        # Attach this flattening information to the componentclass:
        self.reducedcomponent.set_flattener(self)
Пример #3
0
    def remap_analog_ports(self):
        new_analog_ports = flatten_first_level(
            [comp.analog_ports for comp in self.all_components])
        new_analog_ports = dict([(p.name, p) for p in new_analog_ports])

        # Handle port mappings:
        # portconnections = [ (NS -> NS), (NS -> NS ), (NS -> NS) ]
        portconnections = [
            model.portconnections for model in self.all_components]
        portconnections = list(itertools.chain(* portconnections))

        # ONLY ANALOG PORTS
        portconnections = [pc for pc in portconnections if pc[
            0].get_local_name() in new_analog_ports]

        # A. Handle Receive Ports:
        for src_addr, dst_addr in portconnections[:]:

            srcport = new_analog_ports[src_addr.get_local_name()]
            dstport = new_analog_ports[dst_addr.get_local_name()]
            if dstport.mode == 'recv':

                DynamicsExpandPortDefinition(
                    originalname=dstport.name, targetname=srcport.name).visit(
                        self.reducedcomponent)

                del new_analog_ports[dst_addr.get_local_name()]
                del self.reducedcomponent._analog_receive_ports[
                    dst_addr.get_local_name()]
#                    expect_single(
#                        [p for p in self.reducedcomponent.analog_receive_ports
#                         if p.name == ]))

                portconnections.remove((src_addr, dst_addr))

        # B. Handle Reduce Ports:
        # 1/ Make a map { reduce_port -> [send_port1, send_port2, send_port3],
        # ...}
        reduce_connections = defaultdict(list)
        for src, dst in portconnections:
            dstport = new_analog_ports[dst.get_local_name()]
            srcport = new_analog_ports[src.get_local_name()]
            if dstport.mode == 'reduce':
                reduce_connections[dstport].append(srcport)

        # 2/ Substitute each reduce port in turn:
        for dstport, srcport_list in reduce_connections.iteritems():
            src_subs = [s.name for s in srcport_list]
            terms = [dstport.name] + src_subs
            reduce_expr = dstport.reduce_op.join(terms)

            # globalRemapPort( dstport.name, reduce_expr )
            DynamicsExpandPortDefinition(
                originalname=dstport.name, targetname=reduce_expr).visit(
                    self.reducedcomponent)
Пример #4
0
    def create_compound_regime(cls, regimetuple, name):

        # Copy accross all the odes from each regime.
        # We don't worry about transitions yet, we deal with them later.

        # We need to clone the time_derivatives:
        time_derivs = flatten_first_level(
            [r.time_derivatives for r in regimetuple])
        time_derivs = [DynamicsClonerVisitor().visit(td) for td in time_derivs]

        return Regime(name=name, time_derivatives=time_derivs)
Пример #5
0
    def test_flatten_first_level(self):
        # Signature: name(nested_list)
        # Flattens the first level of an iterable, ie
        #
        # >>> flatten_first_level( [ ['This','is'],['a','short'],['phrase'] ] ) #doctest: +NORMALIZE_WHITESPACE
        # ['This', 'is', 'a', 'short', 'phrase']

        self.assertEqual(flatten_first_level([[1, 2], [3, 4, 5], [6]]),
                         [1, 2, 3, 4, 5, 6])

        self.assertEqual(flatten_first_level(((1, 2), (3, 4, 5), (6, ))),
                         [1, 2, 3, 4, 5, 6])

        # Check nesting is not flattened:
        self.assertEqual(
            flatten_first_level([[1, ['a', 'b'], 2], [3, 4, ['c', 'd'], 5],
                                 [6]]),
            [1, ['a', 'b'], 2, 3, 4, ['c', 'd'], 5, 6])

        self.assertRaises(NineMLRuntimeError, flatten_first_level, [None])
        self.assertRaises(NineMLRuntimeError, flatten_first_level, ['abbn'])
        self.assertRaises(NineMLRuntimeError, flatten_first_level, [True])
        self.assertRaises(NineMLRuntimeError, flatten_first_level,
                          [None, None])
Пример #6
0
    def concat(cls, *args):
        """Concatenates all the Namespace Addresses.

        This method take all the arguments supplied, converts each one into a
        namespace object, then, produces a new namespace object which is the
        concatenation of all the arguments' namespaces.

        For example:

        >>> NamespaceAddress.concat('first.second','third.forth','fifth.sixth')
            NameSpaceAddress: '/first/second/third/forth/fifth/sixth'


        """

        # Turn all the arguments into NamespaceAddress Objects:
        args = [NamespaceAddress(a) for a in args]

        # Combine all the location tuples in each argument
        # into one long list.
        loc = flatten_first_level([list(a.loctuple) for a in args])

        # Create a namespace out of this long new tuple:
        return NamespaceAddress(loc=tuple(loc))
Пример #7
0
    def concat(cls, *args):
        """Concatenates all the Namespace Addresses.

        This method take all the arguments supplied, converts each one into a
        namespace object, then, produces a new namespace object which is the
        concatenation of all the arguments' namespaces.

        For example:

        >>> NamespaceAddress.concat('first.second','third.forth','fifth.sixth')
            NameSpaceAddress: '/first/second/third/forth/fifth/sixth'


        """

        # Turn all the arguments into NamespaceAddress Objects:
        args = [NamespaceAddress(a) for a in args]

        # Combine all the location tuples in each argument
        # into one long list.
        loc = flatten_first_level([list(a.loctuple) for a in args])

        # Create a namespace out of this long new tuple:
        return NamespaceAddress(loc=tuple(loc))