Esempio n. 1
0
def introduce_left_crossing(x: ETangleStrands, b1: int, b2: int,
                            crossing: int) -> StrandDiagram:
    a1 = x.left_y_pos(b1)
    a2 = x.left_y_pos(b2)

    orange_strands = {}
    orange_signs = {}
    for orange in range(1, len(x.etangle.signs)):
        if x.etangle.left_y_pos(orange):
            # (left, middle, middle) breaks {0: 0, 1: 2} on a cup with (-1, 1)
            orange_strands[orange] = (x.etangle.left_y_pos(orange),
                                      x.etangle.left_y_pos(orange),
                                      x.etangle.middle_y_pos(orange))
        orange_signs[orange] = x.etangle.signs[orange]
    black_strands = {}
    for black in x.left_strands.values():
        if black == b1:
            black_strands[b1] = (a1, crossing + .1, b1)
        elif black == b2:
            black_strands[b2] = (a2, crossing + .2, b2)
        else:
            black_strands[black] = (x.left_y_pos(black), x.left_y_pos(black),
                                    black)

    return StrandDiagram(orange_strands, orange_signs, black_strands)
Esempio n. 2
0
def d_mixed(module: Module, x: ETangleStrands) -> Module.TensorElement:
    out = module.zero()

    for b1 in x.right_strands.keys():
        for b2 in x.right_strands.keys():
            # if two black strands don't cross on the right
            if b1 < b2 and x.right_y_pos(b1) < x.right_y_pos(b2):
                out += d_mixed_case_1(module, x, b1, b2)

    for b1 in x.left_strands.values():
        for b2 in x.left_strands.values():
            # if two black strands cross on the left
            if b1 < b2 and x.left_y_pos(b1) > x.left_y_pos(b2):
                out += d_mixed_case_2(module, x, b1, b2)

    for b1 in x.right_strands.keys():
        for b2 in x.left_strands.values():
            if b1 < b2:
                out += d_mixed_case_3(module, x, b1, b2)

    for b1 in x.left_strands.values():
        for b2 in x.right_strands.keys():
            if b1 < b2:
                out += d_mixed_case_4(module, x, b1, b2)

    return out
Esempio n. 3
0
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)
Esempio n. 4
0
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
Esempio n. 5
0
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
Esempio n. 6
0
def d_plus(module: Module, x: ETangleStrands) -> Module.TensorElement:
    out = module.zero()
    for black1, black2 in itertools.combinations(x.right_strands.keys(), 2):
        b1 = min(black1, black2)
        b2 = max(black1, black2)
        if x.right_y_pos(b1) > x.right_y_pos(b2):
            # smooth the crossing and add it to the output
            out += smooth_right_crossing(module, x, b1, b2)
    return out
Esempio n. 7
0
def d_minus(module: Module, x: ETangleStrands) -> Module.TensorElement:
    out = module.zero()
    for black1, black2 in itertools.combinations(x.left_strands.values(), 2):
        b1 = min(black1, black2)
        b2 = max(black1, black2)
        # if the black strands don't cross
        if x.left_y_pos(b1) < x.left_y_pos(b2):
            # introduce a crossing and add it to the output
            out += introduce_left_crossing(module, x, b1, b2)
    return out
Esempio n. 8
0
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
Esempio n. 9
0
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)
Esempio n. 10
0
def test_d_mixed():
    # Figure 9 from "An introduction..."
    over3 = ETangle(ETangle.Type.OVER, (1, 1, -1, -1), 2)
    over3_module = empty_da_module(over3)
    sd_over3_1 = ETangleStrands(over3, {1: 2, 2: 1, 3: 4}, {0: 1, 3: 2})

    sd_over3_1_out = over3.ring['U2'] * \
                     ETangleStrands(over3, {1: 1, 2: 2, 3: 4}, {0: 1, 3: 2}).to_generator(over3_module) + \
                     over3.ring['U2'] * over3.ring['U3'] * \
                     ETangleStrands(over3, {1: 2, 2: 3, 3: 4}, {0: 1, 1: 2}).to_generator(over3_module) + \
                     over3.ring['U3'] * \
                     ETangleStrands(over3, {1: 3, 2: 1, 3: 4}, {0: 1, 2: 2}).to_generator(over3_module) + \
                     over3.ring.one() * \
                     ETangleStrands(over3, {1: 2, 2: 1, 3: 3}, {0: 1, 4: 2}).to_generator(over3_module)

    assert d_mixed(over3_module, sd_over3_1) == sd_over3_1_out
Esempio n. 11
0
def type_da_in_left_grading(etangle: ETangle, i: int) -> TypeDA:
    out = TypeDA(etangle.ring, etangle.left_algebra, etangle.right_algebra,
                 etangle.left_scalar_action, etangle.right_scalar_action)

    strands = [
        ETangleStrands(etangle, left_strands, right_strands)
        for left_strands, right_strands in enumerate_gens([
            etangle.left_points(),
            etangle.middle_points(),
            etangle.right_points()
        ], i)
    ]

    for x in strands:
        out.add_generator(x.to_generator(out),
                          (x.to_strand_diagram().maslov(),
                           x.to_strand_diagram().twoalexander()))

    for x in strands:
        out.add_structure_map(x.to_generator(out), delta1_1(out, x))

        for a in etangle.right_algebra.left_gens(list(
                x.right_strands.values())):
            out.add_structure_map(x.to_generator(out)**a, delta1_2(out, x, a))

    return out
Esempio n. 12
0
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))
Esempio n. 13
0
def test_d_minus():
    under1 = ETangle(ETangle.Type.OVER, (-1, -1, -1, -1), 2)
    under1_module = empty_da_module(under1)
    sd_under1_1 = ETangleStrands(under1, {2: 2, 4: 4}, {0: 0, 1: 1, 3: 3})
    sd_under1_1_out = under1.ring['U3'] * under1.ring['U4'] * \
                      ETangleStrands(under1, {2: 4, 4: 2}, {0: 0, 1: 1, 3: 3}).to_generator(under1_module)

    # Figure 9 from "An introduction..."
    over3 = ETangle(ETangle.Type.OVER, (1, 1, -1, -1), 2)
    over3_module = empty_da_module(over3)
    sd_over3_1 = ETangleStrands(over3, {1: 2, 2: 1, 3: 4}, {0: 1, 3: 2})
    sd_over3_1_out = over3.ring['U3'] * \
                     ETangleStrands(over3, {1: 2, 2: 4, 3: 1}, {0: 1, 3: 2}).to_generator(over3_module) + \
                     over3.ring['U3'] * \
                     ETangleStrands(over3, {1: 4, 2: 1, 3: 2}, {0: 1, 3: 2}).to_generator(over3_module)

    assert d_minus(under1_module, sd_under1_1) == sd_under1_1_out
    assert d_minus(over3_module, sd_over3_1) == sd_over3_1_out
Esempio n. 14
0
def test_delta_ell_case_1():
    over1 = ETangle(ETangle.Type.OVER, (-1, -1), 1)
    over1_module = empty_da_module(over1)
    x = ETangleStrands(over1, {0: 2}, {0: 0, 1: 1})
    a1 = 1
    a2 = 2
    y = x
    out = over1.left_algebra.generator({1: 2, 2: 1}).to_element() ** \
          (over1.ring['U2'] * y.to_generator(over1_module))
    assert delta_ell_case_1(over1_module, x, a1, a2) == out
Esempio n. 15
0
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)
Esempio n. 16
0
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))
Esempio n. 17
0
def smooth_right_crossing(x: ETangleStrands, b1: int, b2: int,
                          crossing: int) -> StrandDiagram:
    a1 = x.right_y_pos(b1)
    a2 = x.right_y_pos(b2)

    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():
        if black == b1:
            black_strands[b1] = (b1, crossing + .1, a2)
        elif black == b2:
            black_strands[b2] = (b2, crossing + .2, a1)
        else:
            black_strands[black] = (black, x.right_y_pos(black),
                                    x.right_y_pos(black))

    return StrandDiagram(orange_strands, orange_signs, black_strands)
Esempio n. 18
0
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)
Esempio n. 19
0
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
Esempio n. 20
0
def delta1_2(module: TypeDA, x: ETangleStrands,
             a: AMinus.Generator) -> Module.TensorElement:
    return x.left_idempotent().to_element()**m2(module, x, a)
Esempio n. 21
0
def delta1_1(module: TypeDA, x: ETangleStrands) -> Module.TensorElement:
    return x.left_idempotent().to_element() ** (d_plus(module, x) + d_minus(module, x) + d_mixed(module, x)) \
           + delta_ell(module, x)
Esempio n. 22
0
def test_d_plus():
    under1 = ETangle(ETangle.Type.UNDER, (1, 1, 1, 1), 2)
    under1_module = empty_da_module(under1)
    sd_under1_1 = ETangleStrands(under1, {0: 0, 3: 3, 4: 4}, {1: 4, 2: 3})
    sd_under1_1_out = ETangleStrands(under1, {0: 0, 3: 3, 4: 4}, {1: 3, 2: 4}).to_generator(under1_module)
    sd_under1_2 = ETangleStrands(under1, {0: 0, 2: 2, 3: 3}, {1: 3, 4: 0})
    sd_under1_2_out = under1.ring['U2'] * under1.ring['U3'] * \
                      ETangleStrands(under1, {0: 0, 2: 2, 3: 3}, {1: 0, 4: 3}).to_generator(under1_module)
    under2 = ETangle(ETangle.Type.UNDER, (1, -1, 1, 1), 2)
    under2_module = empty_da_module(under2)
    sd_under2_1 = ETangleStrands(under2, {0: 0, 3: 3, 4: 4}, {1: 4, 2: 3})
    sd_under2_1_out = ETangleStrands(under2, {0: 0, 3: 3, 4: 4}, {1: 3, 2: 4}).to_generator(under2_module)
    sd_under2_2 = ETangleStrands(under2, {0: 0, 2: 2, 3: 3}, {1: 3, 4: 0})
    sd_under2_2_out = under2_module.zero()

    over1 = ETangle(ETangle.Type.OVER, (1, 1, 1, 1), 2)
    over1_module = empty_da_module(over1)
    sd_over1_1 = ETangleStrands(over1, {4: 4, 1: 1, 3: 3}, {2: 2, 0: 4})
    sd_over1_1_out = over1.ring['U2'] * \
                     ETangleStrands(over1, {4: 4, 1: 1, 3: 3}, {0: 2, 2: 4}).to_generator(over1_module)
    sd_over1_2 = ETangleStrands(over1, {1: 1, 4: 4, 3: 3}, {2: 1, 0: 4})
    sd_over1_2_out = over1.ring['U2'] * \
                     ETangleStrands(over1, {1: 1, 4: 4, 3: 3}, {0: 1, 2: 4}).to_generator(over1_module)
    over2 = ETangle(ETangle.Type.OVER, (1, 1, -1, 1), 2)
    over2_module = empty_da_module(over2)
    sd_over2_1 = ETangleStrands(over2, {1: 1, 0: 0, 4: 4}, {3: 1, 2: 4})
    sd_over2_1_out = over2_module.zero()
    # Figure 9 from "An introduction..."
    over3 = ETangle(ETangle.Type.OVER, (1, 1, -1, -1), 2)
    over3_module = empty_da_module(over3)
    sd_over3_1 = ETangleStrands(over3, {1: 2, 2: 1, 3: 4}, {0: 1, 3: 2})
    sd_over3_1_out = over3_module.zero()

    cap1 = ETangle(ETangle.Type.CAP, (1, 1, -1, 1), 2)
    cap1_module = empty_da_module(cap1)
    sd_cap1_1 = ETangleStrands(cap1, {0: 0, 1: 1}, {4: 1, 3: 2})
    sd_cap1_1_out = cap1.ring['U3'] * ETangleStrands(cap1, {0: 0, 1: 1}, {4: 2, 3: 1}).to_generator(cap1_module)
    sd_cap1_2 = ETangleStrands(cap1, {3: 3, 1: 1}, {4: 0, 0: 2})
    sd_cap1_2_out = cap1.ring['U1'] * cap1.ring['U3'] * \
                    ETangleStrands(cap1, {3: 3, 1: 1}, {4: 2, 0: 0}).to_generator(cap1_module)

    assert d_plus(under1_module, sd_under1_1) == sd_under1_1_out
    assert d_plus(under1_module, sd_under1_2) == sd_under1_2_out
    assert d_plus(under2_module, sd_under2_1) == sd_under2_1_out
    assert d_plus(under2_module, sd_under2_2) == sd_under2_2_out

    assert d_plus(over1_module, sd_over1_1) == sd_over1_1_out
    assert d_plus(over1_module, sd_over1_2) == sd_over1_2_out
    assert d_plus(over2_module, sd_over2_1) == sd_over2_1_out
    assert d_plus(over3_module, sd_over3_1) == sd_over3_1_out

    assert d_plus(cap1_module, sd_cap1_1) == sd_cap1_1_out
    assert d_plus(cap1_module, sd_cap1_2) == sd_cap1_2_out