def make_map_latex(map_str): # FIXME: Get rid of nu when map is defined over QQ if "nu" not in map_str: R0 = QQ else: R0 = PolynomialRing(QQ,'nu') R = PolynomialRing(R0,2,'x,y') F = FractionField(R) phi = F(map_str) num = phi.numerator() den = phi.denominator() c_num = num.denominator() c_den = den.denominator() lc = c_den/c_num # rescale coeffs to make them integral. then try to factor out gcds # numerator num_new = c_num*num num_cs = num_new.coefficients() if R0 == QQ: num_cs_ZZ = num_cs else: num_cs_ZZ = [] for el in num_cs: num_cs_ZZ = num_cs_ZZ + el.coefficients() num_gcd = gcd(num_cs_ZZ) # denominator den_new = c_den*den den_cs = den_new.coefficients() if R0 == QQ: den_cs_ZZ = den_cs else: den_cs_ZZ = [] for el in den_cs: den_cs_ZZ = den_cs_ZZ + el.coefficients() den_gcd = gcd(den_cs_ZZ) lc = lc*(num_gcd/den_gcd) num_new = num_new/num_gcd den_new = den_new/den_gcd # make strings for lc, num, and den num_str = latex(num_new) den_str = latex(den_new) if lc==1: lc_str="" else: lc_str = latex(lc) if den_new==1: if lc ==1: phi_str = num_str else: phi_str = lc_str+"("+num_str+")" else: phi_str = lc_str+"\\frac{"+num_str+"}"+"{"+den_str+"}" return phi_str
def xi(self,A): r""" The eight-root of unity in front of the Weil representation. INPUT: -''N'' -- integer -''A'' -- element of PSL(2,Z) EXAMPLES:: sage: A=SL2Z([41,77,33,62]) sage: WR.xi(A) -zeta8^3] sage: S,T=SL2Z.gens() sage: WR.xi(S) -zeta8^3 sage: WR.xi(T) 1 sage: A=SL2Z([-1,1,-4,3]) sage: WR.xi(A) -zeta8^2 sage: A=SL2Z([0,1,-1,0]) sage: WR.xi(A) -zeta8 """ a=Integer(A[0,0]); b=Integer(A[0,1]) c=Integer(A[1,0]); d=Integer(A[1,1]) if(c==0): return 1 z=CyclotomicField(8).gen() N=self._N N2=odd_part(N) Neven=ZZ(2*N).divide_knowing_divisible_by(N2) c2=odd_part(c) Nc=gcd(Integer(2*N),Integer(c)) cNc=ZZ(c).divide_knowing_divisible_by(Nc) f1=kronecker(-a,cNc) f2=kronecker(cNc,ZZ(2*N).divide_knowing_divisible_by(Nc)) if(is_odd(c)): s=c*N2 elif( c % Neven == 0): s=(c2+1-N2)*(a+1) else: s=(c2+1-N2)*(a+1)-N2*a*c2 r=-1-QQ(N2)/QQ(gcd(c,N2))+s xi=f1*f2*z**r return xi
def print_as_polynomial_in_E4_and_E6(self): r""" """ if(self.level() != 1): return "" try: [poldeg, monomials, X] = self.as_polynomial_in_E4_and_E6() except ValueError: return "" s = "" e4 = "E_{4}" e6 = "E_{6}" dens = map(denominator, X) g = gcd(dens) s = "\\frac{1}{" + str(g) + "}\left(" for n in range(len(X)): c = X[n] * g if(c == -1): s = s + "-" elif(c != 1): s = s + str(c) if(n > 0 and c > 0): s = s + "+" d4 = monomials[n][0] d6 = monomials[n][1] if(d6 > 0): s = s + e6 + "^{" + str(d6) + "}" if(d4 > 0): s = s + e4 + "^{" + str(d4) + "}" s = s + "\\right)" return "\(" + s + "\)"
def galois_orbit(cusp,G): N=G.level() orbit=set([]) for i in xrange(1,N): if gcd(i,N)==1: orbit.add(G.reduce_cusp(galois_action(cusp,i,N))) return tuple(sorted(orbit))
def x5__with_prec(prec): ''' Returns formal q-expansion f s.t. f * q1^(-1/2)*t^(1/2)*q2^(-1/2) equals to x5 (x10 == x5^2). ''' if prec not in ZZ: prec = prec._max_value() pwsr_prec = (2 * prec - 1) ** 2 def jacobi_g(n, r): return x5_jacobi_g(n, r, pwsr_prec) prec = PrecisionDeg2(prec) fc_dct = {} for n, r, m in prec: if 4 * n * m - r ** 2 == 0: fc_dct[(n, r, m)] = 0 else: n1 = 2 * n - 1 r1 = 2 * r + 1 m1 = 2 * m - 1 if 4 * n1 * m1 - r1 ** 2 > 0: fc_dct[(n, r, m)] = sum([d ** 4 * jacobi_g(n1 * m1 // (d ** 2), r1 // d) for d in gcd([n1, r1, m1]).divisors()]) res = QexpLevel1(fc_dct, prec) return ModFormQsrTimesQminushalf(res, 5)
def __init__(self, modulus=1, number=1, update_from_db=True, compute=False): r""" Init self. """ emf_logger.critical("In WebChar {0}".format((modulus, number, update_from_db, compute))) if not gcd(number, modulus) == 1: raise ValueError, "Character number {0} of modulus {1} does not exist!".format(number, modulus) if number > modulus: number = number % modulus self._properties = WebProperties( WebInt("conductor"), WebInt("modulus", value=modulus), WebInt("number", value=number), WebInt("modulus_euler_phi"), WebInt("order"), WebStr("latex_name"), WebStr("label", value="{0}.{1}".format(modulus, number)), WebNoStoreObject("sage_character", type(trivial_character(1))), WebDict("_values_algebraic"), WebDict("_values_float"), WebDict("_embeddings"), WebFloat("version", value=float(emf_version)), ) emf_logger.debug("Set properties in WebChar!") super(WebChar, self).__init__(update_from_db=update_from_db) if self._has_updated_from_db is False: self.init_dynamic_properties() # this was not done if we exited early compute = True if compute: self.compute(save=True) # emf_logger.debug('In WebChar, self.__dict__ = {0}'.format(self.__dict__)) emf_logger.debug("In WebChar, self.number = {0}".format(self.number))
def label_to_number(modulus, number, all=False): """ Takes the second part of a character label and converts it to the second part of a Conrey label. This could be trivial (just casting to an int) or could require converting from an orbit label to a number. If the label is invalid, returns 0. """ try: number = int(number) except ValueError: # encoding Galois orbit if modulus < 10000: try: orbit_label = '{0}.{1}'.format(modulus, 1 + class_to_int(number)) except ValueError: return 0 else: number = db.char_dir_orbits.lucky({'orbit_label':orbit_label}, 'galois_orbit') if number is None: return 0 if not all: number = number[0] else: return 0 else: if number <= 0 or gcd(modulus, number) != 1 or number > modulus: return 0 return number
def galoisorbit(self): order = self.order mod, num = self.modulus, self.number prim = self.isprimitive #beware this **must** be a generator orbit = ( power_mod(num, k, mod) for k in xsrange(1, order) if gcd(k, order) == 1) # use xsrange not xrange return ( self._char_desc(num, prim=prim) for num in orbit )
def projective_height(projective_point, abs_val=lambda x: x.abs()): """The projective exponential height function (works only over the rationals?).""" denoms = [v.denominator() for v in projective_point] nums = [v.numerator() for v in projective_point] d = lcm(denoms) g = gcd(nums) return abs_val(d)/abs_val(g) * max([abs_val(v) for v in projective_point])
def diamond_orbit(E,N=None): """ """ if N==None: N=E([0,0]).order() for d in xrange(1,N): if gcd(d,N)==1: yield diamond_operator(E,d)
def normal_vertices(Delta): vertices = [] for ineq in Delta.inequalities_list(): c = ineq[0] ineq = ineq[1:] assert gcd(ineq) == 1 vertices.append(vector(ZZ, ineq)) return vertices
def inverse_gcd(i,N): """ Function IG in Mark his code """ i = ZZ(i); N = ZZ(N) if N == 2*i and (i==1 or i==2): return 1 return N/gcd(i,N)
def render_Dirichletwebpage(modulus=None, number=None): if modulus == None: return render_DirichletNavigation() modulus = modulus.replace(' ','') if number == None and re.match('^[1-9][0-9]*\.[1-9][0-9]*$', modulus): return redirect(url_for(".render_Dirichletwebpage", label=modulus), 301) args={} args['type'] = 'Dirichlet' args['modulus'] = modulus args['number'] = number try: modulus = int(modulus) except ValueError: modulus = 0 if modulus <= 0: flash_error ("%s is not a valid modulus for a Dirichlet character. It should be a positive integer.", args['modulus']) return redirect(url_for(".render_Dirichletwebpage")) if modulus > 10**20: flash_error ("specified modulus %s is too large, it should be less than $10^{20}$.", modulus) return redirect(url_for(".render_Dirichletwebpage")) if number == None: if modulus < 100000: info = WebDirichletGroup(**args).to_dict() else: info = WebSmallDirichletGroup(**args).to_dict() info['bread'] = [('Characters', url_for(".render_characterNavigation")), ('Dirichlet', url_for(".render_Dirichletwebpage")), ('%d'%modulus, url_for(".render_Dirichletwebpage", modulus=modulus))] info['learnmore'] = learn() info['code'] = dict([(k[4:],info[k]) for k in info if k[0:4] == "code"]) info['code']['show'] = { lang:'' for lang in info['codelangs'] } # use default show names if 'gens' in info: info['generators'] = ', '.join([r'<a href="%s">$\chi_{%s}(%s,\cdot)$'%(url_for(".render_Dirichletwebpage",modulus=modulus,number=g),modulus,g) for g in info['gens']]) return render_template('CharGroup.html', **info) try: number = int(number) except ValueError: number = 0; if number <= 0 or gcd(modulus,number) != 1 or number > modulus: flash_error("the value %s is invalid. It should be a positive integer coprime to and no greater than the modulus %s.", args['number'],args['modulus']) return redirect(url_for(".render_Dirichletwebpage")) if modulus < 100000: webchar = WebDirichletCharacter(**args) info = webchar.to_dict() else: info = WebSmallDirichletCharacter(**args).to_dict() info['bread'] = [('Characters', url_for(".render_characterNavigation")), ('Dirichlet', url_for(".render_Dirichletwebpage")), ('%s'%modulus, url_for(".render_Dirichletwebpage", modulus=modulus)), ('%s'%number, url_for(".render_Dirichletwebpage", modulus=modulus, number=number)) ] info['learnmore'] = learn() info['code'] = dict([(k[4:],info[k]) for k in info if k[0:4] == "code"]) info['code']['show'] = { lang:'' for lang in info['codelangs'] } # use default show names return render_template('Character.html', **info)
def circle_drops(A,B): # Drops going around the unit circle for those A and B. # See http://user.math.uzh.ch/dehaye/thesis_students/Nicolas_Wider-Integrality_of_factorial_ratios.pdf # for longer description (not original, better references exist) marks = lcm(lcm(A),lcm(B)) tmp = [0 for i in range(marks)] for a in A: # print tmp for i in range(a): if gcd(i, a) == 1: tmp[i*marks/a] -= 1 for b in B: # print tmp for i in range(b): if gcd(i, b) == 1: tmp[i*marks/b] += 1 # print tmp return [sum(tmp[:j]) for j in range(marks)]
def polygon_expand(Delta, len=1): ieqs = [] for ineq in Delta.inequalities_list(): c = ineq[0] ineq = ineq[1:] assert c in ZZ assert gcd(ineq) == 1 ieqs.append([c + len] + ineq) return Polyhedron(ieqs=ieqs)
def value(self, val): val = int(val) chartex = self.char2tex(self.modulus,self.number,val=val,tag=False) # FIXME: bug in dirichlet_conrey logvalue if gcd(val, self.modulus) == 1: val = self.texlogvalue(self.chi.logvalue(val)) else: val = 0 return '\(%s=%s\)'%(chartex,val)
def _i_func(q): '''Return i(B) in Katsurada's paper. ''' m = ZZ(2) * (q.matrix()) ** (-1) i = valuation(gcd(m.list()), ZZ(2)) m = ZZ(2) ** (-i) * m if all(m[a, a] % 2 == 0 for a in range(m.ncols())): return - i - 1 else: return - i
def degree_cusp(i,N): """ Function DegreeCusp in Mark his code returns the degree over Q of the cusp $q^(i/n)\zeta_n^j$ on X_1(N) """ i = ZZ(i); N = ZZ(N) d = euler_phi(gcd(i,N)) if i == 0 or 2*i == N: return ceil(d/2) return d
def min_formula(N,t): """ Function MinFormula in Mark his code """ N = ZZ(N); t = QQ(t) if N < 2: raise ValueError if N == 2: return 4 * t -1 if N == 3: return 9 * min(t, ZZ(1)/3) - 8*t return sum(N * Phi(gcd(i,N)) * (min(t, i/N) - 4*(i/N)*(1-i/N)*t) for i in srange(1,(N-1)//2+1))
def gcd_of_norms(self, bd=False): ''' Returns the g.c.d of absolute norms of Fourier coefficients. ''' def norm(x): if x in QQ: return x else: return x.norm() if bd is False: bd = self.prec return gcd([QQ(norm(self.fc_dct[t])) for t in PrecisionDeg2(bd)])
def Gelts(self): res = [] m,n,k = self.modulus, 1, 1 while k < m and n <= self.maxcols: if gcd(k,m) == 1: res.append(k) n += 1 k += 1 if n > self.maxcols: self.coltruncate = True return res
def prevchar(m, n, onlyprimitive=False): """ Assume m>1 """ if onlyprimitive: return WebDirichlet.prevprimchar(m, n) if n == 1: m, n = m - 1, m if m <= 2: return m, 1 # important : 2,2 is not a character for k in xrange(n - 1, 0, -1): if gcd(m, k) == 1: return m, k raise Exception("prevchar")
def Gelts(self): res = [] m,n = self.modulus, 1 for k in xrange(1,m): if gcd(k,m) == 1: res.append(k) n += 1 if n > self.maxcols: self.coltruncate = True break return res
def _latex_using_dpd_depth1(self, dpd_dct): names = [dpd_dct[c] for c in self._consts] _gcd = QQ(gcd(self._coeffs)) coeffs = [c / _gcd for c in self._coeffs] coeffs_names = [(c, n) for c, n in zip(coeffs, names) if c != 0] tail_terms = ["%s %s %s" % ("+" if c > 0 else "", c, n) for c, n in coeffs_names[1:]] c0, n0 = coeffs_names[0] head_term = str(c0) + " " + str(n0) return r"\frac{{{pol_num}}}{{{pol_dnm}}} \left({terms}\right)".format( pol_dnm=latex(_gcd.denominator() * self._scalar_const._polynomial_expr()), pol_num=latex(_gcd.numerator()), terms=" ".join([head_term] + tail_terms), )
def check_amn_slow(self, rec, verbose=False): """ Check that a_{pn} = a_p * a_n for p < 32 prime, n prime to p """ Z = [0] + [CC(*elt) for elt in rec['an_normalized']] for pp in prime_range(len(Z)-1): for k in range(1, (len(Z) - 1)//pp + 1): if gcd(k, pp) == 1: if (Z[pp*k] - Z[pp]*Z[k]).abs() > 1e-13: if verbose: print "amn failure", k, pp, Z[pp*k], Z[pp]*Z[k] return False return True
def test(): f, enc, q_orig, a_orig = get_test() print(a_orig) key = xor(f[:8], enc, cut='min') print(key) a_stream = bits(key) print(a_stream) print(bin(a_orig)) p, q = small_fcsr_finder(a_stream) p, q = p//gcd(p,q), q//gcd(p,q) p, q = abs(int(p)), abs(int(q)) print(bin(p)) print(bin(q)) print(p,q) r = q.bit_length()-1 a = int(''.join(map(str, a_stream[:r][::-1])), 2) fcsr = FCSR(q, 0, a) decrypted = fcsr.encrypt(enc) print(decrypted == f) breakpoint()
def nextprimchar(m, n): if m < 3: return 3, 2 while 1: n += 1 if n >= m: m, n = m + 1, 2 if gcd(m, n) != 1: continue # we have a character, test if it is primitive chi = ConreyCharacter(m,n) if chi.is_primitive(): return m, n
def type_three_not_momose(K, embeddings, strong_type_3_epsilons): """Compute a superset of TypeThreeNotMomosePrimes""" if len(strong_type_3_epsilons) == 0: return [], [] C_K = K.class_group() h_K = C_K.order() # Since the data in strong_type_3_epsilons also contains the # IQF L, we need to extract only the epsilons for the actual # computation. On the other hand, we also want to report the Ls # higher up the stack, so we get those as well actual_type_3_epsilons = set(strong_type_3_epsilons.keys()) type_3_fields = set(strong_type_3_epsilons.values()) if h_K == 1: return [], type_3_fields aux_gen_list = auxgens(K) bound_dict = {eps: 0 for eps in actual_type_3_epsilons} for gen_list in aux_gen_list: eps_lcm_dict = get_eps_lcm_dict( C_K, actual_type_3_epsilons, embeddings, gen_list ) for eps in actual_type_3_epsilons: bound_dict[eps] = gcd(bound_dict[eps], eps_lcm_dict[eps]) for eps in actual_type_3_epsilons: bound_dict[eps] = lcm( bound_dict[eps], strong_type_3_epsilons[eps].discriminant() ) Kgal = embeddings[0].codomain() epsilons_for_ice = {eps: "quadratic-non-constant" for eps in actual_type_3_epsilons} output = character_enumeration_filter( K, C_K, Kgal, bound_dict, epsilons_for_ice, 1000, embeddings, auto_stop_strategy=True, ) return output, type_3_fields
def prevchar(m, n, onlyprimitive=False): """ Assume m>1 """ if onlyprimitive: return WebDirichlet.prevprimchar(m, n) if n == 1: m, n = m - 1, m if m <= 2: return m, 1 # important : 2,2 is not a character k = n-1 while k > 0: if gcd(m, k) == 1: return m, k k -= 1 raise Exception("prevchar")
def _compute_echelon(self): A = Matrix(self.parent(), self.A.rows()) # we create a copy of the matrix U = identity_matrix(self.parent(), A.nrows()) if (self.have_ideal): # we do simplifications A = self.simplify(A) ## Step 1: initialize r = 0 c = 0 # we look from the position (r,c) while (r < A.nrows() and c < A.ncols()): ir = self.__find_pivot(A, r, c) A = self.simplify(A) U = self.simplify(U) # we simplify in case relations pop up if (ir != None): # we found a pivot # We do the swapping (if needed) if (ir != r): A.swap_rows(r, ir) U.swap_rows(r, ir) # We do the bareiss step Arc = A[r][c] Arows = A.rows() Urows = U.rows() for i in range(r): # we create zeros on top of the pivot Aic = A[i][c] A.set_row(i, Arc * Arows[i] - Aic * Arows[r]) U.set_row(i, Arc * Urows[i] - Aic * Urows[r]) # We then leave the row r without change for i in range(r + 1, A.nrows()): # we create zeros below the pivot Aic = A[i][c] A.set_row(i, Aic * Arows[r] - Arc * Arows[i]) U.set_row(i, Aic * Urows[r] - Arc * Urows[i]) r += 1 c += 1 else: # no pivot then only advance in column c += 1 # We finish simplifying the gcds in each row gcds = [gcd(row) for row in A] T = diagonal_matrix([1 / el if el != 0 else 1 for el in gcds]) A = (T * A).change_ring(self.parent()) U = T * U return A, U
def circle_image(A,B): G = Graphics() G += circle((0,0), 1 , color = 'grey') from collections import defaultdict tmp = defaultdict(int) for a in A: for j in range(a): if gcd(j,a) == 1: rational = Rational(j)/Rational(a) tmp[(rational.numerator(),rational.denominator())] += 1 for b in B: for j in range(b): if gcd(j,b) == 1: rational = Rational(j)/Rational(b) tmp[(rational.numerator(),rational.denominator())] -= 1 C = ComplexField() for val in tmp: if tmp[val] > 0: G += text(str(tmp[val]),exp(C(-.2+2*3.14159*I*val[0]/val[1])), fontsize = 30, axes = False, color = "green") if tmp[val] < 0: G += text(str(abs(tmp[val])),exp(C(.2+2*3.14159*I*val[0]/val[1])), fontsize = 30, axes = False, color = "blue") return G
def JG_torsion_upperbound(G, bound=60): """ INPUT: - G - a congruence subgroup - bound (optional, default = 60) - the bound for the primes p up to which to use the hecke matrix `T_p - <p> - p` for bounding the torsion subgroup OUTPUT: - A subgroup of `(S_2(G) \otimes \QQ) / S_2(G)` that is guaranteed to contain the rational torison subgroup, together with a subgroup generated by the rational cusps. The subgroup is given as a subgroup of `S_2(G)/NS_2(G)` for a suitable integer N EXAMPLES:: sage: from mdsage import * sage: d = rational_cuspidal_classgroup(Gamma1(23)).cardinality() sage: upper_bound_index_cusps_in_JG_torsion(Gamma1(23),d) 1 """ N = G.level() M = ModularSymbols(G) Sint = cuspidal_integral_structure(M) kill_mat = (M.star_involution().matrix().restrict(Sint) - 1) kill = kill_mat.transpose().change_ring(ZZ).row_module() for p in prime_range(3, bound): if not N % p == 0: kill += kill_torsion_coprime_to_q( p, M).restrict(Sint).change_ring(ZZ).transpose().row_module() #if kill.matrix().is_square() and kill.matrix().determinant()==d: # #print p # break kill_mat = kill.matrix().transpose() #print N,"index of torsion in stuff killed",kill.matrix().determinant()/d #if kill.matrix().determinant()==d: # return 1 d = prod(kill_mat.smith_form()[0].diagonal()) pm = integral_period_mapping(M) #period_images1=[sum([M.coordinate_vector(M([c,infinity])) for c in cusps])*pm for cusps in galois_orbits(G)] period_images2 = [ M.coordinate_vector(M([c, infinity])) * pm for c in G.cusps() if c != Cusp(oo) ] m = (Matrix(period_images2) * kill_mat).stack(kill_mat) m, d2 = m._clear_denom() d = gcd(d, d2)
def __get_lcm(self, input): try: return lcm(input) except AttributeError: ## No lcm for this class, implementing a general lcm try: ## Relying on gcd p = self.__conversion.poly_ring() res = p(1) for el in input: res = p((res * el) / gcd(res, el)) return res except AttributeError: ## Returning the product of everything return prod(input)
def crack_given_decrypt(n, m): n = Integer(n) m = Integer(m) while True: if is_odd(m): break divide_out = True for _ in range(5): a = randrange(1, n) if gcd(a, n) == 1: if Mod(a, n) ** (m // 2) != 1: divide_out = False break if divide_out: m //= 2 else: break while True: a = randrange(1, n) g = gcd(lift(Mod(a, n) ** (m // 2)) - 1, n) if g != 1 and g != n: return g
def rsa(bits): # only prove correctness up to 1024bits proof = (bits <= 1024) p = next_prime(ZZ.random_element(2**(bits // 2 + 1)), proof=proof) q = next_prime(ZZ.random_element(2**(bits // 2 + 1)), proof=proof) n = p * q phi_n = (p - 1) * (q - 1) while True: e = ZZ.random_element(1, phi_n) if gcd(e, phi_n) == 1: break d = lift(Mod(e, phi_n)**(-1)) return e, d, n
def simplify_sqrt(c, d, rad): assert c.parent() == d.parent() assert rad.parent() == d.parent() # writes sqrt(c + d sqrt(rad)) # as # a sqrt(d1) + b sqrt(d2) # where d1 * d2 = rad g2 = c**2 - d**2 * rad g = sqrt_poly(g2) assert g**2 == g2, "%s != %s" % (g2, g**2) a = gcd(g + c, d) / 2 d1 = (g + c) / (2 * a**2) b = d / (2 * a) d2 = rad / d1 return a, b, d1, d2
def prevprimchar(m, n): if m <= 3: return 1, 1 while True: n -= 1 if n <= 1: # (m,1) is never primitive for m>1 m, n = m - 1, m - 1 if m <= 2: return 1, 1 if gcd(m, n) != 1: continue # we have a character, test if it is primitive chi = ConreyCharacter(m,n) if chi.is_primitive(): return m, n
def circle_image(A, B): G = Graphics() G += circle((0, 0), 1, color='black', thickness=3) G += circle( (0, 0), 1.4, color='black', alpha=0 ) # This adds an invisible framing circle to the plot, which protects the aspect ratio from being skewed. from collections import defaultdict tmp = defaultdict(int) for a in A: for j in range(a): if gcd(j, a) == 1: rational = Rational(j) / Rational(a) tmp[(rational.numerator(), rational.denominator())] += 1 for b in B: for j in range(b): if gcd(j, b) == 1: rational = Rational(j) / Rational(b) tmp[(rational.numerator(), rational.denominator())] -= 1 C = ComplexField() color1 = (41 / 255, 95 / 255, 45 / 255) color2 = (0 / 255, 0 / 255, 150 / 255) for val in tmp: if tmp[val] > 0: G += text(str(tmp[val]), exp(C(-.2 + 2 * 3.14159 * I * val[0] / val[1])), fontsize=30, axes=False, color=color1) if tmp[val] < 0: G += text(str(abs(tmp[val])), exp(C(.2 + 2 * 3.14159 * I * val[0] / val[1])), fontsize=30, axes=False, color=color2) return G
def render_Dirichletwebpage(modulus=None, number=None): #args = request.args #temp_args = to_dict(args) args = {} args['type'] = 'Dirichlet' args['modulus'] = modulus args['number'] = number if modulus == None: return render_characterNavigation() # waiting for new landing page info = WebDirichletFamily(**args).to_dict() info['learnmore'] = learn() return render_template('CharFamily.html', **info) else: modulus = int(modulus) if number == None: if modulus < 100000: info = WebDirichletGroup(**args).to_dict() else: info = WebSmallDirichletGroup(**args).to_dict() m = info['modlabel'] info['bread'] = [ ('Characters', url_for(".render_characterNavigation")), ('Dirichlet', url_for(".render_Dirichletwebpage")), ('Mod %s' % m, url_for(".render_Dirichletwebpage", modulus=m)) ] info['learnmore'] = learn() return render_template('CharGroup.html', **info) else: number = int(number) if gcd(modulus, number) != 1: return flask.abort(404) if modulus < 100000: info = WebDirichletCharacter(**args).to_dict() else: info = WebSmallDirichletCharacter(**args).to_dict() m, n = info['modlabel'], info['numlabel'] info['bread'] = [ ('Characters', url_for(".render_characterNavigation")), ('Dirichlet', url_for(".render_Dirichletwebpage")), ('Mod %s' % m, url_for(".render_Dirichletwebpage", modulus=m)), ('%s' % n, url_for(".render_Dirichletwebpage", modulus=m, number=n)) ] info['learnmore'] = learn() return render_template('Character.html', **info)
def render_Dirichletwebpage(modulus=None, number=None): #args = request.args #temp_args = to_dict(args) args={} args['type'] = 'Dirichlet' args['modulus'] = modulus args['number'] = number if modulus == None: return render_characterNavigation() # waiting for new landing page info = WebDirichletFamily(**args).to_dict() info['learnmore'] = learn() return render_template('CharFamily.html', **info) else: modulus = int(modulus) if number == None: if modulus < 100000: info = WebDirichletGroup(**args).to_dict() else: info = WebSmallDirichletGroup(**args).to_dict() m = info['modlabel'] info['bread'] = [('Characters', url_for(".render_characterNavigation")), ('Dirichlet', url_for(".render_Dirichletwebpage")), ('Mod %s'%m, url_for(".render_Dirichletwebpage", modulus=m))] info['learnmore'] = learn() info['code'] = dict([(k[4:],info[k]) for k in info if k[0:4] == "code"]) info['code']['show'] = { lang:'' for lang in info['codelangs'] } # use default show names return render_template('CharGroup.html', **info) else: number = int(number) if gcd(modulus, number) != 1: return flask.abort(404) if modulus < 100000: webchar = WebDirichletCharacter(**args) info = webchar.to_dict() else: info = WebSmallDirichletCharacter(**args).to_dict() m,n = info['modlabel'], info['numlabel'] info['bread'] = [('Characters', url_for(".render_characterNavigation")), ('Dirichlet', url_for(".render_Dirichletwebpage")), ('Mod %s'%m, url_for(".render_Dirichletwebpage", modulus=m)), ('%s'%n, url_for(".render_Dirichletwebpage", modulus=m, number=n)) ] info['learnmore'] = learn() info['code'] = dict([(k[4:],info[k]) for k in info if k[0:4] == "code"]) info['code']['show'] = { lang:'' for lang in info['codelangs'] } # use default show names return render_template('Character.html', **info)
def nextprimchar(m, n): if m < 3: return 3, 2 if n < m - 1: Gm = DirichletGroup_conrey(m) while 1: n += 1 if n >= m: m, n = m + 1, 2 Gm = DirichletGroup_conrey(m) if gcd(m, n) != 1: continue # we have a character, test if it is primitive chi = Gm[n] if chi.is_primitive(): return m, n
def nextchar(m, n, onlyprimitive=False): """ we know that the characters chi_m(1,.) and chi_m(m-1,.) always exist for m>1. They are extremal for a given m. """ if onlyprimitive: return WebDirichlet.nextprimchar(m, n) if m == 1: return 2, 1 if n == m - 1: return m + 1, 1 for k in xrange(n + 1, m): if gcd(m, k) == 1: return m, k raise Exception("nextchar")
def normalise_laurent_polynomial(f): """ Rescale a Laurent polynomial by Laurent monomials. Details TBA. """ # Since Sage's Laurent polynomials are useless, we just use rational # functions instead. # First make sure, 'f' really is one. R = f.parent() K = FractionField(R) f = K(f) if K.ngens() == 0: return R(0) if not f else R(1) f = f.numerator() return R(f / gcd(f.monomials()))
def jacobi_sum(self, val): mod, num = self.modulus, self.number val = int(val) if gcd(mod, val) > 1: raise Warning ("n must be coprime to the modulus : %s"%mod) psi = self.H[val] chi = self.chi.sage_character() psi = psi.sage_character() jacobi_sum = chi.jacobi_sum(psi) chitex = self.char2tex(mod, num, tag=False) psitex = self.char2tex(mod, val, tag=False) Gtex = '\Z/%s\Z' % mod chitexr = self.char2tex(mod, num, 'r', tag=False) psitex1r = self.char2tex(mod, val, '1-r', tag=False) deftex = r'\sum_{r\in %s} %s %s'%(Gtex,chitexr,psitex1r) from sage.all import latex return r"\( \displaystyle J(%s,%s) = %s = %s.\)" % (chitex, psitex, deftex, latex(jacobi_sum))
def __init__(self, modulus=1, number=1, update_from_db=True, compute_values=False, init_dynamic_properties=True): r""" Init self. """ emf_logger.debug("In WebChar {0}".format( (modulus, number, update_from_db, compute_values))) if isinstance(modulus, basestring): try: m, n = modulus.split('.') modulus = int(m) number = int(n) except: raise ValueError, "{0} does not correspond to the label of a WebChar".format( modulus) if not gcd(number, modulus) == 1: raise ValueError, "Character number {0} of modulus {1} does not exist!".format( number, modulus) if number > modulus: number = number % modulus self._properties = WebProperties( WebInt('conductor'), WebInt('modulus', value=modulus), WebInt('number', value=number), WebInt('modulus_euler_phi'), WebInt('order'), WebStr('latex_name'), WebStr('label', value="{0}.{1}".format(modulus, number)), WebNoStoreObject('sage_character', type(trivial_character(1))), WebDict('_values_algebraic'), WebDict('_values_float'), WebDict('_embeddings'), WebFloat('version', value=float(emf_version))) emf_logger.debug('Set properties in WebChar!') super(WebChar, self).__init__(update_from_db=update_from_db, init_dynamic_properties=init_dynamic_properties) #if not self.has_updated_from_db(): # self.init_dynamic_properties() # this was not done if we exited early # compute = True if compute_values: self.compute_values() #emf_logger.debug('In WebChar, self.__dict__ = {0}'.format(self.__dict__)) emf_logger.debug('In WebChar, self.number = {0}'.format(self.number))
def prevprimchar(m, n): if m <= 3: return 1, 1 if n > 2: Gm = DirichletGroup_conrey(m) while True: n -= 1 if n <= 1: # (m,1) is never primitive for m>1 m, n = m - 1, m - 1 Gm = DirichletGroup_conrey(m) if m <= 2: return 1, 1 if gcd(m, n) != 1: continue # we have a character, test if it is primitive chi = Gm[n] if chi.is_primitive(): return m, n
def windingelement_hecke_cutter_projected(data, extra_cutter_bound=None): "Creates winding element projected to the subspace where the hecke cutter condition of the data is satisfied" M = modular_symbols_ambient_from_lmfdb_mf(data) #dim = M.dimension() S = M.cuspidal_subspace() K = M.base_ring() R = PolynomialRing(K, "x") cutters = data[u'hecke_cutters'] cutters_maxp = cutters[-1][0] if cutters else 1 weight = data[u'weight'] assert weight % 2 == 0 cuts_eisenstein = False winding_element = M.modular_symbol([weight // 2 - 1, 0, oo]).element() if extra_cutter_bound: N = data[u'level'] wn = WebNewform(data) #qexp = qexp_as_nf_elt(wn,prec=extra_cutter_bound) for p in prime_range(cutters_maxp, extra_cutter_bound): if N % p == 0: continue cutters.append([p, qexp_as_nf_elt(wn)[p].minpoly().list()]) for c in cutters: p = c[0] fM = M.hecke_polynomial(p) fS = S.hecke_polynomial(p) cutter = gcd(R(c[1]), fS) assert not cutter.is_constant() for cp, ce in cutter.factor(): assert ce == 1 e = fM.valuation(cp) if fS.valuation(cp) == e: cuts_eisenstein = True winding_element = polynomial_matrix_apply(fM // cp**e, M.hecke_matrix(p), winding_element) if winding_element == 0: return winding_element #print fS.valuation(cp),fM.valuation(cp),ce assert cuts_eisenstein return winding_element
def simplify_equation(poly): """ Simplifies the given polynomial in three ways: 1. Cancels any M*m and L*l pairs. 2. Sets a0 = 1. 3. Since all variables represent non-zero quantities, divides by the gcd of the monomials terms. sage: R = PolynomialRing(QQ, ['M', 'L', 'm', 'l', 'a0', 'x', 'y', 'z']) sage: simplify_equation(R('5*M*m^2*L*l^3*x*y + 3*M*m*L*l + 11*M^10*m^3*L^5*l^2*z')) 11*M^7*L^3*z + 5*m*l^2*x*y + 3 sage: simplify_equation(R('-a0*x + M^7*m^7*x + L^9*l^3*z + a0^2')) L^6*z + 1 sage: simplify_equation(R('M^2*L*a0*x - M*L*y^2*x + M*z^2*x')) -L*y^2 + M*L + z^2 """ R = poly.parent() ans = R.zero() try: # Should we just permanently commit to c_1100_0 poly = poly.subs(a0=1) except: poly = poly.subs(c_1100_0=1) for coeff, monomial in list(poly): e = monomial.exponents()[0] M_exp = e[0] - e[2] L_exp = e[1] - e[3] if M_exp >= 0: M_p, M_n = M_exp, 0 else: M_p, M_n = 0, -M_exp if L_exp >= 0: L_p, L_n = L_exp, 0 else: L_p, L_n = 0, -L_exp ans += coeff * R.monomial(M_p, L_p, M_n, L_n, *e[4:]) ans = ans // gcd([mono for coeff, mono in list(ans)]) return ans
def K(self, m, n, c): r""" K(m,n,c) = sum_{d (c)} e((md+n\bar{d})/c) """ summa = 0 z = CyclotomicField(c).gen() print("z={0}".format(z)) for d in range(c): if gcd(d, c) > 1: continue try: dbar = inverse_mod(d, c) except ZeroDivisionError: print("c={0}".format(c)) print("d={0}".format(d)) raise ZeroDivisionError arg = m * dbar + n * d #print "arg=",arg summa = summa + z**arg return summa
def _get_element_nullspace(self, M): from ajpastor.misc.bareiss import BareissAlgorithm ## We take the domain where our elements will lie parent = M.parent().base().base() ## Computing the kernell of the matrix try: lcms = [lcm([el.denominator() for el in row]) for row in M] N = Matrix(parent, [[el*lcms[i] for el in M[i]] for i in range(M.nrows())]) ba = BareissAlgorithm(parent, N, lambda p : False) ker = ba.syzygy().transpose() except Exception as e: print(e) ker = M.right_kernel_matrix() #ker = M.right_kernel_matrix() ## If the nullspace has hight dimension, we try to reduce the final vector computing zeros at the end aux = [row for row in ker] i = 1 while(len(aux) > 1): new = [] current = None for j in range(len(aux)): if(aux[j][-(i)] == 0): new += [aux[j]] elif(current is None): current = j else: new += [aux[current]*aux[j][-(i)] - aux[j]*aux[current][-(i)]] current = j aux = [el/gcd(el) for el in new] i = i+1 ## When exiting the loop, aux has just one vector sol = aux[0] ## Our solution has denominators. We clean them all p = prod([el.denominator() for el in sol]) return vector(parent, [el*p for el in sol])
def R_du(d, u, M, columns=None, a_inv=False): """Returns a matrix that can be used to verify formall immersions on X_0(p) for all p > 2*M*d, such that p*u = 1 mod M. Args: d ([int]): degree of number field u ([int]): a unit mod M whose formal immersion properties we'd like to check M ([int]): an auxilary integer. Returns: [Matrix]: The Matrix of Corollary 6.8 of Derickx-Kamienny-Stein-Stoll. """ if columns is None: columns = [a for a in range(M) if gcd(a, M) == 1] a_inv = False if not a_inv: columns = [(a, int((ZZ(1) / a) % M)) for a in columns] return Matrix( ZZ, [[((0 if 2 * ((r * a[0]) % M) < M else 1) - (0 if 2 * ((r * u * a[1]) % M) < M else 1)) for a in columns] for r in range(1, d + 1)], )
def is_involution(self, W, verbose=0): r""" Explicit test if W is an involution of Gamma0(self._level) """ G = Gamma0(self._level) for g in G.gens(): gg = Matrix(ZZ, 2, 2, g.matrix().list()) g1 = W * gg * W**-1 if verbose > 0: print "WgW^-1=", g1 if g1 not in G: return False W2 = W * W c = gcd(W2.list()) if c > 1: W2 = W2 / c if verbose > 0: print "W^2=", W2 if W2 not in G: return False return True
def _unverified_short_slopes_from_translations(translations, length = 6): m_tran, l_tran = translations if isinstance(m_tran, complex): raise Exception("Expected real meridian translation") if not isinstance(m_tran, float): if m_tran.imag() != 0.0: raise Exception("Expected real meridian translation") if not m_tran > 0: raise Exception("Expected positive merdian translation") length = length * 1.001 result = [] max_abs_l = _floor(length / abs(_imag(l_tran))) for l in range(0, max_abs_l + 1): total_l_tran = l * l_tran max_real_range_sqr = length ** 2 - _imag(total_l_tran) ** 2 if max_real_range_sqr >= 0: max_real_range = sqrt(max_real_range_sqr) if l == 0: min_m = 1 else: min_m = _ceil( (- _real(total_l_tran) - max_real_range) / m_tran) max_m = _floor( (- _real(total_l_tran) + max_real_range) / m_tran) for m in range(min_m, max_m + 1): if gcd(m, l) in [-1, +1]: result.append((m,l)) return result
def label_to_number(modulus, number, all=False): """ Takes the second part of a character label and converts it to the second part of a Conrey label. This could be trivial (just casting to an int) or could require converting from an orbit label to a number. If the label is invalid, returns 0. """ try: number = int(number) except ValueError: # encoding Galois orbit if modulus < 10000: try: orbit_label = '{0}.{1}'.format(modulus, 1 + class_to_int(number)) except ValueError: raise ValueError( "Dirichlet Character of this label not found in database") else: number = db.char_dir_orbits.lucky({'orbit_label': orbit_label}, 'galois_orbit') if number is None: raise ValueError( "Dirichlet Character of this label not found in database" ) if not all: number = number[0] else: raise ValueError("The modulus cannot be larger than 10,000") else: if number <= 0: raise ValueError("The number after the '.' cannot be negative") elif gcd(modulus, number) != 1: raise ValueError( "The two numbers either side of '.' must be coprime") elif number > modulus: raise ValueError( "The number after the '.' must be less than the number before") return number
def dirichlet_group(self, prime_bound=10000): f = self.conductor() if f == 1: # To make the trivial case work correctly return [1] if euler_phi(f) > dir_group_size_bound: return [] # Can do quadratic fields directly if self.degree() == 2: if is_odd(f): return [1, f - 1] f1 = f / 4 if is_odd(f1): return [1, f - 1] # we now want f with all powers of 2 removed f1 = f1 / 2 if is_even(f1): raise Exception('Invalid conductor') if (self.disc() / 8) % 4 == 3: return [1, 4 * f1 - 1] # Finally we want congruent to 5 mod 8 and -1 mod f1 if (f1 % 4) == 3: return [1, 2 * f1 - 1] return [1, 6 * f1 - 1] from dirichlet_conrey import DirichletGroup_conrey G = DirichletGroup_conrey(f) K = self.K() S = Set(G[1].kernel()) # trivial character, kernel is whole group for P in K.primes_of_bounded_norm_iter(ZZ(prime_bound)): a = P.norm() % f if gcd(a, f) > 1: continue S = S.intersection(Set(G[a].kernel())) if len(S) == self.degree(): return list(S) raise Exception( 'Failure in dirichlet group for K=%s using prime bound %s' % (K, prime_bound))
def dirichlet_character_conrey_galois_orbit_embeddings(N, xi): r""" Returns a dictionary that maps the Conrey numbers of the Dirichlet characters in the Galois orbit of x to the powers of $\zeta_{\phi(N)}$ so that the corresponding embeddings map the labels. Let $\zeta_{\phi(N)}$ be the generator of the cyclotomic field of $N$-th roots of unity which is the base field for the coefficients of a modular form contained in the database. Considering the space $S_k(N,\chi)$, where $\chi = \chi_N(m, \cdot)$, if embeddings()[m] = n, then $\zeta_{\phi(N)}$ is mapped to $\zeta_{\phi(N)}^n = \mathrm{exp}(2\pi i n /\phi(N))$. """ embeddings = {} base_number = 0 base_number = xi embeddings[base_number] = 1 for n in range(2, N): if gcd(n, N) == 1: embeddings[Mod(base_number, N)**n] = n return embeddings