def latex2equation_parser(s): F = get_F(s) ak = get_ak(F) print(F) print(ak) ak_poly_part = expressions.expression_parser('({})/({})-1'.format( F.replace('n', '(n+1)'), F)) ak_poly_part.simplify_complete() ak_rest_part = F quotient_string = get_quotient_string(ak) quotient = expressions.expression_parser(quotient_string) quotient.simplify_complete() assert type(quotient) == expressions.expression_rat, \ 'Quotient type has to be expression_rat, not {}'.format(type(quotient)) assert len(quotient.num.addends) == 1 and len(quotient.den.addends) == 1, \ 'Numerator and denominator has to have length 1, not {}, {}'.\ format(len(quotient.num.addends),len(quotient.den.addends)) assert len(quotient.num.addends[0].factors) == 1 and len(quotient.den.addends[0].factors) == 1,\ 'Numerator and denominator factors have to have length 1, not {}, {}'.\ format(len(quotient.num.addends[0].factors),len(quotient.den.addends[0].factors)) assert factor.is_polynomial(quotient.num.addends[0].factors[0]) and \ factor.is_polynomial(quotient.den.addends[0].factors[0]), \ 'type of numerator and denominator has to be polynomial, not {} {}'.\ format(type(quotient.num.addends[0].factors[0]),type(quotient.den.addends[0].factors[0])) return F, ( ak_poly_part, ak_rest_part ), quotient.num.addends[0].factors[0], quotient.den.addends[0].factors[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
def simplify(self): facs = [] include_1 = True for f in self.factors: if not (factor.is_polynomial(f) and f.equals(polynomial.constant(1))): include_1 = False for f in self.factors: if factor.is_factorial(f): facs.append(f) continue if factor.is_polynomial(f) and f.equals( polynomial.constant(1)) and (not include_1): continue done = False for i in range(len(facs)): if factor.is_polynomial(f) and factor.is_polynomial(facs[i]): facs[i] = facs[i].multiply(f) done = True break if factor.is_power(f) and factor.is_power(facs[i]): if facs[i].multiply(f) != None: facs[i] = facs[i].multiply(f) done = True break if not done: facs.append(f) self.factors = facs
def simplify(self): # self.PRINT() self.num.simplify() self.den.simplify() candidates = [f for f in self.den.addends[0].factors] for expr_m in self.num.addends: candidates2 = [] for cand in candidates: new_cands = expr_m.is_divisible(cand) for new_cand in new_cands: if factor.is_polynomial(new_cand) and new_cand.equals( polynomial.constant(1)): continue candidates2.append(new_cand) candidates = candidates2 for expr_m in self.den.addends: candidates2 = [] for cand in candidates: new_cands = expr_m.is_divisible(cand) for new_cand in new_cands: if factor.is_polynomial(new_cand) and new_cand.equals( polynomial.constant(1)): continue candidates2.append(new_cand) candidates = candidates2 for x in self.num.addends + self.den.addends: for f in x.factors: if factor.is_power(f) and f.exponent.is_constant and ( not factor.is_positive_constant(f.exponent)): candidates.append(f) if not candidates: return d = candidates[0] # print('PRINTING DIVISOR') # d.PRINT() # print('=====================================') for i in range(len(self.num.addends)): self.num.addends[i] = self.num.addends[i].divide(d) for i in range(len(self.den.addends)): self.den.addends[i] = self.den.addends[i].divide(d) self.simplify()
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
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 is_zero(self): addends = [x for x in self.addends] candidates = [f for f in addends[0].factors] while candidates: for expr_m in addends: candidates2 = [] for cand in candidates: new_cands = expr_m.is_divisible(cand) for new_cand in new_cands: if factor.is_polynomial(new_cand) and new_cand.equals( polynomial.constant(1)): continue candidates2.append(new_cand) candidates = candidates2 for expr_m in addends: for f in expr_m.factors: if factor.is_power(f) and f.exponent.is_constant and ( not factor.is_positive_constant(f.exponent)): candidates.append(f) if not candidates: break d = candidates[0] for i in range(len(addends)): addends[i] = addends[i].divide(d) addends[i].simplify() temp = expression_add(addends) temp.simplify_complete() addends = [x for x in temp.addends] if not addends: break candidates = [f for f in addends[0].factors] if not addends: return True for i in range(len(addends)): addends[i].simplify() all_poly = True for a in addends: if not a.is_polynomial(): all_poly = False if not all_poly: return False x = addends[0].factors[0] for a in addends[1:]: x = x.add(a.factors[0]) return x.is_zero
def is_polynomial(self): self.simplify() return len(self.factors) == 1 and factor.is_polynomial(self.factors[0])