예제 #1
0
    def __lin_reduce__(par_integral):
        used_chung_wu = False
        _k = Symbol("k_l")

        _num, _denom = par_integral.as_numer_denom()

        constant = 1
        factors = _denom.as_ordered_factors()
        if len(factors) > 1:
            _denom = factors[1]
            constant = factors[0]
            assert factors[0].is_constant(
            ), "assumed first factor is a constant prefactor but might need to do something smarter"

        #assert has single term with power
        tup = list(
            _denom.as_powers_dict().items()
        )[-1]  #the single pair of; term and power but there may be an integer constant prefactor
        _p = expand(
            tup[0])  #expand inside so that we have just a polynommial in k
        _power = tup[1]
        #_p = _p.subs(_k, -1*_k)
        _p = collect(_p, Symbol("k_l"))  #organise the poly into powers of k
        p = Poly(_p, _k)
        coeff = p.all_coeffs()
        assert len(
            coeff
        ) == 3, "there is a problem. the polynomial in the propagator is not of order 2 in loop momentum"

        _denom.as_powers_dict().items()

        el = determine_elimination_variable(p)
        aps = list(__alpha_params__(_p))
        if el != None:
            print("Apply checng-wu, setting", el, "to 1")
            _p = _p.subs(el, 1)  #cheng-wu says set one of the variables = 1
            coeff = Poly(_p, _k).all_coeffs()  #refresh coefficients
            used_chung_wu = True
        elif len(aps) == 2:
            #TODO - there is a smarter choice to make here - we should coose the param that simplifies the expression the most
            _p = simplify(
                _p.subs(aps[0], 1 - aps[1])
            )  #special case simplification assuming we dont want to use them for linearisation
            coeff = Poly(_p, _k).all_coeffs()  #refresh coefficients

        _p = simplify(_p / coeff[0])
        p = Poly(_p, _k)

        coeff = p.all_coeffs()

        if len(coeff) == 3 and coeff[1] == 0: pass
        else:
            sub = Symbol("k_l") - (coeff[1]) / 2
            _p = expand(_p.subs(_k, sub))
            p = Poly(_p)

        kpropagator.__assert_k2_coeff__(_p)

        return _num / (constant * (_p**_power)), used_chung_wu, p
예제 #2
0
def power_dict(n, irr, p):
    result = {(1, ): 0}
    test_poly = Poly(1, alpha)
    for i in range(1, n - 1):
        test_poly = (Poly(Poly(alpha, alpha) * test_poly, alpha) %
                     irr).set_domain(GF(p))
        if tuple(test_poly.all_coeffs()) in result:
            return result
        result[tuple(test_poly.all_coeffs())] = i
    return result
예제 #3
0
def gauss_lobatto_points(p):
    """
    Returns the list of Gauss-Lobatto points of the order 'p'.
    """
    x = Symbol("x")
    print "creating"
    e = legendre(p, x).diff(x)
    e = Poly(e, x)
    print "polydone"
    if e == 0:
        return []
    print "roots"
    if e == 1:
        r = []
    else:
        with workdps(40):
            r, err = polyroots(e.all_coeffs(), error=True)
        #if err > 1e-40:
        #    raise Exception("Internal Error: Root is not precise")
    print "done"
    p = []
    p.append("-1.0")
    for x in r:
        if abs(x) < 1e-40: x = 0
        p.append(str(x))
    p.append("1.0")
    return p
예제 #4
0
def sym_probs(num_dice=1,
              die_faces=6,
              success_count=None,
              obstacle_limit=10,
              log=False):
    # This is so much easier when not exploding, just discreet normal
    if success_count == None:
        success_count = die_faces // 2
    # Probability of a die roll being a success
    success_chance = Rational(str(success_count) + "/" + str(die_faces))
    # Probability of a die roll failing
    failure_chance = 1 - success_chance

    if log:
        print(
            f"Die faces: {die_faces}, success count: {success_count}, success chance: {success_chance}"
        )

    pol = Poly(failure_chance + success_chance * x, x)**num_dice
    coeffs = np.array(pol.all_coeffs())
    if log:
        print("Generating function: ", pol)
        print("Cummulative prob (low means raise obstacle limit): ",
              float(coeffs.sum()))

    cum_coeffs = coeffs.cumsum()[::-1] + (1 - coeffs.sum())

    return cum_coeffs
예제 #5
0
def sym_explode_probs(num_dice=1,
                      die_faces=6,
                      success_count=None,
                      explode_count=1,
                      obstacle_limit=10,
                      log=False):
    # This is so much easier when not exploding, just discreet normal
    if success_count == None:
        success_count = die_faces // 2
    # Probability of a die roll being a success
    success_chance = Rational(str(success_count) + "/" + str(die_faces))
    # Probability of a *success* exploding
    explode_chance = Rational(str(explode_count) + "/" + str(success_count))
    # Probability of a die roll failing
    failure_chance = 1 - success_chance
    # Probability of a *success* not exploding
    dud_chance = 1 - explode_chance

    if log:
        print(
            f"Die faces: {die_faces}, success count: {success_count}, success chance: {success_chance}, explode count: {explode_count}, explode_chance: {explode_chance}"
        )

    # There is probably a way to do this that doesn't involve calculating the
    # first two terms and finding the ratio this is how I did it by hand though
    # and I don't remember enough combinatorics to know a better way
    p_0 = failure_chance
    p_1 = success_chance * (dud_chance + explode_chance * failure_chance)
    p_2 = success_chance * explode_chance * success_chance * (
        dud_chance + explode_chance * failure_chance)
    if log:
        print("p_0 = ", p_0)
        print("p_1 = ", p_1)
        print("p_2 = ", p_2)

    term_relation = p_2 / p_1

    # We will need p_0 to be the failure chance, that doesn't always work out, so we force it
    # I don't really know why this works, but it does in the BW case
    initial = p_1 / term_relation

    correction = p_0 - initial
    if log:
        print("term relation = ", term_relation)
        print("initial = ", initial)
        print("correction = ", correction)

    p_n = initial * (success_chance * explode_chance)**(n)
    g = Sum(p_n * x**n, (n, 0, obstacle_limit)).doit()
    pol = Poly(g + correction, x)**num_dice
    coeffs = np.array(pol.all_coeffs())
    if log:
        print("Generating function: ", pol)
        print("Cummulative prob (low means raise obstacle limit): ",
              float(coeffs.sum()))
        print("Coefficients: ", coeffs[::-1])
    # We do this here so our cummulative sum includes higher order terms
    cum_coeffs = coeffs.cumsum()[::-1] + (1 - coeffs.sum())

    return cum_coeffs
예제 #6
0
def gauss_lobatto_points(p):
    """
    Returns the list of Gauss-Lobatto points of the order 'p'.
    """
    x = Symbol("x")
    print "creating"
    e = legendre(p, x).diff(x)
    e = Poly(e, x)
    print "polydone"
    if e == 0:
        return []
    print "roots"
    if e == 1:
        r = []
    else:
        with workdps(40):
            r, err = polyroots(e.all_coeffs(), error=True)
        #if err > 1e-40:
        #    raise Exception("Internal Error: Root is not precise")
    print "done"
    p = []
    p.append("-1.0")
    for x in r:
        if abs(x) < 1e-40: x = 0
        p.append(str(x))
    p.append("1.0")
    return p
예제 #7
0
    def _eval_expand_func(self, **hints):
        from sympy import exp, I, floor, Add, Poly, Dummy, exp_polar, unpolarify
        z, s, a = self.args
        if z == 1:
            return zeta(s, a)
        if s.is_Integer and s <= 0:
            t = Dummy('t')
            p = Poly((t + a)**(-s), t)
            start = 1/(1 - t)
            res = S(0)
            for c in reversed(p.all_coeffs()):
                res += c*start
                start = t*start.diff(t)
            return res.subs(t, z)

        if a.is_Rational:
            # See section 18 of
            #   Kelly B. Roach.  Hypergeometric Function Representations.
            #   In: Proceedings of the 1997 International Symposium on Symbolic and
            #   Algebraic Computation, pages 205-211, New York, 1997. ACM.
            # TODO should something be polarified here?
            add = S(0)
            mul = S(1)
            # First reduce a to the interaval (0, 1]
            if a > 1:
                n = floor(a)
                if n == a:
                    n -= 1
                a -= n
                mul = z**(-n)
                add = Add(*[-z**(k - n)/(a + k)**s for k in xrange(n)])
            elif a <= 0:
                n = floor(-a) + 1
                a += n
                mul = z**n
                add = Add(*[z**(n - 1 - k)/(a - k - 1)**s for k in xrange(n)])

            m, n = S([a.p, a.q])
            zet = exp_polar(2*pi*I/n)
            root = z**(1/n)
            return add + mul*n**(s - 1)*Add(
                *[polylog(s, zet**k*root)._eval_expand_func(**hints)
                  / (unpolarify(zet)**k*root)**m for k in xrange(n)])

        # TODO use minpoly instead of ad-hoc methods when issue 2789 is fixed
        if z.func is exp and (z.args[0]/(pi*I)).is_Rational or z in [-1, I, -I]:
            # TODO reference?
            if z == -1:
                p, q = S([1, 2])
            elif z == I:
                p, q = S([1, 4])
            elif z == -I:
                p, q = S([-1, 4])
            else:
                arg = z.args[0]/(2*pi*I)
                p, q = S([arg.p, arg.q])
            return Add(*[exp(2*pi*I*k*p/q)/q**s*zeta(s, (k + a)/q)
                         for k in xrange(q)])

        return lerchphi(z, s, a)
예제 #8
0
파일: transforms.py 프로젝트: tuhina/sympy
 def linear_arg(arg):
     """ Test if arg is of form a*s+b, raise exception if not. """
     if not arg.is_polynomial(s):
         raise exception(fact)
     p = Poly(arg, s)
     if p.degree() != 1:
         raise exception(fact)
     return p.all_coeffs()
예제 #9
0
 def linear_arg(arg):
     """ Test if arg is of form a*s+b, raise exception if not. """
     if not arg.is_polynomial(s):
         raise exception(fact)
     p = Poly(arg, s)
     if p.degree() != 1:
         raise exception(fact)
     return p.all_coeffs()
def zero_upper_bound_of_positive_poly(poly):
    poly = Poly(poly.expand())
    cs = poly.all_coeffs()
    cs0 = abs(cs[0])
    assert cs[0] == LC(poly)
    height = max(map(abs, cs))
    upper = ceiling(two * height / cs0)
    upper = int(upper)
    assert upper >= 2
    return upper
예제 #11
0
def extract_coefficients(func, t):
    tx = (diff(func[0], t))
    ty = (diff(func[1], t))

    eq = together(tx * tx + ty * ty)
    n, _ = fraction(eq)
    poly = Poly(n, t)
    coeffs = poly.all_coeffs()
    coeffs.reverse()

    return poly, coeffs
예제 #12
0
def read_input():
    global epsilon, kmax, tries
    epsilon = float(en_eps.get())
    kmax = int(sb_kmax.get())
    tries = int(sb_tries.get())
    expr = str(en_func.get())

    transformations = (standard_transformations + (implicit_multiplication_application,))
    expr = Poly(parse_expr(expr, transformations=transformations), x)
    coefficients = expr.all_coeffs()

    return expr, coefficients
예제 #13
0
파일: evalf.py 프로젝트: arghdos/sympy
def check_convergence(numer, denom, n):
    """
    Returns (h, g, p) where
    -- h is:
        > 0 for convergence of rate 1/factorial(n)**h
        < 0 for divergence of rate factorial(n)**(-h)
        = 0 for geometric or polynomial convergence or divergence

    -- abs(g) is:
        > 1 for geometric convergence of rate 1/h**n
        < 1 for geometric divergence of rate h**n
        = 1 for polynomial convergence or divergence

        (g < 0 indicates an alternating series)

    -- p is:
        > 1 for polynomial convergence of rate 1/n**h
        <= 1 for polynomial divergence of rate n**(-h)

    """
    from sympy import Poly
    npol = Poly(numer, n)
    dpol = Poly(denom, n)
    p = npol.degree()
    q = dpol.degree()
    rate = q - p
    if rate:
        return rate, None, None
    constant = dpol.LC() / npol.LC()
    if abs(constant) != 1:
        return rate, constant, None
    if npol.degree() == dpol.degree() == 0:
        return rate, constant, 0
    pc = npol.all_coeffs()[1]
    qc = dpol.all_coeffs()[1]
    return rate, constant, (qc - pc)/dpol.LC()
예제 #14
0
파일: evalf.py 프로젝트: hridog00/Proyecto
def check_convergence(numer, denom, n):
    """
    Returns (h, g, p) where
    -- h is:
        > 0 for convergence of rate 1/factorial(n)**h
        < 0 for divergence of rate factorial(n)**(-h)
        = 0 for geometric or polynomial convergence or divergence

    -- abs(g) is:
        > 1 for geometric convergence of rate 1/h**n
        < 1 for geometric divergence of rate h**n
        = 1 for polynomial convergence or divergence

        (g < 0 indicates an alternating series)

    -- p is:
        > 1 for polynomial convergence of rate 1/n**h
        <= 1 for polynomial divergence of rate n**(-h)

    """
    from sympy import Poly
    npol = Poly(numer, n)
    dpol = Poly(denom, n)
    p = npol.degree()
    q = dpol.degree()
    rate = q - p
    if rate:
        return rate, None, None
    constant = dpol.LC() / npol.LC()
    if abs(constant) != 1:
        return rate, constant, None
    if npol.degree() == dpol.degree() == 0:
        return rate, constant, 0
    pc = npol.all_coeffs()[1]
    qc = dpol.all_coeffs()[1]
    return rate, constant, (qc - pc) / dpol.LC()
예제 #15
0
def first_alpha_power_root(poly, irr_poly, p, elements_to_check=None):
    poly = Poly([(Poly(coeff, alpha) % irr_poly).trunc(p).as_expr()
                 for coeff in poly.all_coeffs()], x)
    test_poly = Poly(1, alpha)
    log.debug(f"testing f:{poly}")
    for i in range(1, p**irr_poly.degree()):
        test_poly = (Poly(Poly(alpha, alpha) * test_poly, alpha) %
                     irr_poly).set_domain(GF(p))
        if elements_to_check is not None and i not in elements_to_check:
            continue
        value = Poly((Poly(poly.eval(test_poly.as_expr()), alpha) % irr_poly),
                     alpha).trunc(p)
        log.debug(f"testing alpha^{i} f({test_poly})={value}")
        if value.is_zero:
            return i
    return -1
예제 #16
0
def _valid_expr(expr):
    """
    return coefficients of expr if it is a univariate polynomial
    with integer coefficients else raise a ValueError.
    """

    from sympy import Poly
    from sympy.polys.domains import ZZ
    if not expr.is_polynomial():
        raise ValueError("The expression should be a polynomial")
    polynomial = Poly(expr)
    if not  polynomial.is_univariate:
        raise ValueError("The expression should be univariate")
    if not polynomial.domain == ZZ:
        raise ValueError("The expression should should have integer coefficients")
    return polynomial.all_coeffs()
예제 #17
0
파일: common.py 프로젝트: MathPhys/hermes
def gauss_lobatto_points(p):
    """
    Returns the list of Gauss-Lobatto points of the order 'p'.
    """
    x = Symbol("x")
    e = (1-x**2)*legendre(p, x).diff(x)
    e = Poly(e, x)
    if e == 0:
        return []
    with workdps(40):
        r, err = polyroots(e.all_coeffs(), error=True)
    if err > 1e-40:
        raise Exception("Internal Error: Root is not precise")
    p = []
    for x in r:
        if abs(x) < 1e-40: x = 0
        p.append(str(x))
    return p
예제 #18
0
def _valid_expr(expr):
    """This function is used by `polynomial_congruence`.
    If `expr` is a univariate polynomial will integer
    coefficients the it returns its coefficients,
    otherwise it raises Valuerror
    """

    from sympy import Poly
    from sympy.polys.domains import ZZ
    if not expr.is_polynomial():
        raise ValueError("The expression should be a polynomial")
    polynomial = Poly(expr)
    if not polynomial.is_univariate:
        raise ValueError("The expression should be univariate")
    if not polynomial.domain == ZZ:
        raise ValueError(
            "The expression should should have integer coefficients")
    return polynomial.all_coeffs()
예제 #19
0
def minimal_poly(i, n, q, irr_poly):
    ti = int(i)
    checked = np.zeros(n, dtype=bool)
    checked[ti] = True
    poly = Poly(x - alpha**ti, x)
    for k in range(n):
        ti = (ti * q) % n
        if checked[ti]:
            polys = [(Poly(c, alpha) % irr_poly).trunc(q)
                     for c in poly.all_coeffs()]
            for p in polys:
                if p.degree() > 0:
                    raise Exception("Couldn't find minimal polynomial")
            coeffs = [p.nth(0) for p in polys]
            return Poly(coeffs, x)
        checked[ti] = True
        poly = poly * Poly(x - alpha**ti, x)
    return None
예제 #20
0
def min_poly(i, prim_poly):
    """
    Calculate minimal polynomial for a given i and primitive polynomial.
    """
    checked = np.zeros(n, dtype=bool)
    checked[i] = True
    poly = Poly(x - alpha**i, x)
    for j in range(n):
        i = (i * q) % n
        if checked[i]:
            polys = [(Poly(c, alpha) % prim_poly).trunc(q)
                     for c in poly.all_coeffs()]
            for p in polys:
                if p.degree() > 0:
                    raise Exception('Couldnt find minimal polynomial')
            coeffs = [p.nth(0) for p in polys]
            return Poly(coeffs, x)
        poly = poly * Poly(x - alpha**i, x)
    return None
print 'W0: ', W0
print 'B: ', B, '\n'
# Defining a list [0,0,...1] of size N+1 required to generate the coefficients of Nth order Cheyshev Polynomial
c = zeros(N+1)
c[-1] = 1.0
#
TnS = polynomial.chebyshev.Chebyshev(c)
TnS_coeff = polynomial.chebyshev.cheb2poly(TnS.coef)
# print 'Coefficients: ', TnS_coeff
CnW = 0.0
for i in xrange(int(N+1)):
	CnW = CnW + TnS_coeff[i]*(-1j*s)**i
# HcS_sq = 1.0/(1.0 + (eps**2)*(CnW**2))
denom_all = Poly(1.0 + (eps**2)*(CnW**2), s)
# print denom_all
denom_all = denom_all.all_coeffs()
leading_coeff = denom_all[0]
denom_all = [i/leading_coeff for i in denom_all]
norm_fac = (leading_coeff/abs(leading_coeff))*pow(abs(leading_coeff),0.5)
poles_all = roots(denom_all)
poles_LHP = zeros(N,dtype=complex64)
j = 0
denominator_LHP = 1.0 + 0j
for i in xrange(int(2*N)):
	if ((poles_all[i]).real<0):
		poles_LHP[j] = poles_all[i]
		j = j+1
		denominator_LHP = expand(denominator_LHP*(s-poles_all[i]))
# print poles
denom_poly = Poly(denominator_LHP,s)
denom_poly = denom_poly.all_coeffs()
예제 #22
0
def synthetic(divisor: int, dividend: str, quiet=False):
    eqn = toValidEqn(dividend)
    eqn = sympify("Eq(" + eqn + ", 0)")
    symbol = list(eqn.free_symbols)[0]
    eqn = Poly(eqn, symbol)
    coeffs = eqn.all_coeffs()
    current = coeffs[0]

    new_coeffs = []
    middle_numbers = ['']

    for coefficient in coeffs[1:]:
        new_coeffs.append(current)
        current = Decimal(str(divisor)) * Decimal(str(current))
        middle_numbers.append(current)
        current += Decimal(str(coefficient))

    coefficient_printable = ''
    middle_numbers_printable = ''
    new_coeffs_printable = ''
    for coef, num, new_coef in zip(coeffs, middle_numbers,
                                   new_coeffs + [current]):
        coef = str(coef)
        num = str(num)
        new_coef = str(new_coef)

        # pad numbers with space
        max_length_number = max(len(coef), len(num), len(new_coef))

        coef = coef.rjust(max_length_number)
        num = num.rjust(max_length_number)
        new_coef = new_coef.rjust(max_length_number)

        coefficient_printable = coefficient_printable + '    ' + coef
        middle_numbers_printable = middle_numbers_printable + '    ' + num
        new_coeffs_printable = new_coeffs_printable + '    ' + new_coef

    # remove extra whitespace
    coefficient_printable = '|' + coefficient_printable[4:]
    middle_numbers_printable = '|' + middle_numbers_printable[4:]
    new_coeffs_printable = ' ' + new_coeffs_printable[4:]

    if not quiet:
        print(theme['styles']['normal'] + str(divisor) + '  ' +
              coefficient_printable)

        print((len(str(divisor)) + 2) * ' ' + '\u001b[4m' +
              middle_numbers_printable + '\u001b[0m')

        print(theme['styles']['normal'] + (len(str(divisor)) + 2) * ' ' +
              new_coeffs_printable)

        print()

        degree = len(new_coeffs) - 1

        equation = ''
        for coef in new_coeffs:
            if coef != 0:
                # skip coefs that are 0
                if degree != len(new_coeffs) and coef > 0:
                    # not first number and positive
                    equation += '+'
                equation += str(coef) if coef != 1 else ''
                if degree != 0:
                    equation += str(symbol)
                if degree > 1:
                    equation += f'^{degree}'
            degree -= 1

    return equation.lstrip('+')
예제 #23
0
def poly2list(p):
    if p == 0:
        return [0]
    return Poly.all_coeffs(p)
예제 #24
0
def _rewrite_gamma(f, s, a, b):
    """
    Try to rewrite the product f(s) as a product of gamma functions,
    so that the inverse mellin transform of f can be expressed as a meijer
    G function.

    Return (an, ap), (bm, bq), arg, exp, fac such that
    G((an, ap), (bm, bq), arg/z**exp)*fac is the inverse mellin transform of f(s).

    Raises IntegralTransformError or MellinTransformStripError on failure.

    It is asserted that f has no poles in the fundamental strip designated by
    (a, b). One of a and b is allowed to be None. The fundamental strip is
    important, because it determines the inversion contour.

    This function can handle exponentials, linear factors, trigonometric
    functions.

    This is a helper function for inverse_mellin_transform that will not
    attempt any transformations on f.

    >>> from sympy.integrals.transforms import _rewrite_gamma
    >>> from sympy.abc import s
    >>> from sympy import oo
    >>> _rewrite_gamma(s*(s+3)*(s-1), s, -oo, oo)
    (([], [-3, 0, 1]), ([-2, 1, 2], []), 1, 1, -1)
    >>> _rewrite_gamma((s-1)**2, s, -oo, oo)
    (([], [1, 1]), ([2, 2], []), 1, 1, 1)

    Importance of the fundamental strip:

    >>> _rewrite_gamma(1/s, s, 0, oo)
    (([1], []), ([], [0]), 1, 1, 1)
    >>> _rewrite_gamma(1/s, s, None, oo)
    (([1], []), ([], [0]), 1, 1, 1)
    >>> _rewrite_gamma(1/s, s, 0, None)
    (([1], []), ([], [0]), 1, 1, 1)
    >>> _rewrite_gamma(1/s, s, -oo, 0)
    (([], [1]), ([0], []), 1, 1, -1)
    >>> _rewrite_gamma(1/s, s, None, 0)
    (([], [1]), ([0], []), 1, 1, -1)
    >>> _rewrite_gamma(1/s, s, -oo, None)
    (([], [1]), ([0], []), 1, 1, -1)

    >>> _rewrite_gamma(2**(-s+3), s, -oo, oo)
    (([], []), ([], []), 1/2, 1, 8)
    """
    from itertools import repeat
    from sympy import (Poly, gamma, Mul, re, RootOf, exp as exp_, E, expand,
                       roots, ilcm, pi, sin, cos, tan, cot, igcd, exp_polar)
    # Our strategy will be as follows:
    # 1) Guess a constant c such that the inversion integral should be
    #    performed wrt s'=c*s (instead of plain s). Write s for s'.
    # 2) Process all factors, rewrite them independently as gamma functions in
    #    argument s, or exponentials of s.
    # 3) Try to transform all gamma functions s.t. they have argument
    #    a+s or a-s.
    # 4) Check that the resulting G function parameters are valid.
    # 5) Combine all the exponentials.

    a_, b_ = S([a, b])
    def left(c, is_numer):
        """
        Decide whether pole at c lies to the left of the fundamental strip.
        """
        # heuristically, this is the best chance for us to solve the inequalities
        c = expand(re(c))
        if a_ is None:
            return c < b_
        if b_ is None:
            return c <= a_
        if (c >= b_) is True:
            return False
        if (c <= a_) is True:
            return True
        if is_numer:
            return None
        if a_.free_symbols or b_.free_symbols or c.free_symbols:
            return None # XXX
            #raise IntegralTransformError('Inverse Mellin', f,
            #                     'Could not determine position of singularity %s'
            #                     ' relative to fundamental strip' % c)
        raise MellinTransformStripError('Pole inside critical strip?')

    # 1)
    s_multipliers = []
    for g in f.atoms(gamma):
        if not g.has(s):
            continue
        arg = g.args[0]
        if arg.is_Add:
            arg = arg.as_independent(s)[1]
        coeff, _ = arg.as_coeff_mul(s)
        s_multipliers += [coeff]
    for g in f.atoms(sin, cos, tan, cot):
        if not g.has(s):
            continue
        arg = g.args[0]
        if arg.is_Add:
            arg = arg.as_independent(s)[1]
        coeff, _ = arg.as_coeff_mul(s)
        s_multipliers += [coeff/pi]
    s_multipliers = [abs(x) for x in s_multipliers if x.is_real]
    common_coefficient = S(1)
    for x in s_multipliers:
        if not x.is_Rational:
            common_coefficient = x
            break
    s_multipliers = [x/common_coefficient for x in s_multipliers]
    if any(not x.is_Rational for x in s_multipliers):
        raise NotImplementedError
    s_multiplier = common_coefficient/reduce(ilcm, [S(x.q) for x in s_multipliers], S(1))
    if s_multiplier == common_coefficient:
        if len(s_multipliers) == 0:
            s_multiplier = common_coefficient
        else:
            s_multiplier = common_coefficient \
                           *reduce(igcd, [S(x.p) for x in s_multipliers])

    exponent = S(1)
    fac = S(1)
    f = f.subs(s, s/s_multiplier)
    fac /= s_multiplier
    exponent = 1/s_multiplier
    if a_ is not None:
        a_ *= s_multiplier
    if b_ is not None:
        b_ *= s_multiplier

    # 2)
    numer, denom = f.as_numer_denom()
    numer = Mul.make_args(numer)
    denom = Mul.make_args(denom)
    args = zip(numer, repeat(True)) + zip(denom, repeat(False))

    facs = []
    dfacs = []
    # *_gammas will contain pairs (a, c) representing Gamma(a*s + c)
    numer_gammas = []
    denom_gammas = []
    # exponentials will contain bases for exponentials of s
    exponentials = []
    def exception(fact):
        return IntegralTransformError("Inverse Mellin", f, "Unrecognised form '%s'." % fact)
    while args:
        fact, is_numer = args.pop()
        if is_numer:
            ugammas, lgammas = numer_gammas, denom_gammas
            ufacs, lfacs = facs, dfacs
        else:
            ugammas, lgammas = denom_gammas, numer_gammas
            ufacs, lfacs = dfacs, facs

        def linear_arg(arg):
            """ Test if arg is of form a*s+b, raise exception if not. """
            if not arg.is_polynomial(s):
                raise exception(fact)
            p = Poly(arg, s)
            if p.degree() != 1:
                raise exception(fact)
            return p.all_coeffs()

        # constants
        if not fact.has(s):
            ufacs += [fact]
        # exponentials
        elif fact.is_Pow or isinstance(fact, exp_):
            if fact.is_Pow:
                base = fact.base
                exp  = fact.exp
            else:
                base = exp_polar(1)
                exp  = fact.args[0]
            if exp.is_Integer:
                cond = is_numer
                if exp < 0:
                    cond = not cond
                args += [(base, cond)]*abs(exp)
                continue
            elif not base.has(s):
                a, b = linear_arg(exp)
                if not is_numer:
                    base = 1/base
                exponentials += [base**a]
                facs += [base**b]
            else:
                raise exception(fact)
        # linear factors
        elif fact.is_polynomial(s):
            p = Poly(fact, s)
            if p.degree() != 1:
                # We completely factor the poly. For this we need the roots.
                # Now roots() only works in some cases (low degree), and RootOf
                # only works without parameters. So try both...
                coeff = p.LT()[1]
                rs = roots(p, s)
                if len(rs) != p.degree():
                    rs = RootOf.all_roots(p)
                ufacs += [coeff]
                args += [(s - c, is_numer) for c in rs]
                continue
            a, c = p.all_coeffs()
            ufacs += [a]
            c /= -a
            # Now need to convert s - c
            if left(c, is_numer):
                ugammas += [(S(1), -c + 1)]
                lgammas += [(S(1), -c)]
            else:
                ufacs += [-1]
                ugammas += [(S(-1), c + 1)]
                lgammas += [(S(-1), c)]
        elif isinstance(fact, gamma):
            a, b = linear_arg(fact.args[0])
            if is_numer:
                if (a > 0 and (left(-b/a, is_numer) is False)) or \
                   (a < 0 and (left(-b/a, is_numer) is True)):
                    raise NotImplementedError('Gammas partially over the strip.')
            ugammas += [(a, b)]
        elif isinstance(fact, sin):
            # We try to re-write all trigs as gammas. This is not in
            # general the best strategy, since sometimes this is impossible,
            # but rewriting as exponentials would work. However trig functions
            # in inverse mellin transforms usually all come from simplifying
            # gamma terms, so this should work.
            a = fact.args[0]
            if is_numer:
                # No problem with the poles.
                gamma1, gamma2, fac_ = gamma(a/pi), gamma(1 - a/pi), pi
            else:
                gamma1, gamma2, fac_ = _rewrite_sin(linear_arg(a), s, a_, b_)
            args += [(gamma1, not is_numer), (gamma2, not is_numer)]
            ufacs += [fac_]
        elif isinstance(fact, tan):
            a = fact.args[0]
            args += [(sin(a, evaluate=False), is_numer),
                     (sin(pi/2 - a, evaluate=False), not is_numer)]
        elif isinstance(fact, cos):
            a = fact.args[0]
            args += [(sin(pi/2 - a, evaluate=False), is_numer)]
        elif isinstance(fact, cot):
            a = fact.args[0]
            args += [(sin(pi/2 - a, evaluate=False), is_numer),
                     (sin(a, evaluate=False), not is_numer)]
        else:
            raise exception(fact)

    fac *= Mul(*facs)/Mul(*dfacs)

    # 3)
    an, ap, bm, bq = [], [], [], []
    for gammas, plus, minus, is_numer in [(numer_gammas, an, bm, True),
                                          (denom_gammas, bq, ap, False)]:
        while gammas:
            a, c = gammas.pop()
            if a != -1 and a != +1:
                # We use the gamma function multiplication theorem.
                p = abs(S(a))
                newa = a/p
                newc = c/p
                assert a.is_Integer
                for k in range(p):
                    gammas += [(newa, newc + k/p)]
                if is_numer:
                    fac *= (2*pi)**((1 - p)/2) * p**(c - S(1)/2)
                    exponentials += [p**a]
                else:
                    fac /= (2*pi)**((1 - p)/2) * p**(c - S(1)/2)
                    exponentials += [p**(-a)]
                continue
            if a == +1:
                plus.append(1 - c)
            else:
                minus.append(c)

    # 4)
    # TODO

    # 5)
    arg = Mul(*exponentials)

    # for testability, sort the arguments
    an.sort()
    ap.sort()
    bm.sort()
    bq.sort()

    return (an, ap), (bm, bq), arg, exponent, fac
예제 #25
0
            for k in range(len(Ds[l])):
                solns[m][sol_ind] = solns[m][sol_ind].subs(
                    Ds[l][k], solns[l][1 + k])

Lambdap_exp = log(2) / tau.subs(sigb, S)
for i in range(len(Cs)):
    Lambdap_exp += log(2) / tau.subs(sigb,
                                     S) * solns[i][0].expand() * a**(2 * i + 2)

lam0, lam1, n = symbols('lam0 lam1 n')
lam_prl = lambda t: (lam0 + lam1 * t**n) / (1 + t**n)
tau_prl = lambda x: integrate(1 / V / lam_prl((x - S) / V + S), (V, 1, 2))
Lambdap_exp_prl = Lambdap_exp.replace(Function('tau')(S), tau_prl(S))

p = Poly(Lambdap_exp_prl, a)
Clst = p.all_coeffs()
C6_S = Clst[-7].subs([(lam0, 1), (lam1, 0), (n, 2)]).doit().evalf()
C4_S = Clst[-5].subs([(lam0, 1), (lam1, 0), (n, 2)]).doit().evalf()
C2_S = Clst[-3].subs([(lam0, 1), (lam1, 0), (n, 2)]).doit().evalf()
C0_S = Clst[-1].subs([(lam0, 1), (lam1, 0), (n, 2)]).doit().evalf()

for s in np.arange(0.01, 1.01, 0.01):
    C6 = C6_S.subs([(S, s)]).doit().evalf()
    C4 = C4_S.subs([(S, s)]).doit().evalf()
    C2 = C2_S.subs([(S, s)]).doit().evalf()
    C0 = C0_S.subs([(S, s)]).doit().evalf()

    np.savetxt('C_damage_S={:.2f}.out'.format(s), [C0, C2, C4, C6])

C6_S = Clst[-7].subs([(lam0, 0.2), (lam1, 1.2), (n, 2)]).doit().evalf()
C4_S = Clst[-5].subs([(lam0, 0.2), (lam1, 1.2), (n, 2)]).doit().evalf()
예제 #26
0
파일: transforms.py 프로젝트: tuhina/sympy
def _rewrite_gamma(f, s, a, b):
    """
    Try to rewrite the product f(s) as a product of gamma functions,
    so that the inverse mellin transform of f can be expressed as a meijer
    G function.

    Return (an, ap), (bm, bq), arg, exp, fac such that
    G((an, ap), (bm, bq), arg/z**exp)*fac is the inverse mellin transform of f(s).

    Raises IntegralTransformError or ValueError on failure.

    It is asserted that f has no poles in the fundamental strip designated by
    (a, b). One of a and b is allowed to be None. The fundamental strip is
    important, because it determines the inversion contour.

    This function can handle exponentials, linear factors, trigonometric
    functions.

    This is a helper function for inverse_mellin_transform that will not
    attempt any transformations on f.

    >>> from sympy.integrals.transforms import _rewrite_gamma
    >>> from sympy.abc import s
    >>> from sympy import oo
    >>> _rewrite_gamma(s*(s+3)*(s-1), s, -oo, oo)
    (([], [-3, 0, 1]), ([-2, 1, 2], []), 1, 1, -1)
    >>> _rewrite_gamma((s-1)**2, s, -oo, oo)
    (([], [1, 1]), ([2, 2], []), 1, 1, 1)

    Importance of the fundamental strip:

    >>> _rewrite_gamma(1/s, s, 0, oo)
    (([1], []), ([], [0]), 1, 1, 1)
    >>> _rewrite_gamma(1/s, s, None, oo)
    (([1], []), ([], [0]), 1, 1, 1)
    >>> _rewrite_gamma(1/s, s, 0, None)
    (([1], []), ([], [0]), 1, 1, 1)
    >>> _rewrite_gamma(1/s, s, -oo, 0)
    (([], [1]), ([0], []), 1, 1, -1)
    >>> _rewrite_gamma(1/s, s, None, 0)
    (([], [1]), ([0], []), 1, 1, -1)
    >>> _rewrite_gamma(1/s, s, -oo, None)
    (([], [1]), ([0], []), 1, 1, -1)

    >>> _rewrite_gamma(2**(-s+3), s, -oo, oo)
    (([], []), ([], []), 1/2, 1, 8)
    """
    from itertools import repeat
    from sympy import (Poly, gamma, Mul, re, RootOf, exp as exp_, E, expand,
                       roots, ilcm, pi, sin, cos, tan, cot, igcd)
    # Our strategy will be as follows:
    # 1) Guess a constant c such that the inversion integral should be
    #    performed wrt s'=c*s (instead of plain s). Write s for s'.
    # 2) Process all factors, rewrite them independently as gamma functions in
    #    argument s, or exponentials of s.
    # 3) Try to transform all gamma functions s.t. they have argument
    #    a+s or a-s.
    # 4) Check that the resulting G function parameters are valid.
    # 5) Combine all the exponentials.

    a_, b_ = S([a, b])

    def left(c, is_numer):
        """
        Decide whether pole at c lies to the left of the fundamental strip.
        """
        # heuristically, this is the best chance for us to solve the inequalities
        c = expand(re(c))
        if a_ is None:
            return c < b_
        if b_ is None:
            return c <= a_
        if (c >= b_) is True:
            return False
        if (c <= a_) is True:
            return True
        if is_numer:
            return None
        if a_.free_symbols or b_.free_symbols or c.free_symbols:
            return None  # XXX
            #raise IntegralTransformError('Inverse Mellin', f,
            #                     'Could not determine position of singularity %s'
            #                     ' relative to fundamental strip' % c)
        raise ValueError('Pole inside critical strip?')

    # 1)
    s_multipliers = []
    for g in f.atoms(gamma):
        if not g.has(s):
            continue
        arg = g.args[0]
        if arg.is_Add:
            arg = arg.as_independent(s)[1]
        coeff, _ = arg.as_coeff_mul(s)
        s_multipliers += [coeff]
    for g in f.atoms(sin, cos, tan, cot):
        if not g.has(s):
            continue
        arg = g.args[0]
        if arg.is_Add:
            arg = arg.as_independent(s)[1]
        coeff, _ = arg.as_coeff_mul(s)
        s_multipliers += [coeff / pi]
    s_multipliers = [abs(x) for x in s_multipliers if x.is_real]
    common_coefficient = S(1)
    for x in s_multipliers:
        if not x.is_Rational:
            common_coefficient = x
            break
    s_multipliers = [x / common_coefficient for x in s_multipliers]
    if any(not x.is_Rational for x in s_multipliers):
        raise NotImplementedError
    s_multiplier = common_coefficient / reduce(
        ilcm, [S(x.q) for x in s_multipliers], S(1))
    if s_multiplier == common_coefficient:
        if len(s_multipliers) == 0:
            s_multiplier = common_coefficient
        else:
            s_multiplier = common_coefficient \
                           *reduce(igcd, [S(x.p) for x in s_multipliers])

    exponent = S(1)
    fac = S(1)
    f = f.subs(s, s / s_multiplier)
    fac /= s_multiplier
    exponent = 1 / s_multiplier
    if a_ is not None:
        a_ *= s_multiplier
    if b_ is not None:
        b_ *= s_multiplier

    # 2)
    numer, denom = f.as_numer_denom()
    numer = Mul.make_args(numer)
    denom = Mul.make_args(denom)
    args = zip(numer, repeat(True)) + zip(denom, repeat(False))

    facs = []
    dfacs = []
    # *_gammas will contain pairs (a, c) representing Gamma(a*s + c)
    numer_gammas = []
    denom_gammas = []
    # exponentials will contain bases for exponentials of s
    exponentials = []

    def exception(fact):
        return IntegralTransformError("Inverse Mellin", f,
                                      "Unrecognised form '%s'." % fact)

    while args:
        fact, is_numer = args.pop()
        if is_numer:
            ugammas, lgammas = numer_gammas, denom_gammas
            ufacs, lfacs = facs, dfacs
        else:
            ugammas, lgammas = denom_gammas, numer_gammas
            ufacs, lfacs = dfacs, facs

        def linear_arg(arg):
            """ Test if arg is of form a*s+b, raise exception if not. """
            if not arg.is_polynomial(s):
                raise exception(fact)
            p = Poly(arg, s)
            if p.degree() != 1:
                raise exception(fact)
            return p.all_coeffs()

        # constants
        if not fact.has(s):
            ufacs += [fact]
        # exponentials
        elif fact.is_Pow or isinstance(fact, exp_):
            if fact.is_Pow:
                base = fact.base
                exp = fact.exp
            else:
                base = E
                exp = fact.args[0]
            if exp.is_Integer:
                cond = is_numer
                if exp < 0:
                    cond = not cond
                args += [(base, cond)] * abs(exp)
                continue
            elif not base.has(s):
                a, b = linear_arg(exp)
                if not is_numer:
                    base = 1 / base
                exponentials += [base**a]
                facs += [base**b]
            else:
                raise exception(fact)
        # linear factors
        elif fact.is_polynomial(s):
            p = Poly(fact, s)
            if p.degree() != 1:
                # We completely factor the poly. For this we need the roots.
                # Now roots() only works in some cases (low degree), and RootOf
                # only works without parameters. So try both...
                coeff = p.LT()[1]
                rs = roots(p, s)
                if len(rs) != p.degree():
                    rs = RootOf.all_roots(p)
                ufacs += [coeff]
                args += [(s - c, is_numer) for c in rs]
                continue
            a, c = p.all_coeffs()
            ufacs += [a]
            c /= -a
            # Now need to convert s - c
            if left(c, is_numer):
                ugammas += [(S(1), -c + 1)]
                lgammas += [(S(1), -c)]
            else:
                ufacs += [-1]
                ugammas += [(S(-1), c + 1)]
                lgammas += [(S(-1), c)]
        elif isinstance(fact, gamma):
            a, b = linear_arg(fact.args[0])
            if is_numer:
                if (a > 0 and (left(-b/a, is_numer) is False)) or \
                   (a < 0 and (left(-b/a, is_numer) is True)):
                    raise NotImplementedError(
                        'Gammas partially over the strip.')
            ugammas += [(a, b)]
        elif isinstance(fact, sin):
            # We try to re-write all trigs as gammas. This is not in
            # general the best strategy, since sometimes this is impossible,
            # but rewriting as exponentials would work. However trig functions
            # in inverse mellin transforms usually all come from simplifying
            # gamma terms, so this should work.
            a = fact.args[0]
            if is_numer:
                # No problem with the poles.
                gamma1, gamma2, fac_ = gamma(a / pi), gamma(1 - a / pi), pi
            else:
                gamma1, gamma2, fac_ = _rewrite_sin(linear_arg(a), s, a_, b_)
            args += [(gamma1, not is_numer), (gamma2, not is_numer)]
            ufacs += [fac_]
        elif isinstance(fact, tan):
            a = fact.args[0]
            args += [(sin(a, evaluate=False), is_numer),
                     (sin(pi / 2 - a, evaluate=False), not is_numer)]
        elif isinstance(fact, cos):
            a = fact.args[0]
            args += [(sin(pi / 2 - a, evaluate=False), is_numer)]
        elif isinstance(fact, cot):
            a = fact.args[0]
            args += [(sin(pi / 2 - a, evaluate=False), is_numer),
                     (sin(a, evaluate=False), not is_numer)]
        else:
            raise exception(fact)

    fac *= Mul(*facs) / Mul(*dfacs)

    # 3)
    an, ap, bm, bq = [], [], [], []
    for gammas, plus, minus, is_numer in [(numer_gammas, an, bm, True),
                                          (denom_gammas, bq, ap, False)]:
        while gammas:
            a, c = gammas.pop()
            if a != -1 and a != +1:
                # We use the gamma function multiplication theorem.
                p = abs(S(a))
                newa = a / p
                newc = c / p
                assert a.is_Integer
                for k in range(p):
                    gammas += [(newa, newc + k / p)]
                if is_numer:
                    fac *= (2 * pi)**((1 - p) / 2) * p**(c - S(1) / 2)
                    exponentials += [p**a]
                else:
                    fac /= (2 * pi)**((1 - p) / 2) * p**(c - S(1) / 2)
                    exponentials += [p**(-a)]
                continue
            if a == +1:
                plus.append(1 - c)
            else:
                minus.append(c)

    # 4)
    # TODO

    # 5)
    arg = Mul(*exponentials)

    # for testability, sort the arguments
    an.sort()
    ap.sort()
    bm.sort()
    bq.sort()

    return (an, ap), (bm, bq), arg, exponent, fac
# plot(abs(freq_res_LPF), (s,0,100))
print 'HcS: ', HcS
HcS_Bandpass = HcS.subs(s, transform)
# freq_res_BPF = HcS_Bandpass.subs(s,1j*2.0*pi*s)
# plot(abs(freq_res_BPF), (s,0,50))
print 'HcS_Bandpass: '******'Hz: ', Hz
# print 'Numerator: ', fraction(Hz)[0]
# print 'Denominator: ', fraction(Hz)[1]
ax = Poly(fraction(Hz)[0], x) # Separating out the numerator
ax = ax.all_coeffs() # Array of size [(order of ax) + 1] with ax[0] being coeff of x^n
ax = list(reversed(ax)) # Reversing it so that ax[0] is coeff of order x^0
ay = Poly(fraction(Hz)[1], x) # Separating out the denominator
ay = ay.all_coeffs()
ay = list(reversed(ay))
norm_fac = ay[0]
# print 'ay[0]: ', ay[0]
ax = [i/norm_fac for i in ax]
ay = [i/norm_fac for i in ay]
print 'ax: ', ax
print 'ay: ', ay
# print 'Length of ax: ', len(ax)
# print 'Length of ay: ', len(ay)
#
# ax[i] and ay[i] are the coefficients of x[n-i] and y[n-i]  respectively in the difference equation.
# The difference equation is implemented by the function 'filter' on any specified x[n]