def polynomial_gcd(a, b): """Function to find gcd of two poly1d polynomials. Return gcd, s, t, u, v with a s + bt = gcd (Bezout s theorem) a = u gcd b = v gcd Hence s u + t v = 1 These are used in diagimalize procedure """ s = sp.Poly(0, x, domain='QQ').as_expr() old_s = sp.Poly(1, x, domain='QQ').as_expr() t = sp.Poly(1, x, domain='QQ').as_expr() old_t = sp.Poly(0, x, domain='QQ').as_expr() r = b old_r = a while not is_zero_polynomial(r): quotient, remainder = sp.div(old_r, r, x) (old_r, r) = (r, remainder) (old_s, s) = (s, old_s - quotient * s) (old_t, t) = (t, old_t - quotient * t) # output "Bézout coefficients:", (old_s, old_t) # output "greatest common divisor:", old_r # output "quotients by the gcd:", (t, s) u, _ = sp.div(a, old_r, x, domain='QQ') v, _ = sp.div(b, old_r, x, domain='QQ') return old_r.as_expr(), old_s.as_expr(),\ old_t.as_expr(), u.as_expr(), v.as_expr()
def diffieHellman(conn, meFirst=True): #hard-coded constants (you can change these if you want, but primpoly should stay degree 10) primPoly = sympy.Poly.from_list([1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1], gens=x) G = 100 #randomly choose A and B -> construct polynomials Arand = random.randint(1, G) A = sympy.Poly.from_list([1] + [0] * Arand, gens=x) #apply modulo -> map to Galois field GF(2) Ya = GF((sympy.div(A, primPoly, domain='QQ')[1])) #exchange Ya and Yb #JSON won't encode a coefficient list from sympy for some reason, so manually reconstruct Yb if (meFirst): Yb = conn.recv(BUFFER_SIZE).decode('utf-8') Yb = sympy.Poly.from_list( [int(Yb[i]) for i in range(2, len(Yb) - 2, 3)], gens=x) conn.send(encoder.encode(Ya.all_coeffs().__str__()).encode("utf-8")) else: conn.send(encoder.encode(Ya.all_coeffs().__str__()).encode("utf-8")) Yb = conn.recv(BUFFER_SIZE).decode('utf-8') Yb = sympy.Poly.from_list( [int(Yb[i]) for i in range(2, len(Yb) - 2, 3)], gens=x) #apply modulo -> map to Galois field GF(2) Yba = GF(sympy.div(GF(Yb**Arand), primPoly, domain='QQ')[1]) #convert poly to key key = Yba.all_coeffs() key = [0] * (10 - len(key)) + key return key
def smith_mcmillan_form(self): """return P, A, Q such that self = P * A * Q P Q are unimodular and A is diagonal if numerator is None it returns the smith normal form """ n_row, n_col = self.shape[:2] A = self.copy() n = min(n_row, n_col) cnt = 0 det_factor = 1 P = SymPyPolynomialMatrix.eye(n_row) Q = SymPyPolynomialMatrix.eye(n_col) while cnt < n: cleared = False while not cleared: position = _find_smallest_degree(A, cnt, n_row, n_col) cleared = _check_row_col_cleared(A, cnt, n_row, n_col) if False and (position == (cnt, cnt) and cleared): coeffs = sp.Poly(A[position], x).coeffs() if (coeffs[0] != 0 and coeffs[0] != 1): det_factor *= coeffs[0] P[:, cnt] *= coeffs[0] A[position] /= coeffs[0] A[position] = sp.simplify(A[position]) else: if cnt != position[0]: A.swap_rows(cnt, position[0], P) det_factor *= -1 if cnt != position[1]: A.swap_cols(cnt, position[1], Q) det_factor *= -1 for i in xrange(cnt + 1, n_row): try: q, r = sp.div(A[i, cnt], A[cnt, cnt], x) except Exception as e: print('Trying to divide by zero %f' % A[cnt, cnt]) raise (e) if expr_degree(A[cnt, cnt]) == 0: r = 0 A.subtract_rows(i, cnt, q, r, P) for i in xrange(cnt + 1, n_col): q, r = sp.div(A[cnt, i], A[cnt, cnt], x) if expr_degree(A[cnt, cnt]) == 0: r = 0 A.subtract_cols(i, cnt, q, r, Q) cnt += 1 P = cleanup(P) Q = cleanup(Q) A = cleanup(A) det_factor = sp.simplify(det_factor) return P, A, Q, det_factor
def division(m, p, q): if q == 2: e, r = div(m, p, x) pol_r = r.as_poly(x, domain='GF(2)').args[0] pol_e = e.as_poly(x, domain='GF(2)').args[0] else: e, r = div(m, p, x) pol_r = r.as_poly(x, domain='GF(3)').args[0] pol_e = e.as_poly(x, domain='GF(3)').args[0] return pol_e, pol_r
def as_residue_parts(expr, var): N, D, delay = as_ratfun_delay(expr, var) # Perform polynomial long division so expr = Q + M / D Q, M = sym.div(N, D, var) expr = M / D sexpr = Ratfun(expr, var) P = sexpr.poles() F = [] R = [] for p in P: # Number of occurrences of the pole. N = P[p] f = var - p if N == 1: F.append(f) R.append(sexpr.residue(p, P)) continue # Handle repeated poles. expr2 = expr * f ** N for n in range(1, N + 1): m = N - n F.append(f ** n) dexpr = sym.diff(expr2, var, m) R.append(sym.limit(dexpr, var, p) / sym.factorial(m)) return F, R, Q, delay
def convolution(self, other): ''' Multiplication in truncated polynomial rings. If an exponent is after typical polynomial multiplication is greater than N, the corresponding coefficient is added to the exponent mod N. ''' init_prod = self*other if bernstein18: print("In long division!") x = symbols('x') element = Poly(init_prod, x) divisor = np.zeros(N + 1) if N != 0: divisor[0] = 1 divisor[-2] = -1 divisor[-1] = -1 divisor = Poly(divisor, x) quo = div(element, divisor) return trunc_polynomial(np.array(quo[1].all_coeffs())) print("Not in long division!") result = trunc_polynomial(np.zeros(N)) if not bernstein18: for ct in range(len(init_prod)+1): if ct < N: result[ct] += init_prod[ct] else: result[ct % N] += init_prod[ct] * a return result
def parity (name1, name2): file1 = open (name1, "r") read_ls = file1.readlines() file1.close () p = int (read_ls[0].split()[0]) n = int (read_ls[1].split()[0]) new_ls = read_ls[2].split() gen = sum ([int (new_ls[i])*x**i for i in range (n)]) num = x**n - 1 q, r = sp.div (num, gen, x, modulus=p) file2 = open (name2, "w") if not r == 0: file2.write ('NO\n') file2.close() return file2.write ('YES\n') h = sp.poly (q).all_coeffs() for i in reversed (range (len (h))): if not i == len (h) - 1: file2.write (' ') file2.write (str (h[i] % p)) for i in (range (n - sp.degree (q) - 1)): file2.write (' 0') file2.write ('\n') file2.close()
def get_tables_log_exp(GF_step, p, use_latex): global x degree_of_symbol_x = np.zeros((2 ** GF_step + 1, 3), dtype=object) degree_of_symbol_x_latex = np.zeros((2 ** GF_step + 1, 3), dtype=object) degree_of_symbol_x[0][2] = '{:>0{GF}b}'.format(0, GF=GF_step) for i in range(1, 2 ** GF_step + 1): degree_of_symbol_x[i][0] = x ** (i - 1) degree_of_symbol_x[i][1] = degree_of_symbol_x[i - 1][0] * x if i != 1 else 1 q, pol = div(degree_of_symbol_x[i][1], p) pol = pol.as_poly(x, domain='GF(2)') degree_of_symbol_x[i][1] = pol.args[0] degree_of_symbol_x[i][2] = '{:>0{GF}s}'.format(''.join([str(x) for x in list(pol.all_coeffs())]), GF=GF_step) if use_latex: degree_of_symbol_x_latex[i][0] = '$' + latex(degree_of_symbol_x[i][0]) + '$' degree_of_symbol_x_latex[i][1] = '$' + latex(degree_of_symbol_x[i][1]) + '$' degree_of_symbol_x_latex[i][2] = degree_of_symbol_x[i][2] log_table = np.zeros((2 ** GF_step, 2), dtype=object) for i in range(2 ** GF_step): log_table[i][0] = '{:>0{GF}b}'.format(i, GF=GF_step) if i == 0: log_table[i][1] = -np.inf else: k, l = np.where(degree_of_symbol_x[:-1] == '{:>0{GF}b}'.format(i, GF=GF_step)) log_table[i][1] = k[0] - 1 exp_table = np.fliplr(log_table[log_table[:, 1].argsort()])[1:] if use_latex: return degree_of_symbol_x_latex, log_table, exp_table return degree_of_symbol_x, log_table, exp_table
def equivalent(expr1, expr2): if expr1.is_Equality != expr2.is_Equality: # Equation vs. expression return False if expr1.is_Equality: # Test for equivalent equations # Two equations are equivalent if they are linearly dependent # This can be checked by taking RHS - LHS for the equations and seeing if they are multiples d1 = simplify((expr1.rhs - expr1.lhs).expand()) d2 = simplify((expr2.rhs - expr2.lhs).expand()) # Handle boundary case of zero if d1 == 0 or d2 == 0: return d1 == d2 # Check for linear dependence q, r = div(d1, d2) return q.is_number and r == 0 # Test for equivalent expressions, using progressively stronger tactics # First check for identical expressions after simplification; this is for expressions involving infinity if simplify(expr1) == simplify(expr2): return True # Expressions are equivalent iff their difference simplifies to zero try: equiv = simplify(expr2 - expr1) == 0 except NotImplementedError: print 'sympy could not simplify', expr2 - expr1 equiv = False return equiv
def thetas_alphas(rat_func, prec, *, use_intervals=False, eps=None): """ Do a partial fraction decomposition of rat_func Returns (thetas, alphas, alpha0), where thetas and alphas are lists of values such that rat_func = alpha0 + sum([alpha/(t - theta) for theta, alpha in zip(thetas, alphas)]) The thetas and alphas are in general complex numbers. Assumes that rat_func has the same degree numerator as denominator. If use_intervals=True, this uses the intevals() algorithm to do root finding. This algorithm is very slow, but has guaranteed precision, and is guaranteed to find all the roots. If it is False (the default), nsolve is used. eps is the length of the intervals for root finding. By default it is set to 10**-prec but it may need to be set smaller if there are roots smaller than ~1/10 to get full precision. If use_intervals=False, eps is ignored. """ import mpmath mpmath.mp.dps = prec num, den = fraction(rat_func) d = degree(den) if use_intervals: rational_rat_func = nsimplify(rat_func) num, den = fraction(rational_rat_func) if d % 1: raise NotImplementedError("Odd degrees are not yet supported with use_intervals=True") # Note, eps is NOT the precision. It's the length of the interval. # If a root is small (say, on the order of 10**-N), then eps will need to be 10**(-N - d) # to get d digits of precision. For our exp(-t) approximations, the roots # (thetas) are all # within order 10**-1...10**1, so eps is *roughly* the precision. eps = eps or 10**-prec roots = intervals(den, all=True, eps=eps)[1] # eps ought to be small enough that either side of the interval is the # precision we want, but take the average (center of the rectangle) # anyway. # XXX: Make sure to change the evalf precision if eps is lowered. thetas = [((i + j)/2).evalf(prec) for ((i, j), _) in roots] # error = [(j - i).evalf(prec) for ((i, j), _) in roots] else: thetas = list(allroots(den, d, prec)) alphas = [] for theta in thetas: q, r = div(den, t - theta) alpha = (num/q).evalf(prec, subs={t: theta}) alphas.append(alpha) alpha0 = (LC(num)/LC(den)).evalf(prec) return thetas, alphas, alpha0
def poly_power_mod(base, exponent, quotient): """ Needs vetted for matematical accuracy usese same theory as power_mod over the integers except applied to polys using remainders (i just kinda assumed it was isomorphic) """ ret = 1 _, base = div(base, quotient, domain="ZZ") while exponent > 0: if exponent % 2 == 1: _, ret = div(ret * base, quotient, domain="ZZ") exponent = exponent // 2 _, base = div(base * base, quotient, domain="ZZ") return ret
def create_matrix(equations, coeffs): A = zeros(len(equations)) i = 0; j = 0 for j in range(0, len(coeffs)): c = coeffs[j] for i in range(0, len(equations)): e = equations[i] d, r = div(e, c, *coeffs) A[i,j] = d return A
def check_poly_ncongruence(r, n): L = math.floor(math.sqrt(totient(r)*math.log(n, 2))) a = 1 while a <= L: _, rem = div((x+a)**n - (x**n+a), x**r-1, domain="ZZ") rem = rem.as_coefficients_dict().values() for c in rem: if c % n != 0: return False a += 1 return True
def poly_div_mod(num, den, mod): ''' Divides polynomials under a certain modulus utilizing sympy. ''' x = symbols('x') num = Poly(num, x, modulus = mod) den = Poly(den, x, modulus = mod) quo = div(num, den, modulus = mod) return [np.array(quo[0].all_coeffs()) % mod, np.array(quo[1].all_coeffs()) % mod]
def as_QMA(self): """Decompose expression into Q, M, A, delay, undef where `expression = (Q + M / A) * exp(-delay * var) * undef`""" B, A, delay, undef = self.as_B_A_delay_undef() # Perform polynomial long division so expr = Q + M / A Q, M = sym.div(B, A, self.var) return Q, M, A, delay, undef
def as_QMD(self): """Decompose expression into Q, M, D, delay, undef where expression = (Q + M / D) * exp(-delay * var) * undef""" N, D, delay, undef = self.as_ratfun_delay_undef() # Perform polynomial long division so expr = Q + M / D Q, M = sym.div(N, D, self.var) return Q, M, D, delay, undef
def decompose_lie_derivative(self): """ Decompose the Lie derivative into slow manifold, co-factor and additional rest. """ equation = self.slow_mf() Phi = sp.Symbol(r'\Phi') Psi = sp.Symbol(r'\Psi') lie_deriv = self.lie_derivative() k, Psi = sp.div(lie_deriv, equation.lhs) return lie_deriv, k, Psi
def polyDiv(p,L): """ Accepts a polynomial p and a list of polynomials L. Returns the remainder after division of p by L. Input should by sympy polynomials.: """ from sympy import symbols,Poly,LT,div print type(LT(p)) print type(p) print p r = p k = 0 while(r!=0 and k!= -1): k = -1 for i in range(len(L)): if div(Poly(LT(r)),LT(Poly(L[i])))[1] == 0: k = i break if k!=-1: r = (r - div(Poly(LT(r)),Poly(LT(L[i])))[0]*L[k]).expand() return r
def myDiv(lst, f, t, gen, dom): a = [0] * len(lst) r = 0 p = f while p != 0: i = 0 divisionoccured = False while i < len(lst) and divisionoccured == False: if sym.div(Poly(LT(p, order=t), gen, domain=dom), Poly(LT(lst[i], order=t), gen, domain=dom))[1] == 0: a[i] = a[i] + sym.div( Poly(LT(p, order=t), gen, domain=dom), Poly(LT(lst[i], order=t), gen, domain=dom))[0] p = p - sym.div(Poly(LT(p, order=t), gen, domain=dom), Poly(LT(lst[i], order=t), gen, domain=dom))[0] * lst[i] divisionoccured = True else: i = i + 1 if divisionoccured == False: r = r + LT(p, order=t) p = p - LT(p, order=t) return a, r
def solve_quartic(self, params): poly = x**(4+self.num_of_keys) for n in xrange(4+self.num_of_keys): poly += params[n]*x**(4+self.num_of_keys-n-1) key = 1 for n in xrange(self.num_of_keys): key *= (x-params[4+self.num_of_keys+n]) if self.debug: print "[*] div:", poly, "with", key quartic, r = div(poly, key) if r != 0: return "ERROR!" else: return solve(factor(quartic, gaussian=True))
def diff_hell(): modu = sympy.Poly.from_list([1, 0, 0, 0, 0, 0, 0, 0, 1, 1], gens=x) privateA = random.randint(1, 55) privateB = random.randint(1, 55) expoA = sympy.Poly.from_list([1] + [0] * privateA, gens=x) expoB = sympy.Poly.from_list([1] + [0] * privateB, gens=x) resultA = sympy.div(expoA, modu, domain='QQ')[1] resultB = sympy.div(expoB, modu, domain='QQ')[1] resultA = field(resultA) resultB = field(resultB) #this is where a and b should send eachother their keys #this part sucked to figure out AA = field(sympy.div(field(resultB**privateA), modu, domain='QQ')[1]) #BB = field(sympy.div(field(resultA**privateB), modu, domain = 'QQ')[1]) key = AA.all_coeffs() key = [0] * (10 - len(key)) + key return key
def response(self, x, t): """Evaluate response to input signal x at times t.""" from numpy import allclose, diff, ones, zeros, arange, convolve, hstack if len(x) != len(t): raise ValueError('x must have same length as t') dt = t[1] - t[0] if not allclose(diff(t), ones(len(t) - 1) * dt): raise (ValueError, 't values not equally spaced') # Perform polynomial long division so expr = Q + M / D N, D, delay, undef = self._as_N_D_delay_undef() if undef != 1: raise ValueError('Have undefined expression %s' % undef) Q, M = div(N, D) expr = M / D N = len(t) # Evaluate transient response. th = arange(N) * dt - dt h = ZDomainExpression(expr).transient_response(th) print('Convolving...') ty = t y = convolve(x, h)[0:N] * dt if Q: # Handle Dirac deltas and their derivatives. C = Q.all_coeffs() for n, c in enumerate(C): y += c * x x = diff(x) / dt x = hstack((x, 0)) from scipy.interpolate import interp1d if delay != 0.0: print('Interpolating...') # Try linear interpolation; should oversample first... y = interp1d(ty, y, bounds_error=False, fill_value=0) y = y(t - delay) return y
def mixedfrac(self): """Convert rational function into mixed fraction form. See also canonical, general, partfrac and ZPK""" N, D, delay, undef = self.as_ratfun_delay_undef() var = self.var # Perform polynomial long division so expr = Q + M / D Q, M = sym.div(N, D, var) expr = Q + sym.cancel(M / D, var) if delay != 0: expr *= sym.exp(-self.var * delay) return expr * undef
def division(self, divisor): X = Poly(self.CheckforDiv(self)) X_size = self.size_p() Y = Poly(self.CheckforDiv(divisor)) Y_size = 1 Z = div(X, Y) print(Z) Z_str = str(Z) result = "" i = 6 while i < len(Z_str) and Z_str[i] != ",": result += Z_str[i] i += 1 return self.StrToMulti(result, max(X_size, Y_size))
def get_hyperbolic_centers(max_period: int) -> List[List[np.complex_]]: x = sp.var("x") p = x reduced_polys = [] for period in range(1, max_period): reduced_poly = p for i in periodic_divisors(period): q, r = sp.div(reduced_poly, reduced_polys[i - 1]) assert r == 0 reduced_poly = q yield np.complex128(sp.solve(reduced_poly, minimal=True)) # roots.append(np.roots(sp.Poly(reduced_poly).all_coeffs())) reduced_polys.append(reduced_poly) p = p * p + x
def mixedfrac(self): """Convert rational function into mixed fraction form. See also canonical, general, partfrac and ZPK""" N, D, delay = self.as_ratfun_delay() var = self.var # Perform polynomial long division so expr = Q + M / D Q, M = sym.div(N, D, var) expr = Q + sym.cancel(M / D, var) if delay != 0: expr *= sym.exp(-self.var * delay) return expr
def check_poly_ncongruence(r, n): L = math.floor(math.sqrt(totient(r)) * math.log(n, 2)) a = Symbol('a') _, rem = div((x + a)**n - (x**n + a), x**r - 1, domain="ZZ") #Possible Alternate calculation for rem #rem = poly_power_mod(x+a, n, x**r-1) #_, rem2 = div(x**n-a, x**r-1, domain="ZZ") #rem -= rem2 rem.map_coeffs(lambda c: c % n) aa = 1 while aa <= L: remAA = rem remAA.subs({a: aa}) remAA.map_coeffs(lambda c: c % n) if remAA != 0: return False aa += 1 return True
def shturm_amount_of_roots(poly = None, left_border = None, right_border = None): def shturm_range_value(_poly_range_, value): counter = 0 size = len(_poly_range_) current_sgn = _poly_range_[0](value) > 0 for i in range(size - 1): new_sgn = _poly_range_[i + 1](value) > 0 if new_sgn != current_sgn: counter += 1 current_sgn = new_sgn return counter shturm_sequence = [] shturm_sequence.append(poly) shturm_sequence.append(sp.diff(poly)) sequence_range = sp.degree(poly, gen = x) for i in range(sequence_range - 1): shturm_sequence.append(-sp.div(shturm_sequence[i], shturm_sequence[i + 1])[1]) return shturm_range_value(shturm_sequence, left_border) - shturm_range_value(shturm_sequence, right_border)
def reduce_gf28(poly): """ Reduces the given sympy polynomial under the GF(2**8) polynomial x**8 + x**4 + x**3 + x + 1 Example: >>> # Example taken from the textbook >>> f = Poly(x**2 * (x**7 + x**6 + x**3 + x + 1), x, domain='GF(2)') >>> f Poly(x**9 + x**8 + x**5 + x**3 + x**2, x, modulus=2) >>> reduce_gf28(f) Poly(1, x, modulus=2) >>> reduce_gf28(Poly((x**2 + x + 1) * (x**8 + x**6 + x**2 + 1), x, modulus=2)) Poly(x**7 + 1, x, modulus=2) """ _, remainder = div(poly, gf28_mod, x) # GF(2) sets coefficients as elements of Z_2 return remainder.as_poly(x, domain='GF(2)')
def pade_approximant(coefficients, numerator_degree): m = numerator_degree n = len(coefficients) - m x = sym.symbols('x') poly = sum([coefficients[i] * x**i for i in range(len(coefficients))]) factor = poly divided = x**(m+n+1) while 1: q, r = sym.div(divided, factor, domain = 'QQ') print("q:", q) print("r:", r) if sym.degree(r) <= m: break divided = factor factor = r
def response(self, x, t): """Evaluate response to input signal x at times t.""" if len(x) != len(t): raise ValueError('x must have same length as t') dt = t[1] - t[0] if not np.allclose(np.diff(t), np.ones(len(t) - 1) * dt): raise (ValueError, 't values not equally spaced') # Perform polynomial long division so expr = Q + M / D N, D, delay = self._decompose() Q, M = div(N, D) expr = M / D N = len(t) # Evaluate transient response. th = np.arange(N) * dt - dt h = sExpr(expr).transient_response(th) print('Convolving...') ty = t y = np.convolve(x, h)[0:N] * dt if Q: # Handle Dirac deltas and their derivatives. C = Q.all_coeffs() for n, c in enumerate(C): y += c * x x = np.diff(x) / dt x = np.hstack((x, 0)) from scipy.interpolate import interp1d if delay != 0.0: print('Interpolating...') # Try linear interpolation; should oversample first... y = interp1d(ty, y, bounds_error=False, fill_value=0) y = y(t - delay) return y
def response(self, x, t): """Evaluate response to input signal x at times t.""" if len(x) != len(t): raise ValueError('x must have same length as t') dt = t[1] - t[0] if not np.allclose(np.diff(t), np.ones(len(t) - 1) * dt): raise (ValueError, 't values not equally spaced') # Perform polynomial long division so expr = Q + M / D N, D, delay = self.decompose() Q, M = sym.div(N, D) expr = M / D N = len(t) # Evaluate transient response. th = np.arange(N) * dt - dt h = sExpr(expr).transient_response(th) print('Convolving...') ty = t y = np.convolve(x, h)[0:N] * dt if Q: # Handle Dirac deltas and their derivatives. C = Q.all_coeffs() for n, c in enumerate(C): y += c * x x = np.diff(x) / dt x = np.hstack((x, 0)) from scipy.interpolate import interp1d if delay != 0.0: print('Interpolating...') # Try linear interpolation; should oversample first... y = interp1d(ty, y, bounds_error=False, fill_value=0) y = y(t - delay) return y
def eval_sign(expr, pos_polynoms=None): sign = sympy.sign(expr.factor()) if sign in [0, -1, +1]: return sign if pos_polynoms is None: pos_polynoms = [] expr = get_sign_expr(sign) for pos_poly in pos_polynoms: quot, rem = sympy.div(expr, pos_poly) if quot == 0: continue try: squot = eval_sign(quot, pos_polynoms) srem = eval_sign(rem, pos_polynoms) if squot * srem >= 0: return squot except UnknownSign: continue raise UnknownSign(expr)
def truncate_long_div(self, polynomial, mod): ''' Divide our element by x^n-lambda and return remainder. This polynomial is in the quotient ring Z_q[x]/(x^n-x-1) ''' print("In Long Division!") x = symbols('x') element = Poly(polynomial, x) divisor = np.zeros(self.n + 1) if self.n != 0: divisor[0] = 1 # x^n divisor[-2] = -1 # -x divisor[-1] = -1 # -1 else: divisor[-1] = self.consta divisor = Poly(divisor, x) quo = div(element, divisor) return trunc_poly(np.array(quo[1].all_coeffs()) % mod, self.n, -1)
def _b( self, n: int, parent_subterm: Callable[[int], Terms], children_subterms: SubTerms, ) -> Terms: """ The terms of length n for the flipped child. """ a = self._a(n, parent_subterm, children_subterms) c = self._c(children_subterms) a_poly = self._terms_to_poly(a) c_poly = self._terms_to_poly(c) if self._num_parent_params > 0: b_poly, remainder = sympy.div(a_poly, c_poly, domain="ZZ") assert remainder == 0 else: b_poly = a_poly // c_poly assert a_poly % c_poly == 0 return self._poly_to_terms(b_poly)
def buchMol(points, ordering, weightVector=(1, 1, 1)): """ Given X = [(c11,c12,...,c1n),...,(cs1,cs2,...,csn)] affine point set and ordering 'lex','grlex','grevlex', or 'weighted' (plus a weight vector) computes reduced Groebner basis and Q-basis of the ring mod the ideal """ from sympy import symbols, Poly, div, Rational, Matrix from newLT import monomialOrdering dim = len(points[0]) for pt in points: # check that all pts have same dimension assert len(pt) == dim if dim in [1, 2, 3]: l = ["x", "x,y", "x,y,z"] varlist = symbols(l[dim - 1]) else: varstring = "x0" for i in xrange(1, dim): varstring += ",x" + str(i) varlist = symbols(varstring) monClass = monomialOrdering(varlist, ordering, weightVector) counter = 0 # keep track of number of rows of matrix & size of S G, normalSet, S = [], [], [] L = [Poly(1, varlist, domain="QQ")] M = Matrix(0, len(points), []) pivots = {} # {column:row} while L != []: # step 2: t = L[0] for elmt in L: if monClass.compare(t.as_dict().keys()[0], elmt.as_dict().keys()[0]): t = elmt L.remove(t) evalVector = Matrix(1, len(points), [t.eval(pt) for pt in points]) print "hi" print M print evalVector v, a = vecReduce(evalVector, M, pivots) print v viszero = False if firstNonzero(v) == -1: viszero = True toAdd = t for i in xrange(counter): toAdd += Poly(-1, varlist) * Poly(a[i], varlist) * S[i] if viszero: G.append(toAdd) for mon in L: if div(t, mon)[1] == 0: L.remove(mon) else: pivSpot = firstNonzero(v) pivots[pivSpot] = M.shape[0] M = M.col_join(v) S.append(toAdd) counter += 1 normalSet.append(t) for variable in varlist: toCheck = Poly(variable, varlist) * t isMultiple = False for elmt in L: if div(elmt, toCheck)[1] == 0: isMultiple = True break if isMultiple: continue for elmt in G: if div(monClass.LT(elmt), toCheck)[1] == 0: isMultiple = True break if isMultiple == False: L.append(toCheck) return G, normalSet
def poly_factor(polynome, variable, corps = None, approchee = None): u"""Factorise un polynome à une variable. Le corps peut être R ou C. Par défaut, le corps de factorisation est celui des coefficients.""" from .sympy_functions import simplifier_racines if approchee is None: # Paramètre utilisé en interne par 'l'interpreteur' de commandes # (cf. méth. evaluer() de la classe Interprete(), dans custom_objects.py) approchee = getattr(param, 'calcul_approche', False) if polynome.is_Mul: return reduce(lambda x,y:x*y, [poly_factor(fact, variable, corps = corps) for fact in polynome.args], 1) sym_poly = polynome.as_poly(variable) coeffs = sym_poly.all_coeffs() if any(_is_num(coeff) for coeff in coeffs): approchee = True racines_brutes = {}.fromkeys(nroots(coeffs), 1) else: if corps == "R": if not all(coeff.is_real for coeff in coeffs): raise ValueError, "factorisation dans 'R' impossible." elif corps is None: if all(coeff.is_real for coeff in coeffs): corps = "R" else: corps = "C" racines_brutes = roots(polynome, variable, cubics=True, quartics=True) racines = list((simplifier_racines(racine), mult) for racine, mult in racines_brutes.iteritems()) if approchee: nbr_racines = sum(multiplicite for racine, multiplicite in racines) if nbr_racines < sym_poly.degree(): # On cherche une approximation des racines manquantes sol_approchees = list(nroots(coeffs)) # On associe à chaque racine l'approximation qui lui correspond for racine, multiplicite in racines: distances = [(sol, abs(complex(racine) - sol)) for sol in sol_approchees] distances.sort(key = lambda x:x[1]) for i in range(multiplicite): distances.pop(0) # Les racines approchées qui restent ne correspondent à aucune racine exacte sol_approchees = [sol for sol, distance in distances] racines.extend((sympify(sol), sol_approchees.count(sol)) for sol in set(sol_approchees)) coefficient = coeffs[0] produit = 1 if corps == "R": racines_en_stock = [] multiplicites_en_stock = [] for racine, multiplicite in racines: if not isinstance(racine, Basic): racine = sympify(racine) reel = racine.is_real if not reel: # is_real n'est pas fiable (26/11/2009) # cf. ((54*6**(1/3)*93**(1/2) - 162*I*6**(1/3)*31**(1/2) - 522*6**(1/3) + 6*6**(2/3)*(-522 + 54*93**(1/2))**(1/3) + 522*I*3**(1/2)*6**(1/3) + 6*I*3**(1/2)*6**(2/3)*(-522 + 54*93**(1/2))**(1/3) - 24*(-522 + 54*93**(1/2))**(2/3))/(36*(-522 + 54*93**(1/2))**(2/3))).is_real re, im = racine.expand(complex=True).as_real_imag() reel = im.is_zero or im.evalf(80).epsilon_eq(0,'10e-80') if reel: racine = re # Approximation utile (?) pour la factorisation de certains polynômes de degrés 3 et 4 # De toute manière, une vérification de la factorisation par division euclidienne # a lieu à la fin de l'algorithme. if reel: produit *= (variable - racine)**multiplicite else: conjuguee = racine.conjugate() if conjuguee in racines_en_stock: produit *= (variable**2 - 2*re*variable + re**2 + im**2)**multiplicite i = racines_en_stock.index(conjuguee) racines_en_stock.pop(i) multiplicites_en_stock.pop(i) else: racines_en_stock.append(racine) multiplicites_en_stock.append(multiplicite) if racines_en_stock: # Il reste des racines qu'on n'a pas réussi à appareiller. P = 1 for racine, multiplicite in zip(racines_en_stock, multiplicites_en_stock): P *= (variable - racine)**multiplicite produit *= P.expand() else: for racine, multiplicite in racines: produit *= (variable - racine)**multiplicite # print produit quotient, reste = div(polynome, coefficient*produit, variable) if reste != 0 and not approchee: raise NotImplementedError poly_factorise = coefficient*produit*quotient if isinstance(poly_factorise, Mul) and poly_factorise.args[0] == 1.: poly_factorise = Mul(*poly_factorise.args[1:]) # sinon, poly_factor(x**2+2.5*x+1,x) donne 1.0*(x + 0.5)*(x + 2.0) return poly_factorise
def as_fraction(eq): n,d = eq.as_numer_denom() q,r = sympy.div(n,d,Symbols(eq)) return (q*d+r)/d
def as_whole_frac(eq): n,d = eq.as_numer_denom() q,r = sympy.div(n,d,Symbols(eq)) return q+r/d
import socket import fractions import sympy x = sympy.symbols('x') HOST = "54.64.40.172" PORT = 5454 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.connect((HOST, PORT)) while 1: n = int(s.recv(20000)) all = s.recv(20000) all = all.split("\n") c1 = int(all[1]) c2 = int(all[2]) f = x**3-int(c1) g = (x+1)**3-int(c2) q, r = sympy.div(f, g, x) print q print r print sympy.gcd(g, r) print f print g print x #gcd = x - M (find m from expression above) send m s.send(str(int(1)) + "\n") print s.recv(10000)
def div(self, p, q): return sympy.div(p, q, self._variable)
def inverse_laplace_ratfun(expr, s, t): N, D, delay = Ratfun(expr, s).as_ratfun_delay() # The delay should be zero Q, M = sym.div(N, D, s) result1 = sym.S.Zero if Q: Qpoly = sym.Poly(Q, s) C = Qpoly.all_coeffs() for n, c in enumerate(C): result1 += c * sym.diff(sym.DiracDelta(t), t, len(C) - n - 1) expr = M / D for factor in expr.as_ordered_factors(): if factor == sym.oo: return factor sexpr = Ratfun(expr, s) P = sexpr.poles() result2 = sym.S.Zero P2 = P.copy() for p in P2: # Number of occurrences of the pole. N = P2[p] if N == 0: continue f = s - p if N == 1: r = sexpr.residue(p, P) pc = p.conjugate() if pc != p and pc in P: # Remove conjugate from poles and process pole with its # conjugate. Unfortunately, for symbolic expressions # we cannot tell if a quadratic has two real poles, # a repeat real pole, or a complex conjugate pair of poles. P2[pc] = 0 p_re = sym.re(p) p_im = sym.im(p) r_re = sym.re(r) r_im = sym.im(r) et = sym.exp(p_re * t) result2 += 2 * r_re * et * sym.cos(p_im * t) result2 -= 2 * r_im * et * sym.sin(p_im * t) else: result2 += r * sym.exp(p * t) continue # Handle repeated poles. expr2 = expr * f ** N for n in range(1, N + 1): m = N - n r = sym.limit( sym.diff(expr2, s, m), s, p) / sym.factorial(m) result2 += r * sym.exp(p * t) * t**(n - 1) # result1 is a sum of Dirac deltas and its derivatives so is known # to be causal. return result1, result2