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 divide(self, other): if is_positive_constant(self.value.subtract(other.value)): out = polynomial.polynomial([polynomial.constant(1)], self.value.variables[0]) to_mult = other.value while not to_mult.equals(self.value): to_mult = to_mult.add(to_mult.get_constant(1)) out = out.multiply(to_mult) return out, polynomial.constant(1) elif is_positive_constant(other.value.subtract(self.value)): den, num = other.divide(self) return num, den return None
def try_divide(a, b): if type(a) != type(b): return None if is_polynomial(a): return a.gcd(b) if is_factorial(a): if is_positive_constant(a.value.subtract(b.value)): return b elif is_positive_constant(b.value.subtract(a.value)): return a return polynomial.constant(1) if is_power(a): if a.divide(b) != None: return b return polynomial.constant(1)
def simplify_complete(self): for i in range(len(self.num.addends)): for j in range(len(self.num.addends[i].factors)): if factor.is_power( self.num.addends[i].factors[j] ) and factor.is_positive_constant( self.num.addends[i].factors[j].exponent): self.num.addends[i].factors[j] = polynomial.constant(pow(self.num.addends[i].factors[j].base,\ int(self.num.addends[i].factors[j].exponent.to_string()))) for i in range(len(self.den.addends)): for j in range(len(self.den.addends[i].factors)): if factor.is_power( self.den.addends[i].factors[j] ) and factor.is_positive_constant( self.den.addends[i].factors[j].exponent): self.den.addends[i].factors[j] = polynomial.constant(pow(self.den.addends[i].factors[j].base,\ int(self.den.addends[i].factors[j].exponent.to_string()))) self.simplify()
def to_expr_r(x): if type(x) == expression_rat: return x if factor.is_factor(x): num = expression_add([expression_mult([x])]) if type(x) == expression_mult: num = expression_add([x]) if type(x) == expression_add: num = x den = expression_add([expression_mult([polynomial.constant(1)])]) return expression_rat(num, den)
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 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
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
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 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)
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 negate(self): return expression_mult(self.factors + [polynomial.constant(-1)])
def power(self, n): if n == 0: return to_expr_r(polynomial.constant(1)) if n < 0: return self.negate().power(-n) return self.multiply(self.power(n - 1))
f1 = factor.factorial(polynomial.polynomial_parser('n+2')) f2 = factor.factorial(polynomial.polynomial_parser('n')) n, d = f1.divide(f2) n.PRINT() d.PRINT() p1 = factor.power(2, polynomial.polynomial_parser('n')) p2 = factor.power(2, polynomial.polynomial_parser('m')) p3 = factor.power(3, polynomial.polynomial_parser('n')) p4 = p1.multiply(p2) p5 = p1.multiply(p3) p1.PRINT() p2.PRINT() p3.PRINT() p4.PRINT() p5.PRINT() c1 = polynomial.constant(1) p1 = polynomial.polynomial_parser('n+m+1') c1.add(p1).PRINT() p1.add(c1).PRINT() print('\n\n\n\n\n\n\n') f1 = factor.factorial(polynomial.polynomial_parser('n')) f2 = factor.factorial(polynomial.polynomial_parser('n+2')) n, d = f1.divide(f2) f1.PRINT() f2.PRINT() n.PRINT() d.PRINT() n, d = f2.divide(f1) n.PRINT() d.PRINT()