def test_is_gluing_point(self): """Test is gluing point""" dst = space_time.generate_flat_spacetime(2, 2) e1 = event.Event(dst, event.GluingPoint(0)) e2 = event.Event(dst, 0) assert e1.is_gluing_point assert not e2.is_gluing_point
def test_multiple_imove(self): """Test inverse move""" dst = generate_flat_spacetime(4, 4) n = event.Event(dst, 5) moves.decrease(dst, n) n = event.Event(dst, 5) moves.decrease(dst, n) assert isinstance(dst, SpaceTime)
def test_coerce_gluing_point(self): """Test gluing point coercion""" dst_1 = space_time.generate_flat_spacetime(2, 2) e0_1 = event.Event(dst_1, 0) dst_2 = dst_1.pop([e0_1]) e0_2 = event.Event(dst_2, 0) e0_star = event.coerce_gluing_point(dst_1, e0_2) assert not isinstance(e0_1.key, event.GluingPoint) assert not isinstance(e0_2.key, event.GluingPoint) assert isinstance(e0_star.key, event.GluingPoint)
def test_event_equality(self): """Test Event equality""" dst = space_time.generate_flat_spacetime(2, 2) e1 = event.Event(space_time=dst, event_key=1) e2 = event.Event(space_time=dst, event_key=1) assert e1 == e2 # TODO uncomment the below test once equality defined for SpaceTime dst2 = space_time.generate_flat_spacetime(2, 3) e1_2 = event.Event(space_time=dst2, event_key=1) assert e1 != e1_2
def decrease(st, node): """merges node.left in to node""" # cut out the sub_space that will be effected by the move left = node.left sub_space = st.pop([node, left]) # identify the nodes that will be merged in the sub_space left_s = event.Event(sub_space, left.key) node_s = event.Event(sub_space, node.key) # ------- modify the nodes ------- # the new neighbors of the merged node new_future = set(left_s.future).union(node_s.future) new_past = set(left_s.past).union(node_s.past) new_left = left_s.left # connect new neighbors to node and remove connections from left event.connect_spatial(new_left, node_s) event.connect_temporal(node_s, past=new_past, future=new_future) event.connect_temporal(left_s, past=set(), future=set()) # ------- modify the faces ------- # only two faces are "removed" while some others need to be relabeled. faces_containing_left = [] faces_for_deletion = [] for f in face.faces(sub_space): if left_s.key in f.nodes: if node.key in f.nodes: faces_for_deletion.append(f) else: faces_containing_left.append(f) for f in face.faces(sub_space, faces_containing_left): new_f_nodes = set(f.nodes) new_f_nodes.remove(left_s.key) new_f_nodes.add(node_s.key) sub_space.face_nodes[f.key] = frozenset(new_f_nodes) # connect the newly adjacent faces and remove the old face that used to be between them for f in face.faces(sub_space, faces_for_deletion): face.connect_spatial(f.left, f.right) sub_space.remove_face(f.key) sub_space.remove_key(left_s.key) # push the modified sub_space back in to the space_time st.push(sub_space)
def test_push_pop_gluing_points(self): st = space_time.generate_flat_spacetime(10, 10) node = event.Event(st, 13) st.push(st.pop([node])) gp_nodes, gp_refs = audit.find_gluing_point_references(st) assert gp_nodes == [] assert gp_refs == []
def test_pop_push_unique(self): """Test for temporal connection uniqueness, based on Jackson's repro 2021-02-21""" st = space_time.generate_flat_spacetime(10, 10) node = event.Event(st, 13) st.push(st.pop([node])) dups = audit.find_duplicate_temporal_connections(st) assert dups is None
def test_push(self): dst = space_time.generate_flat_spacetime(3, 3) e0 = event.Event(dst, 0) dst2 = dst.pop([e0]) dst.push(dst2) # TODO add real equivalence check assert isinstance(dst, SpaceTime)
def test_push_pop_identity(self): """Test that push * pop == identity""" base = space_time.generate_flat_spacetime(10, 10) # to compare against st = space_time.generate_flat_spacetime(10, 10) assert base == st node = event.Event(st, 13) st.push(st.pop([node])) assert base == st
def test_equality(self): """Test equality""" dst = space_time.generate_flat_spacetime(3, 3) dst_2 = space_time.generate_flat_spacetime(3, 3) assert dst == dst_2 e4 = event.Event(dst, 4) sub_dst = dst.pop([e4]) assert dst != dst_2
def get_average_coords(st): theta_x, theta_t = get_naive_coords(st) for i in range(200): # print(i) for n in st.nodes: # print(n) # sums the x length of all connections to n e = event.Event(st, n) total_x_length = sum([ angular_seperation(theta_x[n], theta_x[c.key]) for c in e.neighbors ]) # print(angular_seperation(total_x_length, 0)) # attempt to change posiotion by the total difference therby reducing the total difference to zero new_x_theta = (theta_x[n] + total_x_length / 200.0) % (2 * pi) l = theta_x[st.node_left[n]] r = theta_x[st.node_right[n]] if is_between(l, r, new_x_theta): theta_x[n] = new_x_theta return (theta_x, theta_t)
def test_pop(self): dst = space_time.generate_flat_spacetime(3, 3) e0 = event.Event(dst, 0) dst2 = dst.pop([e0]) assert isinstance(dst2, SpaceTime)
def test_layer(self): dst = space_time.generate_flat_spacetime(2, 2) e1 = event.Event(dst, event.GluingPoint(0)) assert isinstance(e1.layer, int) assert e1.layer == 0
def increase(st, node, future, past): """ A move should add one node and 2 faces. we can pop all the structures to be modified out of the dicts and then push them back in once they've been modified. This mean we need to know what could get modfified in any given move. """ # remove the sub_space that is going to be modified layer = node.layer sub_space = st.pop([node]) future_s = event.Event(sub_space, future) # Need these two because they have been "popped" out of the original spacetime past_s = event.Event(sub_space, past) # increment the total node counter new_node_num = max(st.nodes.union(sub_space.nodes)) + 1 sub_space.add_key(new_node_num, layer=layer) # create a node object for easy manipulation. This also automatically adds the node to the sub_space new_s = event.Event(sub_space, new_node_num) node_s = event.Event(sub_space, node) left_s = event.Event(sub_space, node_s.left) left = node_s.left right = node_s.right # spatial changes event.connect_spatial(new_s, node_s) # new_s.right = node_s and node_s.left = new_s event.connect_spatial(left_s, new_s) # new_s.left = left_s and left_s.right = new_s # future changes # TODO examine algorithm concept of connection vs Spacetime (e.g. after popping a node out, what does asking for "left" mean?) new_future_set = {future_s} f = future_s.left while f in node_s.future and not f.is_gluing_point: new_future_set.add(f) sub_space.node_future[node.key].remove(f.key) # TODO cleanup the event key coercion by figuring out workaround for node.future.remove() sub_space.node_past[f.key].remove(node.key) f = f.left event.connect_temporal(new_s, future=new_future_set) old_future_set = node_s.future.difference(new_future_set).union({future_s}) event.connect_temporal(node_s, future=old_future_set) # sub_space.node_past[future].append(new_node) # past changes new_past_set = {past_s} p = past_s.left while p in node_s.past: new_past_set.add(p) sub_space.node_past[node_s.key].remove(p.key) sub_space.node_future[p.key].remove(node_s.key) p = p.left event.connect_temporal(new_s, past=new_past_set) old_past_set = node_s.past.difference(new_past_set).union({past_s}) event.connect_temporal(node_s, past=old_past_set) # sub_space.node_future[past].append(new_node) # face changes for f in face.faces(sub_space): if node_s.key in f.nodes: modified = [i.key for i in list(new_future_set | new_past_set | {node_s, left})] if all(item in modified for item in f.nodes): new_nodes = set(f.nodes) new_nodes.remove(node_s.key) new_nodes.add(new_s.key) sub_space.face_nodes[f.key] = frozenset(new_nodes) sub_space.faces_containing[node_s.key].remove(f.key) sub_space.faces_containing[new_s.key].add(f.key) f1r = face.Face(sub_space, (set(sub_space.faces_containing[new_s.key]) & set(sub_space.faces_containing[future_s.key])).pop()) f1l = face.Face(sub_space, (set(sub_space.faces_containing[node_s.key]) & set(sub_space.faces_containing[future_s.key])).pop()) f2r = face.Face(sub_space, (set(sub_space.faces_containing[new_s.key]) & set(sub_space.faces_containing[past_s.key])).pop()) f2l = face.Face(sub_space, (set(sub_space.faces_containing[node_s.key]) & set(sub_space.faces_containing[past_s.key])).pop()) new_face_key = max(st.faces.union(sub_space.faces)) + 1 f_new_1 = face.Face(sub_space, sub_space.add_face(frozenset({new_s.key, node_s.key, future_s.key}), new_face_key)) sub_space.face_type[f_new_1.key] = 0 f_new_2 = face.Face(sub_space, sub_space.add_face(frozenset({new_s.key, node_s.key, past_s.key}), new_face_key + 1)) sub_space.face_type[f_new_2.key] = 1 face.connect_spatial(f1r, f_new_1) face.connect_spatial(f_new_1, f1l) face.connect_spatial(f2r, f_new_2) face.connect_spatial(f_new_2, f2l) # face.connect_temporal(f_new_1, f_new_2) st.push(sub_space)
def test_event_safe_getattr(self): """Test event getattr behavior for non passthru attributes""" dst = space_time.generate_flat_spacetime(2, 2) e0 = event.Event(space_time=dst, event_key=0) assert isinstance(e0.space_time, SpaceTime) assert isinstance(e0.key, int)
def test_event_repr(self): """Test event string representation""" dst = space_time.generate_flat_spacetime(2, 2) e = event.Event(space_time=dst, event_key=1) assert repr(e) == 'Event(ST4, 1)'
def test_event_init(self): """Test event init from spacetime and key""" dst = space_time.generate_flat_spacetime(2, 2) e = event.Event(space_time=dst, event_key=1) assert isinstance(e, event.Event) assert id(e.space_time) == id(dst) # passthru