def _repr_(self): """ Return string representation of self. EXAMPLES:: sage: A.<x,y,z>=FreeAlgebra(ZZ,3) sage: repr(-x+3*y*z) # indirect doctest '-x + 3*y*z' Trac ticket :trac:`11068` enables the use of local variable names:: sage: from sage.structure.parent_gens import localvars sage: with localvars(A, ['a','b','c']): ....: print(-x+3*y*z) -a + 3*b*c """ v = sorted(self._monomial_coefficients.items()) P = self.parent() M = P.monoid() from sage.structure.parent_gens import localvars with localvars(M, P.variable_names(), normalize=False): x = repr_lincomb(v, strip_one=True) return x
def _repr_(self): """ Return string representation of self. EXAMPLES:: sage: A.<x,y,z>=FreeAlgebra(ZZ,3) sage: repr(-x+3*y*z) '-x + 3*y*z' Trac ticket #11068 enables the use of local variable names:: sage: from sage.structure.parent_gens import localvars sage: with localvars(A, ['a','b','c']): ... print -x+3*y*z ... -a + 3*b*c """ v = self.__monomial_coefficients.items() v.sort() mons = [ m for (m, _) in v ] cffs = [ x for (_, x) in v ] P = self.parent() M = P.monoid() from sage.structure.parent_gens import localvars with localvars(M, P.variable_names(), normalize=False): x = repr_lincomb(mons, cffs).replace("*1 "," ") if x[len(x)-2:] == "*1": return x[:len(x)-2] else: return x
def _repr_(self): """ Return string representation of self. EXAMPLES:: sage: A.<x,y,z>=FreeAlgebra(ZZ,3) sage: repr(-x+3*y*z) '-x + 3*y*z' Trac ticket #11068 enables the use of local variable names:: sage: from sage.structure.parent_gens import localvars sage: with localvars(A, ['a','b','c']): ... print -x+3*y*z ... -a + 3*b*c """ v = self.__monomial_coefficients.items() v.sort() mons = [m for (m, _) in v] cffs = [x for (_, x) in v] P = self.parent() M = P.monoid() from sage.structure.parent_gens import localvars with localvars(M, P.variable_names(), normalize=False): x = repr_lincomb(mons, cffs).replace("*1 ", " ") if x[len(x) - 2:] == "*1": return x[:len(x) - 2] else: return x
def _latex_(self): """ EXAMPLES:: sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ) sage: ((2/3)*i - j)._latex_() '\\frac{2}{3}i + \\left(-1\\right)j' """ Q = self.parent() M = Q.monoid() with localvars(M, Q.variable_names()): cffs = tuple(self.__vector) mons = Q.monomial_basis() return repr_lincomb(zip(mons, cffs), is_latex=True, strip_one=True)
def _repr_(self): """ EXAMPLES:: sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ) sage: i._repr_() 'i' """ Q = self.parent() M = Q.monoid() with localvars(M, Q.variable_names()): cffs = list(self.__vector) mons = Q.monomial_basis() return repr_lincomb(zip(mons, cffs), strip_one=True)
def _latex_(self): """ EXAMPLES:: sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ) sage: ((2/3)*i - j)._latex_() '\\frac{2}{3}i - j' """ Q = self.parent() M = Q.monoid() with localvars(M, Q.variable_names()): cffs = tuple(self.__vector) mons = Q.monomial_basis() return repr_lincomb(zip(mons, cffs), is_latex=True, strip_one=True)
def _repr_(self): """ EXAMPLES:: sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ) sage: i._repr_() 'i' """ Q = self.parent() M = Q.monoid() with localvars(M, Q.variable_names()): cffs = list(self.__vector) mons = Q.monomial_basis() x = repr_lincomb(mons, cffs).replace("*1 ", " ") if x[len(x) - 2:] == "*1": return x[:len(x) - 2] else: return x
def _latex_(self): """ EXAMPLES:: sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ) sage: ((2/3)*i - j)._latex_() '\\frac{2}{3}i + \\left(-1\\right)j' """ Q = self.parent() M = Q.monoid() with localvars(M, Q.variable_names()): cffs = list(self.__vector) mons = Q.monomial_basis() x = repr_lincomb(mons, cffs, True).replace("*1 "," ") if x[len(x)-2:] == "*1": return x[:len(x)-2] else: return x
def _latex_(self): """ EXAMPLES:: sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(QQ) sage: ((2/3)*i - j)._latex_() '\\frac{2}{3}i + \\left(-1\\right)j' """ Q = self.parent() M = Q.monoid() with localvars(M, Q.variable_names()): cffs = list(self.__vector) mons = Q.monomial_basis() x = repr_lincomb(mons, cffs, True).replace("*1 ", " ") if x[len(x) - 2:] == "*1": return x[:len(x) - 2] else: return x
def _repr_(self): """ EXAMPLES:: sage: H, (i,j,k) = sage.algebras.free_algebra_quotient.hamilton_quatalg(ZZ) sage: i._repr_() 'i' """ Q = self.parent() M = Q.monoid() with localvars(M, Q.variable_names()): cffs = list(self.__vector) mons = Q.monomial_basis() x = repr_lincomb(mons, cffs).replace("*1 "," ") if x[len(x)-2:] == "*1": return x[:len(x)-2] else: return x
def _repr_(self): """ String representation. TESTS:: sage: R.<x,y> = QQ[]; S.<a,b> = R.quo(x^2 + y^2); type(a) <class 'sage.rings.quotient_ring_element.QuotientRing_generic_with_category.element_class'> sage: a-2*a*b # indirect doctest -2*a*b + a In trac ticket #11068, the case of quotient rings without assigned names has been covered as well:: sage: S = SteenrodAlgebra(2) sage: I = S*[S.0+S.1]*S sage: Q = S.quo(I) sage: Q.0 Sq(1) """ from sage.structure.parent_gens import localvars P = self.parent() R = P.cover_ring() # We print by temporarily (and safely!) changing the variable # names of the covering structure R to those of P. # These names get changed back, since we're using "with". # However, it may occur that no variable names are assigned. # That holds, in particular, if there are infinitely many # generators, as for Steenrod algebras. try: names = P.variable_names() except ValueError: return str(self.__rep) with localvars(R, P.variable_names(), normalize=False): return str(self.__rep)
def simon_two_descent(E, verbose=0, lim1=None, lim3=None, limtriv=None, maxprob=20, limbigprime=30, known_points=[]): """ Interface to Simon's gp script for two-descent. .. NOTE:: Users should instead run E.simon_two_descent() EXAMPLES:: sage: import sage.schemes.elliptic_curves.gp_simon sage: E=EllipticCurve('389a1') sage: sage.schemes.elliptic_curves.gp_simon.simon_two_descent(E) (2, 2, [(5/4 : 5/8 : 1), (-3/4 : 7/8 : 1)]) TESTS:: sage: E = EllipticCurve('37a1').change_ring(QuadraticField(-11,'x')) sage: E.simon_two_descent() (1, 1, [(0 : 0 : 1)]) An example with an elliptic curve defined over a relative number field:: sage: F.<a> = QuadraticField(29) sage: x = QQ['x'].gen() sage: K.<b> = F.extension(x^2-1/2*a+1/2) sage: E = EllipticCurve(K,[1, 0, 5/2*a + 27/2, 0, 0]) # long time (about 3 s) sage: E.simon_two_descent(lim1=2, limtriv=3) (1, 1, ...) Check that :trac:`16022` is fixed:: sage: K.<y> = NumberField(x^4 + x^2 - 7) sage: E = EllipticCurve(K, [1, 0, 5*y^2 + 16, 0, 0]) sage: E.simon_two_descent(lim1=2, limtriv=3) # long time (about 3 s) (1, 1, ...) An example that checks that :trac:`9322` is fixed (it should take less than a second to run):: sage: K.<w> = NumberField(x^2-x-232) sage: E = EllipticCurve([2-w,18+3*w,209+9*w,2581+175*w,852-55*w]) sage: E.simon_two_descent() (0, 2, []) """ init() current_randstate().set_seed_gp(gp) K = E.base_ring() K_orig = K # The following is to correct the bug at \#5204: the gp script # fails when K is a number field whose generator is called 'x'. # It also deals with relative number fields. E_orig = E if not K is QQ: K = K_orig.absolute_field('a') from_K, to_K = K.structure() E = E_orig.change_ring(to_K) known_points = [P.change_ring(to_K) for P in known_points] # Simon's program requires that this name be y. with localvars(K.polynomial().parent(), 'y'): gp.eval("K = bnfinit(%s);" % K.polynomial()) if verbose >= 2: print("K = bnfinit(%s);" % K.polynomial()) gp.eval("%s = Mod(y,K.pol);" % K.gen()) if verbose >= 2: print("%s = Mod(y,K.pol);" % K.gen()) else: from_K = lambda x: x to_K = lambda x: x # The block below mimicks the defaults in Simon's scripts, and needs to be changed # when these are updated. if K is QQ: cmd = 'ellrank(%s, %s);' % (list( E.ainvs()), [P._pari_() for P in known_points]) if lim1 is None: lim1 = 5 if lim3 is None: lim3 = 50 if limtriv is None: limtriv = 3 else: cmd = 'bnfellrank(K, %s, %s);' % (list( E.ainvs()), [P._pari_() for P in known_points]) if lim1 is None: lim1 = 2 if lim3 is None: lim3 = 4 if limtriv is None: limtriv = 2 gp('DEBUGLEVEL_ell=%s; LIM1=%s; LIM3=%s; LIMTRIV=%s; MAXPROB=%s; LIMBIGPRIME=%s;' % (verbose, lim1, lim3, limtriv, maxprob, limbigprime)) if verbose >= 2: print(cmd) s = gp.eval('ans=%s;' % cmd) if s.find(" *** ") != -1: raise RuntimeError( "\n%s\nAn error occurred while running Simon's 2-descent program" % s) if verbose > 0: print(s) v = gp.eval('ans') if v == 'ans': # then the call to ellrank() or bnfellrank() failed raise RuntimeError( "An error occurred while running Simon's 2-descent program") if verbose >= 2: print("v = %s" % v) # pari represents field elements as Mod(poly, defining-poly) # so this function will return the respective elements of K def _gp_mod(*args): return args[0] ans = sage_eval(v, {'Mod': _gp_mod, 'y': K.gen(0)}) lower = ZZ(ans[0]) upper = ZZ(ans[1]) points = [E_orig([from_K(c) for c in list(P)]) for P in ans[2]] points = [P for P in points if P.has_infinite_order()] return lower, upper, points
def simon_two_descent(E, verbose=0, lim1=5, lim3=50, limtriv=10, maxprob=20, limbigprime=30): """ Interface to Simon's gp script for two-descent. .. NOTE:: Users should instead run E.simon_two_descent() EXAMPLES:: sage: import sage.schemes.elliptic_curves.gp_simon sage: E=EllipticCurve('389a1') sage: sage.schemes.elliptic_curves.gp_simon.simon_two_descent(E) [2, 2, [(1 : 0 : 1), (-11/9 : -55/27 : 1)]] sage: E.simon_two_descent() (2, 2, [(1 : 0 : 1), (-11/9 : -55/27 : 1)]) TESTS:: sage: E = EllipticCurve('37a1').change_ring(QuadraticField(-11,'x')) sage: E.simon_two_descent() (1, 1, [(-1 : 0 : 1)]) """ init() current_randstate().set_seed_gp(gp) K = E.base_ring() K_orig = K # The following is to correct the bug at \#5204: the gp script # fails when K is a number field whose generator is called 'x'. if not K is QQ: K = K.change_names('a') E_orig = E E = EllipticCurve(K,[K(list(a)) for a in E.ainvs()]) F = E.integral_model() if K != QQ: # Simon's program requires that this name be y. with localvars(K.polynomial().parent(), 'y'): gp.eval("K = bnfinit(%s);" % K.polynomial()) if verbose >= 2: print "K = bnfinit(%s);" % K.polynomial() gp.eval("%s = Mod(y,K.pol);" % K.gen()) if verbose >= 2: print "%s = Mod(y,K.pol);" % K.gen() if K == QQ: cmd = 'ellrank([%s,%s,%s,%s,%s]);' % F.ainvs() else: cmd = 'bnfellrank(K, [%s,%s,%s,%s,%s]);' % F.ainvs() gp('DEBUGLEVEL_ell=%s; LIM1=%s; LIM3=%s; LIMTRIV=%s; MAXPROB=%s; LIMBIGPRIME=%s;'%( verbose, lim1, lim3, limtriv, maxprob, limbigprime)) if verbose >= 2: print cmd s = gp.eval('ans=%s;'%cmd) if s.find("***") != -1: raise RuntimeError, "\n%s\nAn error occurred while running Simon's 2-descent program"%s if verbose > 0: print s v = gp.eval('ans') if v=='ans': # then the call to ellrank() or bnfellrank() failed return 'fail' if verbose >= 2: print "v = ", v # pari represents field elements as Mod(poly, defining-poly) # so this function will return the respective elements of K def _gp_mod(*args): return args[0] ans = sage_eval(v, {'Mod': _gp_mod, 'y': K.gen(0)}) inv_transform = F.isomorphism_to(E) ans[2] = [inv_transform(F(P)) for P in ans[2]] ans[2] = [E_orig([K_orig(list(c)) for c in list(P)]) for P in ans[2]] return ans
def simon_two_descent(E, verbose=0, lim1=None, lim3=None, limtriv=None, maxprob=20, limbigprime=30, known_points=[]): """ Interface to Simon's gp script for two-descent. .. NOTE:: Users should instead run E.simon_two_descent() EXAMPLES:: sage: import sage.schemes.elliptic_curves.gp_simon sage: E=EllipticCurve('389a1') sage: sage.schemes.elliptic_curves.gp_simon.simon_two_descent(E) (2, 2, [(5/4 : 5/8 : 1), (-3/4 : 7/8 : 1)]) TESTS:: sage: E = EllipticCurve('37a1').change_ring(QuadraticField(-11,'x')) sage: E.simon_two_descent() (1, 1, [(0 : 0 : 1)]) An example with an elliptic curve defined over a relative number field:: sage: F.<a> = QuadraticField(29) sage: x = QQ['x'].gen() sage: K.<b> = F.extension(x^2-1/2*a+1/2) sage: E = EllipticCurve(K,[1, 0, 5/2*a + 27/2, 0, 0]) # long time (about 3 s) sage: E.simon_two_descent(lim1=2, limtriv=3) (1, 1, ...) Check that :trac:`16022` is fixed:: sage: K.<y> = NumberField(x^4 + x^2 - 7) sage: E = EllipticCurve(K, [1, 0, 5*y^2 + 16, 0, 0]) sage: E.simon_two_descent(lim1=2, limtriv=3) # long time (about 3 s) (1, 1, ...) An example that checks that :trac:`9322` is fixed (it should take less than a second to run) sage: K.<w> = NumberField(x^2-x-232) sage: E = EllipticCurve([2-w,18+3*w,209+9*w,2581+175*w,852-55*w]) sage: E.simon_two_descent() (0, 2, []) """ init() current_randstate().set_seed_gp(gp) K = E.base_ring() K_orig = K # The following is to correct the bug at \#5204: the gp script # fails when K is a number field whose generator is called 'x'. # It also deals with relative number fields. E_orig = E if not K is QQ: K = K_orig.absolute_field('a') from_K,to_K = K.structure() E = E_orig.change_ring(to_K) known_points = [P.change_ring(to_K) for P in known_points] # Simon's program requires that this name be y. with localvars(K.polynomial().parent(), 'y'): gp.eval("K = bnfinit(%s);" % K.polynomial()) if verbose >= 2: print("K = bnfinit(%s);" % K.polynomial()) gp.eval("%s = Mod(y,K.pol);" % K.gen()) if verbose >= 2: print("%s = Mod(y,K.pol);" % K.gen()) else: from_K = lambda x: x to_K = lambda x: x # The block below mimicks the defaults in Simon's scripts, and needs to be changed # when these are updated. if K is QQ: cmd = 'ellrank(%s, %s);' % (list(E.ainvs()), [P._pari_() for P in known_points]) if lim1 is None: lim1 = 5 if lim3 is None: lim3 = 50 if limtriv is None: limtriv = 3 else: cmd = 'bnfellrank(K, %s, %s);' % (list(E.ainvs()), [P._pari_() for P in known_points]) if lim1 is None: lim1 = 2 if lim3 is None: lim3 = 4 if limtriv is None: limtriv = 2 gp('DEBUGLEVEL_ell=%s; LIM1=%s; LIM3=%s; LIMTRIV=%s; MAXPROB=%s; LIMBIGPRIME=%s;'%( verbose, lim1, lim3, limtriv, maxprob, limbigprime)) if verbose >= 2: print(cmd) s = gp.eval('ans=%s;'%cmd) if s.find(" *** ") != -1: raise RuntimeError("\n%s\nAn error occurred while running Simon's 2-descent program"%s) if verbose > 0: print(s) v = gp.eval('ans') if v=='ans': # then the call to ellrank() or bnfellrank() failed raise RuntimeError("An error occurred while running Simon's 2-descent program") if verbose >= 2: print("v = %s" % v) # pari represents field elements as Mod(poly, defining-poly) # so this function will return the respective elements of K def _gp_mod(*args): return args[0] ans = sage_eval(v, {'Mod': _gp_mod, 'y': K.gen(0)}) lower = ZZ(ans[0]) upper = ZZ(ans[1]) points = [E_orig([from_K(c) for c in list(P)]) for P in ans[2]] points = [P for P in points if P.has_infinite_order()] return lower, upper, points