Esempio n. 1
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)
Esempio n. 2
0
    def phi(self):
        def rule(tree):
            'elementary weight'
            if tree == empty_tree:
                return 1  # We haven't even allowed for non-consistent RK-methods.
            return np.dot(self.b, self.g_vector(tree))[0]

        return BseriesRule(rule)
Esempio n. 3
0
def stepsize_adjustment(a, A):
    """Corresponds to letting h -> A h."""
    base_rule = a._call

    def new_rule(tree):
        return A**tree.order() * base_rule(tree)

    return BseriesRule(new_rule)
Esempio n. 4
0
def adjoint(a):
    """The adjoint is the inverse with reversed time step.

    Returns a BseriesRule.
    """
    def new_rule(tree):
        return (-1)**tree.order() * inverse(a)(tree)

    return BseriesRule(new_rule)
Esempio n. 5
0
def inverse(a):
    r"""Return the inverse of *a* in the Butcher group.

    The returned BseriesRule is calculated as
    :math:`\left(a \circ S\right)(\tau)`,
    where :math:`S` denotes the antipode.
    """
    # TODO: Test that a is of the right kind.
    @memoized
    def new_rule(tree):
        return a(antipode_ck(tree))

    return BseriesRule(new_rule)
Esempio n. 6
0
def conjugate_by_commutator(a, c):
    """The conjugate of ``a`` with change of coordinates ``c``.

    Calculated using the commutator.
    """
    def new_rule(tree):
        if tree == empty_tree:
            return 0
        tmp = a
        result = 0
        for n in range(tree.order() + 1):
            result += Fraction((-1)**n, factorial(n)) * tmp(tree)
            tmp = series_commutator(c, tmp)
        return result

    return BseriesRule(new_rule)
Esempio n. 7
0
    def test_it(self):
        method = RKimplicitMidpoint.phi()
        result = conjugate_to_symplectic(method)
        self.assertEqual(4, result)

        method = RKlobattoIIIA4.phi()
        result = conjugate_to_symplectic(method)
        self.assertEqual(6, result)

        method = RKlobattoIIIB4.phi()
        result = conjugate_to_symplectic(method)
        self.assertEqual(4, result)

        method = BseriesRule(_kahan)
        result = conjugate_to_symplectic(method, quadratic_vectorfield=True)
        self.assertEqual(4, result)
Esempio n. 8
0
def composition(a, b):
    r"""Composition of methods, b after a.

    Return the composition :math:`a \circ b`.
    The returned object is a :class:`BseriesRule` if
    :math:`a(\emptyset) = 1` and a :class:`ForestRule`
    otherwise.
    """
    @memoized
    def new_rule(arg):  # arg is tree or forest.
        result = 0
        for pair, multiplicity in subtrees(arg).items():
            result += a(pair[0]) * b(pair[1]) * multiplicity
        return result

    if a(empty_tree) != 1:
        return ForestRule(new_rule)
    else:
        return BseriesRule(new_rule)
Esempio n. 9
0
def composition_ssa(a, b):
    """Same as :func:`composition`, except that it
    halves the stepsize afterwards.

    Equivalent to ``stepsize_adjustment(composition(a,b),Fraction(1, 2))``.
    """
    if a(empty_tree) != 1:
        raise ValueError(
            'Composition can only be performed on consistent B-series.')

    @memoized
    def new_rule(tree):
        sub_trees = subtrees(tree)
        result = 0
        for pair, multiplicity in sub_trees.items():
            result += a(pair[0]) * b(pair[1]) * multiplicity
        return Fraction(result, 2**tree.order())

    return BseriesRule(new_rule)
Esempio n. 10
0
def hf_composition(a):
    r"""The composition :math:`a b`,
    where :math:`b` is the B-series representing
    the vector field corresponding to the exact solution.

    That is :math:`b = \delta_{\circ}`.
    """  # TODO: include some trees in the sphinx docs.
    if a(empty_tree) != 1:
        raise ValueError(
            'Composition can only be performed on consistent B-series.')

    def new_rule(tree):
        if tree == empty_tree:
            return 0
        else:
            result = 1
            for subtree, multiplicity in tree.items():
                result *= a(subtree)**multiplicity
            return result

    return BseriesRule(new_rule)
Esempio n. 11
0
def exp(a, quadratic_vectorfield=False):
    """The exponential.

    If ``a`` is the rule for the B-serie of some modified equation,
    it returns the B-series rule for the numerical method.
    """
    if a(empty_tree) != 0:
        raise ValueError('Can not calculate the exponential for this rule.')

    @memoized
    def new_rule(tree):
        if tree == empty_tree:
            return 1
        result = a(tree)
        b = a
        for n in range(2, tree.order() + 1):
            b = composition(b, a)
            result += Fraction(b(tree), factorial(n))
        return result

    result = BseriesRule(new_rule)
    if quadratic_vectorfield:
        result = remove_non_binary(result)
    return result
Esempio n. 12
0
del tmp
print('let t =', str(t) + ', then:')
print('order(t) = ', order(t))
print('number_of_children(t) = ', number_of_children(t))
print('density(t) = ', density(t))
print('symmetry(t) = ', symmetry(t))
print('alpha(t) =', alpha(t))
print('F(t) = "' + F(t) + '" (A string)')
print('t.multiplicities() =', t.multiplicities(), '(A, list)')
print("")
print('Tree commutator: treeCommutator(t, ButcherTree.basetree()) = ',
      treeCommutator(t, ButcherTree.basetree()))
print('Splitting: split(tree) = ', split(tree))
print("")
print('B-series:')
a = BseriesRule('exact')
print("Let a = BseriesRule('exact')")
b = hf_composition(a)
print("Then b = hf_composition(a) gives:")
b = hf_composition(a)
tmp = treeGenerator()
tmp_tree = tmp.next()
print(tmp_tree, ', b = ', b(tmp_tree))
tmp_tree = tmp.next()
print(tmp_tree, ', b = ', b(tmp_tree))
tmp_tree = tmp.next()
print(tmp_tree, ', b = ', b(tmp_tree))
tmp_tree = tmp.next()
print(tmp_tree, ', b = ', b(tmp_tree))

c = modifiedEquation(a)
Esempio n. 13
0
 def test_sum_series(self):
     thesum = LinearCombination()
     thesum += leaf
     rule1 = BseriesRule(thesum)
     self.assertEqual(0, rule1(empty_tree))
     self.assertEqual(1, rule1(leaf))
Esempio n. 14
0
 def test_zero_series(self):
     rule1 = BseriesRule()
     tree1 = leaf
     self.assertEqual(0, rule1(tree1))