示例#1
0
def antipode_ck(tree):
    """Return the antipode in the Butcher, Connes, Kreimer Hopf-algebra."""
    # TODO: Should be memoized, but linearCOmbination is mutable.
    # Make LinComb clonable??
    result = LinearCombination()
    if tree == empty_tree:
        result[empty_tree] = 1
        return result
    elif isinstance(tree, Forest):
        result[empty_tree] = 1
        for tree1, multiplicity in tree.items():
            for i in range(multiplicity):
                tmp = LinearCombination()
                for forest1, multiplicity1 in antipode_ck(tree1).items():
                    for forest2, multiplicity2 in result.items():
                        tmp[forest1 * forest2] += multiplicity1 * multiplicity2
                result = tmp
        return result
        # TODO: implement multiplication of LinComb.
    result[Forest((tree, ))] -= 1
    for (forest,
         subtree), multiplicity in _subtrees_for_antipode(tree).items():
        for forest2, coefficient in antipode_ck(forest).items():
            result[forest2.add(subtree)] -= coefficient * multiplicity
    return result
示例#2
0
def differentiate(thing):
    """performs grafting corresponding to
    derivate once more with respect to *t*."""
    if isinstance(thing, LinearCombination):
        result = LinearCombination()
        for tree, factor in thing.items():
            result += treeD(tree) * factor
    elif isinstance(thing, UnorderedTree):
        result = treeD(thing)
    elif thing == empty_tree:
        result = LinearCombination()
        result += leaf
    return result
示例#3
0
 def test_last(self):
     t1 = UnorderedTree([self.t3_2, self.t3_2])
     result = symp_split(t1)
     t2 = UnorderedTree([self.t3_2, self.t2_1])
     expected = LinearCombination()
     expected[t2] = 4
     self.assertEqual(expected, result)
示例#4
0
 def test_second(self):
     result = subtrees(self.t2_1)
     expected = LinearCombination()
     expected[(self.et, self.t2_1)] = 1
     expected[(Forest((self.t1_1, )), self.t1_1)] = 1
     expected[(Forest((self.t2_1, )), self.et)] = 1
     self.assertEqual(expected, result)
示例#5
0
def linCombCommutator(op1, op2, max_order=None):
    """Tree commutator for linear combinations of trees."""
    if isinstance(op1, UnorderedTree) or op1 == empty_tree:
        tmp = LinearCombination()
        tmp += op1
        op1 = tmp
    if isinstance(op2, UnorderedTree) or op2 == empty_tree:
        tmp = LinearCombination()
        tmp += op2
        op2 = tmp
    result = LinearCombination()
    for tree1, factor1 in op1.items():
        for tree2, factor2 in op2.items():
            if (not max_order) or tree1.order() + tree2.order() <= max_order:
                result += (factor1 * factor2) * tree_commutator(tree1, tree2)
    return result
示例#6
0
 def test_fourth(self):
     result = antipode_ck(self.t3_2)
     expected = LinearCombination()
     expected[Forest((self.t3_2, ))] = -1
     expected[Forest((self.t2_1, self.t1_1))] = 2
     expected[Forest((self.t1_1, self.t1_1, self.t1_1))] = -1
     self.assertEqual(expected, result)
示例#7
0
def _subtrees_for_antipode(tree):
    r"""Slightly modified edition of ``subtrees`` used by ``antipode_ck``

    Does not include
    :math:`\tau \otimes \emptyset` and
    :math:`\emptyset \otimes \tau`.
    """
    result = LinearCombination()
    tmp = [subtrees(child_tree)
           for child_tree in tree.elements()]  # TODO: more efficient looping.
    if tmp:
        tmp = [elem.items() for elem in tmp]  # TODO: Try using iterators.
        for item in product(*tmp):  # iterator over all combinations.
            tensorproducts, factors = zip(*item)
            multiplicity = 1
            for factor in factors:
                multiplicity *= factor
            cuttings, to_be_grafted = zip(*tensorproducts)
            with Forest().clone() as forest_of_cuttings:
                for forest in cuttings:
                    forest_of_cuttings.inplace_multiset_sum(forest)
            result[(forest_of_cuttings,
                    UnorderedTree(to_be_grafted))] += multiplicity
    result[(empty_tree, tree)] = 0  # TODO: FIND NICER WAY.
    return result
示例#8
0
 def test_eighth(self):
     result = _subtrees_for_antipode(self.t4_4)
     expected = LinearCombination()
     expected[(Forest((self.t1_1, self.t1_1, self.t1_1)), self.t1_1)] = 1
     expected[(Forest((self.t1_1, self.t1_1)), self.t2_1)] = 3
     expected[(Forest((self.t1_1, )), self.t3_2)] = 3
     self.assertEqual(expected, result)
示例#9
0
def series_commutator(a, b):
    """Corresponds to tree commutator, just for series."""

    # TODO: TEST ME!

    def new_rule(tree):
        order = tree.order()
        if order in new_rule.orders:
            return new_rule.storage[tree] * tree.symmetry()
            # TODO: Move the correction by symmetry to initialisation.
        else:
            result = LinearCombination()
            for tree1, tree2 in tree_tuples_of_order(order):
                result += \
                    Fraction(a(tree1) * b(tree2),
                             tree1.symmetry() * tree2.symmetry()) * \
                    tree_commutator(tree1, tree2)
            new_rule.orders.add(order)
            new_rule.storage += result
            return new_rule.storage[tree] * tree.symmetry()

    new_rule.storage = LinearCombination()
    new_rule.orders = set(
        (0, ))  # the coefficient of the empty tree is always 0.
    return BseriesRule(new_rule)
示例#10
0
 def test_fourth(self):
     result = subtrees(self.t3_2)
     expected = LinearCombination()
     expected[(Forest((self.t3_2, )), self.et)] = 1
     expected[(Forest((self.t1_1, self.t1_1)), self.t1_1)] = 1
     expected[(Forest((self.t1_1, )), self.t2_1)] = 2
     expected[(self.et, self.t3_2)] = 1
     self.assertEqual(expected, result)
示例#11
0
 def test_first_second(self):
     tree1 = leaf
     tree2 = list(D(tree1).keys())[0]
     expected = LinearCombination()
     forest1 = Forest([tree1, tree1])
     tree3 = UnorderedTree(forest1)
     expected -= tree3
     result = tree_commutator(tree2, tree1)
     self.assertEqual(result, expected)
示例#12
0
 def test_sixth(self):
     result = _subtrees_for_antipode(self.t4_2)
     expected = LinearCombination()
     expected[(Forest((self.t3_2, )), self.t1_1)] = 1
     expected[(Forest((self.t1_1, self.t1_1)), self.t2_1)] = 1
     expected[(Forest((self.t1_1, )), self.t3_1)] = 2
     print(expected)
     print(result)
     self.assertEqual(expected, result)
示例#13
0
def subtrees(tree):
    """Return the HCK coproduct.

    This is function does the heavy lifting when composing B-series.
    The return value is a :class:`LinearCombination` of 2 tuples.
    The 0th element in the tuples are the forests of cutting,
    while the 1st element is the subtree.
    """
    result = LinearCombination()
    if tree == empty_tree:
        result += (empty_tree, empty_tree)
        return result
    elif isinstance(tree, Forest):
        if tree.number_of_trees() == 1:
            for elem in tree:
                return subtrees(elem)
        else:  # several trees.
            for elem in tree:
                amputated_forest = tree.sub(elem)
                break
            for pair1, multiplicity1 in subtrees(elem).items():
                for pair2, multiplicity2 in subtrees(amputated_forest).items():
                    if isinstance(pair1[1], UnorderedTree):
                        pair1_1 = Forest((pair1[1], ))
                    else:
                        pair1_1 = pair1[1]
                    if isinstance(pair2[1], UnorderedTree):
                        pair2_1 = Forest((pair2[1], ))
                    else:
                        pair2_1 = pair2[1]  # TODO: Nasty workaround.
                    pair = (pair1[0] * pair2[0], pair1_1 * pair2_1)
                    result[pair] += multiplicity1 * multiplicity2
            return result
    result[(Forest((tree, )), empty_tree)] = 1
    if tree == leaf:
        result[(empty_tree, tree)] = 1
        return result
    tmp = [subtrees(child_tree) for child_tree in tree.elements()]
    # TODO: more efficient looping.
    # TODO: The multiplicities in "tree" are accounted for by "elements()".
    tmp = [elem.items() for elem in tmp]  # TODO: Try using iterators.
    for item in product(*tmp):  # iterator over all combinations.
        tensorproducts, factors = zip(*item)
        multiplicity = 1
        for factor in factors:
            multiplicity *= factor
        cuttings, to_be_grafted = zip(*tensorproducts)
        with Forest().clone() as forest_of_cuttings:
            for forest in cuttings:
                forest_of_cuttings.inplace_multiset_sum(forest)
        result[(forest_of_cuttings, UnorderedTree(to_be_grafted))] += \
            multiplicity
    return result
示例#14
0
def _split(tree):
    """Return the splitting of tree except for :math:`tree \otimes \emptyset`.

    Used by `split()`.
    """
    result = LinearCombination()
    for childtree, multiplicity in tree.items():
        amputated_tree = tree.sub(childtree)
        result[(childtree, amputated_tree)] = multiplicity
        childSplits = _split(childtree)
        for pair, multiplicity2 in childSplits.items():
            new_tree = amputated_tree.add(pair[1])
            new_pair = (pair[0], new_tree)
            result[new_pair] = multiplicity * multiplicity2
    return result
示例#15
0
 def new_rule(tree):
     order = tree.order()
     if order in new_rule.orders:
         return new_rule.storage[tree] * tree.symmetry()
         # TODO: Move the correction by symmetry to initialisation.
     else:
         result = LinearCombination()
         for tree1, tree2 in tree_tuples_of_order(order):
             result += \
                 Fraction(a(tree1) * b(tree2),
                          tree1.symmetry() * tree2.symmetry()) * \
                 tree_commutator(tree1, tree2)
         new_rule.orders.add(order)
         new_rule.storage += result
         return new_rule.storage[tree] * tree.symmetry()
示例#16
0
def graft(other, base):
    r"""Grafting *other* :math:`\curvearrowright` *base*."""
    result = LinearCombination()
    if base == empty_tree:
        result += other
    elif other == empty_tree:
        result += base
    else:
        result += base.butcher_product(other)
        for subtree, multiplicity1 in base.items():
            amputated_tree = base.sub(subtree)
            replacements = graft(other, subtree)
            for replacement, multiplicity2 in replacements.items():
                new_tree = amputated_tree.add(replacement)
                result[new_tree] += multiplicity1 * multiplicity2
    return result
示例#17
0
def symp_split(tree):
    """Perform the split needed for symplecticity checks.

    It differs from the ``split``-function
    by only splitting off leaves."""
    result = LinearCombination()
    for childtree, multiplicity in tree.items():
        amputated_tree = tree.sub(childtree)
        if childtree == leaf:
            result[amputated_tree] += multiplicity
        else:
            child_splits = symp_split(childtree)
            for tree2, multiplicity2 in child_splits.items():
                new_tree = amputated_tree.add(tree2)
                result[new_tree] += multiplicity * multiplicity2
    return result
示例#18
0
 def test_thirteenth(self):
     result = symp_split(self.t5_5)
     expected = LinearCombination()
     expected[self.t4_1] = 1
     expected[self.t4_3] = 1
     self.assertEqual(expected, result)
示例#19
0
 def test_first(self):
     result = antipode_ck(self.t1_1)
     expected = LinearCombination()
     expected[Forest((leaf, ))] = -1
     self.assertEqual(expected, result)
示例#20
0
 def test_first(self):
     result = symp_split(self.t1_1)
     expected = LinearCombination()  # TODO: right way to do it?
     self.assertEqual(expected, result)
示例#21
0
 def test_second(self):
     result = antipode_ck(self.t2_1)
     expected = LinearCombination()
     expected[Forest((self.t2_1, ))] = -1
     expected[Forest((self.t1_1, self.t1_1))] = 1
     self.assertEqual(expected, result)
示例#22
0
 def test_fourth(self):
     result = symp_split(self.t3_2)
     expected = LinearCombination()
     expected[self.t2_1] = 2
     self.assertEqual(expected, result)
示例#23
0
 def test_second(self):
     result = symp_split(self.t2_1)
     expected = LinearCombination()
     expected += self.t1_1
     self.assertEqual(expected, result)
示例#24
0
 def test_tenth(self):
     result = symp_split(self.t5_2)
     expected = LinearCombination()
     expected[self.t4_1] = 2
     self.assertEqual(expected, result)
示例#25
0
 def test_fifth(self):
     result = symp_split(self.t4_1)
     expected = LinearCombination()
     expected[self.t3_1] = 1
     self.assertEqual(expected, result)
示例#26
0
 def test_eleventh(self):
     result = symp_split(self.t5_3)
     expected = LinearCombination()
     expected[self.t4_1] = 1
     expected[self.t4_2] = 1
     self.assertEqual(expected, result)
示例#27
0
 def test_empty(self):
     result = subtrees(self.et)
     expected = LinearCombination()
     expected[(self.et, self.et)] = 1
     self.assertEqual(expected, result)
示例#28
0
 def test_twelfth(self):
     result = symp_split(self.t5_4)
     expected = LinearCombination()
     expected[self.t4_2] = 3
     self.assertEqual(expected, result)
示例#29
0
 def test_seventeenth(self):
     result = symp_split(self.t5_9)
     expected = LinearCombination()
     expected[self.t4_4] = 4
     self.assertEqual(expected, result)
示例#30
0
 def test_sixthteenth(self):
     result = symp_split(self.t5_8)
     expected = LinearCombination()
     expected[self.t4_4] = 1
     expected[self.t4_3] = 2
     self.assertEqual(expected, result)