def factor(f, var=None, order=None): """Factorization of polynomials over the rationals. A thin wrapper that returns a SymPy expression by multiplying the different factors coming from L{factor_.factor} """ # Re-assemble factors: return Mul(*[ff.sympy_expr for ff in factor_.factor(f, var, order)])
def factorization(poly, linear=False): """Returns a list with polynomial factors over rationals or, if 'linear' flag is set over Q(i). This simple handler should be merged with original factor() method. >>> from sympy import * >>> x, y = symbols('xy') >>> factorization(x**2 - y**2) set([1, x - y, x + y]) >>> factorization(x**2 + 1) set([1, 1 + x**2]) >>> factorization(x**2 + 1, linear=True) set([1, x - I, I + x]) """ factored = set([ q.as_basic() for q in factor_.factor(poly) ]) if not linear: return factored else: factors = [] for factor in factored: symbols = factor.atoms(Symbol) if len(symbols) == 1: x = symbols.pop() else: factors += [ factor ] continue linearities = [ x - r for r in roots(factor, x) ] if not linearities: factors += [ factor ] else: unfactorable = quo(factor, Basic.Mul(*linearities)) if not isinstance(unfactorable, Basic.Number): factors += [ unfactorable ] factors += linearities return set(factors)
def roots(f, var=None): """Compute the roots of a univariate polynomial. Usage: ====== The input f is assumed to be a univariate polynomial, either as SymPy expression or as instance of Polynomial. In the latter case, you can optionally specify the variable with 'var'. The output is a list of all found roots with multiplicity. Examples: ========= >>> x, y = symbols('xy') >>> roots(x**2 - 1) [1, -1] >>> roots(x - y, x) [y] Also see L{factor_.factor}, L{quadratic}, L{cubic}. L{n-poly}, L{count_real_roots}. """ from sympy.polynomials import factor_ if not isinstance(f, Polynomial): f = Polynomial(f, var=var, order=None) if len(f.var) == 0: return [] if len(f.var) > 1: raise PolynomialException('Multivariate polynomials not supported.') # Determine type of coeffs (for factorization purposes) symbols = f.sympy_expr.atoms(type=Symbol) symbols = filter(lambda a: not a in f.var, symbols) if symbols: coeff = 'sym' else: coeff = coeff_ring(get_numbers(f.sympy_expr)) if coeff == 'rat': denom, f = f.as_integer() coeff = 'int' if coeff == 'int': content, f = f.as_primitive() # Hack to get some additional cases right: result = n_poly(f) if result is not None: return result factors = factor_.factor(f) else: # It's not possible to factorize. factors = [f] # Now check for roots in each factor. result = [] for p in factors: n = p.coeffs[0][1] # Degree of the factor. if n == 0: # We have a constant factor. pass elif n == 1: if len(p.coeffs) == 2: result += [-(p.coeffs[1][0] / p.coeffs[0][0])] else: result += [S.Zero] elif n == 2: result += quadratic(p) elif n == 3: result += cubic(p) else: res = n_poly(p) if res is not None: result += res # With symbols, __nonzero__ returns a StrictInequality, Exception. try: result.sort() except: pass return result