def _fraction_field(ring): r""" Return a fraction field of ``ring``. EXAMPLES: This works around some annoyances with ``ring.fraction_field()``:: sage: R.<x> = ZZ[] sage: S = R.quo(x^2 + 1) sage: S.fraction_field() Fraction Field of Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1 sage: from mac_lane.padic_valuation import _fraction_field sage: _fraction_field(S) Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 + 1 """ from sage.categories.all import Fields if ring in Fields(): return ring from sage.rings.polynomial.polynomial_quotient_ring import is_PolynomialQuotientRing if is_PolynomialQuotientRing(ring): from sage.categories.all import IntegralDomains if ring in IntegralDomains(): return ring.base().change_ring(ring.base_ring().fraction_field()).quo(ring.modulus()) return ring.fraction_field()
def extensions(self, ring): r""" Return the extensions of this valuation to ``ring``. EXAMPLES:: sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone sage: v = pAdicValuation(ZZ, 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: pAdicValuation(M, 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: pAdicValuation(QQ, 2).extensions(L) [2-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) else: 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 valuation_space import DiscretePseudoValuationSpace parent = DiscretePseudoValuationSpace(ring) approximants = self.mac_lane_approximants(ring.fraction_field().relative_polynomial().change_ring(self.domain()), assume_squarefree=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_object(self, version, key): ring, polynomial, names = key R = ring.base_ring() from sage.categories.all import IntegralDomains if R in IntegralDomains(): try: is_irreducible = polynomial.is_irreducible() except NotImplementedError: # is_irreducible sometimes not implemented pass else: if is_irreducible: from sage.categories.all import Fields if R in Fields(): from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_field return PolynomialQuotientRing_field(ring, polynomial, names) else: from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_domain return PolynomialQuotientRing_domain(ring, polynomial, names) from sage.rings.polynomial.polynomial_quotient_ring import PolynomialQuotientRing_generic return PolynomialQuotientRing_generic(ring, polynomial, names)
def is_injective(self): r""" TESTS:: sage: sys.path.append(os.getcwd()); from mac_lane import * # optional: standalone sage: QQ.coerce_map_from(ZZ).is_injective() # indirect doctest True sage: Hom(ZZ,QQ['x']).natural_map().is_injective() True sage: R.<x> = ZZ[] sage: R.<xbar> = R.quo(x^2+x+1) sage: Hom(ZZ,R).natural_map().is_injective() True sage: R.<x> = QQbar[] sage: R.coerce_map_from(QQbar).is_injective() True """ from sage.categories.all import Fields, IntegralDomains from sage.rings.number_field.order import AbsoluteOrder from sage.rings.polynomial.polynomial_ring import is_PolynomialRing # this should be implemented as far down as possible if self.domain() in Fields(): return True if self.domain() == sage.all.ZZ and self.codomain().characteristic() == 0: return True if isinstance(self.domain(), AbsoluteOrder) and self(self.domain().gen()) != 0 and self.codomain() in IntegralDomains(): return True # this should be implemented somewhere else if is_PolynomialRing(self.codomain()) and self.codomain().base_ring() is self.domain(): return True coercion = self.codomain().coerce_map_from(self.domain()) if coercion is not None: try: return coercion.is_injective() except NotImplementedError: # PolynomialBaseringInjection does not implement is_surjective/is_injective if isinstance(coercion, sage.categories.map.FormalCompositeMap): if all([f.is_injective() for f in list(coercion)]): return True except AttributeError: # DefaultConvertMap_unique does not implement is_injective/surjective at all pass raise NotImplementedError
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)