Example #1
0
def test_hyper_as_trig():
    from sympy.simplify.fu import _osborne, _osbornei

    eq = sinh(x)**2 + cosh(x)**2
    t, f = hyper_as_trig(eq)
    assert f(fu(t)) == cosh(2 * x)
    e, f = hyper_as_trig(tanh(x + y))
    assert f(TR12(e)) == (tanh(x) + tanh(y)) / (tanh(x) * tanh(y) + 1)

    d = Dummy()
    assert _osborne(sinh(x), d) == I * sin(x * d)
    assert _osborne(tanh(x), d) == I * tan(x * d)
    assert _osborne(coth(x), d) == cot(x * d) / I
    assert _osborne(cosh(x), d) == cos(x * d)
    assert _osborne(sech(x), d) == sec(x * d)
    assert _osborne(csch(x), d) == csc(x * d) / I
    for func in (sinh, cosh, tanh, coth, sech, csch):
        h = func(pi)
        assert _osbornei(_osborne(h, d), d) == h
    # /!\ the _osborne functions are not meant to work
    # in the o(i(trig, d), d) direction so we just check
    # that they work as they are supposed to work
    assert _osbornei(cos(x * y + z), y) == cosh(x + z * I)
    assert _osbornei(sin(x * y + z), y) == sinh(x + z * I) / I
    assert _osbornei(tan(x * y + z), y) == tanh(x + z * I) / I
    assert _osbornei(cot(x * y + z), y) == coth(x + z * I) * I
    assert _osbornei(sec(x * y + z), y) == sech(x + z * I)
    assert _osbornei(csc(x * y + z), y) == csch(x + z * I) * I
Example #2
0
def test_hyper_as_trig():
    from sympy.simplify.fu import _osborne as o, _osbornei as i, TR12

    eq = sinh(x)**2 + cosh(x)**2
    t, f = hyper_as_trig(eq)
    assert f(fu(t)) == cosh(2*x)
    e, f = hyper_as_trig(tanh(x + y))
    assert f(TR12(e)) == (tanh(x) + tanh(y))/(tanh(x)*tanh(y) + 1)

    d = Dummy()
    assert o(sinh(x), d) == I*sin(x*d)
    assert o(tanh(x), d) == I*tan(x*d)
    assert o(coth(x), d) == cot(x*d)/I
    assert o(cosh(x), d) == cos(x*d)
    for func in (sinh, cosh, tanh, coth):
        h = func(pi)
        assert i(o(h, d), d) == h
    # /!\ the _osborne functions are not meant to work
    # in the o(i(trig, d), d) direction so we just check
    # that they work as they are supposed to work
    assert i(cos(x*y), y) == cosh(x)
    assert i(sin(x*y), y) == sinh(x)/I
    assert i(tan(x*y), y) == tanh(x)/I
    assert i(cot(x*y), y) == coth(x)*I
    assert i(sec(x*y), y) == 1/cosh(x)
    assert i(csc(x*y), y) == I/sinh(x)
Example #3
0
def test_hyper_as_trig():
    from sympy.simplify.fu import _osborne, _osbornei

    eq = sinh(x)**2 + cosh(x)**2
    t, f = hyper_as_trig(eq)
    assert f(fu(t)) == cosh(2 * x)
    assert _osborne(cosh(x)) == cos(x)
    assert _osborne(sinh(x)) == I * sin(x)
    assert _osborne(tanh(x)) == I * tan(x)
    assert _osborne(coth(x)) == cot(x) / I
    assert _osbornei(cos(x)) == cosh(x)
    assert _osbornei(sin(x)) == sinh(x) / I
    assert _osbornei(tan(x)) == tanh(x) / I
    assert _osbornei(cot(x)) == coth(x) * I
    assert _osbornei(sec(x)) == 1 / cosh(x)
    assert _osbornei(csc(x)) == I / sinh(x)
Example #4
0
def test_hyper_as_trig():
    from sympy.simplify.fu import _osborne, _osbornei

    eq = sinh(x)**2 + cosh(x)**2
    t, f = hyper_as_trig(eq)
    assert f(fu(t)) == cosh(2*x)
    assert _osborne(cosh(x)) == cos(x)
    assert _osborne(sinh(x)) == I*sin(x)
    assert _osborne(tanh(x)) == I*tan(x)
    assert _osborne(coth(x)) == cot(x)/I
    assert _osbornei(cos(x)) == cosh(x)
    assert _osbornei(sin(x)) == sinh(x)/I
    assert _osbornei(tan(x)) == tanh(x)/I
    assert _osbornei(cot(x)) == coth(x)*I
    assert _osbornei(sec(x)) == 1/cosh(x)
    assert _osbornei(csc(x)) == I/sinh(x)
Example #5
0
def futrig(e, **kwargs):
    """Return simplified ``e`` using Fu-like transformations.
    This is not the "Fu" algorithm. This is called by default
    from ``trigsimp``. By default, hyperbolics subexpressions
    will be simplified, but this can be disabled by setting
    ``hyper=False``.

    Examples
    ========

    >>> from sympy import trigsimp, tan, sinh, tanh
    >>> from sympy.simplify.trigsimp import futrig
    >>> from sympy.abc import x
    >>> trigsimp(1/tan(x)**2)
    tan(x)**(-2)

    >>> futrig(sinh(x)/tanh(x))
    cosh(x)

    """
    from sympy.simplify.fu import hyper_as_trig
    from sympy.simplify.simplify import bottom_up

    e = sympify(e)

    if not isinstance(e, Basic):
        return e

    if not e.args:
        return e

    old = e
    e = bottom_up(e, lambda x: _futrig(x, **kwargs))

    if kwargs.pop('hyper', True) and e.has(HyperbolicFunction):
        e, f = hyper_as_trig(e)
        e = f(_futrig(e))

    if e != old and e.is_Mul and e.args[0].is_Rational:
        # redistribute leading coeff on 2-arg Add
        e = Mul(*e.as_coeff_Mul())
    return e
Example #6
0
def futrig(e, **kwargs):
    """Return simplified ``e`` using Fu-like transformations.
    This is not the "Fu" algorithm. This is called by default
    from ``trigsimp``. By default, hyperbolics subexpressions
    will be simplified, but this can be disabled by setting
    ``hyper=False``.

    Examples
    ========

    >>> from sympy import trigsimp, tan, sinh, tanh
    >>> from sympy.simplify.trigsimp import futrig
    >>> from sympy.abc import x
    >>> trigsimp(1/tan(x)**2)
    tan(x)**(-2)

    >>> futrig(sinh(x)/tanh(x))
    cosh(x)

    """
    from sympy.simplify.fu import hyper_as_trig
    from sympy.simplify.simplify import bottom_up

    e = sympify(e)

    if not isinstance(e, Basic):
        return e

    if not e.args:
        return e

    old = e
    e = bottom_up(e, lambda x: _futrig(x, **kwargs))

    if kwargs.pop('hyper', True) and e.has(HyperbolicFunction):
        e, f = hyper_as_trig(e)
        e = f(_futrig(e))

    if e != old and e.is_Mul and e.args[0].is_Rational:
        # redistribute leading coeff on 2-arg Add
        e = Mul(*e.as_coeff_Mul())
    return e
Example #7
0
def exptrigsimp(expr):
    """
    Simplifies exponential / trigonometric / hyperbolic functions.

    Examples
    ========

    >>> from sympy import exptrigsimp, exp, cosh, sinh
    >>> from sympy.abc import z

    >>> exptrigsimp(exp(z) + exp(-z))
    2*cosh(z)
    >>> exptrigsimp(cosh(z) - sinh(z))
    exp(-z)
    """
    from sympy.simplify.fu import hyper_as_trig, TR2i
    from sympy.simplify.simplify import bottom_up

    def exp_trig(e):
        # select the better of e, and e rewritten in terms of exp or trig
        # functions
        choices = [e]
        if e.has(*_trigs):
            choices.append(e.rewrite(exp))
        choices.append(e.rewrite(cos))
        return min(*choices, key=count_ops)
    newexpr = bottom_up(expr, exp_trig)

    def f(rv):
        if not rv.is_Mul:
            return rv
        commutative_part, noncommutative_part = rv.args_cnc()
        # Since as_powers_dict loses order information,
        # if there is more than one noncommutative factor,
        # it should only be used to simplify the commutative part.
        if (len(noncommutative_part) > 1):
            return f(Mul(*commutative_part))*Mul(*noncommutative_part)
        rvd = rv.as_powers_dict()
        newd = rvd.copy()

        def signlog(expr, sign=1):
            if expr is S.Exp1:
                return sign, 1
            elif isinstance(expr, exp):
                return sign, expr.args[0]
            elif sign == 1:
                return signlog(-expr, sign=-1)
            else:
                return None, None

        ee = rvd[S.Exp1]
        for k in rvd:
            if k.is_Add and len(k.args) == 2:
                # k == c*(1 + sign*E**x)
                c = k.args[0]
                sign, x = signlog(k.args[1]/c)
                if not x:
                    continue
                m = rvd[k]
                newd[k] -= m
                if ee == -x*m/2:
                    # sinh and cosh
                    newd[S.Exp1] -= ee
                    ee = 0
                    if sign == 1:
                        newd[2*c*cosh(x/2)] += m
                    else:
                        newd[-2*c*sinh(x/2)] += m
                elif newd[1 - sign*S.Exp1**x] == -m:
                    # tanh
                    del newd[1 - sign*S.Exp1**x]
                    if sign == 1:
                        newd[-c/tanh(x/2)] += m
                    else:
                        newd[-c*tanh(x/2)] += m
                else:
                    newd[1 + sign*S.Exp1**x] += m
                    newd[c] += m

        return Mul(*[k**newd[k] for k in newd])
    newexpr = bottom_up(newexpr, f)

    # sin/cos and sinh/cosh ratios to tan and tanh, respectively
    if newexpr.has(HyperbolicFunction):
        e, f = hyper_as_trig(newexpr)
        newexpr = f(TR2i(e))
    if newexpr.has(TrigonometricFunction):
        newexpr = TR2i(newexpr)

    # can we ever generate an I where there was none previously?
    if not (newexpr.has(I) and not expr.has(I)):
        expr = newexpr
    return expr
Example #8
0
def exptrigsimp(expr):
    """
    Simplifies exponential / trigonometric / hyperbolic functions.

    Examples
    ========

    >>> from sympy import exptrigsimp, exp, cosh, sinh
    >>> from sympy.abc import z

    >>> exptrigsimp(exp(z) + exp(-z))
    2*cosh(z)
    >>> exptrigsimp(cosh(z) - sinh(z))
    exp(-z)
    """
    from sympy.simplify.fu import hyper_as_trig, TR2i
    from sympy.simplify.simplify import bottom_up

    def exp_trig(e):
        # select the better of e, and e rewritten in terms of exp or trig
        # functions
        choices = [e]
        if e.has(*_trigs):
            choices.append(e.rewrite(exp))
        choices.append(e.rewrite(cos))
        return min(*choices, key=count_ops)

    newexpr = bottom_up(expr, exp_trig)

    def f(rv):
        if not rv.is_Mul:
            return rv
        commutative_part, noncommutative_part = rv.args_cnc()
        # Since as_powers_dict loses order information,
        # if there is more than one noncommutative factor,
        # it should only be used to simplify the commutative part.
        if (len(noncommutative_part) > 1):
            return f(Mul(*commutative_part)) * Mul(*noncommutative_part)
        rvd = rv.as_powers_dict()
        newd = rvd.copy()

        def signlog(expr, sign=1):
            if expr is S.Exp1:
                return sign, 1
            elif isinstance(expr, exp):
                return sign, expr.args[0]
            elif sign == 1:
                return signlog(-expr, sign=-1)
            else:
                return None, None

        ee = rvd[S.Exp1]
        for k in rvd:
            if k.is_Add and len(k.args) == 2:
                # k == c*(1 + sign*E**x)
                c = k.args[0]
                sign, x = signlog(k.args[1] / c)
                if not x:
                    continue
                m = rvd[k]
                newd[k] -= m
                if ee == -x * m / 2:
                    # sinh and cosh
                    newd[S.Exp1] -= ee
                    ee = 0
                    if sign == 1:
                        newd[2 * c * cosh(x / 2)] += m
                    else:
                        newd[-2 * c * sinh(x / 2)] += m
                elif newd[1 - sign * S.Exp1**x] == -m:
                    # tanh
                    del newd[1 - sign * S.Exp1**x]
                    if sign == 1:
                        newd[-c / tanh(x / 2)] += m
                    else:
                        newd[-c * tanh(x / 2)] += m
                else:
                    newd[1 + sign * S.Exp1**x] += m
                    newd[c] += m

        return Mul(*[k**newd[k] for k in newd])

    newexpr = bottom_up(newexpr, f)

    # sin/cos and sinh/cosh ratios to tan and tanh, respectively
    if newexpr.has(HyperbolicFunction):
        e, f = hyper_as_trig(newexpr)
        newexpr = f(TR2i(e))
    if newexpr.has(TrigonometricFunction):
        newexpr = TR2i(newexpr)

    # can we ever generate an I where there was none previously?
    if not (newexpr.has(I) and not expr.has(I)):
        expr = newexpr
    return expr
Example #9
0
def exptrigsimp(expr, simplify=True):
    """
    Simplifies exponential / trigonometric / hyperbolic functions.
    When ``simplify`` is True (default) the expression obtained after the
    simplification step will be then be passed through simplify to
    precondition it so the final transformations will be applied.

    Examples
    ========

    >>> from sympy import exptrigsimp, exp, cosh, sinh
    >>> from sympy.abc import z

    >>> exptrigsimp(exp(z) + exp(-z))
    2*cosh(z)
    >>> exptrigsimp(cosh(z) - sinh(z))
    exp(-z)
    """
    from sympy.simplify.fu import hyper_as_trig, TR2i
    from sympy.simplify.simplify import bottom_up

    def exp_trig(e):
        # select the better of e, and e rewritten in terms of exp or trig
        # functions
        choices = [e]
        if e.has(*_trigs):
            choices.append(e.rewrite(exp))
        choices.append(e.rewrite(cos))
        return min(*choices, key=count_ops)

    newexpr = bottom_up(expr, exp_trig)

    if simplify:
        newexpr = newexpr.simplify()

    # conversion from exp to hyperbolic
    ex = newexpr.atoms(exp, S.Exp1)
    ex = [ei for ei in ex if 1 / ei not in ex]
    ## sinh and cosh
    for ei in ex:
        e2 = ei**-2
        if e2 in ex:
            a = e2.args[0] / 2 if not e2 is S.Exp1 else S.Half
            newexpr = newexpr.subs((e2 + 1) * ei, 2 * cosh(a))
            newexpr = newexpr.subs((e2 - 1) * ei, 2 * sinh(a))
    ## exp ratios to tan and tanh
    for ei in ex:
        n, d = ei - 1, ei + 1
        et = n / d
        etinv = d / n  # not 1/et or else recursion errors arise
        a = ei.args[0] if ei.func is exp else S.One
        if a.is_Mul or a is S.ImaginaryUnit:
            c = a.as_coefficient(I)
            if c:
                t = S.ImaginaryUnit * tan(c / 2)
                newexpr = newexpr.subs(etinv, 1 / t)
                newexpr = newexpr.subs(et, t)
                continue
        t = tanh(a / 2)
        newexpr = newexpr.subs(etinv, 1 / t)
        newexpr = newexpr.subs(et, t)

    # sin/cos and sinh/cosh ratios to tan and tanh, respectively
    if newexpr.has(HyperbolicFunction):
        e, f = hyper_as_trig(newexpr)
        newexpr = f(TR2i(e))
    if newexpr.has(TrigonometricFunction):
        newexpr = TR2i(newexpr)

    # can we ever generate an I where there was none previously?
    if not (newexpr.has(I) and not expr.has(I)):
        expr = newexpr
    return expr
Example #10
0
def exptrigsimp(expr, simplify=True):
    """
    Simplifies exponential / trigonometric / hyperbolic functions.
    When ``simplify`` is True (default) the expression obtained after the
    simplification step will be then be passed through simplify to
    precondition it so the final transformations will be applied.

    Examples
    ========

    >>> from sympy import exptrigsimp, exp, cosh, sinh
    >>> from sympy.abc import z

    >>> exptrigsimp(exp(z) + exp(-z))
    2*cosh(z)
    >>> exptrigsimp(cosh(z) - sinh(z))
    exp(-z)
    """
    from sympy.simplify.fu import hyper_as_trig, TR2i
    from sympy.simplify.simplify import bottom_up

    def exp_trig(e):
        # select the better of e, and e rewritten in terms of exp or trig
        # functions
        choices = [e]
        if e.has(*_trigs):
            choices.append(e.rewrite(exp))
        choices.append(e.rewrite(cos))
        return min(*choices, key=count_ops)
    newexpr = bottom_up(expr, exp_trig)

    if simplify:
        newexpr = newexpr.simplify()

    # conversion from exp to hyperbolic
    ex = newexpr.atoms(exp, S.Exp1)
    ex = [ei for ei in ex if 1/ei not in ex]
    ## sinh and cosh
    for ei in ex:
        e2 = ei**-2
        if e2 in ex:
            a = e2.args[0]/2 if not e2 is S.Exp1 else S.Half
            newexpr = newexpr.subs((e2 + 1)*ei, 2*cosh(a))
            newexpr = newexpr.subs((e2 - 1)*ei, 2*sinh(a))
    ## exp ratios to tan and tanh
    for ei in ex:
        n, d = ei - 1, ei + 1
        et = n/d
        etinv = d/n  # not 1/et or else recursion errors arise
        a = ei.args[0] if ei.func is exp else S.One
        if a.is_Mul or a is S.ImaginaryUnit:
            c = a.as_coefficient(I)
            if c:
                t = S.ImaginaryUnit*tan(c/2)
                newexpr = newexpr.subs(etinv, 1/t)
                newexpr = newexpr.subs(et, t)
                continue
        t = tanh(a/2)
        newexpr = newexpr.subs(etinv, 1/t)
        newexpr = newexpr.subs(et, t)

    # sin/cos and sinh/cosh ratios to tan and tanh, respectively
    if newexpr.has(HyperbolicFunction):
        e, f = hyper_as_trig(newexpr)
        newexpr = f(TR2i(e))
    if newexpr.has(TrigonometricFunction):
        newexpr = TR2i(newexpr)

    # can we ever generate an I where there was none previously?
    if not (newexpr.has(I) and not expr.has(I)):
        expr = newexpr
    return expr