def _adjoint_monomials(f,x,y,bi,P,c): """ Obtain the adjoint monomials corresponding to the integral basis element bi. This is done by demanding that bi * P be a polynomial where P = sum( c_{ij} x**i y**j ) """ f = f.expand() n = sympy.degree(f,y) d = f.as_poly().total_degree() rhs = _solve_for_leading_y(f,x,y) Pi = bi * P Pi = _eliminate_higher_orders(Pi,x,y,n,rhs) p = sympy.Wild('p') q = sympy.Wild('q') coeff = sympy.Wild('coeff') monoms = set([]) for term in Pi.as_ordered_terms(): if sympy.degree(x) < 0: # strips out the cij from the monomial cij = term.as_independent(x,y)[0].free_symbols.pop() i,j = c[cij] monoms.add(x**i*y**j)
def partition(f, LB, UB): Sseq = sturm(f) print("sturm: \n", Sseq) sL = [] [sL.append(Sseq[i].subs(x, LB)) for i in range(degree(f, x) + 1)] print('sL = ', sL, '\n') vsL = variations(sL) print('vsL = ', vsL, '\n') print("bounds using upperBound LMQ: ", UB, "\n") sR = [] [sR.append(Sseq[i].subs(x, UB)) for i in range(0, degree(f, x) + 1)] print('sR = ', sR, '\n') vsR = variations(sR) print('vsR = ', vsR, '\n') number_of_roots = vsR - vsL print("THE NUMBER OF REAL ROOTS BETWEEN", LB, " AND ", UB, " IS: ", abs(number_of_roots)) return abs(number_of_roots)
def get_npg(self, func=None): ''' returns the number of gauss point to be used for the exact numerical integration of the order specified using the rule 'p <= 2n + 1' for all line element or the next higher value in the 'npg_list' of the element. ''' x, y = sy.symbols('x y') if func is None: order = 0 for i in self.p_ref: if isinstance(i, sy.Float): pass else: p_order = sy.degree(i) if p_order > order: order = p_order npg = ceil((order + 1) / 2) # from Belytchko p. 88 else: npg = ceil( (sy.degree(func, gen=x) + sy.degree(func, gen=y) + 1) / 2) if npg in self.npg_list: return npg else: for i in self.npg_list: if i > npg: return i
def is_proper(m, s, strict=False): """is_proper tests if the sp.degree of the numerator does not exceed the sp.degree of the denominator for all entries of a given sp.Matrix. Parameters ========== m : sp.Matrix sp.Matrix to test if proper Flags ===== strict = False if rue, the sp.Function returns True only if the sp.degree of the denominator is always greater than the sp.degree of the numerator """ if strict is False: return all( sp.degree(en.as_numer_denom()[0], s) <= sp.degree( en.as_numer_denom()[1], s) for en in m) else: return all( sp.degree(en.as_numer_denom()[0], s) < sp.degree( en.as_numer_denom()[1], s) for en in m)
def sympy_get_monomials(dimension, degree, vector=False): xs = smp.symbols(['x[{:d}]'.format(ii) for ii in range(dimension)], real=True) monos = smp.polys.monomials.itermonomials(xs, degree) for xx in xs: monos = [smp.horner(mm, wrt=xx) for mm in monos] monos = sorted(monos, key=smp.polys.orderings.monomial_key('grlex', xs[::-1]))[1:] if vector: expressions = [ Constant([0 for ll in range(kk)] + [1] + [0 for ll in range(kk + 1, dimension)]) for kk in range(dimension) ] expressions += [ Expression(['0' for ll in range(kk)] + [smp.ccode(mm)] + ['0' for ll in range(kk + 1, dimension)], degree=int(smp.degree(mm))) for mm in monos for kk in range(dimension) ] else: expressions = [Constant(1)] expressions += [ Expression(smp.ccode(mm), degree=int(smp.degree(mm))) for mm in monos ] return expressions
def construct(self): # generate self.Psi, self.F and self.G p, q = sym.degree(self.AR, B), sym.degree(self.MA, B) m = max(p, q) Psi = self._find_Psi(self.AR, self.MA, p, q, m) F = self._find_F(self.AR, m) G = self._find_G(self, m) for y in self.model.v: # loop over model's variables if self.name in y.input_s: # if Variable is input of y, then proceed AR_y = y.AR_s[self.name] * self.AR MA_y = y.MA_s[self.name] * self.MA p_y, q_y = sym.degree(AR_y, B), sym.degree(MA_y, B) m_y = max(p_y, q_y) Psi_y = self._find_Psi(AR_y, MA_y, p_y, q_y, m_y) Psi = np.concatenate((Psi, Psi_y)) F_y = self._find_F(AR_y, m_y) F = linalg.block_diag(F, F_y) G_y = self._find_G(y, m_y) G = np.concatenate((G, G_y), axis=1) self.Psi = Psi self.F = F self.G = G
def get_big_poly(p, t): n = sympy.degree(p) d = high_decimation(p, t) while len(d) < (2 * n): d += d cd = sympy.Poly(1, sym_x, modulus=2) l, m, bd = 0, -1, 1 for i in range(2 * n): sub_cd = list(reversed(cd.all_coeffs()))[1:l + 1] sub_s = list(reversed(d[i - l:i])) sub_cd += [0] * (len(sub_s) - len(sub_cd)) disc = d[i] + sum(map(mul, sub_cd, sub_s)) if disc % 2 == 1: td = cd cd += bd * sympy.Poly(sym_x**(i - m), sym_x, modulus=2) if l <= i / 2: l = i + 1 - l m = i bd = td if sympy.degree(cd) == n: cd = sympy.Poly(reversed(cd.all_coeffs()), sym_x, modulus=2) return cd else: return None
def poly_decimation(p, t): """Decimates polynomial and returns decimated polynomial. :type p: sympy.Poly :type t: int :rtype: sympy.Poly """ from sympy.abc import x from operator import mul n = sympy.degree(p) s = seq_decimation(p, t) while len(s) < 2 * n: s += s cd = sympy.Poly(1, x, modulus=2) l, m, bd = 0, -1, 1 for i in range(2 * n): sub_cd = list(reversed(cd.all_coeffs()))[1:l + 1] sub_s = list(reversed(s[i - l:i])) sub_cd += [0] * (len(sub_s) - len(sub_cd)) disc = s[i] + sum(map(mul, sub_cd, sub_s)) if disc % 2 == 1: td = cd cd += bd * sympy.Poly(x**(i - m), x, modulus=2) if l <= i / 2: l = i + 1 - l m = i bd = td if sympy.degree(cd) == n: cd = sympy.Poly(reversed(cd.all_coeffs()), x, modulus=2) return cd else: return None
def remove_r(P, Q, s, bracket=None, at_infinity=False, at_zero=False): Z = P / Q f = rp(Z, s) if True: plot(f) if at_infinity: degreeP = sympy.degree(P) R = sympy.limit(Z, s, sympy.oo) w0 = sympy.oo Z = Z - R P, Q = Z.as_numer_denom() if degreeP == sympy.degree(P): P = remove_leading_coeff(P) return P, Q, w0, R elif at_zero: R = sympy.limit(Z, s, 0) w0 = 0 else: result = scipy.optimize.minimize_scalar(f, method="brent", bracket=bracket) assert result.success R = result.fun w0 = result.x Z = Z - R P, Q = Z.as_numer_denom() return P, Q, w0, R
def PSC(F, G, x): """PSC(F, G, x) returns a set with the non-zero principal subresultant coefficients (psc) of the two polynomials F and G with respect to the variable x. If the degree of the polynomial F is strictly less than the degree of the polynomial G, then F and G are interchanged. Extended psc beyond the n-th are not considered, where n is the minimum of the degrees of F and G with respect to x. >>> PSC(0, 0, var('x')) set() >>> PSC(poly('2*x'), poly('3*y'), var('x')) {3*y} >>> PSC(poly('2*x'), poly('3*y + 5*x**2'), var('x')) == {12*var('y'), 2} True >>> PSC(poly('x**3'), poly('x**3 + x'), var('x')) {1} """ subs = subresultants(F, G, x) s = set() i = len(subs) - 1 if i < 0: return s currDeg = degree(subs[i], x) while i > 0: nextDeg = degree(subs[i - 1], x) s.add(LC(subs[i], x)**(nextDeg - currDeg)) currDeg = nextDeg i -= 1 return s
def get_legendre_transform(order): """Get a transform matrix which takes polynomials from the standard basis to the Legendre basis""" import sympy from sympy.abc import x, y, z if order > 3: raise ValueError('Supports only up to order 3 polynomials!') def legendre(v, order): return [1, v, sympy.Rational(1, 2) *(3 * v * v - 1), sympy.Rational(1, 2) * (5 * v * v * v - 3 * v)][:(order+1)] def digits_to_number(digits): return int(''.join([str(d) for d in digits])) def sort_key(poly, order): deg = sympy.degree(poly, gen=x) + sympy.degree(poly, gen=y) + sympy.degree(poly, gen=z) all_degs = [order - deg, sympy.degree(poly, gen=x), sympy.degree(poly, gen=y), sympy.degree(poly, gen=z)] return digits_to_number(all_degs) leg_x = legendre(x, order) leg_y = legendre(y, order) leg_z = legendre(z, order) orig_basis = [] for d in range(order + 1): for i in range(d + 1): for j in range(i + 1): dx = d - i dy = d - dx - j dz = d - dx - dy term = x ** dx * y ** dy * z ** dz orig_basis.append(term) new_basis = [] for i in leg_x: for j in leg_y: for k in leg_z: new_p = i * j * k deg = sympy.degree(new_p, gen=x) + sympy.degree(new_p, gen=y) + sympy.degree(new_p, gen=z) if deg <= order: new_basis.append(new_p) new_basis = sorted(new_basis, key=lambda poly: sort_key(poly, order)) new_basis.reverse() for i, term in enumerate(new_basis): coeff = sympy.integrate(term * term, (x, -1, 1)) coeff = sympy.integrate(coeff, (y, -1, 1)) coeff = sympy.integrate(coeff, (z, -1, 1)) new_basis[i] = term / sympy.sqrt(coeff) # For each term in the original basis: Integrate it against all new basis vectors to get coefficients transform_matrix = np.zeros((len(orig_basis), len(orig_basis))) for i, term in enumerate(orig_basis): for j, term2 in enumerate(new_basis): coeff = sympy.integrate(term * term2, (x, -1, 1)) coeff = sympy.integrate(coeff, (y, -1, 1)) coeff = sympy.integrate(coeff, (z, -1, 1)) transform_matrix[j, i] = coeff return transform_matrix
def PSC(F, G, x): n = min(degree(F, x), degree(G, x)) if n < 0: return [] subs = sRes(F, G, -1, x)[2:] # subresultants PRS s = [] for p in reversed(subs): s.append(LC(p, x)) return s
def check_quadratic_equations(self): # Look for something quadratic to solve 'x^2 * (u) + x * (v) + (w) = 0' for eq in self.cl_eqs: eq_expand = sp.expand(eq) if not eq_expand.is_Add: continue for x in [ s for s in eq_expand.free_symbols if s in self.vars and sp.degree(eq_expand, s) == 2]: w = sp.Add(*[ t for t in eq_expand.args if x not in t.free_symbols ]) v = sp.cancel(sp.Add(*[ t for t in eq_expand.args if sp.degree(t, x) == 1 ]) / x) u = sp.cancel((eq_expand - w - v * x) / x**2) # The discriminant must be a square, otherwise the isomorphism we want to setup is not an algebraic map! discr = v**2 - 4*u*w sqrt_D = is_square(discr) if sqrt_D == None: continue # Case (u) = 0: if u.is_complex: c_u_is_zero = 0 else: c_u_is_zero = System(self.vars, [ e for e in self.cl_eqs if e != eq ] + [ u, x * v + w ], self.op_eqs).compute_class() if c_u_is_zero == None: continue # Case (u) != 0: # Case A: discr = 0 and x = -v / (2 * u) c_A_cl_eqs = [ eq_subs_by_fraction(e, x, -v, 2*u) for e in self.cl_eqs if e != eq ] + [ discr ] c_A_op_eqs = [ eq_subs_by_fraction(e, x, -v, 2*u) for e in self.op_eqs ] + [ u ] c_A = System(self.vars.difference({x,}), c_A_cl_eqs, c_A_op_eqs).compute_class() if c_A == None: continue # Case B: discr != 0 and x = (-v + sqrt_D) / (2 * u) c_B_cl_eqs = [ eq_subs_by_fraction(e, x, -v + sqrt_D, 2*u) for e in self.cl_eqs if e != eq ] c_B_op_eqs = [ eq_subs_by_fraction(e, x, -v + sqrt_D, 2*u) for e in self.op_eqs ] + [ u, discr ] c_B = System(self.vars.difference({x,}), c_B_cl_eqs, c_B_op_eqs).compute_class() if c_B == None: continue # Case C: discr != 0 and x = (-v - sqrt_D) / (2 * u) c_C_cl_eqs = [ eq_subs_by_fraction(e, x, -v - sqrt_D, 2*u) for e in self.cl_eqs if e != eq ] c_C_op_eqs = [ eq_subs_by_fraction(e, x, -v - sqrt_D, 2*u) for e in self.op_eqs ] + [ u, discr ] c_C = System(self.vars.difference({x,}), c_C_cl_eqs, c_C_op_eqs).compute_class() if c_C == None: continue return c_u_is_zero + c_A + c_B + c_C return None
def chop_s(P, Q, s): degreeP = sympy.degree(P) print(f"P: {P}") print(f"Q: {Q}") B = sympy.limit(P / (s * Q), s, sympy.oo) print(f"B: {B}") P_prime = P - B * s * Q print(f"degrees: {degreeP} {sympy.degree(P_prime)}") if degreeP == sympy.degree(P_prime): P_prime = remove_leading_coeff(P_prime) return P_prime, Q
def poly_decimation(p, t): """ Decimates the given polynomial and returns another polynomial. This function decimates the calculated sequence and reconstructs the polynomial corresponding to that sequence using the Berlekamp-Massey algorithm. Parameters ---------- p : SymPy polynomial A binary polynomial corresponding to a LFSR. t : integer The decimation value. Returns ------- q : SymPy polynomial The polynomial corresponding to the decimated sequence. Note that if the degree of `q` does not equal the degree of `p`, this function returns None. """ from operator import mul n = sympy.degree(p) s = seq_decimation(p, t) while len(s) < 2 * n: s += s cd = sympy.Poly(1, x, modulus=2) l, m, bd = 0, -1, 1 for i in range(2 * n): sub_cd = list(reversed(cd.all_coeffs()))[1:l + 1] sub_s = list(reversed(s[i - l:i])) sub_cd += [0] * (len(sub_s) - len(sub_cd)) disc = s[i] + sum(map(mul, sub_cd, sub_s)) if disc % 2 == 1: td = cd cd += bd * sympy.Poly(x**(i - m), x, modulus=2) if l <= i / 2: l = i + 1 - l m = i bd = td if sympy.degree(cd) == n: cd = sympy.Poly(reversed(cd.all_coeffs()), x, modulus=2) return cd else: return None
def complex_field_reducible(expr): '''Determines if the polynomial is reducible over the complex field. According to the fundamental theorem of algebra, a polynomial is reducible if and only if the degree is one. However, for this library, we won't count monomials such as x^4, as being reducible. Args: expr: a standard Sympy expression Returns: a tuple containing: [0] - boolean result of the function [1] - string describing the result ''' result = is_monomial_form(expr) if result[0]: return False, PolynomialOutput.strout("IS_MONOMIAL") if isinstance(expr, Mul): for i in expr.args: result = complex_field_reducible(i) if result[0]: return result return False, PolynomialOutput.strout("COMPLEX_FACTORED") if isinstance(expr, Pow): return complex_field_reducible(expr.args[0]) if degree(expr) > 1: return True, PolynomialOutput.strout("COMPLEX_HIGH_DEGREE") return False, PolynomialOutput.strout("COMPLEX_FACTORED")
def get_trial_derivative_L2(self, expected): # Get the L2 norm error for the given expected function vs FEM results integral = 0 for i in self.elements.keys(): xi = sy.symbols('xi') expr_exp = sy.sympify(expected) expr_approx = self.elements[i].trial_prime expr_error = (expr_exp - expr_approx) ** 2 domain = [self.elements[i].start, self.elements[i].end] order = sy.degree(expr_error, x) length = domain[-1] - domain[0] npg = ceil((order + 1) / 2) new_x = (0.5 * (domain[0] + domain[1]) + 0.5 * xi * (domain[1] - domain[0])) expr = expr_error.subs(x, new_x) [new_xi, w] = p_roots(npg) for j in range(len(new_xi)): integral = (integral + (w[j] * length * 0.5 * expr.subs(xi, new_xi[j])) ) print(integral) self.L2_error = integral
def seq_decimation(p, t, offset=0, c_state=None): """Decimation of a given sequence, making sure not to have a list too big. :type p: sympy.Poly :type t: int :type offset: int :type c_state: list[int] :rtype: list[int] """ deg = sympy.degree(p) if c_state is None: c_state = [1] * deg ret = [0] * (2 * deg) for _ in range(offset): c_state = LFSR_from_poly(p, c_state) indexes = map(lambda x: (x * t) % (2**deg - 1), range(2 * deg)) ctr = 0 i = 0 while ctr < 2 * deg: if i in indexes: pos = indexes.index(i) ret[pos] = c_state[0] indexes[pos] = -1 ctr += 1 c_state = LFSR_from_poly(p, c_state) i += 1 if i >= 2**deg - 1: i -= 2**deg - 1 return ret
def Hcalc(Lap): Lap = Lap.simplify() Lap = Lap.expand() num, den = sym.fraction(Lap) num_deg = sym.degree(num) den_deg = sym.degree(den) num_c = np.empty(num_deg + 1) den_c = np.empty(den_deg + 1) for i in range(num_deg + 1): num_c[i] = num.coeff(s, i) for i in range(den_deg + 1): den_c[i] = den.coeff(s, i) num_c = num_c[::-1] den_c = den_c[::-1] H = sig.lti(num_c, den_c) return (H)
def filtro_f(f, list_variables, order): """ Parameters ---------- f : function list_variables: ingresar variables de f (symbols) order : numero entero Returns devuelve los terminos de la funcion que tienen grado <= al order (considerando todas las variables de la funcion) """ # list_variables = [x,y,a] f_2 = f.expand() f_3 = f_2.as_expr().as_coefficients_dict() monomios = f_3.keys() coef1 = f_3.values() coef1_2 = [] for coeff in coef1: coef1_2.append(coeff) f_4 = 0 k = 0 for monos in monomios: list_grados = [] for var in list_variables: grado = degree(monos, gen=var) list_grados.append(grado) if np.sum(list_grados) <= order: f_4 = f_4 + monos * coef1_2[k] k = k + 1 return f_4
def get_special_state(p, t): from operator import add deg = sympy.degree(p) if (2**deg - 1) % t != 0: return base = [1] + [0] * (deg - 1) base_state = seq_decimation(p, t, c_state=base)[:deg] ones = [] init = base[:] for i in range(1, deg): init[i] = 1 init[i - 1] = 0 if i % t != 0: state = seq_decimation(p, t, c_state=init)[:deg] ones.append((init[:], state)) i = 0 for i in range(2**len(ones)): cstate = base_state[:] for j in range(len(ones)): if i & 2**j != 0: cstate = map(add, cstate, ones[j][1]) cstate = map(lambda x: x % 2, cstate) if cstate == base: break for j in range(len(ones)): if i & 2**j != 0: base = map(add, base, ones[j][0]) base = map(lambda x: x % 2, base) return base
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 _floor_div_nth_cf__end(poly, q): #print('count') assert count_roots(poly, 1) == 1 assert count_roots(poly, -oo, +oo) <= 2 - (int(degree(poly)) & 1) assert eval_poly(poly, q, 1) <= 0 ## rs = real_roots(left) ## qt = max(rs) ## Q = floor(qt) ## Q = int(neval(Q, ?)) if not eval_poly(poly, q, 2) <= 0: Q = 1 else: #print('refine_root') upper = zero_upper_bound_of_positive_poly(poly) #print(upper) try: assert eval_poly(poly, q, upper) > 0 except: print(poly, upper, eval_poly(poly, q, upper)) raise ndigit = num_radix_digits(upper, 10) eps = (one / 10)**(ndigit + 3) low, up = refine_root(poly, 1, upper, eps=eps) Q = int(floor(low)) assert Q == int(floor(up)) assert Q >= 1 assert not poly.subs(q, Q) > 0 assert not poly.subs(q, Q + 1) <= 0 return Q
def zechlog_from_magma_loop(p, i, e, t): import requests from lxml import etree deg = sympy.degree(p) poly_string = p.as_expr().replace('**', '^') uri = "http://magma.maths.usyd.edu.au/xml/calculator.xml" m_input = ("P<x>:=PolynomialRing(GF(2));\n" "f := {};\n".format(poly_string) + "K<w> := ExtensionField<GF(2), x|f>;\n" "Init := {};\n".format(i) + "Goal := {};\n".format(e) + "for m := 1 to #Init do\n" " i := Init[m];\n" " if i eq 0 then\n" " i +:= {};\n".format(t) + " end if;\n" " while i lt 2^{}-1 do\n".format(deg) + " z := ZechLog(K, i);\n" " if (z mod {}) eq Goal[m] then;\n".format(t) + " printf \"%o,%o\\n\", i, z;\n" " break;\n" " end if;\n" " i +:= {};\n".format(t) + " end while;\n" "end for;\n") r = requests.post(uri, data={'input': m_input}) result = etree.fromstring(r.text).xpath('results')[0] s = '\n'.join( [child.text for child in result if child.tag == 'line' and child.text]) return map(lambda x: tuple(map(int, x.split(','))), s.split('\n'))
def get_powers(p): deg = sympy.degree(p) l = [] for i in range(deg, -1, -1): if p.coeff_monomial(sym_x**i): l.append(i) return l
def check_linear_equations(self): # Look for something of the form 'x * (w) + (u) = 0' with x not in (w), (u) for eq in self.cl_eqs: eq_expand = sp.expand(eq) if not eq_expand.is_Add: continue for x in [ s for s in eq_expand.free_symbols if s in self.vars and sp.degree(eq_expand, s) == 1]: u = sp.Add(*[ t for t in eq_expand.args if x not in t.free_symbols ]) w = sp.expand((eq_expand - u) / x) # Now either (w) = 0 (implying (u) = 0 as well): if w.is_complex: c_1 = 0 else: c_1 = System(self.vars, [ e for e in self.cl_eqs if e != eq ] + [ w, u ], self.op_eqs).compute_class() if c_1 == None: continue # Or (w) != 0 and we can use the equation to solve for x = -u / w: c_2_cl_eqs = [ eq_subs_by_fraction(e, x, -u, w) for e in self.cl_eqs if e != eq ] c_2_op_eqs = [ eq_subs_by_fraction(e, x, -u, w) for e in self.op_eqs ] + [ w ] c_2 = System(self.vars.difference({x,}), c_2_cl_eqs, c_2_op_eqs).compute_class() if c_2 == None: continue return c_1 + c_2 return None
def _roots(poly, var): """ like roots, but works on higher-order polynomials. """ r = roots(poly, var, multiple=True) n = degree(poly) if len(r) != n: r = [rootof(poly, var, k) for k in range(n)] return r
def wave2coeff(_f): _f = _f.expand().subs({phi(1): z}).collect(z) _nw = sy.degree(_f) _coeff = [_f.coeff(z, 0)] for i in range(1, _nw + 1): _coeff.append(_f.coeff(z, i)) return _coeff
def __init__(self, equations, field): def genus(self): """ The arithmetic genus of H """ f = equations[0].subs(y**2, 0) if degree(f) == 3: return 1 else: return 2 self.genus = self.genus() def operation((u1, v1), (u2, v2)): """ Addition of two divisors using cantor's algorithm """ f = equations[0].subs(y**2, 0) g = self.genus e1, e2, d1 = sp.gcdex(u1, u2) c1, c2, d = sp.gcdex(d1, v1 + v2) s1, s2, s3 = c1 * e1, c1 * e2, c2 u = u1 * u2 / d**2 v = sp.rem((s1 * u1 * v2 + s2 * u2 * v1 + s3 * (v1 * v2 + f)) / d, u) while sp.degree(u) > g: u = (f - v**2) / u v = sp.rem(-v, u) if u.coeffs()[len(u.coeffs()) - 1] != 1: u = u / u.coeffs()[len(u.coeffs()) - 1] return (u, v)
def matrix_coeff(m, s): """returns the sp.Matrix valued coefficients N_i in m(x) = N_1 * x**(n-1) + N_2 * x**(n-2) + .. + N_deg(m) m : sp.Matrix sp.Matrix to get coefficient matrices from s : sp.Symbol to compute coefficient list (coefficients are ambiguous for expressins with multiple symbols) """ m_deg = matrix_degree(m, s) res = [sp.zeros(m.shape[0], m.shape[1])] * (m_deg + 1) for r, row in enumerate(m.tolist()): for e, entry in enumerate(row): entry_coeff_list = sp.Poly(entry, s).all_coeffs() if sp.simplify(entry) == 0: coeff_deg = 0 else: coeff_deg = sp.degree(entry, s) for c, coeff in enumerate(entry_coeff_list): res[c + m_deg - coeff_deg] += \ sp.SparseMatrix(m.shape[0], m.shape[1], {(r, e): 1}) * coeff return res
def __init__(self, f, x, y, kappa=3.0/5.0): """ The monodromy group corresponding to the complex plane algebraic curve `f = f(x,y)`. Inputs: -- f,x,y: a Sympy/Sage plane algebraic curve -- kappa: a relaxation factor used to determine the radius of the monodromy path circles about the branch points. If `kappa = 1` then the radius of the circles are 1/2 the distance to the nearest branch points. """ self.f = f self.x = x self.y = y dfdx = sympy.diff(f, x).simplify() dfdy = sympy.diff(f, y).simplify() self._f = sympy.lambdify((x,y), f, "mpmath") self.dfdx = sympy.lambdify((x,y), dfdx, "mpmath") self.dfdy = sympy.lambdify((x,y), dfdy, "mpmath") self.deg = sympy.degree(f,y) self.kappa = kappa self._base_point = None self._base_lift = None self._discriminant_points = None self._monodromy_graph = None self._monodromy_graph = self.monodromy_graph() self._monodromy = None
def matrix_coeff(m, s): """returns the matrix valued coefficients N_i in m(x) = N_1 * x**(n-1) + N_2 * x**(n-2) + .. + N_deg(m) Parameters ========== m : Matrix matrix to get coefficient matrices from s : symbol to compute coefficient list (coefficients are ambiguous for expressins with multiple symbols) """ m_deg = matrix_degree(m, s) res = [zeros(m.shape[0], m.shape[1])] * (m_deg + 1) for r, row in enumerate(m.tolist()): for e, entry in enumerate(row): entry_coeff_list = Poly(entry, s).all_coeffs() if simplify(entry) == 0: coeff_deg = 0 else: coeff_deg = degree(entry, s) for c, coeff in enumerate(entry_coeff_list): res[c + m_deg - coeff_deg] += SparseMatrix(m.shape[0], m.shape[1], {(r, e): 1}) * coeff return res
def __init__(self, expression, operator=None, domain=S.Reals): """ Class constructor. Analyze the given expression string and computes the result(s) and places it in ´self.solution´ or raise and ´ExpressionError´ on syntax parsing failure. This constructor is not usable by itself as the Expression class is abstract. The intended use case is for children subclassing. e.g Equation : __init__(self, expression, domain): Expression.__init__(self, '=', domain) The expression is checked and sanitized internally. It is thus not necessary to treat the given string beyond standard expression syntax. :param expression: str The expression string :param operator: str The expression equality/inequality comparator, taken from the expression string if not present. :param domain: sympy.S The domain of the solution, reals by default. """ self._symbols = [symbols(sym) for sym in self._symbols_of(expression)] self._domain = domain lo, self._operator, ro = self._split(expression, operator) lo = self._sanitize(lo) ro = self._sanitize(ro) try: lcs = {} for sym in self._symbols: lcs[str(sym)] = sym self._left_operand = sympify(lo, locals=lcs) self._right_operand = sympify(ro, locals=lcs) except Exception as e: raise ExpressionError('Invalid expression syntax, expression: ' + expression + "\nLeft operand: " + lo + "\nRIght operand: " + ro) lod = degree(self._left_operand) if self._has_symbol(lo) else 0 rod = degree(self._right_operand) if self._has_symbol(ro) else 0 self._degree = lod if lod > rod else rod self._solution = self.resolve()
def _solve_for_leading_y(f,x,y): """ Given `f(x,y) = a_n(x) * y**n + ... + a_0(x)`, return (-a_{n-1}(x) - ... - a_o(x)) / a_n(x) """ n = sympy.degree(f,y) sol = sympy.S(0) a_n = sympy.S(1) for term in f.expand().as_ordered_terms(): if sympy.degree(term,y) == n: a_n = term.coeff(y**n) else: sol -= term return sol/a_n
def _eliminate_higher_orders(h,x,y,deg,expr): """ Given a rational function `h = h(x,y) \in C(x)[y]`, replace all powers of `y**deg` with `expr`. """ m = sympy.degree(h,y) h = h.expand() hred = sympy.S(0) for term in h.as_ordered_terms(): term_deg = sympy.degree(term,y) term = term.replace(sympy.Pow, lambda arg, pow: arg**(pow-deg)*expr if arg == y and pow >= deg else arg**pow) hred += term return hred.expand()
def matrix_degree(m, s): """returns the highest degree of any entry in m with respect to s Parameters ========== m: Matrix matrix to get degree from s: Symbol Symbol to get degree from (degree can be ambiguous with multiple coefficients in a expression) """ return max(m.applyfunc(lambda en: degree(en, s)))
def t_degree(expr, max_deg): """ Takes an expression f(x,y) and computes the Taylor expansion in x and y up to bi-degree fixed by max_deg. Then, picks the term of highest bi-degree, and returns the value of the degree. For example: x / (1 - y) with value of max_deg = 3 will give t * x + t**2 * x * y up to bi-degree 2. Will return 2. """ f = expr.subs([(x, t*x), (y, t*y)]) return degree(series(f, t, 0, max_deg).removeO(), t)
def is_proper(m, s, strict=False): """is_proper tests if the degree of the numerator does not exceed the degree of the denominator for all entries of a given matrix. Parameters ========== m : Matrix matrix to test if proper Flags ===== strict = False if rue, the function returns True only if the degree of the denominator is always greater than the degree of the numerator """ if strict is False: return all(degree(en.as_numer_denom()[0], s) <= degree(en.as_numer_denom()[1], s) for en in m) else: return all(degree(en.as_numer_denom()[0], s) < degree(en.as_numer_denom()[1], s) for en in m)
def differentials(f,x,y): """ Returns a basis of the holomorphic differentials defined on the Riemann surface `X: f(x,y) = 0`. Input: - f: a Sympy object describing a complex plane algebraic curve. - x,y: the independent and dependent variables, respectively. """ d = f.as_poly().total_degree() n = sympy.degree(f,y) # coeffiecients and general adjoint polynomial c_arr = sympy.symarray('c',(d-3,d-3)).tolist() c = dict( (cij,(c_arr.index(ci),ci.index(cij))) for ci in c_arr for cij in ci ) P = sum( c_arr[i][j]*x**i*y**j for i in range(d-3) for j in range(d-3) if i+j <= d-3) S = singularities(f,x,y) differentials = set([]) for (alpha, beta, gamma), (m,delta,r) in S: g,u,v,u0,v0 = _transform(f,x,y,(alpha,beta,gamma)) # if delta > m*(m-1)/2: if True: # Use integral basis method. b = integral_basis(g,u,v) for bi in b: monoms = _adjoint_monomials(f,x,y,bi,P,c) differentials.add(monom for monom in monoms) else: # Use Puiseux series method b = integral_basis(g,u,v) return [differential/sympy.diff(f,y) for differential in differentials]
r += 1 #Expand the exponentials and discard higher order terms: print "Exponentiating sums" ExpSum = sympy.series(sympy.exp(-Sum), z, n=Nexpansion+1).subs(sympy.O(z**(Nexpansion+1)), 0) print "done with first" #ExpSumT = sympy.series(sympy.exp(-SumT), z, n=Nexpansion+1).subs(sympy.O(z**(Nexpansion+1)), 0) ExpSumphi = sympy.series(sympy.exp(-Sumphi), z, n=Nexpansion+1).subs(sympy.O(z**(Nexpansion+1)), 0) print "done with second" ExpSumLy = sympy.series(sympy.exp(-SumLy), z, n=Nexpansion+1).subs(sympy.O(z**(Nexpansion+1)), 0) print "Expanding exponentials" SpectralDeterminant = (SpectralDeterminant * ExpSum).expand() #AvgT = (AvgT * ExpSumT).expand() Avgphi = (Avgphi * ExpSumphi).expand() AvgLy = (AvgLy * ExpSumLy).expand() print "Fixing degrees" while sympy.degree(SpectralDeterminant, z) > Nexpansion: SpectralDeterminant = SpectralDeterminant - sympy.LT(SpectralDeterminant, z) SpectralDeterminant = sympy.collect(SpectralDeterminant, z) #while sympy.degree(AvgT, z) > Nexpansion: # AvgT = AvgT - sympy.LT(AvgT, z) # AvgT = sympy.collect(AvgT, z) while sympy.degree(Avgphi, z) > Nexpansion: Avgphi = Avgphi - sympy.LT(Avgphi, z) Avgphi = sympy.collect(Avgphi, z) while sympy.degree(AvgLy, z) > Nexpansion: AvgLy = AvgLy - sympy.LT(AvgLy, z) AvgLy = sympy.collect(AvgLy, z)
def _find_realization(self, G, s): """ Represenatation [A, B, C, D] of the state space model Returns the representation in state space of a given transfer function Parameters ========== G: Matrix Matrix valued transfer function G(s) in laplace space s: symbol variable s, where G is dependent from See Also ======== Utils : some quick tools for matrix polynomials References ========== Joao P. Hespanha, Linear Systems Theory. 2009. """ A, B, C, D = 4 * [None] try: m, k = G.shape except AttributeError: raise TypeError("G must be a matrix") # test if G is proper if not utl.is_proper(G, s, strict=False): raise ValueError("G must be proper!") # define D as the limit of G for s to infinity D = G.limit(s, oo) # define G_sp as the (stricly proper) difference of G and D G_sp = simplify(G - D) # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # get the coefficients of the monic least common denominator of all entries of G_sp # compute a least common denominator using utl and lcm lcd = lcm(utl.fraction_list(G_sp, only_denoms=True)) # make it monic lcd = simplify(lcd / LC(lcd, s)) # and get a coefficient list of its monic. The [1:] cuts the LC away (thats a one) lcd_coeff = Poly(lcd, s).all_coeffs()[1:] # get the degree of the lcd lcd_deg = degree(lcd, s) # get the Matrix Valued Coeffs of G_sp in G_sp = 1/lcd * (N_1 * s**(n-1) + N_2 * s**(n-2) .. +N_n) G_sp_coeff = utl.matrix_coeff(simplify(G_sp * lcd), s) G_sp_coeff = [zeros(m, k)] * (lcd_deg - len(G_sp_coeff)) + G_sp_coeff # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # now store A, B, C, D in terms of the coefficients of lcd and G_sp # define A A = (-1) * lcd_coeff[0] * eye(k) for alpha in lcd_coeff[1:]: A = A.row_join((-1) * alpha * eye(k)) for i in xrange(lcd_deg - 1): if i == 0: tmp = eye(k) else: tmp = zeros(k) for j in range(lcd_deg)[1:]: if j == i: tmp = tmp.row_join(eye(k)) else: tmp = tmp.row_join(zeros(k)) if tmp is not None: A = A.col_join(tmp) # define B B = eye(k) for i in xrange(lcd_deg - 1): B = B.col_join(zeros(k)) # define C C = G_sp_coeff[0] for i in range(lcd_deg)[1:]: C = C.row_join(G_sp_coeff[i]) # return the state space representation return [simplify(A), simplify(B), simplify(C), simplify(D)]
def my_subresultants (p, q, x): """ So far we obtain the Sturm sequence, whether complete or incomplete. Next, we will obtain the subresultant prs """ subresL = [p, q] my_poly = p p = my_poly if(sp.LC(my_poly) < 0): p = -p q = -q degree_rem_poly = 0 poly1 = p # polynomial q is the first derivative of p # q = sp.simplify(sp.diff(p,x)) poly2 = q ui = 0; vi = 0; rho_neg = sp.LC(poly1) # is the LC of poly1 -> we'll use it in the rest of the cases... r0_i = rho_neg # this will always be multiplied in the denominator # of the formula mass_of_u = pi = p0 = 1 fd = sp.degree(poly1) while(1): rhoi = sp.LC(poly2) # is the rho0, rho1 of the formula rem_poly = -sp.rem(poly1,poly2,x) p_plusplus = sp.degree(poly2) - sp.degree(rem_poly) pold = p_plusplus degree_rem_poly = sp.degree(rem_poly) # so as to know where to stop rem_LC = sp.LC(rem_poly) # the LC of the new remnant poly1=poly2 # refresh poly1 and poly2 poly2=rem_poly # if we are in the first loop this is p1 # if we are in the second loop this is p2 fd = sp.LC(poly1) ui = sp.summation(i,(i,1,pi)); vi = vi + pi; mass_of_u = (-1)**ui * mass_of_u; sign = mass_of_u * (-1)**vi; pi = p_plusplus; if(p_plusplus>1): r0_i = r0_i * rhoi**(1+p0) # the result of the Pell_Gordon formula else: r0_i = r0_i * rhoi**(p_plusplus+p0) # multiply the denominator od the formula with # the r0_i so as to find the det of the current submatrix LC = (rem_poly * r0_i)/sp.LC(my_poly)/sign # print(LC) subresL.append(LC) # when the remnant is finally a number # LC and degree function throw an exception # so let's take a different case if(degree_rem_poly==1): rhoi = sp.LC(poly2) rem_poly = -sp.rem(poly1,poly2,x) p_plusplus = sp.degree(poly1)-1 rem_LC = rem_poly ui = sp.summation(i,(i,1,pi)) vi = vi + pi mass_of_u = (-1)**ui * mass_of_u sign = mass_of_u * (-1)**vi if(p_plusplus>1): if(rhoi<0): r0_i = -r0_i*fd**(pold-p0) *(rhoi**(pold+p0))/sign # the result of the Pell_Gordon formula else: r0_i = r0_i*fd**(pold-p0) *(rhoi**(pold+p0)) else: r0_i = r0_i * rhoi**(1+p0) LC = (rem_LC * r0_i)/sign #print(LC) subresL.append(LC) break #print("End of Current Computation") return subresL
def degree(self, p): return sympy.degree(p, self._variable)
m2_2 = G[:,[0,2]] m2 = m2_1.row_join(m2_2) m2_3 = G[:,[0,1]] m2 = m2.row_join(m2_3) print(m2_1) print(m2_2) print(m2_3) # combine order one and two minors print('---All poles---') m1count = np.shape(m1)[0] #find out how many roots there are in total between all 1st order minors n1Roots = 0 for m in range(m1count): n1Roots = n1Roots + sp.degree(sp.denom(m1[m]),s) #find out how many roots there are in total between all 2nd order minors n2Roots = 0 r,c = np.shape(m2) for i in range(r): for j in range(c): n2Roots = n2Roots + sp.degree(sp.denom(m2[i,j]),s) print(n2Roots) # calculate and find common roots roots_denom = [None]*(n1Roots + n2Roots) n = 0 for m in range(m1count): denom_roots = sp.solve(sp.denom(m1[m])) for i in range(len(denom_roots)):
def integral_basis(f,x,y): """ Compute the integral basis {b1, ..., bg} of the algebraic function field C[x,y] / (f). """ # If the curve is not monic then map y |-> y/lc(x) where lc(x) # is the leading coefficient of f T = sympy.Dummy('T') d = sympy.degree(f,y) lc = sympy.LC(f,y) if x in lc: f = sympy.ratsimp( f.subs(y,y/lc)*lc**(d-1) ) else: f = f/lc lc = 1 # # Compute df # p = sympy.Poly(f,[x,y]) n = p.degree(y) res = sympy.resultant(p,p.diff(y),y) factors = sympy.factor_list(res)[1] df = [k for k,deg in factors if (deg > 1) and (sympy.LC(k) == 1)] # # Compute series truncations at appropriate x points # alpha = [] r = [] for l in range(len(df)): k = df[l] alphak = sympy.roots(k).keys()[0] rk = compute_series_truncations(f,x,y,alphak,T) alpha.append(alphak) r.append(rk) # # Main Loop # a = [sympy.Dummy('a%d'%k) for k in xrange(n)] b = [1] for d in range(1,n): bd = y*b[-1] for l in range(len(df)): k = df[l] alphak = alpha[l] rk = r[l] found_something = True while found_something: # construct system of equations consisting of the coefficients # of negative powers of (x-alphak) in the substitutions # A(r_{k,1}),...,A(r_{k,n}) A = (sum(ak*bk for ak,bk in zip(a,b)) + bd) / (x - alphak) coeffs = [] for rki in rk: # substitute and extract coefficients A_rki = A.subs(y,rki) coeffs.extend(_negative_power_coeffs(A_rki, x, alphak)) # solve the coefficient equations for a0,...,a_{d-1} coeffs = [coeff.as_numer_denom()[0] for coeff in coeffs] sols = sympy.solve_poly_system(coeffs, a[:d]) if sols is None or sols == []: found_something = False else: sol = sols[0] bdm1 = sum( sol[i]*bk for i,bk in zip(range(d),b) ) bd = (bdm1 + bd) / k # bd found. Append to list of basis elements b.append( bd ) # finally, convert back to singularized curve if necessary for i in xrange(1,len(b)): b[i] = b[i].subs(y,y*lc).ratsimp() return b
# compute f and its derivatives with respect to y along with # additional data f1 = (x**2 - x + 1)*y**2 - 2*x**2*y + x**4 f2 = -x**7 + 2*x**3*y + y**3 f3 = (y**2-x**2)*(x-1)*(2*x-3) - 4*(x**2+y**2-2*x)**2 f4 = y**2 + x**3 - x**2 f5 = (x**2 + y**2)**3 + 3*x**2*y - y**3 f6 = y**4 - y**2*x + x**2 # case with only one finite disc pt f7 = y**3 - (x**3 + y)**2 + 1 f8 = (x**6)*y**3 + 2*x**3*y - 1 f9 = 2*x**7*y + 2*x**7 + y**3 + 3*y**2 + 3*y f10= (x**3)*y**4 + 4*x**2*y**2 + 2*x**3*y - 1 f = f9 n = sympy.degree(f,y) coeffs = coeff_functions(sympy.poly(f,y),x) # compute the path parameterization around a given branch point bpt = 3 G = monodromy_graph(f,x,y) path_segments = path_around_branch_point(G,bpt,1) nseg = len(path_segments) # select a root at the base_point a = G.node[0]['basepoint'] fibre = map(numpy.complex,sympy.nroots(f.subs(x,a),n=15)) # analytically continue ypath = []
#a numpy array floquetobj = StringIO(str(floquetFetch).strip('[ ]')) floquet = np.loadtxt(floquetobj) TopLength = len(str(itinerary)) #if str(itinerary)=='001': #continue Zeta0 = Zeta0 * (1 - (sympy.exp(-s*T)*z**TopLength)/np.abs(floquet[0])) conn.close() from sympy import degree, LT #Zeta0 = sympy.expand(Zeta0) #Zeta00 = [] #ExpOrder = 4 raw_input("fdasfdsafdsa") for j in range(ExpOrder,0,-1): while degree(Zeta00) > j: Zeta0 = Zeta0 - LT(Zeta0) if degree(Zeta0) <= ExpOrder: Zeta00.insert(0, (np.float(Zeta00.subs(z,1)))) #print Zeta00 #print Zeta00.subs(z, 1) print Zeta00Val plot(range(1, ExpOrder+1),Zeta00Val) plt.show()
for rpono in range(1,Ncycle+1): c.execute("SELECT * FROM rpos WHERE rpono = "+str(rpono)) a = c.fetchall() rpono, itinerary, x1, y1, x2, y2, T, phifetch , floquetFetch= a[0] #Format the Floquet exponents such that it would be readable by loadtxt as #a numpy array floquetobj = StringIO(str(floquetFetch).strip('[ ]')) floquet = np.loadtxt(floquetobj) TopLength = len(str(itinerary)) #if str(itinerary)=='001': #continue Zeta0 = Zeta0 * (1 - (sympy.exp(-s*T)/np.abs(floquet[0])) Zeta0 = Zeta0.expand() while sympy.degree(Zeta0, z) > ExpOrder: Zeta0 = Zeta0 - sympy.LT(Zeta0, z) Zeta0 = sympy.collect(Zeta0, z) conn.close() Zeta0 = Zeta0.subs(z,1) ConservationRule.append(Zeta0.subs(s,0)) print "Conservation rule:", ConservationRule f = sympy.lambdify(s, Zeta0, "numpy") def fcomplex(xy): x, y = xy fcomp = np.array([np.real(f(x + 1j*y)), np.imag(f(x + 1j*y))]) return fcomp