def create_object(self, version, key, **extra_args): r""" Create a Gauss valuation from normalized parameters. TESTS:: sage: v = QQ.valuation(2) sage: R.<x> = QQ[] sage: GaussValuation.create_object(0, (R, v)) Gauss valuation induced by 2-adic valuation """ domain, v = key from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace parent = DiscretePseudoValuationSpace(domain) return parent.__make_element_class__(GaussValuation_generic)(parent, v)
def create_object(self, version, key): r""" Return the valuation described by ``key``. TESTS:: sage: from henselization import * sage: K = QQ.henselization(5) sage: K.valuation() # indirect doctest 5-adic valuation """ domain, = key from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace parent = DiscretePseudoValuationSpace(domain) return parent.__make_element_class__(HenselizationValuation)(parent)
def create_object(self, version, key, **extra_args): r""" Create the valuation specified by ``key``. EXAMPLES:: sage: K.<x> = FunctionField(QQ) sage: R.<x> = QQ[] sage: w = valuations.GaussValuation(R, QQ.valuation(2)) sage: v = K.valuation(w); v # indirect doctest 2-adic valuation """ domain, valuation = key from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace parent = DiscretePseudoValuationSpace(domain) if isinstance(valuation, tuple) and len(valuation) == 3: valuation, to_valuation_domain, from_valuation_domain = valuation if domain is domain.base() and valuation.domain() is valuation.domain().base() and to_valuation_domain == domain.hom([~valuation.domain().gen()]) and from_valuation_domain == valuation.domain().hom([~domain.gen()]): # valuation on the rational function field after x |--> 1/x if valuation == valuation.domain().valuation(valuation.domain().gen()): # the classical valuation at the place 1/x return parent.__make_element_class__(InfiniteRationalFunctionFieldValuation)(parent) from sage.structure.dynamic_class import dynamic_class clazz = RationalFunctionFieldMappedValuation if valuation.is_discrete_valuation(): clazz = dynamic_class("RationalFunctionFieldMappedValuation_discrete", (clazz, DiscreteValuation)) else: clazz = dynamic_class("RationalFunctionFieldMappedValuation_infinite", (clazz, InfiniteDiscretePseudoValuation)) return parent.__make_element_class__(clazz)(parent, valuation, to_valuation_domain, from_valuation_domain) return parent.__make_element_class__(FunctionFieldExtensionMappedValuation)(parent, valuation, to_valuation_domain, from_valuation_domain) if domain is valuation.domain(): # we can not just return valuation in this case # as this would break uniqueness and pickling raise ValueError("valuation must not be a valuation on domain yet but %r is a valuation on %r"%(valuation, domain)) if domain.base_field() is domain: # valuation is a base valuation on K[x] that induces a valuation on K(x) if valuation.restriction(domain.constant_base_field()).is_trivial() and valuation.is_discrete_valuation(): # valuation corresponds to a finite place return parent.__make_element_class__(FiniteRationalFunctionFieldValuation)(parent, valuation) else: from sage.structure.dynamic_class import dynamic_class clazz = NonClassicalRationalFunctionFieldValuation if valuation.is_discrete_valuation(): clazz = dynamic_class("NonClassicalRationalFunctionFieldValuation_discrete", (clazz, DiscreteFunctionFieldValuation_base)) else: clazz = dynamic_class("NonClassicalRationalFunctionFieldValuation_negative_infinite", (clazz, NegativeInfiniteDiscretePseudoValuation)) return parent.__make_element_class__(clazz)(parent, valuation) else: # valuation is a limit valuation that singles out an extension return parent.__make_element_class__(FunctionFieldFromLimitValuation)(parent, valuation, domain.polynomial(), extra_args['approximants']) raise NotImplementedError("valuation on %r from %r on %r"%(domain, valuation, valuation.domain()))
def create_object(self, version, key, **extra_args): r""" Create a Gauss valuation from normalized parameters. TESTS:: sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone sage: v = pAdicValuation(QQ, 2) sage: R.<x> = QQ[] sage: GaussValuation.create_object(0, (R, v)) Gauss valuation induced by 2-adic valuation """ domain, v = key from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace parent = DiscretePseudoValuationSpace(domain) return parent.__make_element_class__(GaussValuation_generic)(parent, v)
def create_object(self, version, key, **extra_args): r""" Create a `p`-adic valuation from ``key``. EXAMPLES:: sage: ZZ.valuation(5) # indirect doctest 5-adic valuation """ from sage.rings.all import ZZ, QQ from sage.rings.padics.padic_generic import pAdicGeneric from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing from sage.rings.number_field.number_field import is_NumberField R = key[0] parent = DiscretePseudoValuationSpace(R) if isinstance(R, pAdicGeneric): assert(len(key)==1) return parent.__make_element_class__(pAdicValuation_padic)(parent) elif R is ZZ or R is QQ: prime = key[1] assert(len(key)==2) return parent.__make_element_class__(pAdicValuation_int)(parent, prime) else: v = key[1] approximants = extra_args['approximants'] parent = DiscretePseudoValuationSpace(R) K = R.fraction_field() if is_NumberField(K): G = K.relative_polynomial() elif is_PolynomialQuotientRing(R): G = R.modulus() else: raise NotImplementedError return parent.__make_element_class__(pAdicFromLimitValuation)(parent, v, G.change_ring(R.base_ring()), approximants)
def _extensions_to_quotient(self, ring, approximants=None): r""" Return the extensions of this valuation to an integral quotient over the domain of this valuation. EXAMPLES:: sage: R.<x> = QQ[] sage: QQ.valuation(2)._extensions_to_quotient(R.quo(x^2 + x + 1)) [2-adic valuation] """ from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace parent = DiscretePseudoValuationSpace(ring) approximants = approximants or self.mac_lane_approximants( ring.modulus().change_ring(self.domain()), assume_squarefree=True, require_incomparability=True) return [ pAdicValuation(ring, approximant, approximants) for approximant in approximants ]
def create_object(self, version, key, **extra_args): r""" Create a `p`-adic valuation from ``key``. EXAMPLES:: sage: ZZ.valuation(5) # indirect doctest 5-adic valuation """ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.padics.padic_generic import pAdicGeneric from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing from sage.rings.number_field.number_field import is_NumberField R = key[0] parent = DiscretePseudoValuationSpace(R) if isinstance(R, pAdicGeneric): assert (len(key) == 1) return parent.__make_element_class__(pAdicValuation_padic)(parent) elif R is ZZ or R is QQ: prime = key[1] assert (len(key) == 2) return parent.__make_element_class__(pAdicValuation_int)(parent, prime) else: v = key[1] approximants = extra_args['approximants'] parent = DiscretePseudoValuationSpace(R) K = R.fraction_field() if is_NumberField(K): G = K.relative_polynomial() elif is_PolynomialQuotientRing(R): G = R.modulus() else: raise NotImplementedError return parent.__make_element_class__(pAdicFromLimitValuation)( parent, v, G.change_ring(R.base_ring()), approximants)
def extensions(self, ring): r""" Return the extensions of this valuation to ``ring``. EXAMPLES:: sage: v = ZZ.valuation(2) sage: v.extensions(GaussianIntegers()) [2-adic valuation] TESTS:: sage: R.<a> = QQ[] sage: L.<a> = QQ.extension(x^3 - 2) sage: R.<b> = L[] sage: M.<b> = L.extension(b^2 + 2*b + a) sage: M.valuation(2) 2-adic valuation Check that we can extend to a field written as a quotient:: sage: R.<x> = QQ[] sage: K.<a> = QQ.extension(x^2 + 1) sage: R.<y> = K[] sage: L.<b> = R.quo(x^2 + a) sage: QQ.valuation(2).extensions(L) [2-adic valuation] A case where there was at some point an internal error in the approximants code:: sage: R.<x> = QQ[] sage: L.<a> = NumberField(x^4 + 2*x^3 + 2*x^2 + 8) sage: QQ.valuation(2).extensions(L) [[ 2-adic valuation, v(x + 2) = 3/2 ]-adic valuation, [ 2-adic valuation, v(x) = 1/2 ]-adic valuation] A case where the extension was incorrect at some point:: sage: v = QQ.valuation(2) sage: L.<a> = NumberField(x^2 + 2) sage: M.<b> = L.extension(x^2 + 1) sage: w = v.extension(L).extension(M) sage: w(w.uniformizer()) 1/4 A case where the extensions could not be separated at some point:: sage: v = QQ.valuation(2) sage: R.<x> = QQ[] sage: F = x^48 + 120*x^45 + 56*x^42 + 108*x^36 + 32*x^33 + 40*x^30 + 48*x^27 + 80*x^24 + 112*x^21 + 96*x^18 + 96*x^15 + 24*x^12 + 96*x^9 + 16*x^6 + 96*x^3 + 68 sage: L.<a> = QQ.extension(F) sage: v.extensions(L) [[ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 10*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation, [ 2-adic valuation, v(x) = 1/24, v(x^24 + 4*x^18 + 2*x^12 + 12*x^6 + 8*x^3 + 6) = 29/8 ]-adic valuation] """ if self.domain() is ring: return [self] domain_fraction_field = _fraction_field(self.domain()) if domain_fraction_field is not self.domain(): if domain_fraction_field.is_subring(ring): return pAdicValuation(domain_fraction_field, self).extensions(ring) if self.domain().is_subring(ring): from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing if is_PolynomialQuotientRing(ring): if is_PolynomialQuotientRing(self.domain()): if self.domain().modulus() == ring.modulus(): base_extensions = self._base_valuation.extensions( self._base_valuation.domain().change_ring( self._base_valuation.domain().base_ring( ).fraction_field())) return [ pAdicValuation(ring, base._initial_approximation) for base in base_extensions ] if ring.base_ring() is self.domain(): from sage.categories.all import IntegralDomains if ring in IntegralDomains(): return self._extensions_to_quotient(ring) elif self.domain().is_subring(ring.base_ring()): return sum([ w.extensions(ring) for w in self.extensions(ring.base_ring()) ], []) from sage.rings.number_field.number_field import is_NumberField if is_NumberField(ring.fraction_field()): if ring.base_ring().fraction_field() is self.domain( ).fraction_field(): from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace parent = DiscretePseudoValuationSpace(ring) approximants = self.mac_lane_approximants( ring.fraction_field().relative_polynomial( ).change_ring(self.domain()), assume_squarefree=True, require_incomparability=True) return [ pAdicValuation(ring, approximant, approximants) for approximant in approximants ] if ring.base_ring() is not ring and self.domain().is_subring( ring.base_ring()): return sum([ w.extensions(ring) for w in self.extensions(ring.base_ring()) ], []) return super(pAdicValuation_base, self).extensions(ring)
def create_key_and_extra_args(self, domain, prime): r""" Create a unique key which identifies the valuation given by ``prime`` on ``domain``. TESTS: We specify a valuation on a function field by two different means and get the same object:: sage: K.<x> = FunctionField(QQ) sage: v = K.valuation(x - 1) # indirect doctest sage: R.<x> = QQ[] sage: w = GaussValuation(R, valuations.TrivialValuation(QQ)).augmentation(x - 1, 1) sage: K.valuation(w) is v True The normalization is, however, not smart enough, to unwrap substitutions that turn out to be trivial:: sage: w = GaussValuation(R, QQ.valuation(2)) sage: w = K.valuation(w) sage: w is K.valuation((w, K.hom([~K.gen()]), K.hom([~K.gen()]))) False """ from sage.categories.function_fields import FunctionFields if domain not in FunctionFields(): raise ValueError("Domain must be a function field.") if isinstance(prime, tuple): if len(prime) == 3: # prime is a triple of a valuation on another function field with # isomorphism information return self.create_key_and_extra_args_from_valuation_on_isomorphic_field(domain, prime[0], prime[1], prime[2]) from sage.rings.valuation.valuation_space import DiscretePseudoValuationSpace if prime.parent() is DiscretePseudoValuationSpace(domain): # prime is already a valuation of the requested domain # if we returned (domain, prime), we would break caching # because this element has been created from a different key # Instead, we return the key that was used to create prime # so the caller gets back a correctly cached version of prime if not hasattr(prime, "_factory_data"): raise NotImplementedError("Valuations on function fields must be unique and come out of the FunctionFieldValuation factory but %r has been created by other means"%(prime,)) return prime._factory_data[2], {} if prime in domain: # prime defines a place return self.create_key_and_extra_args_from_place(domain, prime) if prime.parent() is DiscretePseudoValuationSpace(domain._ring): # prime is a discrete (pseudo-)valuation on the polynomial ring # that the domain is constructed from return self.create_key_and_extra_args_from_valuation(domain, prime) if domain.base_field() is not domain: # prime might define a valuation on a subring of domain and have a # unique extension to domain base_valuation = domain.base_field().valuation(prime) return self.create_key_and_extra_args_from_valuation(domain, base_valuation) from sage.rings.ideal import is_Ideal if is_Ideal(prime): raise NotImplementedError("a place can not be given by an ideal yet") raise NotImplementedError("argument must be a place or a pseudo-valuation on a supported subring but %r does not satisfy this for the domain %r"%(prime, domain))