Esempio n. 1
0
def roots_binomial(f):
    """Returns a list of roots of a binomial polynomial."""

    add_eq(f.as_expr(), 0)
    n = f.degree()
    
    a, b = f.nth(n), f.nth(0)
    alpha = (-cancel(b/a))**Rational(1, n)
    beta = (-cancel(b/a))
    tmp = str(Poly(f.as_expr()).factor_list()).split(',')[2][1:]
    TMP = tmp
    if (n > 1):
        TMP += '**' + str(n)
    add_eq(TMP, str(beta))
    if alpha.is_number:
        alpha = alpha.expand(complex=True)

    roots, I = [], S.ImaginaryUnit

    for k in xrange(n):
        zeta = exp(2*k*S.Pi*I/n).expand(complex=True)
        roots.append((alpha*zeta).expand(power_base=False))

    roots = sorted(roots, key=default_sort_key)

    num = 1
    for i in roots:
        add_eq(tmp + str(num), str(i))
        num += 1
    add_comment('')
    return roots
Esempio n. 2
0
def test_binomial_symbolic():
    n = 2
    p = symbols('p', positive=True)
    X = Binomial('X', n, p)
    t = Symbol('t')

    assert simplify(E(X)) == n * p == simplify(moment(X, 1))
    assert simplify(variance(X)) == n * p * (1 - p) == simplify(cmoment(X, 2))
    assert cancel(skewness(X) - (1 - 2 * p) / sqrt(n * p * (1 - p))) == 0
    assert cancel((kurtosis(X)) - (3 + (1 - 6 * p * (1 - p)) / (n * p *
                                                                (1 - p)))) == 0
    assert characteristic_function(X)(t) == p**2 * exp(
        2 * I * t) + 2 * p * (-p + 1) * exp(I * t) + (-p + 1)**2
    assert moment_generating_function(X)(
        t) == p**2 * exp(2 * t) + 2 * p * (-p + 1) * exp(t) + (-p + 1)**2

    # Test ability to change success/failure winnings
    H, T = symbols('H T')
    Y = Binomial('Y', n, p, succ=H, fail=T)
    assert simplify(E(Y) - (n * (H * p + T * (1 - p)))) == 0

    # test symbolic dimensions
    n = symbols('n')
    B = Binomial('B', n, p)
    raises(NotImplementedError, lambda: P(B > 2))
    assert density(B).dict == Density(BinomialDistribution(n, p, 1, 0))
    assert set(density(B).dict.subs(n, 4).doit().keys()) == \
    {S.Zero, S.One, S(2), S(3), S(4)}
    assert set(density(B).dict.subs(n, 4).doit().values()) == \
    {(1 - p)**4, 4*p*(1 - p)**3, 6*p**2*(1 - p)**2, 4*p**3*(1 - p), p**4}
    k = Dummy('k', integer=True)
    assert E(B > 2).dummy_eq(
        Sum(
            Piecewise((k * p**k * (1 - p)**(-k + n) * binomial(n, k), (k >= 0)
                       & (k <= n) & (k > 2)), (0, True)), (k, 0, n)))
Esempio n. 3
0
def ratint_ratpart(f, g, x):
    """
    Horowitz-Ostrogradsky algorithm.

    Explanation
    ===========

    Given a field K and polynomials f and g in K[x], such that f and g
    are coprime and deg(f) < deg(g), returns fractions A and B in K(x),
    such that f/g = A' + B and B has square-free denominator.

    Examples
    ========

        >>> from sympy.integrals.rationaltools import ratint_ratpart
        >>> from sympy.abc import x, y
        >>> from sympy import Poly
        >>> ratint_ratpart(Poly(1, x, domain='ZZ'),
        ... Poly(x + 1, x, domain='ZZ'), x)
        (0, 1/(x + 1))
        >>> ratint_ratpart(Poly(1, x, domain='EX'),
        ... Poly(x**2 + y**2, x, domain='EX'), x)
        (0, 1/(x**2 + y**2))
        >>> ratint_ratpart(Poly(36, x, domain='ZZ'),
        ... Poly(x**5 - 2*x**4 - 2*x**3 + 4*x**2 + x - 2, x, domain='ZZ'), x)
        ((12*x + 6)/(x**2 - 1), 12/(x**2 - x - 2))

    See Also
    ========

    ratint, ratint_logpart
    """
    f = Poly(f, x)
    g = Poly(g, x)

    u, v, _ = g.cofactors(g.diff())

    n = u.degree()
    m = v.degree()

    A_coeffs = [ Dummy('a' + str(n - i)) for i in range(0, n) ]
    B_coeffs = [ Dummy('b' + str(m - i)) for i in range(0, m) ]

    C_coeffs = A_coeffs + B_coeffs

    A = Poly(A_coeffs, x, domain=ZZ[C_coeffs])
    B = Poly(B_coeffs, x, domain=ZZ[C_coeffs])

    H = f - A.diff()*v + A*(u.diff()*v).quo(u) - B*u

    result = solve(H.coeffs(), C_coeffs)

    A = A.as_expr().subs(result)
    B = B.as_expr().subs(result)

    rat_part = cancel(A/u.as_expr(), x)
    log_part = cancel(B/v.as_expr(), x)

    return rat_part, log_part
Esempio n. 4
0
def roots_binomial(f):
    """Returns a list of roots of a binomial polynomial."""

    add_comment("Solve the equation")
    add_eq(f.as_expr(), 0)
    n = f.degree()

    a, b = f.nth(n), f.nth(0)

    add_comment("Rewrite this equation as")
    add_eq(f.gen**n, -b/a)


    alpha = (-cancel(b/a))**Rational(1, n)

    if alpha.is_number:
        alpha = alpha.expand(complex=True)

    roots, I = [], S.ImaginaryUnit

    add_comment("We have the following roots")
    for k in xrange(n):
        zeta = exp(2*k*S.Pi*I/n).expand(complex=True)
        add_eq(f.gen, Mul(alpha, zeta, evaluate=False))
        roots.append((alpha*zeta).expand(power_base=False))

    roots = sorted(roots, key=default_sort_key)

    return roots
Esempio n. 5
0
    def is_coplanar(self, o):
        """ Returns True if `o` is coplanar with self, else False.

        Examples
        ========

        >>> from sympy import Plane, Point3D
        >>> o = (0, 0, 0)
        >>> p = Plane(o, (1, 1, 1))
        >>> p2 = Plane(o, (2, 2, 2))
        >>> p == p2
        False
        >>> p.is_coplanar(p2)
        True
        """
        if isinstance(o, Plane):
            x, y, z = map(Dummy, "xyz")
            return not cancel(
                self.equation(x, y, z) / o.equation(x, y, z)).has(x, y, z)
        if isinstance(o, Point3D):
            return o in self
        elif isinstance(o, LinearEntity3D):
            return all(i in self for i in self)
        elif isinstance(
                o,
                GeometryEntity):  # XXX should only be handling 2D objects now
            return all(i == 0 for i in self.normal_vector[:2])
Esempio n. 6
0
def roots_binomial(f):
    """Returns a list of roots of a binomial polynomial."""
    n = f.degree()

    a, b = f.nth(n), f.nth(0)
    alpha = (-cancel(b/a))**Rational(1, n)

    if alpha.is_number:
        alpha = alpha.expand(complex=True)

    roots, I = [], S.ImaginaryUnit

    for k in xrange(n):
        zeta = exp(2*k*S.Pi*I/n).expand(complex=True)
        roots.append((alpha*zeta).expand(power_base=False))

    if all([ r.is_number for r in roots ]):
        reals, complexes = [], []

        for root in roots:
            if root.is_real:
                reals.append(root)
            else:
                complexes.append(root)

        roots = sorted(reals) + sorted(complexes, key=lambda r: (re(r), -im(r)))

    return roots
Esempio n. 7
0
def roots_binomial(f):
    """Returns a list of roots of a binomial polynomial."""
    n = f.degree()

    a, b = f.nth(n), f.nth(0)
    alpha = (-cancel(b / a))**Rational(1, n)

    if alpha.is_number:
        alpha = alpha.expand(complex=True)

    roots, I = [], S.ImaginaryUnit

    for k in xrange(n):
        zeta = exp(2 * k * S.Pi * I / n).expand(complex=True)
        roots.append((alpha * zeta).expand(power_base=False))

    if all([r.is_number for r in roots]):
        reals, complexes = [], []

        for root in roots:
            if root.is_real:
                reals.append(root)
            else:
                complexes.append(root)

        roots = sorted(reals) + sorted(complexes,
                                       key=lambda r: (re(r), -im(r)))

    return roots
Esempio n. 8
0
def get_sol_2F1_hypergeometric(eq, func, match_object):
    x = func.args[0]
    from sympy.simplify.hyperexpand import hyperexpand
    from sympy.polys.polytools import factor
    C0, C1 = get_numbered_constants(eq, num=2)
    a = match_object['a']
    b = match_object['b']
    c = match_object['c']
    A = match_object['A']

    sol = None

    if c.is_integer == False:
        sol = C0 * hyper([a, b], [c], x) + C1 * hyper([a - c + 1, b - c + 1],
                                                      [2 - c], x) * x**(1 - c)
    elif c == 1:
        y2 = Integral(
            exp(Integral((-(a + b + 1) * x + c) / (x**2 - x), x)) /
            (hyperexpand(hyper([a, b], [c], x))**2), x) * hyper([a, b], [c], x)
        sol = C0 * hyper([a, b], [c], x) + C1 * y2
    elif (c - a - b).is_integer == False:
        sol = C0 * hyper([a, b], [1 + a + b - c], 1 - x) + C1 * hyper(
            [c - a, c - b], [1 + c - a - b], 1 - x) * (1 - x)**(c - a - b)

    if sol:
        # applying transformation in the solution
        subs = match_object['mobius']
        dtdx = simplify(1 / (subs.diff(x)))
        _B = ((a + b + 1) * x - c).subs(x, subs) * dtdx
        _B = factor(_B + ((x**2 - x).subs(x, subs)) * (dtdx.diff(x) * dtdx))
        _A = factor((x**2 - x).subs(x, subs) * (dtdx**2))
        e = exp(logcombine(Integral(cancel(_B / (2 * _A)), x), force=True))
        sol = sol.subs(x, match_object['mobius'])
        sol = sol.subs(x, x**match_object['k'])
        e = e.subs(x, x**match_object['k'])

        if not A.is_zero:
            e1 = Integral(A / 2, x)
            e1 = exp(logcombine(e1, force=True))
            sol = cancel((e / e1) * x**((-match_object['k'] + 1) / 2)) * sol
            sol = Eq(func, sol)
            return sol

        sol = cancel((e) * x**((-match_object['k'] + 1) / 2)) * sol
        sol = Eq(func, sol)
    return sol
Esempio n. 9
0
    def _verify(self, fx) -> bool:
        P, Q = self.wilds()
        x = self.ode_problem.sym
        y = Dummy('y')

        m, n = self.wilds_match()

        m = m.subs(fx, y)
        n = n.subs(fx, y)
        numerator = cancel(m.diff(y) - n.diff(x))

        if numerator.is_zero:
            # Is exact
            return True
        else:
            # The following few conditions try to convert a non-exact
            # differential equation into an exact one.
            # References:
            # 1. Differential equations with applications
            # and historical notes - George E. Simmons
            # 2. https://math.okstate.edu/people/binegar/2233-S99/2233-l12.pdf

            factor_n = cancel(numerator / n)
            factor_m = cancel(-numerator / m)
            if y not in factor_n.free_symbols:
                # If (dP/dy - dQ/dx) / Q = f(x)
                # then exp(integral(f(x))*equation becomes exact
                factor = factor_n
                integration_variable = x
            elif x not in factor_m.free_symbols:
                # If (dP/dy - dQ/dx) / -P = f(y)
                # then exp(integral(f(y))*equation becomes exact
                factor = factor_m
                integration_variable = y
            else:
                # Couldn't convert to exact
                return False

            factor = exp(Integral(factor, integration_variable))
            m *= factor
            n *= factor
            self._wilds_match[P] = m.subs(y, fx)
            self._wilds_match[Q] = n.subs(y, fx)
            return True
Esempio n. 10
0
def roots_binomial(f):
    """Returns a list of roots of a binomial polynomial. If the domain is ZZ
    then the roots will be sorted with negatives coming before positives.
    The ordering will be the same for any numerical coefficients as long as
    the assumptions tested are correct, otherwise the ordering will not be
    sorted (but will be canonical).
    """
    n = f.degree()

    a, b = f.nth(n), f.nth(0)
    base = -cancel(b/a)
    alpha = root(base, n)

    if alpha.is_number:
        alpha = alpha.expand(complex=True)

    # define some parameters that will allow us to order the roots.
    # If the domain is ZZ this is guaranteed to return roots sorted
    # with reals before non-real roots and non-real sorted according
    # to real part and imaginary part, e.g. -1, 1, -1 + I, 2 - I
    neg = base.is_negative
    even = n % 2 == 0
    if neg:
        if even == True and (base + 1).is_positive:
            big = True
        else:
            big = False

    # get the indices in the right order so the computed
    # roots will be sorted when the domain is ZZ
    ks = []
    imax = n//2
    if even:
        ks.append(imax)
        imax -= 1
    if not neg:
        ks.append(0)
    for i in range(imax, 0, -1):
        if neg:
            ks.extend([i, -i])
        else:
            ks.extend([-i, i])
    if neg:
        ks.append(0)
        if big:
            for i in range(0, len(ks), 2):
                pair = ks[i: i + 2]
                pair = list(reversed(pair))

    # compute the roots
    roots, d = [], 2*I*pi/n
    for k in ks:
        zeta = exp(k*d).expand(complex=True)
        roots.append((alpha*zeta).expand(power_base=False))

    return roots
Esempio n. 11
0
def match_2nd_hypergeometric(eq, func):
    x = func.args[0]
    df = func.diff(x)
    a3 = Wild('a3', exclude=[func, func.diff(x), func.diff(x, 2)])
    b3 = Wild('b3', exclude=[func, func.diff(x), func.diff(x, 2)])
    c3 = Wild('c3', exclude=[func, func.diff(x), func.diff(x, 2)])
    deq = a3 * (func.diff(x, 2)) + b3 * df + c3 * func
    r = collect(eq, [func.diff(x, 2), func.diff(x), func]).match(deq)
    if r:
        if not all(val.is_polynomial() for val in r.values()):
            n, d = eq.as_numer_denom()
            eq = expand(n)
            r = collect(eq, [func.diff(x, 2), func.diff(x), func]).match(deq)

    if r and r[a3] != 0:
        A = cancel(r[b3] / r[a3])
        B = cancel(r[c3] / r[a3])
        return [A, B]
    else:
        return []
Esempio n. 12
0
def test_risch_integrate():
    assert risch_integrate(t0*exp(x), x) == t0*exp(x)
    assert risch_integrate(sin(x), x, rewrite_complex=True) == -exp(I*x)/2 - exp(-I*x)/2

    # From my GSoC writeup
    assert risch_integrate((1 + 2*x**2 + x**4 + 2*x**3*exp(2*x**2))/
    (x**4*exp(x**2) + 2*x**2*exp(x**2) + exp(x**2)), x) == \
        NonElementaryIntegral(exp(-x**2), x) + exp(x**2)/(1 + x**2)


    assert risch_integrate(0, x) == 0

    # also tests prde_cancel()
    e1 = log(x/exp(x) + 1)
    ans1 = risch_integrate(e1, x)
    assert ans1 == (x*log(x*exp(-x) + 1) + NonElementaryIntegral((x**2 - x)/(x + exp(x)), x))
    assert cancel(diff(ans1, x) - e1) == 0

    # also tests issue #10798
    e2 = (log(-1/y)/2 - log(1/y)/2)/y - (log(1 - 1/y)/2 - log(1 + 1/y)/2)/y
    ans2 = risch_integrate(e2, y)
    assert ans2 == log(1/y)*log(1 - 1/y)/2 - log(1/y)*log(1 + 1/y)/2 + \
            NonElementaryIntegral((I*pi*y**2 - 2*y*log(1/y) - I*pi)/(2*y**3 - 2*y), y)
    assert expand_log(cancel(diff(ans2, y) - e2), force=True) == 0

    # These are tested here in addition to in test_DifferentialExtension above
    # (symlogs) to test that backsubs works correctly.  The integrals should be
    # written in terms of the original logarithms in the integrands.

    # XXX: Unfortunately, making backsubs work on this one is a little
    # trickier, because x**x is converted to exp(x*log(x)), and so log(x**x)
    # is converted to x*log(x). (x**2*log(x)).subs(x*log(x), log(x**x)) is
    # smart enough, the issue is that these splits happen at different places
    # in the algorithm.  Maybe a heuristic is in order
    assert risch_integrate(log(x**x), x) == x**2*log(x)/2 - x**2/4

    assert risch_integrate(log(x**y), x) == x*log(x**y) - x*y
    assert risch_integrate(log(sqrt(x)), x) == x*log(sqrt(x)) - x/2
Esempio n. 13
0
def roots_binomial(f):
    """Returns a list of roots of a binomial polynomial."""
    n = f.degree()

    a, b = f.nth(n), f.nth(0)
    alpha = (-cancel(b/a))**Rational(1, n)

    if alpha.is_number:
        alpha = alpha.expand(complex=True)

    roots, I = [], S.ImaginaryUnit

    for k in xrange(n):
        zeta = exp(2*k*S.Pi*I/n).expand(complex=True)
        roots.append((alpha*zeta).expand(power_base=False))

    return sorted(roots, key=default_sort_key)
Esempio n. 14
0
def roots_binomial(f):
    """Returns a list of roots of a binomial polynomial."""
    n = f.degree()

    a, b = f.nth(n), f.nth(0)
    alpha = (-cancel(b / a))**Rational(1, n)

    if alpha.is_number:
        alpha = alpha.expand(complex=True)

    roots, I = [], S.ImaginaryUnit

    for k in xrange(n):
        zeta = exp(2 * k * S.Pi * I / n).expand(complex=True)
        roots.append((alpha * zeta).expand(power_base=False))

    return sorted(roots, key=default_sort_key)
Esempio n. 15
0
    def is_coplanar(self, o):
        """ Returns True if `o` is coplanar with self, else False.

        Examples
        ========

        >>> from sympy import Plane, Point3D
        >>> o = (0, 0, 0)
        >>> p = Plane(o, (1, 1, 1))
        >>> p2 = Plane(o, (2, 2, 2))
        >>> p == p2
        False
        >>> p.is_coplanar(p2)
        True
        """
        if isinstance(o, Plane):
            x, y, z = map(Dummy, 'xyz')
            return not cancel(self.equation(x, y, z)/o.equation(x, y, z)).has(x, y, z)
        if isinstance(o, Point3D):
            return o in self
        elif isinstance(o, LinearEntity3D):
            return all(i in self for i in self)
        elif isinstance(o, GeometryEntity):  # XXX should only be handling 2D objects now
            return all(i == 0 for i in self.normal_vector[:2])
Esempio n. 16
0
    def equals(self, o):
        """
        Returns True if self and o are the same mathematical entities.

        Examples
        ========

        >>> from sympy import Plane, Point3D
        >>> a = Plane(Point3D(1, 2, 3), normal_vector=(1, 1, 1))
        >>> b = Plane(Point3D(1, 2, 3), normal_vector=(2, 2, 2))
        >>> c = Plane(Point3D(1, 2, 3), normal_vector=(-1, 4, 6))
        >>> a.equals(a)
        True
        >>> a.equals(b)
        True
        >>> a.equals(c)
        False
        """
        if isinstance(o, Plane):
            a = self.equation()
            b = o.equation()
            return cancel(a/b).is_constant()
        else:
            return False
Esempio n. 17
0
def _quintic_simplify(expr):
    expr = powsimp(expr)
    expr = cancel(expr)
    return together(expr)
Esempio n. 18
0
def integral_steps(integrand, symbol, **options):
    """Returns the steps needed to compute an integral.

    This function attempts to mirror what a student would do by hand as
    closely as possible.

    SymPy Gamma uses this to provide a step-by-step explanation of an
    integral. The code it uses to format the results of this function can be
    found at
    https://github.com/sympy/sympy_gamma/blob/master/app/logic/intsteps.py.

    Examples
    ========

    >>> from sympy import exp, sin, cos
    >>> from sympy.integrals.manualintegrate import integral_steps
    >>> from sympy.abc import x
    >>> print(repr(integral_steps(exp(x) / (1 + exp(2 * x)), x))) \
    # doctest: +NORMALIZE_WHITESPACE
    URule(u_var=_u, u_func=exp(x), constant=1,
        substep=ArctanRule(context=1/(_u**2 + 1), symbol=_u),
        context=exp(x)/(exp(2*x) + 1), symbol=x)
    >>> print(repr(integral_steps(sin(x), x))) \
    # doctest: +NORMALIZE_WHITESPACE
    TrigRule(func='sin', arg=x, context=sin(x), symbol=x)
    >>> print(repr(integral_steps((x**2 + 3)**2 , x))) \
    # doctest: +NORMALIZE_WHITESPACE
    RewriteRule(rewritten=x**4 + 6*x**2 + 9,
    substep=AddRule(substeps=[PowerRule(base=x, exp=4, context=x**4, symbol=x),
        ConstantTimesRule(constant=6, other=x**2,
            substep=PowerRule(base=x, exp=2, context=x**2, symbol=x),
                context=6*x**2, symbol=x),
        ConstantRule(constant=9, context=9, symbol=x)],
    context=x**4 + 6*x**2 + 9, symbol=x), context=(x**2 + 3)**2, symbol=x)


    Returns
    =======
    rule : namedtuple
        The first step; most rules have substeps that must also be
        considered. These substeps can be evaluated using ``manualintegrate``
        to obtain a result.

    """
    integrand_ = integrand
    if integrand.is_Mul:
        num, den = integrand.as_numer_denom()
        if num.is_Pow and den.is_Pow and num.args[1] == den.args[1]:
            p = den.args[1]
            e = cancel(num.args[0] / den.args[0])
            n, d = e.as_numer_denom()
            if n < 0:
                integrand = pow(-n, p) / pow(-d, p)
            else:
                integrand = pow(n, p) / pow(d, p)
            add_comment("Evaluate the integral")
            add_exp(sympy.Integral(integrand_, symbol))
            add_comment("Rewrite the integrand")
            add_eq(integrand_, integrand)
    cachekey = (integrand, symbol)
    if cachekey in _integral_cache:
        if _integral_cache[cachekey] is None:
            # cyclic integral! null_safe will eliminate that path
            return None
        else:
            return _integral_cache[cachekey]
    else:
        _integral_cache[cachekey] = None

    integral = IntegralInfo(integrand, symbol)

    def key(integral):
        integrand = integral.integrand

        if isinstance(integrand, TrigonometricFunction):
            return TrigonometricFunction
        elif isinstance(integrand, sympy.Derivative):
            return sympy.Derivative
        elif symbol not in integrand.free_symbols:
            return sympy.Number
        else:
            for cls in (sympy.Pow, sympy.Symbol, sympy.exp, sympy.log,
                        sympy.Add, sympy.Mul, sympy.atan):
                if isinstance(integrand, cls):
                    return cls

    def integral_is_subclass(*klasses):
        def _integral_is_subclass(integral):
            k = key(integral)
            return k and issubclass(k, klasses)
        return _integral_is_subclass

    result = do_one(
        null_safe(switch(key, {
            sympy.Pow: do_one(null_safe(power_rule), null_safe(arctan_rule), null_safe(cos_m2_rule),null_safe(sin_m2_rule), null_safe(sqrt_rule)),
            sympy.Symbol: power_rule,
            sympy.exp: exp_rule,
            sympy.Add: add_rule,
            sympy.Mul: do_one(null_safe(mul_rule), null_safe(trig_product_rule)),
            sympy.Derivative: derivative_rule,
            TrigonometricFunction: trig_rule,
            sympy.Number: constant_rule
        })),
        null_safe(
            alternatives(
                substitution_rule,
                condition(
                    integral_is_subclass(sympy.Mul, sympy.log, sympy.atan),
                    parts_rule),
                condition(
                    integral_is_subclass(sympy.Mul, sympy.Pow),
                    partial_fractions_rule),
                condition(
                    integral_is_subclass(sympy.Mul, sympy.Pow),
                    distribute_expand_rule),
                trig_powers_products_rule
            )
        ),
        fallback_rule)(integral)
    del _integral_cache[cachekey]
    return result
Esempio n. 19
0
def fresnel_coefficients(angle_of_incidence, medium1, medium2):
    """
    This function uses Fresnel equations to calculate reflection and
    transmission coefficients. Those are obtained for both polarisations
    when the electric field vector is in the plane of incidence (labelled 'p')
    and when the electric field vector is perpendicular to the plane of
    incidence (labelled 's'). There are four real coefficients unless the
    incident ray reflects in total internal in which case there are two complex
    ones. Angle of incidence is the angle between the incident ray and the
    surface normal. ``medium1`` and ``medium2`` can be ``Medium`` or any
    sympifiable object.

    Parameters
    ==========

    angle_of_incidence : sympifiable

    medium1 : Medium or sympifiable
        Medium 1 or its refractive index

    medium2 : Medium or sympifiable
        Medium 2 or its refractive index

    Returns
    =======

    Returns a list with four real Fresnel coefficients:
    [reflection p (TM), reflection s (TE),
    transmission p (TM), transmission s (TE)]
    If the ray is undergoes total internal reflection then returns a
    list of two complex Fresnel coefficients:
    [reflection p (TM), reflection s (TE)]

    Examples
    ========

    >>> from sympy.physics.optics import fresnel_coefficients
    >>> fresnel_coefficients(0.3, 1, 2)
    [0.317843553417859, -0.348645229818821,
            0.658921776708929, 0.651354770181179]
    >>> fresnel_coefficients(0.6, 2, 1)
    [-0.235625382192159 - 0.971843958291041*I,
             0.816477005968898 - 0.577377951366403*I]

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Fresnel_equations
    """
    if not 0 <= 2 * angle_of_incidence < pi:
        raise ValueError('Angle of incidence not in range [0:pi/2)')

    n1 = refractive_index_of_medium(medium1)
    n2 = refractive_index_of_medium(medium2)

    angle_of_refraction = asin(n1 * sin(angle_of_incidence) / n2)
    try:
        angle_of_total_internal_reflection_onset = critical_angle(n1, n2)
    except ValueError:
        angle_of_total_internal_reflection_onset = None

    if angle_of_total_internal_reflection_onset is None or\
    angle_of_total_internal_reflection_onset > angle_of_incidence:
        R_s = -sin(angle_of_incidence - angle_of_refraction)\
                /sin(angle_of_incidence + angle_of_refraction)
        R_p = tan(angle_of_incidence - angle_of_refraction)\
                /tan(angle_of_incidence + angle_of_refraction)
        T_s = 2*sin(angle_of_refraction)*cos(angle_of_incidence)\
                /sin(angle_of_incidence + angle_of_refraction)
        T_p = 2*sin(angle_of_refraction)*cos(angle_of_incidence)\
                /(sin(angle_of_incidence + angle_of_refraction)\
                *cos(angle_of_incidence - angle_of_refraction))
        return [R_p, R_s, T_p, T_s]
    else:
        n = n2 / n1
        R_s = cancel((cos(angle_of_incidence)-\
                I*sqrt(sin(angle_of_incidence)**2 - n**2))\
                /(cos(angle_of_incidence)+\
                I*sqrt(sin(angle_of_incidence)**2 - n**2)))
        R_p = cancel((n**2*cos(angle_of_incidence)-\
                I*sqrt(sin(angle_of_incidence)**2 - n**2))\
                /(n**2*cos(angle_of_incidence)+\
                I*sqrt(sin(angle_of_incidence)**2 - n**2)))
        return [R_p, R_s]
Esempio n. 20
0
def test_aseries_trig():
    assert cancel(
        gruntz(1 / log(atan(x)), x, oo) - 1 / (log(pi) + log(S.Half))) == 0
    assert gruntz(1 / acot(x), x, -oo) is -oo
Esempio n. 21
0
def test_harmonic_rational():
    ne = S(6)
    no = S(5)
    pe = S(8)
    po = S(9)
    qe = S(10)
    qo = S(13)

    Heee = harmonic(ne + pe / qe)
    Aeee = (-log(10) + 2 * (Rational(-1, 4) + sqrt(5) / 4) *
            log(sqrt(-sqrt(5) / 8 + Rational(5, 8))) + 2 *
            (-sqrt(5) / 4 - Rational(1, 4)) *
            log(sqrt(sqrt(5) / 8 + Rational(5, 8))) +
            pi * sqrt(2 * sqrt(5) / 5 + 1) / 2 + Rational(13944145, 4720968))

    Heeo = harmonic(ne + pe / qo)
    Aeeo = (-log(26) +
            2 * log(sin(pi * Rational(3, 13))) * cos(pi * Rational(4, 13)) +
            2 * log(sin(pi * Rational(2, 13))) * cos(pi * Rational(32, 13)) +
            2 * log(sin(pi * Rational(5, 13))) * cos(pi * Rational(80, 13)) -
            2 * log(sin(pi * Rational(6, 13))) * cos(pi * Rational(5, 13)) -
            2 * log(sin(pi * Rational(4, 13))) * cos(pi / 13) +
            pi * cot(pi * Rational(5, 13)) / 2 -
            2 * log(sin(pi / 13)) * cos(pi * Rational(3, 13)) +
            Rational(2422020029, 702257080))

    Heoe = harmonic(ne + po / qe)
    Aeoe = (
        -log(20) + 2 *
        (Rational(1, 4) + sqrt(5) / 4) * log(Rational(-1, 4) + sqrt(5) / 4) +
        2 * (Rational(-1, 4) + sqrt(5) / 4) *
        log(sqrt(-sqrt(5) / 8 + Rational(5, 8))) + 2 *
        (-sqrt(5) / 4 - Rational(1, 4)) *
        log(sqrt(sqrt(5) / 8 + Rational(5, 8))) + 2 *
        (-sqrt(5) / 4 + Rational(1, 4)) * log(Rational(1, 4) + sqrt(5) / 4) +
        Rational(11818877030, 4286604231) + pi * sqrt(2 * sqrt(5) + 5) / 2)

    Heoo = harmonic(ne + po / qo)
    Aeoo = (-log(26) +
            2 * log(sin(pi * Rational(3, 13))) * cos(pi * Rational(54, 13)) +
            2 * log(sin(pi * Rational(4, 13))) * cos(pi * Rational(6, 13)) +
            2 * log(sin(pi * Rational(6, 13))) * cos(pi * Rational(108, 13)) -
            2 * log(sin(pi * Rational(5, 13))) * cos(pi / 13) -
            2 * log(sin(pi / 13)) * cos(pi * Rational(5, 13)) +
            pi * cot(pi * Rational(4, 13)) / 2 -
            2 * log(sin(pi * Rational(2, 13))) * cos(pi * Rational(3, 13)) +
            Rational(11669332571, 3628714320))

    Hoee = harmonic(no + pe / qe)
    Aoee = (-log(10) + 2 * (Rational(-1, 4) + sqrt(5) / 4) *
            log(sqrt(-sqrt(5) / 8 + Rational(5, 8))) + 2 *
            (-sqrt(5) / 4 - Rational(1, 4)) *
            log(sqrt(sqrt(5) / 8 + Rational(5, 8))) +
            pi * sqrt(2 * sqrt(5) / 5 + 1) / 2 + Rational(779405, 277704))

    Hoeo = harmonic(no + pe / qo)
    Aoeo = (-log(26) +
            2 * log(sin(pi * Rational(3, 13))) * cos(pi * Rational(4, 13)) +
            2 * log(sin(pi * Rational(2, 13))) * cos(pi * Rational(32, 13)) +
            2 * log(sin(pi * Rational(5, 13))) * cos(pi * Rational(80, 13)) -
            2 * log(sin(pi * Rational(6, 13))) * cos(pi * Rational(5, 13)) -
            2 * log(sin(pi * Rational(4, 13))) * cos(pi / 13) +
            pi * cot(pi * Rational(5, 13)) / 2 -
            2 * log(sin(pi / 13)) * cos(pi * Rational(3, 13)) +
            Rational(53857323, 16331560))

    Hooe = harmonic(no + po / qe)
    Aooe = (
        -log(20) + 2 *
        (Rational(1, 4) + sqrt(5) / 4) * log(Rational(-1, 4) + sqrt(5) / 4) +
        2 * (Rational(-1, 4) + sqrt(5) / 4) *
        log(sqrt(-sqrt(5) / 8 + Rational(5, 8))) + 2 *
        (-sqrt(5) / 4 - Rational(1, 4)) *
        log(sqrt(sqrt(5) / 8 + Rational(5, 8))) + 2 *
        (-sqrt(5) / 4 + Rational(1, 4)) * log(Rational(1, 4) + sqrt(5) / 4) +
        Rational(486853480, 186374097) + pi * sqrt(2 * sqrt(5) + 5) / 2)

    Hooo = harmonic(no + po / qo)
    Aooo = (-log(26) +
            2 * log(sin(pi * Rational(3, 13))) * cos(pi * Rational(54, 13)) +
            2 * log(sin(pi * Rational(4, 13))) * cos(pi * Rational(6, 13)) +
            2 * log(sin(pi * Rational(6, 13))) * cos(pi * Rational(108, 13)) -
            2 * log(sin(pi * Rational(5, 13))) * cos(pi / 13) -
            2 * log(sin(pi / 13)) * cos(pi * Rational(5, 13)) +
            pi * cot(pi * Rational(4, 13)) / 2 -
            2 * log(sin(pi * Rational(2, 13))) * cos(3 * pi / 13) +
            Rational(383693479, 125128080))

    H = [Heee, Heeo, Heoe, Heoo, Hoee, Hoeo, Hooe, Hooo]
    A = [Aeee, Aeeo, Aeoe, Aeoo, Aoee, Aoeo, Aooe, Aooo]
    for h, a in zip(H, A):
        e = expand_func(h).doit()
        assert cancel(e / a) == 1
        assert abs(h.n() - a.n()) < 1e-12
Esempio n. 22
0
def match_2nd_2F1_hypergeometric(I, k, sing_point, func):
    x = func.args[0]
    a = Wild("a")
    b = Wild("b")
    c = Wild("c")
    t = Wild("t")
    s = Wild("s")
    r = Wild("r")
    alpha = Wild("alpha")
    beta = Wild("beta")
    gamma = Wild("gamma")
    delta = Wild("delta")
    # I0 of the standerd 2F1 equation.
    I0 = ((a-b+1)*(a-b-1)*x**2 + 2*((1-a-b)*c + 2*a*b)*x + c*(c-2))/(4*x**2*(x-1)**2)
    if sing_point != [0, 1]:
        # If singular point is [0, 1] then we have standerd equation.
        eqs = []
        sing_eqs = [-beta/alpha, -delta/gamma, (delta-beta)/(alpha-gamma)]
        # making equations for the finding the mobius transformation
        for i in range(3):
            if i<len(sing_point):
                eqs.append(Eq(sing_eqs[i], sing_point[i]))
            else:
                eqs.append(Eq(1/sing_eqs[i], 0))
        # solving above equations for the mobius transformation
        _beta = -alpha*sing_point[0]
        _delta = -gamma*sing_point[1]
        _gamma = alpha
        if len(sing_point) == 3:
            _gamma = (_beta + sing_point[2]*alpha)/(sing_point[2] - sing_point[1])
        mob = (alpha*x + beta)/(gamma*x + delta)
        mob = mob.subs(beta, _beta)
        mob = mob.subs(delta, _delta)
        mob = mob.subs(gamma, _gamma)
        mob = cancel(mob)
        t = (beta - delta*x)/(gamma*x - alpha)
        t = cancel(((t.subs(beta, _beta)).subs(delta, _delta)).subs(gamma, _gamma))
    else:
        mob = x
        t = x

    # applying mobius transformation in I to make it into I0.
    I = I.subs(x, t)
    I = I*(t.diff(x))**2
    I = factor(I)
    dict_I = {x**2:0, x:0, 1:0}
    I0_num, I0_dem = I0.as_numer_denom()
    # collecting coeff of (x**2, x), of the standerd equation.
    # substituting (a-b) = s, (a+b) = r
    dict_I0 = {x**2:s**2 - 1, x:(2*(1-r)*c + (r+s)*(r-s)), 1:c*(c-2)}
    # collecting coeff of (x**2, x) from I0 of the given equation.
    dict_I.update(collect(expand(cancel(I*I0_dem)), [x**2, x], evaluate=False))
    eqs = []
    # We are comparing the coeff of powers of different x, for finding the values of
    # parameters of standerd equation.
    for key in [x**2, x, 1]:
        eqs.append(Eq(dict_I[key], dict_I0[key]))

    # We can have many possible roots for the equation.
    # I am selecting the root on the basis that when we have
    # standard equation eq = x*(x-1)*f(x).diff(x, 2) + ((a+b+1)*x-c)*f(x).diff(x) + a*b*f(x)
    # then root should be a, b, c.

    _c = 1 - factor(sqrt(1+eqs[2].lhs))
    if not _c.has(Symbol):
        _c = min(list(roots(eqs[2], c)))
    _s = factor(sqrt(eqs[0].lhs + 1))
    _r = _c - factor(sqrt(_c**2 + _s**2 + eqs[1].lhs - 2*_c))
    _a = (_r + _s)/2
    _b = (_r - _s)/2

    rn = {'a':simplify(_a), 'b':simplify(_b), 'c':simplify(_c), 'k':k, 'mobius':mob, 'type':"2F1"}
    return rn
Esempio n. 23
0
    def _eval_nseries(self, x, n, logx, cdir=0):
        # NOTE Please see the comment at the beginning of this file, labelled
        #      IMPORTANT.
        from sympy.functions.elementary.complexes import im
        from sympy.polys.polytools import cancel
        from sympy.series.order import Order
        from sympy.simplify.simplify import logcombine
        from itertools import product
        if not logx:
            logx = log(x)
        if self.args[0] == x:
            return logx
        arg = self.args[0]
        k, l = Wild("k"), Wild("l")
        r = arg.match(k * x**l)
        if r is not None:
            k, l = r[k], r[l]
            if l != 0 and not l.has(x) and not k.has(x):
                r = log(k) + l * logx  # XXX true regardless of assumptions?
                return r

        def coeff_exp(term, x):
            coeff, exp = S.One, S.Zero
            for factor in Mul.make_args(term):
                if factor.has(x):
                    base, exp = factor.as_base_exp()
                    if base != x:
                        try:
                            return term.leadterm(x)
                        except ValueError:
                            return term, S.Zero
                else:
                    coeff *= factor
            return coeff, exp

        # TODO new and probably slow
        try:
            a, b = arg.leadterm(x)
            s = arg.nseries(x, n=n + b, logx=logx)
        except (ValueError, NotImplementedError, PoleError):
            s = arg.nseries(x, n=n, logx=logx)
            while s.is_Order:
                n += 1
                s = arg.nseries(x, n=n, logx=logx)
        a, b = s.removeO().leadterm(x)
        p = cancel(s / (a * x**b) - 1).expand().powsimp()
        if p.has(exp):
            p = logcombine(p)
        if isinstance(p, Order):
            n = p.getn()
        _, d = coeff_exp(p, x)
        if not d.is_positive:
            return log(a) + b * logx + Order(x**n, x)

        def mul(d1, d2):
            res = {}
            for e1, e2 in product(d1, d2):
                ex = e1 + e2
                if ex < n:
                    res[ex] = res.get(ex, S.Zero) + d1[e1] * d2[e2]
            return res

        pterms = {}

        for term in Add.make_args(p):
            co1, e1 = coeff_exp(term, x)
            pterms[e1] = pterms.get(e1, S.Zero) + co1.removeO()

        k = S.One
        terms = {}
        pk = pterms

        while k * d < n:
            coeff = -S.NegativeOne**k / k
            for ex in pk:
                terms[ex] = terms.get(ex, S.Zero) + coeff * pk[ex]
            pk = mul(pk, pterms)
            k += S.One

        res = log(a) + b * logx
        for ex in terms:
            res += terms[ex] * x**(ex)

        if cdir != 0:
            cdir = self.args[0].dir(x, cdir)
        if a.is_real and a.is_negative and im(cdir) < 0:
            res -= 2 * I * S.Pi
        return res + Order(x**n, x)
Esempio n. 24
0
def _quintic_simplify(expr):
    from sympy.simplify.simplify import powsimp
    expr = powsimp(expr)
    expr = cancel(expr)
    return together(expr)
Esempio n. 25
0
def test_cancel():
    assert cancel(A*B - B*A) == A*B - B*A
    assert cancel(A*B*(x - 1)) == A*B*(x - 1)
    assert cancel(A*B*(x**2 - 1)/(x + 1)) == A*B*(x - 1)
    assert cancel(A*B*(x**2 - 1)/(x + 1) - B*A*(x - 1)) == A*B*(x - 1) + (1 - x)*B*A
Esempio n. 26
0
def equivalence_hypergeometric(A, B, func):
    # This method for finding the equivalence is only for 2F1 type.
    # We can extend it for 1F1 and 0F1 type also.
    x = func.args[0]

    # making given equation in normal form
    I1 = factor(cancel(A.diff(x)/2 + A**2/4 - B))

    # computing shifted invariant(J1) of the equation
    J1 = factor(cancel(x**2*I1 + S(1)/4))
    num, dem = J1.as_numer_denom()
    num = powdenest(expand(num))
    dem = powdenest(expand(dem))
    # this function will compute the different powers of variable(x) in J1.
    # then it will help in finding value of k. k is power of x such that we can express
    # J1 = x**k * J0(x**k) then all the powers in J0 become integers.
    def _power_counting(num):
        _pow = {0}
        for val in num:
            if val.has(x):
                if isinstance(val, Pow) and val.as_base_exp()[0] == x:
                    _pow.add(val.as_base_exp()[1])
                elif val == x:
                    _pow.add(val.as_base_exp()[1])
                else:
                    _pow.update(_power_counting(val.args))
        return _pow

    pow_num = _power_counting((num, ))
    pow_dem = _power_counting((dem, ))
    pow_dem.update(pow_num)

    _pow = pow_dem
    k = gcd(_pow)

    # computing I0 of the given equation
    I0 = powdenest(simplify(factor(((J1/k**2) - S(1)/4)/((x**k)**2))), force=True)
    I0 = factor(cancel(powdenest(I0.subs(x, x**(S(1)/k)), force=True)))
    num, dem = I0.as_numer_denom()

    max_num_pow = max(_power_counting((num, )))
    dem_args = dem.args
    sing_point = []
    dem_pow = []
    # calculating singular point of I0.
    for arg in dem_args:
        if arg.has(x):
            if isinstance(arg, Pow):
                # (x-a)**n
                dem_pow.append(arg.as_base_exp()[1])
                sing_point.append(list(roots(arg.as_base_exp()[0], x).keys())[0])
            else:
                # (x-a) type
                dem_pow.append(arg.as_base_exp()[1])
                sing_point.append(list(roots(arg, x).keys())[0])

    dem_pow.sort()
    # checking if equivalence is exists or not.

    if equivalence(max_num_pow, dem_pow) == "2F1":
        return {'I0':I0, 'k':k, 'sing_point':sing_point, 'type':"2F1"}
    else:
        return None