def test_m2(): # Figure 10 from "An introduction..." cap2 = ETangle(ETangle.Type.CAP, (1, -1, -1), 1) cap2_module = empty_da_module(cap2) sd_cap2_1 = ETangleStrands(cap2, {0: 0, 1: 3}, {2: 0}) sd_cap2_1_out = ETangleStrands(cap2, {0: 0, 1: 3}, {2: 1}).to_generator(cap2_module) algebra1 = AMinus((-1,)) elt1 = algebra1.generator({0: 1}) idem = algebra1.generator({0: 0}) assert m2(cap2_module, sd_cap2_1, elt1) == sd_cap2_1_out assert m2(cap2_module, sd_cap2_1, idem) == sd_cap2_1.to_generator(cap2_module) cup1 = ETangle(ETangle.Type.CUP, (1, -1), 1) cup1_module = empty_da_module(cup1) sd_cup1_1 = ETangleStrands(cup1, {}, {2: 1, 0: 0}) algebra2 = AMinus((1, -1)) idem2 = algebra2.generator({0: 0, 1: 1}) elt = algebra2.generator({1: 0, 2: 2}) sd_cup1_2 = ETangleStrands(cup1, {}, {2: 2, 0: 1}) sd_cup1_2_out = cup1_module.ring['U1'] * ETangleStrands(cup1, {}, {2: 2, 0: 0}).to_generator(cup1_module) assert m2(cup1_module, sd_cup1_1, idem2) == sd_cup1_1.to_generator(cup1_module) assert m2(cup1_module, sd_cup1_2, elt) == sd_cup1_2_out cup2 = ETangle(ETangle.Type.CUP, (-1, 1), 1) cup2_module = empty_da_module(cup2) sd_cup2_1 = ETangleStrands(cup2, {}, {0: 0, 2: 1}) elt2 = cup2.right_algebra.generator({0: 0, 1: 2}) sd_cup2_1_out = cup2_module.ring['U1'] * ETangleStrands(cup2, {}, {0: 0, 2: 2}).to_generator(cup2_module) assert m2(cup2_module, sd_cup2_1, elt2) == sd_cup2_1_out
def introduce_left_crossing(module: Module, x: ETangleStrands, b1: int, b2: int) -> Module.TensorElement: a1 = x.left_y_pos(b1) a2 = x.left_y_pos(b2) crossing_range_1 = range(a1, b2 + 1) if a1 < b2 else range(b2, a1 + 1) crossing_range_2 = range(a2, b1 + 1) if a2 < b1 else range(b1, a2 + 1) possible_crossings = list(set(crossing_range_1) & set(crossing_range_2)) sd = introduce_left_crossing(x, b1, b2, possible_crossings[0]) for crossing in possible_crossings[1:]: new_sd = introduce_left_crossing(x, b1, b2, crossing) if new_sd.num_orange_black_crossings() < sd.num_orange_black_crossings( ): sd = new_sd c = x.etangle.ring.one() powers = sd.figure_7_relations() if powers is None: return module.zero() for orange, power in powers.items(): c *= x.etangle.strand_index_to_variable(orange)**power new_left_strands = swap_values(x.left_strands, a1, a2) x_out = ETangleStrands(x.etangle, new_left_strands, x.right_strands) return c * x_out.to_generator(module)
def test_delta_ell(): over1 = ETangle(ETangle.Type.OVER, (-1, -1, 1), 2) over1_module = empty_da_module(over1) x = ETangleStrands(over1, {1: 0, 2: 1}, {3: 0, 2: 2}) y = ETangleStrands(over1, {0: 0, 2: 1}, {3: 0, 2: 2}) c = over1.ring.one() elt = over1.left_algebra.generator({0: 1, 3: 3}).to_element() out = elt ** (c * y.to_generator(over1_module)) assert delta_ell(over1_module, x) == out
def test_delta_ell_case_4(): over1 = ETangle(ETangle.Type.OVER, (-1, -1), 1) over1_module = empty_da_module(over1) x = ETangleStrands(over1, {0: 1, 1: 0}, {2: 2}) a1 = 0 a2 = 2 y = ETangleStrands(over1, {2: 1, 1: 0}, {2: 2}) out = over1.left_algebra.generator({2: 0}).to_element() ** (over1.ring['U2'] * y.to_generator(over1_module)) assert delta_ell_case_4(over1_module, x, a1, a2) == out
def test_delta_ell_case_2(): over1 = ETangle(ETangle.Type.OVER, (1, 1), 1) over1_module = empty_da_module(over1) x = ETangleStrands(over1, {0: 1, 1: 0}, {2: 2}) a1 = 0 a2 = 1 y = ETangleStrands(over1, {0: 0, 1: 1}, {2: 2}) out = (over1.left_algebra.ring['U1'] * over1.left_algebra.generator({2: 2}).to_element()) ** \ y.to_generator(over1_module) assert delta_ell_case_2(over1_module, x, a1, a2) == out
def d_mixed_case_1(module: Module, x: ETangleStrands, b1: int, b2: int) -> Module.TensorElement: c = x.etangle.ring.one() powers = x.to_strand_diagram().figure_8_case_1b(b1, b2) if powers is None: return module.zero() for orange, power in powers.items(): c *= x.etangle.strand_index_to_variable(orange)**power x_out = ETangleStrands(x.etangle, x.left_strands, swap_values(x.right_strands, b1, b2)) return c * x_out.to_generator(module)
def delta_ell_case_2(module: Module, x: ETangleStrands, a1: int, a2: int) -> Module.TensorElement: c1 = module.left_algebra.ring.one() c2 = x.etangle.ring.one() powers = x.idempotent_and_left_strands().figure_8_case_2a(a1, a2) if powers is None: return module.zero() for orange, power in powers.items(): if x.etangle.strand_index_to_left_sign(orange) == 1: c1 *= x.etangle.left_algebra_strand_index_to_variable( orange)**power else: c2 *= x.etangle.strand_index_to_variable(orange)**power elt = x.left_idempotent() y = ETangleStrands(x.etangle, swap_values(x.left_strands, a1, a2), x.right_strands) return (c1 * elt)**(c2 * y.to_generator(module))
def d_mixed_case_4(module: Module, x: ETangleStrands, b1: int, b2: int) -> Module.TensorElement: c = x.etangle.ring.one() powers = x.to_strand_diagram().figure_8_case_4b(b1, b2) if powers is None: return module.zero() for orange, power in powers.items(): c *= x.etangle.strand_index_to_variable(orange)**power a1 = x.left_y_pos(b1) a2 = x.right_y_pos(b2) new_left_strands = dict(x.left_strands) new_left_strands[a1] = b2 new_right_strands = dict(x.right_strands) del new_right_strands[b2] new_right_strands[b1] = a2 x_out = ETangleStrands(x.etangle, new_left_strands, new_right_strands) return c * x_out.to_generator(module)
def m2(module: Module, x: ETangleStrands, a: AMinus.Generator) -> Module.TensorElement: # if the sign sequences do not match, return 0 if x.etangle.right_sign_sequence() != a.algebra.ss: return module.zero() # if the strands cannot be merged, return 0 if set(x.right_strands.values()) != set(a.strands.keys()): return module.zero() orange_strands = {} orange_signs = {} for orange in range(1, len(x.etangle.signs)): if x.etangle.right_y_pos(orange): orange_strands[orange] = (x.etangle.middle_y_pos(orange), x.etangle.right_y_pos(orange), x.etangle.right_y_pos(orange)) orange_signs[orange] = x.etangle.signs[orange] black_strands = {} for black in x.right_strands.keys(): black_strands[black] = (black, x.right_strands[black], a.strands[x.right_strands[black]]) c = x.etangle.ring.one() sd = StrandDiagram(orange_strands, orange_signs, black_strands) powers = sd.figure_6_relations() if powers is None: return module.zero() for orange, power in powers.items(): for _ in range(power): c *= x.etangle.strand_index_to_variable(orange) new_right_strands = { sd.black_left_pos(black): sd.black_right_pos(black) for black in x.right_strands.keys() } x_out = ETangleStrands(x.etangle, x.left_strands, new_right_strands) return c * x_out.to_generator(module)
def delta_ell_case_4(module: Module, x: ETangleStrands, a1: int, a2: int) -> Module.TensorElement: c1 = module.left_algebra.ring.one() c2 = x.etangle.ring.one() powers = x.idempotent_and_left_strands().figure_8_case_4a(a1, a2) if powers is None: return module.zero() for orange, power in powers.items(): if x.etangle.strand_index_to_left_sign(orange) == 1: c1 *= x.etangle.left_algebra_strand_index_to_variable( orange)**power else: c2 *= x.etangle.strand_index_to_variable(orange)**power b1 = x.left_strands[a1] b2 = a2 elt_strands = x.left_idempotent_strands() elt_strands[b2] = a1 new_left_strands = dict(x.left_strands) del new_left_strands[a1] new_left_strands[a2] = b1 elt = x.etangle.left_algebra.generator(elt_strands) y = ETangleStrands(x.etangle, new_left_strands, x.right_strands) return (c1 * elt)**(c2 * y.to_generator(module))