예제 #1
0
def __generate_nand_marbles(input_1: bool, input_2: bool) -> Tuple[Marble]:
    marble1 = Marble(np.array([20, 10]),
                     vel=ZERO,
                     acc=ZERO,
                     mass=BOOL_TO_MASS[input_1],
                     attraction_function=ATTRACTION_FUNCTION,
                     datum=input_1,
                     **STIFFNESS_AND_ATTRACTION)

    marble2 = Marble(np.array([20, 30]),
                     vel=ZERO,
                     acc=ZERO,
                     mass=BOOL_TO_MASS[input_2],
                     attraction_function=ATTRACTION_FUNCTION,
                     datum=input_2,
                     **STIFFNESS_AND_ATTRACTION)
    return marble1, marble2
예제 #2
0
    def test_velocity_weighted_distance_2(self):
        """
        Base case: vel weight not zero.
        """
        pos_1 = torch.tensor([0.0, 15.0])
        m1 = Marble(pos_1, ZERO, ZERO, 0, None, None)

        pos_2 = torch.tensor([0.0, 0.0])
        vel_2 = torch.tensor([0.0, 30.0])
        m2 = Marble(pos_2, vel_2, ZERO, 0, None, None)

        expected = torch.tensor(25.0)
        pos_weight = 1
        vel_weight = 1/3
        result = velocity_weighted_distance(m1, m2, pos_weight, vel_weight)

        torch.testing.assert_allclose(result, expected)
예제 #3
0
 def test_emit_output_type(self):
     """
     Output should be a EmittedMarble, not just a normal Marble.
     """
     prototype = Marble(ZERO, ZERO, ZERO, 0, None, None)
     delay = 0
     emitter = MarbleEmitter(prototype, delay)
     output = emitter.emit()
     self.assertIsInstance(output, EmittedMarble)
예제 #4
0
    def test_error_if_no_other_marbles(self):
        """
        Cannot find closest Marble if no other Marbles exist.
        """
        target = Marble(torch.tensor([12.87, 2.9]), ZERO, ZERO, 0, None, None)
        model = NenwinModel([], [target])

        with self.assertRaises(RuntimeError):
            find_closest_marble_to(target, model)
예제 #5
0
 def test_attraction_marble_2(self):
     """
     Corner case: should not attract any node if the multiplier is 0.
     """
     marble_attraction = 0
     marble = Marble(torch.tensor([-1.], dtype=torch.float), ZERO, ZERO, 0,
                     None, None)
     particle = create_particle(0, 0, marble_attraction, 0)
     result = particle.compute_attraction_force_to(marble)
     self.assertEqual(result, 0)
예제 #6
0
    def test_make_timestep_1(self):
        """
        Base base: single moving Marble, with constant velocity.
        """
        marble = Marble(ZERO, np.array([10]), ZERO, 1, None, None, 0, 0, 0, 0)
        model = NenwinModel([], [marble])

        model.make_timestep(time_passed=1)
        expected_new_pos = torch.tensor([10], dtype=torch.float)

        self.assertTrue(torch.allclose(marble.pos, expected_new_pos))
예제 #7
0
    def test_eaten_marbles_disappear(self):

        # Both are generated at the smame pos, so immediately eaten.
        node = MarbleEaterNode(ZERO, ZERO, ZERO, 10, NewtonianGravity(), 1, 1,
                               1, 0, 10)
        marble = Marble(ZERO, ZERO, ZERO, 10, NewtonianGravity(), datum=None)
        model = NenwinModel([node], [marble])
        model.make_timestep(1.0)

        self.assertSetEqual(model.marbles, set([]))
        self.assertNotIn(marble, model._NenwinModel__all_particles)
예제 #8
0
    def test_find_closest_marble_to_1(self):
        """
        Base case: target particle not in Model.
        """
        marble_positions = (
            (10, 10),
            (5, 10),
            (12.9, 3.2),
            (9.9, -0.7)
        )

        marbles = [Marble(torch.tensor(pos, dtype=torch.float),
                          ZERO, ZERO, 0, None, None)
                   for pos in marble_positions]
        model = NenwinModel([], marbles)

        target = Marble(torch.tensor([12.87, 2.9]), ZERO, ZERO, 0, None, None)

        expected = marbles[2]

        self.assertIs(find_closest_marble_to(target, model), expected)
예제 #9
0
    def set_up_full_emitter(self) -> Tuple:
        prototype = Marble(ZERO, ZERO, ZERO, 0, None, None, 0, 0, 0, 0)
        delay = 1.1
        stored_mass = 1.2
        initial_time_passed = 1.3
        relative_prototype_pos = torch.tensor([1.4])
        emitter = MarbleEmitterVariablePosition(prototype, delay, stored_mass,
                                                initial_time_passed,
                                                relative_prototype_pos)

        output = (prototype, delay, stored_mass, initial_time_passed,
                  relative_prototype_pos, emitter)
        return output
예제 #10
0
    def test_attraction_marble_1(self):
        """
        Check if the marble_attraction multiplier is used to compute force to a
        node.
        """
        marble_attraction = 0.5
        # Position -1 ensures it will be pulled towards '+' x-direction
        marble = Marble(torch.tensor([-1.], dtype=torch.float), ZERO, ZERO, 0,
                        None, None)
        particle = create_particle(0, 0, marble_attraction, 0)

        result = particle.compute_attraction_force_to(marble)
        self.assertEqual(result, ATTRACT_FUNCT.value * marble_attraction)
예제 #11
0
파일: bit.py 프로젝트: Nifrec/nenwin
def __heads_on_to_bit_marble(locker_positions) -> Marble:
    """
    Create a Marble that horizontally collides into the bit center,
    approaching from the left.
    """
    pos = np.array([
        max(map(lambda x: x[0], locker_positions)),
        sum(map(lambda x: x[1], locker_positions)) / len(locker_positions)
    ])
    reader_marble = Marble(pos, np.array([-10,
                                          0]), ZERO, 100, ATTRACTION_FUNCTION,
                           None, **READER_MARBLE_STIFFNESS)
    return reader_marble
예제 #12
0
def gen_marble_at(pos: torch.Tensor,
                  vel: torch.Tensor = ZERO,
                  mass: float = 10,
                  datum: Any = None) -> Marble:
    output = Marble(pos=pos, vel=vel, acc=ZERO,
                    mass=mass,
                    attraction_function=NewtonianGravity(),
                    marble_attraction=0,
                    marble_stiffness=1,
                    node_attraction=0,
                    node_stiffness=0,
                    datum=datum)

    return output
예제 #13
0
파일: canon.py 프로젝트: Nifrec/nenwin
def cannon_experiment():
    """
    Simulate a NAND gate using a Nenwin architecture.
    Also visualizes the simulation and prints the result.
    """
    marble = Marble(pos=np.array([50, 50]),
                    vel=np.array([10, 0]),
                    acc=ZERO,
                    mass=-1,
                    attraction_function=ATTRACTION_FUNCTION,
                    datum=None,
                    **MARBLE_STIFFNESS)
    nodes = __generate_canon_nodes()
    run([marble], nodes)
예제 #14
0
    def test_stiffness_to_marble(self):
        """
        Base case: 50% stiffness to a single Marble.
        """
        marble_stiffness = 0.5
        marble = Marble(torch.tensor([1.], dtype=torch.float), ZERO, ZERO, 0,
                        ATTRACT_FUNCT, None)
        particle = create_particle(marble_stiffness, 0, 0, 0)

        expected = (1 - marble_stiffness) * ATTRACT_FUNCT.value
        result = particle.compute_experienced_force(set([marble]))
        self.assertEqual(
            expected, result,
            "marble_stiffness, " + f"got: {result}, exptected:{expected}")
예제 #15
0
    def test_reset_removed_added_marbles(self):
        """
        NenwinModel.reset() should remove all Marbles
        added with NenwinModel.add_marbles()
        """
        original_marble = Marble(ZERO,
                                 ZERO,
                                 ZERO,
                                 10,
                                 NewtonianGravity(),
                                 datum=None)
        added_marble = original_marble.copy()

        assert added_marble is not original_marble

        model = NenwinModel([], [original_marble])
        model.add_marbles([added_marble])

        model.reset()

        self.assertIn(original_marble, model.marbles)
        self.assertIn(original_marble, model._NenwinModel__all_particles)
        self.assertNotIn(added_marble, model.marbles)
        self.assertNotIn(added_marble, model._NenwinModel__all_particles)
예제 #16
0
    def test_emit_with_location(self):
        """
        MarbleEmitterNodes typically do not emit Marbles at their own position,
        but at the boundary of their radius. 
        Since MarbleEmitterNodes can move, also the position of the emitted
        Marble may vary with time, hence MarbleEmitters should be able
        to set the position of the emitted Marble.
        """
        mass = 10
        prototype = Marble(ZERO, ZERO, ZERO, mass, None, None, 0, 0, 0, 0)
        emitter = MarbleEmitterVariablePosition(prototype, 0, stored_mass=mass)
        spawn_pos = torch.tensor([1], dtype=torch.float)
        result = emitter.emit(spawn_pos)

        self.assertTrue(torch.allclose(spawn_pos, result.pos),
                        f"{spawn_pos} != {result.pos}")
예제 #17
0
    def test_stiffness_zero(self):
        """
        Corner case: 100% stiffness to any particle.
        """
        node_stiffness = 1
        marble_stiffness = 1
        marble = Marble(torch.tensor([1.], dtype=torch.float), ZERO, ZERO, 0,
                        ATTRACT_FUNCT, None)
        node = Node(torch.tensor([1.], dtype=torch.float), ZERO, ZERO, 0,
                    ATTRACT_FUNCT, 0, 0, 1, 1)
        particle = create_particle(marble_stiffness, node_stiffness, 0, 0)

        expected = ZERO
        result = particle.compute_experienced_force(set([node]))
        self.assertTrue(
            torch.allclose(expected, result),
            "zero stiffness, " + f"got: {result}, exptected:{expected}")
예제 #18
0
    def setUp(self):
        self.node = Node(pos=ZERO,
                         vel=ZERO,
                         acc=ZERO,
                         mass=1,
                         attraction_function=NewtonianGravity(),
                         marble_stiffness=1,
                         node_stiffness=1,
                         marble_attraction=1,
                         node_attraction=0)
        self.marble = Marble(pos=np.array([5]),
                             vel=ZERO,
                             acc=ZERO,
                             mass=1,
                             attraction_function=ATTRACT_FUNCT,
                             datum=None)

        self.model = NenwinModel([self.node], [self.marble])
예제 #19
0
    def test_stiffness_to_set(self):
        """
        Base case: multiple other particles in input set of 
            compute_experienced_force()
        """
        node_stiffness = 0.1
        marble_stiffness = 0.6
        node = Node(torch.tensor([1.], dtype=torch.float), ZERO, ZERO, 0,
                    ATTRACT_FUNCT, 0, 0, 1, 1)
        marble = Marble(torch.tensor([-1.], dtype=torch.float), ZERO, ZERO, 0,
                        ATTRACT_FUNCT, None, 0, 0, 1, 1)
        particle = create_particle(marble_stiffness, node_stiffness, 0, 0)

        expected = (1 - node_stiffness)*ATTRACT_FUNCT.value \
            - (1 - marble_stiffness)*ATTRACT_FUNCT.value
        result = particle.compute_experienced_force(set([node, marble]))

        self.assertAlmostEqual(expected, result.item(), delta=1e-5)
예제 #20
0
    def test_emit_with_rel_pos(self):
        """
        Emitted Marbles can have a fixed initial pos set.
        """
        mass = 10
        prototype = Marble(ZERO, ZERO, ZERO, mass, None, None, 0, 0, 0, 0)
        rel_prototype_pos = torch.tensor([11.3])
        emitter = MarbleEmitterVariablePosition(
            prototype,
            0,
            stored_mass=mass,
            rel_prototype_pos=rel_prototype_pos)

        spawn_pos = torch.tensor([1], dtype=torch.float)
        result = emitter.emit(spawn_pos)

        self.assertTrue(
            torch.allclose(spawn_pos + rel_prototype_pos, result.pos),
            f"{spawn_pos} != {result.pos}")
예제 #21
0
파일: bit.py 프로젝트: Nifrec/nenwin
def bit_read_experiment(bit_state: bool = True):
    """
    A bit in state '1' will recoil a reader-Marble into a different angle
    than it approached (because it is just moving towards a position
    slightly off the center of the bit), and it would pass in a straight line
    if the bit is set to '0'.
    """

    locker_nodes = __generate_locker_nodes(LOCKER_POSITIONS)

    reader_marble = __at_angle_toward_bit_marble(BIT_POS, 0.25 * np.pi, 100,
                                                 READER_MARBLE_STIFFNESS, 0.03)
    bit_marble = Marble(**BIT_MARBLE_SETTTINGS)

    # Any position in line of the movement of the reader Marble,
    # will work as long as it is far enough from the bit not to capture
    # the Marble *before* it hit the bit.
    false_output_reader_pos = reader_marble.pos + 17 * reader_marble.vel
    false_output_eater = MarbleEaterNode(false_output_reader_pos,
                                         ZERO,
                                         ZERO,
                                         1,
                                         ATTRACTION_FUNCTION,
                                         radius=6,
                                         **NODE_STIFFNESSES)
    true_output_eater = MarbleEaterNode(np.array([250, 100]),
                                        ZERO,
                                        ZERO,
                                        1,
                                        ATTRACTION_FUNCTION,
                                        radius=6,
                                        **NODE_STIFFNESSES)

    if bit_state:
        marbles = (bit_marble, reader_marble)
    else:
        marbles = (reader_marble, )
    output = run(marbles,
                 locker_nodes + [false_output_eater, true_output_eater])
    print("Read state of bit:", __model_output_to_bit_state(output))
예제 #22
0
파일: bit.py 프로젝트: Nifrec/nenwin
def __at_angle_toward_bit_marble(
        bit_position: torch.Tensor,
        angle: float,
        horizontal_distance: float,
        stiffnesses: Dict[str, float],
        x_error: Optional[float] = 0,
        mass: Optional[float] = 100,
        speed_multiplier: Optional[float] = 0.1) -> Marble:
    """
    Create a Marble that collides into the bit center,
    approaching from the top-left at the given angle.
    """
    vertical_distance = np.tan(angle) * horizontal_distance
    pos = np.array([
        bit_position[0] + horizontal_distance + x_error,
        bit_position[1] + vertical_distance
    ])
    reader_marble = Marble(
        pos,
        speed_multiplier * (bit_position - pos) + np.array([x_error, 0]), ZERO,
        mass, ATTRACTION_FUNCTION, None, **stiffnesses)
    return reader_marble
예제 #23
0
    def test_make_timestep_2(self):
        """
        Base case: initial stationairy Marble, gets attracted and accelerated.
        """
        node = Node(pos=ZERO,
                    vel=ZERO,
                    acc=ZERO,
                    mass=1,
                    attraction_function=ATTRACT_FUNCT,
                    marble_stiffness=1,
                    node_stiffness=1,
                    marble_attraction=1,
                    node_attraction=0)
        marble = Marble(pos=np.array([5]),
                        vel=ZERO,
                        acc=ZERO,
                        mass=1,
                        attraction_function=ATTRACT_FUNCT,
                        datum=None)

        model = NenwinModel([node], [marble])
        time_passed = 1

        expected_pos, expected_vel = runge_kutta_4_step(marble.pos,
                                                        marble.vel,
                                                        -ATTRACT_FUNCT.value,
                                                        duration=time_passed)
        model.make_timestep(time_passed)

        self.assertTrue(torch.allclose(marble.pos, expected_pos, atol=0.01))
        self.assertTrue(torch.allclose(marble.vel, expected_vel, atol=0.01))
        self.assertTrue(
            torch.isclose(marble.acc,
                          torch.tensor(-ATTRACT_FUNCT.value),
                          atol=0.01))

        self.assertTrue(torch.allclose(node.pos, ZERO))
        self.assertTrue(torch.allclose(node.vel, ZERO))
        self.assertTrue(torch.allclose(node.acc, ZERO))
예제 #24
0
def generate_dummy_marble() -> Marble:
    """
    Create a Marble without meaningfull parameters.
    """
    return Marble(ZERO, ZERO, ZERO, 0, None, None, 0, 0, 0, 0)
예제 #25
0
"""
import unittest
import numpy as np
import multiprocessing

from nenwin.input_placer import InputPlacer
from nenwin.output_reader import OutputReader
from nenwin.simulation import Simulation, UICommands, UIMessage
from nenwin.model import NenwinModel
from nenwin.node import Marble
from nenwin.test.test_aux import ZERO

# Just an arbitrary non-trivial object
# ('None' would also be returned when faultly no return value is specified)
MOCK_KEYWORD = "test"
MOCK_MARBLE = Marble(ZERO, ZERO, ZERO, 0, None, None)


class SimulationTestCase(unittest.TestCase):
    def setUp(self):
        self.model = MockNenwinModel()
        self.input_placer = MockInputPlacer()
        self.output_reader = MockOutputReader()
        self.pipe, self.__other_pipe_end = multiprocessing.Pipe(duplex=True)
        self.simulation = Simulation(self.model, self.input_placer,
                                     self.output_reader, self.__other_pipe_end)

    def test_handle_commands_stop(self):
        """
        Base case: test if stop command executed.
        """
예제 #26
0
 def setUp(self):
     self.__prototype = Marble(
         ZERO, ZERO, ZERO, 1, ATTRACT_FUNCT, None, 0, 0, 0, 0)