Beispiel #1
0
    def write(self, extracted_global_state: Sequence[Node]) -> None:
        """
        Extract the shortest separations between all leaf unit pairs in different composite objects and write them to
        the temporary files.

        Parameters
        ----------
        extracted_global_state : Sequence[base.node.Node]
            The extracted global state.
        """
        super().write(extracted_global_state)
        for first_root_cnode_index, first_root_cnode in enumerate(
                extracted_global_state):
            for second_root_cnode_index in range(first_root_cnode_index + 1,
                                                 len(extracted_global_state)):
                second_root_cnode = extracted_global_state[
                    second_root_cnode_index]
                for first_leaf_node in yield_leaf_nodes(first_root_cnode):
                    for second_leaf_node in yield_leaf_nodes(
                            second_root_cnode):
                        first_leaf_identifier = first_leaf_node.value.identifier[
                            -1]
                        second_leaf_identifier = second_leaf_node.value.identifier[
                            -1]
                        identifier_distance = (
                            abs(first_leaf_identifier - second_leaf_identifier)
                            if setting.number_of_node_levels > 1 else 0)
                        separation = setting.periodic_boundaries.separation_vector(
                            first_leaf_node.value.position,
                            second_leaf_node.value.position)
                        print(vectors.norm(separation),
                              file=self._files[identifier_distance])
Beispiel #2
0
    def yield_identifiers_send_event_time(
        self, extracted_active_global_state: Sequence[Node]
    ) -> Iterable[Tuple[StateId, ...]]:
        """
        Generate in-state identifiers for the send_event_time method of this tagger's event handlers.

        The in-state identifiers will be transformed into real in-states using the state handler via the mediator.
        The active global state is given by a sequence of root cnodes where each cnode branch only contains active
        units. The in-state identifiers are generated as a tuple of global state identifiers.

        The generated in-states are given by the factor type map.

        Parameters
        ----------
        extracted_active_global_state : Sequence[base.node.Node]
            The active global state information.

        Yields
        ------
        Tuple[activator.tag_activator.StateId, ...]
            The global state in-state identifiers.
        """
        # TODO Change yield_factor_identifier of factor type map to not call set here?
        yield from set(
            factor for root_cnode in extracted_active_global_state
            for leaf_cnode in yield_leaf_nodes(root_cnode)
            for factor in self._factor_type_map.yield_factor_identifier(
                leaf_cnode.value.identifier))
    def send_out_state(self, target_cnode: Union[Node, None]) -> Sequence[Node]:
        """
        Return the out-state.

        This method receives the branch of the composite object in the sampled target cell. If it is None, the
        time-sliced active composite object branch which was transmitted in the send_event_time method is returned.
        Otherwise, first the event is confirmed. If it is confirmed, the lifting scheme determines the new active leaf
        unit, which is imprinted in the out-state consisting of both branches of the two composite objects.

        Parameters
        ----------
        target_cnode : Node or None
            The root cnode of the composite object in the sampled target cell.

        Returns
        -------
        Sequence[base.node.Node]
            The out-state.
        """
        if target_cnode is None:
            return self._state
        else:
            assert target_cnode.children
            self._state.append(target_cnode)
            for leaf_cnode in yield_leaf_nodes(target_cnode):
                self._leaf_cnodes.append(leaf_cnode)
                self._leaf_units.append(leaf_cnode.value)
            self._construct_leaf_units_of_composite_objects()

            factor_derivative = 0.0
            target_composite_object_factor_derivatives = [0.0] * len(self._target_leaf_units)
            for index, leaf_unit in enumerate(self._target_leaf_units):
                pairwise_derivative = self._potential.derivative(
                    self._active_leaf_unit.velocity,
                    setting.periodic_boundaries.separation_vector(self._active_leaf_unit.position, leaf_unit.position),
                    *self._potential_charges(self._active_leaf_unit, leaf_unit))
                factor_derivative += pairwise_derivative
                target_composite_object_factor_derivatives[index] -= pairwise_derivative
            event_rate = max(0.0, factor_derivative)
            assert self._bounding_event_rate >= 0.0
            bounding_potential_warning(self.__class__.__name__, self._bounding_event_rate, event_rate)
            if event_rate <= random.uniform(0.0, self._bounding_event_rate):
                return self._state

            self._fill_lifting(self._local_leaf_units, self._target_leaf_units,
                               factor_derivative, target_composite_object_factor_derivatives)

            next_active_identifier = self._lifting.get_active_identifier()
            next_active_cnode = [cnode for cnode in self._leaf_cnodes
                                 if cnode.value.identifier == next_active_identifier]
            assert len(next_active_cnode) == 1
            self._exchange_velocity(self._leaf_cnodes[self._active_leaf_unit_index], next_active_cnode[0])
            return self._state
    def send_out_state(
            self, target_unit_root_cnode: Union[Node, None]) -> Sequence[Node]:
        """
        Return the out-state.

        This method receives the branch of the leaf unit in the sampled target cell. If it is None, the time-sliced
        active leaf unit branch which was transmitted in the send_event_time method is returned. Otherwise, first the
        event is confirmed. If it is confirmed, the velocities are exchanged and the branches are kept consistent in the
        out-state.

        Parameters
        ----------
        target_unit_root_cnode : Node or None
            The branch of the leaf unit in the sampled target cell.

        Returns
        -------
        Sequence[base.node.Node]
            The out-state.
        """
        if target_unit_root_cnode is None:
            return self._state
        else:
            self._state.append(target_unit_root_cnode)
            for leaf_cnode in yield_leaf_nodes(target_unit_root_cnode):
                self._leaf_cnodes.append(leaf_cnode)
                self._leaf_units.append(leaf_cnode.value)
            assert len(self._leaf_units) == 2
            self._calculate_out_state_of_two_leaf_unit_bounding_potential(
                setting.periodic_boundaries.separation_vector(
                    self._leaf_units[self._active_leaf_unit_index].position,
                    self._leaf_units[self._active_leaf_unit_index
                                     ^ 1].position),
                self._charges(self._leaf_units[0], self._leaf_units[1]),
            )
            return self._state
    def send_out_state(self, cnodes_with_active_units: Sequence[Node],
                       cnodes_with_new_active_units: Sequence[Node]) -> Sequence[Node]:
        """
        Return the out-state.

        In the out-state, the previously independent active units have a zero velocity and the new independent active
        units have the updated velocity (that is determined by the _get_new_velocity method).

        Parameters
        ----------
        cnodes_with_active_units : Sequence[base.node.Node]
            The root cnodes of the branches of the independent active units.
        cnodes_with_new_active_units : Sequence[base.node.Node]
            The root cnodes of the branches of the units which should get independent active.

        Returns
        -------
        Sequence[base.node.Node]
            The out-state.

        Raises
        ------
        AssertionError
            If not all leaf units in cnodes_with_active_units have the same velocity.
        AssertionError
            If the leaf units in cnodes_with_new_active_units have a non-zero velocity and time stamp but they do not
            appear in cnodes_with_active_units.
        """
        self._store_in_state(cnodes_with_active_units)
        self._time_slice_all_units_in_state()
        self._construct_leaf_cnodes()

        assert all(self._leaf_units[index].velocity == self._leaf_units[0].velocity
                   for index in range(1, len(self._leaf_units)))
        old_velocity = self._leaf_units[0].velocity
        new_velocity = self._get_new_velocity(old_velocity)

        old_active_identifiers = set()
        velocity_changes = {}
        for index, unit in enumerate(self._leaf_units):
            unit.velocity = [0.0 for _ in range(setting.dimension)]
            velocity_changes[unit.identifier] = ([-velocity_component for velocity_component in old_velocity], index)
            old_active_identifiers.add(unit.identifier)

        new_leaf_cnodes = []
        new_leaf_units = []
        for cnode in cnodes_with_new_active_units:
            for leaf_cnode in yield_leaf_nodes(cnode):
                new_leaf_cnodes.append(leaf_cnode)
                new_leaf_units.append(leaf_cnode.value)

        for index, unit in enumerate(new_leaf_units):
            if unit.identifier in old_active_identifiers:
                for velocity_index in range(setting.dimension):
                    velocity_changes[unit.identifier][0][velocity_index] += new_velocity[velocity_index]
                self._leaf_units[velocity_changes[unit.identifier][1]].velocity = copy(new_velocity)
            else:
                assert unit.velocity is None
                assert unit.time_stamp is None
                cnode = new_leaf_cnodes[index]
                self._leaf_units.append(unit)
                self._leaf_cnodes.append(cnode)
                while cnode.parent:
                    cnode = cnode.parent
                if cnode not in self._state:
                    self._state.append(cnode)
                velocity_changes[unit.identifier] = (copy(new_velocity), len(self._leaf_units) - 1)
                unit.velocity = copy(new_velocity)
                unit.time_stamp = copy(self._event_time)

        for leaf_unit in self._leaf_units:
            # noinspection PyTypeChecker
            if all(abs(velocity_component) < 1.0e-13 for velocity_component in leaf_unit.velocity):
                leaf_unit.velocity = None
                leaf_unit.time_stamp = None

        for velocity_change, index in velocity_changes.values():
            self._register_velocity_change_leaf_cnode(self._leaf_cnodes[index], velocity_change)
        self._commit_non_leaf_velocity_changes()
        return self._state