Exemple #1
0
 def is_divisible(self, f):
     left, out = f, []
     factors = list(self.factors)
     change = True
     while change:
         change = False
         for i in range(len(factors)):
             d = factor.try_divide(factors[i], left)
             if d == None: continue
             if type(d) != polynomial.constant and not \
                     (type(d) == polynomial.polynomial and \
                     (d.equals(polynomial.polynomial_parser('1')) or \
                     d.equals(polynomial.polynomial_parser('0')))):
                 changed = True
                 if factor.is_polynomial(factors[i]) or factor.is_factorial(
                         factors[i]):
                     factors[i] = factors[i].divide(d)[0]
                 else:
                     factors[i] = factors[i].divide(d)
                 if factor.is_polynomial(left) or factor.is_factorial(left):
                     left = left.divide(d)[0]
                 else:
                     left = left.divide(d)
                 out.append(d)
     return out
Exemple #2
0
def binom(n, k):
    if type(n) == str: n = polynomial.polynomial_parser(n)
    if type(k) == str: k = polynomial.polynomial_parser(k)
    num = expression_add([expression_mult([factor.factorial(n)])])
    den = expression_add([
        expression_mult([
            factor.factorial(k),
            factor.factorial(
                polynomial.polynomial_parser('{}-({})'.format(
                    n.to_string(), k.to_string())))
        ])
    ])
    return expression_rat(num, den)
Exemple #3
0
def get_A(q, r, L, l, variables, variable='k'):
    qd, _ = polynomial2dict(
        polynomial.polynomial_parser(q.to_string().replace(
            variable, '({}+1)'.format(variable))), variables)
    rd, _ = polynomial2dict(r, variables)
    kvar_index = variables.index(variable)
    V = len(variables)
    A = [[0] * (l**V) for _ in range(L**V)]
    #Adding to A due to factor q_{k+1}f_k.
    for row in range(L**V):
        i = [(row // L**s) % L for s in range(V)]
        for col in range(l**V):
            j = [(col // l**s) % l for s in range(V)]
            jq = [i[s] - j[s] for s in range(V)]
            A[row][col] += qd[tuple(jq)]
    #Filling in A due to factor r_k f_{k-1}.
    for row in range(L**V):
        i = [(row // L**s) % L for s in range(V)]
        for col in range(l**V):
            j = [(col // l**s) % l for s in range(V)]
            jr = [i[s] - j[s] for s in range(V)]
            a = j[kvar_index]
            for s in range(a, l):
                A[row][col + (s - a) * l**kvar_index] -= rd[tuple(jr)] * pow(
                    -1, s - a) * n_choose_k(s, a)
    return A
def get_pqr(num, den, variable):
    q, r = num, den
    p = polynomial.polynomial([polynomial.constant(1)], 'n')
    zero = get_common_factor(q, r, variable)
    while zero != None:
        g = q.gcd(
            polynomial.polynomial_parser(r.to_string().replace(
                variable, '({}+{})'.format(variable, zero))))
        q = q.divide(g)[0]
        r = r.divide(
            polynomial.polynomial_parser(g.to_string().replace(
                variable, '({}-{})'.format(variable, zero))))[0]
        for i in range(zero):
            p = p.multiply(
                polynomial.polynomial_parser(g.to_string().replace(
                    variable, '({}-{})'.format(variable, i))))
        zero = get_common_factor(q, r, variable)
    return p, q, r
Exemple #5
0
 def __init__(self, base, exponent):
     self.base = base
     self.exponent = polynomial.polynomial_parser(exponent.to_string())
     assert type(self.base) == int, 'Base has to be int, not {}'.format(
         type(self.base))
     assert is_polynomial(
         self.exponent
     ), 'Exponent has to be polynomial.polynomial, not {}'.format(
         type(self.exponent))
Exemple #6
0
def try_algo(num, den, variable='k', test_number=None):
    if num == '' or den == '': return
    num, den = polynomial.polynomial_parser(num), polynomial.polynomial_parser(
        den)
    vars = num.get_common_variables(den)
    num, den = num.convert_polynomial(vars), den.convert_polynomial(vars)
    print('=============TRY ALGO STARTED{}==============='.format(
        test_number if test_number != None else ''))
    print('Numerator:  {}\nDenominator: {}\n'.format(num.to_string(),
                                                     den.to_string()))
    p, q, r = gosper.get_pqr(num, den, variable)
    q, r, p = polynomial.polynomial_parser(
        q.to_string()), polynomial.polynomial_parser(
            r.to_string()), polynomial.polynomial_parser(p.to_string())
    print('p: {}\nq: {}\nr: {}\n'.format(p.to_string(), q.to_string(),
                                         r.to_string()))
    f = get_f(p, q, r)
    print('f: {}\n'.format(f if f == None else f.to_string()))
    print('==============TRY ALGO ENDED================')
Exemple #7
0
 def multiply(self, other):
     if self.base == other.base:
         exp = self.exponent.add(other.exponent)
         if is_positive_constant(exp):
             return polynomial.constant(
                 pow(
                     self.base,
                     polynomial.polynomial_parser(
                         exp.to_string()).coefficients[0]))
         return power(self.base, exp)
     elif self.exponent.equals(other.exponent):
         return power(self.base * other.base, self.exponent)
     return None
Exemple #8
0
def dict2polynomial(d, v):
    out = []
    for x in d:
        if d[x] == 0: continue
        out2 = ['(', d[x]]
        for i in range(len(v)):
            out2.append('{}{}{}'.format(v[i] if x[i] > 0 else '',
                                        '^' if x[i] > 1 else '',
                                        x[i] if x[i] > 1 else ''))
        out2.append(')')
        out.append(''.join(map(str, out2)))
    s = '+'.join(out)
    return polynomial.polynomial_parser(s)
Exemple #9
0
def to_polynomial(x, l, variables):
    out = []
    V = len(variables)
    for i in range(l**V):
        if x[i] == 0: continue
        out2 = ['(', x[i]]
        for j in range(V):
            a = (i // (l**j)) % l
            out2.append('{}{}{}'.format(variables[j] if a > 0 else '',
                                        '^' if a > 1 else '',
                                        a if a > 1 else ''))
        out2.append(')')
        out.append(''.join(map(str, out2)))
    return polynomial.polynomial_parser('+'.join(out))
def test_get_pqr(num, den, variable='k'):
    if num == '' or den == '':
        print('==============================')
        print(
            'Testing Gosper does not work for numerator and denominator\n{}\n{}'
            .format(num, den))
        print('==============================')
        return
    print('======TESTING GOSPER======')
    p1, p2 = polynomial.polynomial_parser(num), polynomial.polynomial_parser(
        den)
    print(num)
    print(den)
    print('Numerator: {}'.format(p1.to_string()))
    print('Denominator: {}'.format(p2.to_string()))
    p, q, r = get_pqr(p1, p2, variable)
    print('Now we have:')
    print('q =', q.to_string())
    print('r =', r.to_string())
    print('p =', p.to_string())
    print('such that p(n)*q(n)/(p(n-1)*r(n))')
    print_break()
    print()
def WZmethod(parser, s, variable='k', max_degree=5):
    F, (ak_poly, ak_rest), num, den = parser(s)
    assert factor.is_polynomial(num) and factor.is_polynomial(
        den), 'Wrong type num, den'
    p, q, r, f = gosper.gosper(num,
                               den,
                               variable=variable,
                               max_degree=max_degree)
    # p.PRINT()
    # q.PRINT()
    # r.PRINT()
    if f == None: return None
    ak_poly_num, ak_poly_den = ak_poly.num.addends[0].factors[
        0], ak_poly.den.addends[0].factors[0]
    Snum = ak_poly_num.multiply(
        f.multiply(
            polynomial.polynomial_parser(q.to_string().replace(
                variable, '({}+1)'.format(variable)))))
    Sden = ak_poly_den.multiply(p)
    g = Snum.gcd(Sden)
    Snum = Snum.divide(g)[0]
    Sden = Sden.divide(g)[0]
    Snum1 = polynomial.polynomial_parser(Snum.to_string().replace(
        variable, '({}-1)'.format(variable)))
    Sden1 = polynomial.polynomial_parser(Sden.to_string().replace(
        variable, '({}-1)'.format(variable)))
    S = '(({})/({}))({})'.format(Snum.to_string(), Sden.to_string(), ak_rest)
    R = '({})/({})'.format(Snum1.to_string(), Sden1.to_string())
    G = '(({})/({}))({})'.format(
        Snum1.to_string(), Sden1.to_string(),
        ak_rest.replace(variable, '({}-1)'.format(variable)))
    # print(s)
    # print()
    # print(F)
    # print()
    # print(G)
    return F, G, R
Exemple #12
0
def get_f(p, q, r, max_degree=5, variable='k'):
    variables = p.get_common_variables(q.multiply(r))
    p, q, r = polynomial.polynomial_parser(
        p.to_string(), variables), polynomial.polynomial_parser(
            q.to_string(),
            variables), polynomial.polynomial_parser(r.to_string(), variables)
    l = max_degree + 1
    L = l + max(get_degree(q), get_degree(r))
    assert L >= get_degree(
        p) + 1, 'Does not work to get f because to low degree: {}'.format(
            max_degree)
    B = get_B(p, L, variables)
    A = get_A(q, r, L, l, variables)
    x = gaussianelimination.gauss(A, B)
    if x == None: return None
    ret = to_polynomial(x, l, variables)
    qf = polynomial.polynomial_parser(q.to_string().replace(
        variable, '({}+1)'.format(variable))).multiply(ret)
    rf = polynomial.polynomial_parser(ret.to_string().replace(
        variable, '({}-1)'.format(variable))).multiply(r)
    assert p.equals(qf.add(rf.negate(
    ))), 'Error for p={}, q={}, r={}. Got f={} which is wrong.'.format(
        p.to_string(), q.to_string(), r.to_string(), f.to_string())
    return ret
Exemple #13
0
 def divide(self, other):
     if factor.is_power(other):
         return self.multiply(expression_mult([other.inverse()]))
     left = other
     factors = list(self.factors)
     while not (factor.is_polynomial(left)
                and left.equals(polynomial.constant(1))):
         for i in range(len(factors)):
             d = factor.try_divide(factors[i], left)
             if d == None: continue
             if factor.is_polynomial(d) and d.equals(
                     polynomial.polynomial_parser('1')):
                 continue
             if type(factors[i]) in [
                     polynomial.polynomial, factor.factorial
             ]:
                 factors[i] = factors[i].divide(d)[0]
             else:
                 factors[i] = factors[i].divide(d)
             if type(left) in [polynomial.polynomial, factor.factorial]:
                 left = left.divide(d)[0]
             else:
                 left = left.divide(d)
     return expression_mult(factors)
def get_common_factor(q, r, variable):
    rj = polynomial.polynomial_parser(r.to_string().replace(
        variable, '({}+j)'.format(variable)))
    #Want to find j such that gcd between q and rj is not 1.
    return find_zeros(q, rj)
Exemple #15
0
def parse_rel_part(s):
    s = s.replace('\\cdot', '*')

    def get_next_part_end(s, i):
        if s[i + 1] == '{':
            j = i + 1
            parcount = 1
            while parcount:
                j += 1
                if s[j] == '{': parcount += 1
                elif s[j] == '}': parcount -= 1
            return j
        if s[i + 1].isdigit():
            j = i + 1
            while j < len(s) - 1 and s[j + 1].isdigit():
                j += 1
            return j
        return i + 1

    def get_prev_part_start(s, i):
        if s[i - 1] == ']':
            j = i - 1
            while s[j] != '[':
                j -= 1
            return j - 1
        if s[i - 1] == ')':
            j = i - 1
            parcount = -1
            while parcount:
                j -= 1
                if s[j] == '(': parcount += 1
                elif s[j] == ')': parcount -= 1
            return j
        if s[i - 1].isdigit():
            j = i - 1
            while j > 0 and s[j - 1].isdigit():
                j -= 1
            return j
        return i - 1

    # print(s)
    i = s.find('\\binom')
    while i != -1:
        i0 = s.find('{', i)
        i1, parcount = i0, 1
        while parcount:
            i1 += 1
            if s[i1] in '{}': parcount += 1 if s[i1] == '{' else -1
        i2 = s.find('{', i1)
        i3, parcount = i2, 1
        while parcount:
            i3 += 1
            if s[i3] in '{}': parcount += 1 if s[i3] == '{' else -1
        s = s[:i] + 'B[{},{}]'.format(parse_rel_part(
            s[i0 + 1:i1]), parse_rel_part(s[i2 + 1:i3])) + s[i3 + 1:]
        i = s.find('\\binom')
    i = s.find('\\frac')
    # print(s)
    while i != -1:
        i0 = s.find('{', i)
        i1, parcount = i0, 1
        while parcount:
            i1 += 1
            if s[i1] in '{}': parcount += 1 if s[i1] == '{' else -1
        i2 = s.find('{', i1)
        i3, parcount = i2, 1
        while parcount:
            i3 += 1
            if s[i3] in '{}': parcount += 1 if s[i3] == '{' else -1
        s = s[:i] + '({})/({})'.format(parse_rel_part(
            s[i0 + 1:i1]), parse_rel_part(s[i2 + 1:i3])) + s[i3 + 1:]
        i = s.find('\\frac')
    i = s.find('!')
    # print(s)
    while i != -1:
        j = get_prev_part_start(s, i)
        s = s[:j] + 'F[{}]'.format(s[j:i]) + s[i + 1:]
        i = s.find('!')
    # print(s)
    i = s.find('^')
    while i != -1:
        j2 = get_next_part_end(s, i)
        if all(ch.isdigit() for ch in s[i + 1:j2 + 1]):
            j1 = get_prev_part_start(s, i)
            s = s[:j1] + s[j1:i] * int(s[i + 1:j2 + 1]) + s[j2 + 1:]
        else:
            j1 = get_prev_part_start(s, i)
            if j2 == i + 1:
                s = s[:j1] + 'P[{},{}]'.format(
                    polynomial.polynomial_parser(s[j1:i]).to_string(),
                    s[i + 1:j2 + 1]) + s[j2 + 1:]
            else:
                s = s[:j1] + 'P[{},{}]'.format(
                    polynomial.polynomial_parser(s[j1:i]).to_string(),
                    s[i + 2:j2]) + s[j2 + 1:]
        i = s.find('^')
    # print(s)
    return s
Exemple #16
0
def is_positive_constant(p):
    c = polynomial.polynomial_parser(p.to_string())
    return type(c) == polynomial.constant and c.coefficients[0] >= 0
Exemple #17
0
def expression_parser(s):
    def simplify(stack):
        if len(stack) == 1: return stack
        if stack[-2] == '(': return stack
        if stack[-1] == '(':
            stack.append(to_expr_r(polynomial.constant(0)))
            return stack
        b, op, a = stack.pop(), stack.pop(), stack.pop()
        if a == '(':
            stack.append(a)
            assert op == '-', 'Something is weird'
            stack.append(b.negate())
            return simplify(stack)
        if op == '+':
            stack.append(a.add(b))
        elif op == '-':
            stack.append(a.subtract(b))
        elif op == '*':
            stack.append(a.multiply(b))
        elif op == '/':
            stack.append(a.divide(b))
        else:
            print('SOMETHING IS GOING WRONG')
            print('TRYING TO SIMPLIFY AND HAVE a, op, b AS')
            try:
                print(type(a))
                a.PRINT()
            except:
                print(a)
            try:
                print(type(op))
                op.PRINT()
            except:
                print(op)
            try:
                print(type(b))
                b.PRINT()
            except:
                print(b)
            raise Exception('Parse general error')
        return simplify(stack)

    to_split = ['B[', 'F[', 'P[', ']', ',', '/', '*', '+', '-', '(', ')', '^']
    s = s.replace(' ', '')
    for x in to_split:
        s = s.replace(x, ' {} '.format(x))
    parts = s.split()
    stack = []
    i = 0
    while i < len(parts):
        part = parts[i]
        if len(part) == 0:
            i += 1
            continue
        assert part != ',' and part != ']', 'Parse general error for string {}'.format(
            s)
        if part == '(':
            if stack and type(stack[-1]) == expression_rat:
                stack.append('*')
            stack.append('(')
            i += 1
        elif part == ')':
            stack = simplify(stack)
            stack = stack[:-2] + stack[-1:]
            i += 1
        elif part == 'B[':
            if stack and type(stack[-1]) == expression_rat:
                stack.append('*')
            j = i + 1
            while parts[j] != ',':
                j += 1
            n = polynomial.polynomial_parser(''.join(parts[i + 1:j]))
            i = j
            j = i + 1
            while parts[j] != ']':
                j += 1
            k = polynomial.polynomial_parser(''.join(parts[i + 1:j]))
            stack.append(to_expr_r(binom(n, k)))
            i = j + 1
        elif part == 'F[':
            if stack and type(stack[-1]) == expression_rat:
                stack.append('*')
            j = i + 1
            while parts[j] != ']':
                j += 1
            stack.append(
                to_expr_r(
                    factor.factorial(
                        polynomial.polynomial_parser(''.join(parts[i +
                                                                   1:j])))))
            i = j + 1
        elif part == 'P[':
            if stack and type(stack[-1]) == expression_rat:
                stack.append('*')
            j = i + 1
            while parts[j] != ',':
                j += 1
            a = int(''.join(parts[i + 1:j]))
            i = j
            j = i + 1
            while parts[j] != ']':
                j += 1
            n = polynomial.polynomial_parser(''.join(parts[i + 1:j]))
            stack.append(to_expr_r(factor.power(a, n)))
            i = j + 1
        elif part in ['/', '*']:
            stack.append(part)
            i += 1
        elif part in ['+', '-']:
            stack = simplify(stack)
            stack.append(part)
            i += 1
        elif part == '^':
            cur = stack.pop()
            stack.append(cur.power(int(parts[i + 1])))
            i += 2
        else:
            if stack and type(stack[-1]) == expression_rat:
                stack.append('*')
            stack.append(to_expr_r(polynomial.polynomial_parser(part)))
            i += 1
    stack = simplify(stack)
    return stack[0]
Exemple #18
0
'''Used for testing. Gets F(n,k) and returns a_k/a_{k-1}'''


def get_quotient(fnk):
    num_string = '({})-({})'.format(fnk.replace('n', '(n+1)'), fnk)
    den_string = num_string.replace('k', '(k-1)')
    quot_string = '({})/({})'.format(num_string, den_string)
    out = expression_parser(quot_string)
    out.simplify_complete()
    return out


if __name__ == '__main__':
    print('TESTING EXPRESSIONS')
    p1 = polynomial.polynomial_parser('mn+k^2')
    f1 = factor.factorial(polynomial.polynomial_parser('n'))
    p2 = polynomial.polynomial_parser('m^2n^2+k')
    f2 = factor.factorial(polynomial.polynomial_parser('n+m'))
    em1 = expression_mult([p1, f1])
    em2 = expression_mult([p1, f2])
    em3 = expression_mult([p2, f1])
    em4 = expression_mult([p2, f2])
    ea1 = expression_add([em1, em2])
    ea2 = expression_add([em3, em4])
    er1 = expression_rat(ea1, ea2)
    p1.PRINT()
    f1.PRINT()
    p2.PRINT()
    f2.PRINT()
    em1.PRINT()
def test_get_common_factor(s1, s2):
    print(
        get_common_factor(polynomial.polynomial_parser(s1),
                          polynomial.polynomial_parser(s2), 'k'))
Exemple #20
0
    print('Numerator:  {}\nDenominator: {}\n'.format(num.to_string(),
                                                     den.to_string()))
    p, q, r = gosper.get_pqr(num, den, variable)
    q, r, p = polynomial.polynomial_parser(
        q.to_string()), polynomial.polynomial_parser(
            r.to_string()), polynomial.polynomial_parser(p.to_string())
    print('p: {}\nq: {}\nr: {}\n'.format(p.to_string(), q.to_string(),
                                         r.to_string()))
    f = get_f(p, q, r)
    print('f: {}\n'.format(f if f == None else f.to_string()))
    print('==============TRY ALGO ENDED================')


if __name__ == '__main__':
    print('TESTING CONVERSIONS')
    p1 = polynomial.polynomial_parser('1+xy+xy^2+x^2+y')
    x = [1, 0, 1, 1, 1, 0, 0, 1, 0]
    p2 = to_polynomial(x, 3, ['x', 'y'])
    p1.PRINT()
    p2.PRINT()
    print(p1.equals(p2))
    print(get_B(p1, 4, ['x', 'y']))
    p1 = polynomial.polynomial_parser('1+k+k^2+ky+k^2y')
    A = get_A(p1, p1, 4, 3, ['k', 'y'])
    for a in A:
        print('\t'.join(map(str, a)))
    print('=====================================')
    p = polynomial.polynomial_parser('2k-n-1')
    q = polynomial.polynomial_parser('n+2-k')
    r = polynomial.polynomial_parser('k')
    A = get_A(q, r, 3, 2, ['k', 'n'])